wavecom/sysmocom: Directly send GPS/AIS via UDP to gpsd
This avoids having to have another client program which then passes messages from gsmd into gpsd. Rather, gpsd can directly receive the messages via UDP.
This commit is contained in:
parent
06253f3620
commit
805406e9fb
|
@ -26,6 +26,10 @@
|
|||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "gsmd.h"
|
||||
|
||||
#include <gsmd/gsmd.h>
|
||||
|
@ -37,6 +41,13 @@
|
|||
#include <gsmd/vendorplugin.h>
|
||||
#include <gsmd/unsolicited.h>
|
||||
|
||||
#define AISGPS_UDP_HOST "127.0.0.1"
|
||||
#define GPS_UDP_PORT 12345
|
||||
#define AIS_UDP_PORT 12346
|
||||
|
||||
static int gps_udp_fd = -1;
|
||||
static int ais_udp_fd = -1;
|
||||
|
||||
struct cell_info_fsq {
|
||||
uint8_t cur;
|
||||
uint8_t full;
|
||||
|
@ -144,11 +155,39 @@ struct gsmd_ucmd *usock_build_gps(uint8_t subtype, const char *data, uint16_t le
|
|||
return ucmd;
|
||||
}
|
||||
|
||||
const char *crlf = "\r\n";
|
||||
|
||||
static int send_crlf(int fd, const char *buf, int len)
|
||||
{
|
||||
struct iovec iov[2];
|
||||
struct msghdr mh;
|
||||
|
||||
if (len <= strlen(AIS_PFX))
|
||||
return 0;
|
||||
|
||||
len -= strlen(AIS_PFX);
|
||||
buf += strlen(AIS_PFX);
|
||||
|
||||
iov[0].iov_base = (void *) buf;
|
||||
iov[0].iov_len = len;
|
||||
iov[1].iov_base = (void *) crlf;
|
||||
iov[1].iov_len = strlen(crlf);
|
||||
|
||||
memset(&mh, 0, sizeof(mh));
|
||||
mh.msg_iov = iov;
|
||||
mh.msg_iovlen = ARRAY_SIZE(iov);
|
||||
|
||||
return sendmsg(fd, &mh, MSG_DONTWAIT);
|
||||
}
|
||||
|
||||
static int sgps_parse(const char *buf, int len, const char *param,
|
||||
struct gsmd *gsmd)
|
||||
{
|
||||
struct gsmd_ucmd *ucmd = usock_build_gps(GSMD_EVT_GPS, buf, len);
|
||||
struct gsmd_ucmd *ucmd;
|
||||
|
||||
send_crlf(gps_udp_fd, buf, len);
|
||||
|
||||
ucmd = usock_build_gps(GSMD_EVT_GPS, buf, len);
|
||||
if (!ucmd)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -161,8 +200,11 @@ static int sais_parse(const char *buf, int len, const char *param,
|
|||
struct gsmd *gsmd)
|
||||
{
|
||||
|
||||
struct gsmd_ucmd *ucmd = usock_build_gps(GSMD_EVT_AIS, buf, len);
|
||||
struct gsmd_ucmd *ucmd;
|
||||
|
||||
send_crlf(ais_udp_fd, buf, len);
|
||||
|
||||
ucmd = usock_build_gps(GSMD_EVT_AIS, buf, len);
|
||||
if (!ucmd)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -187,6 +229,26 @@ static int wavecom_initsettings(struct gsmd *g)
|
|||
{
|
||||
int rc = 0;
|
||||
struct gsmd_atcmd *cmd;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
gps_udp_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
ais_udp_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (gps_udp_fd < 0 || ais_udp_fd < 0)
|
||||
return -1;
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
inet_aton(AISGPS_UDP_HOST, &sin.sin_addr);
|
||||
|
||||
sin.sin_port = htons(GPS_UDP_PORT);
|
||||
rc = connect(gps_udp_fd, (struct sockaddr *)&sin, sizeof(sin));
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
sin.sin_port = htons(AIS_UDP_PORT);
|
||||
rc = connect(ais_udp_fd, (struct sockaddr *)&sin, sizeof(sin));
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* use +WREGC to enter "spy mode" (no transmit / registration) */
|
||||
rc |= gsmd_simplecmd(g, "AT+WREGC=0");
|
||||
|
|
Loading…
Reference in New Issue