summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gsmd/vendor_wavecom.c66
1 files changed, 64 insertions, 2 deletions
diff --git a/src/gsmd/vendor_wavecom.c b/src/gsmd/vendor_wavecom.c
index 1331053..883ea39 100644
--- a/src/gsmd/vendor_wavecom.c
+++ b/src/gsmd/vendor_wavecom.c
@@ -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");
personal git repositories of Harald Welte. Your mileage may vary