summaryrefslogtreecommitdiff
path: root/gps2udp.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2013-05-01 13:37:46 -0400
committerEric S. Raymond <esr@thyrsus.com>2013-05-01 13:37:46 -0400
commita56272e6490a46f04013f2a58cbfbc45e21c1c06 (patch)
tree5bfdc3c76bd93ee97c862424e9c88a6b24d5e220 /gps2udp.c
parent981e23a67af4e9c5d225f07979eb81dcc00d2291 (diff)
downloadgpsd-a56272e6490a46f04013f2a58cbfbc45e21c1c06.tar.gz
Splint cleanup, spelling, and style fixes.
Diffstat (limited to 'gps2udp.c')
-rw-r--r--gps2udp.c547
1 files changed, 298 insertions, 249 deletions
diff --git a/gps2udp.c b/gps2udp.c
index 271ee2ac..cb1b0655 100644
--- a/gps2udp.c
+++ b/gps2udp.c
@@ -4,10 +4,10 @@
* Dump NMEA to UDP socket for AIShub
* gps2udp -u data.aishub.net:1234
*
- * Author Fulup Ar Foll (directly inspired from gpspipe.c from gpsd official distrib)
- * Date 01-march-2013
+ * Author: Fulup Ar Foll (directly inspired from gpspipe.c)
+ * Date: 2013-03-01
*
- * This file is Copyright (c) 2010 by the GPSD project
+ * This file is Copyright (c) 2013 by the GPSD project
* BSD terms apply: see the file COPYING in the distribution root for details.
*
*/
@@ -32,11 +32,15 @@
#include "gpsdclient.h"
#include "revision.h"
+#ifndef S_SPLINT_S
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
+#endif /* S_SPLINT_S */
+#define MAX_TIME_LEN 80
+#define MAX_GPSD_RETRY 10
static struct gps_data_t gpsdata;
@@ -44,18 +48,18 @@ static struct gps_data_t gpsdata;
#define MAX_UDP_DEST 5
static struct sockaddr_in remote[MAX_UDP_DEST];
static int sock[MAX_UDP_DEST];
-static int udpchanel;
+static int udpchannel;
/* gpsclient source */
-#define MAX_GPSD_RETRY 10
static struct fixsource_t gpsd_source;
-static int flags;
-static int debug=0;
-static int aisonly=0;
+static unsigned int flags;
+static int debug = 0;
+static bool aisonly = false;
-// return local time hh:mm:ss
-static char* time2string (void) {
- #define MAX_TIME_LEN 80
+/*@-statictrans@*/
+/*@observer@*/static char* time2string(void)
+/* return local time hh:mm:ss */
+{
static char buffer[MAX_TIME_LEN];
time_t curtime;
struct tm *loctime;
@@ -66,48 +70,57 @@ static char* time2string (void) {
/* Convert it to local time representation. */
loctime = localtime (&curtime);
-
/* Print it out in a nice format. */
- strftime (buffer, MAX_TIME_LEN, "%H:%M:%S", loctime);
+ (void)strftime (buffer, MAX_TIME_LEN, "%H:%M:%S", loctime);
-return (buffer);
+ return (buffer);
}
+/*@+statictrans@*/
-static int send_udp (char *nmeastring, int ind) {
- char message [255];
- char *buffer;
- int status, chanel;
-
- /* if string lenght is unknow make a copy and compute it */
- if (ind == 0) {
- /* compute message size and add 0x0a 0x0d */
- for (ind=0; nmeastring [ind] != '\0'; ind ++) {
- if (ind > (int)sizeof (message)) {
- fprintf(stderr, "gps2udp: too big [%s] \n", nmeastring);
- return -1;
- }
- message[ind] = nmeastring[ind];
- }
- buffer = message;
- } else {
- /* use directly nmeastring but change terminition */
- buffer = nmeastring;
- ind=ind-1;
- }
- /* Add termination to NMEA feed for AISHUB */
- buffer[ind]='\n'; ind ++;
- buffer[ind]='\r'; ind ++;
- buffer[ind]='\0';
-
- /* send message on udp chanel */
- for (chanel=0; chanel < udpchanel; chanel ++) {
- status=sendto(sock[chanel],buffer,ind,0,&remote[chanel],sizeof(remote));
- if (status < ind) {
- fprintf(stderr, "gps2udp: fail to send [%s] \n", nmeastring);
- return -1;
- }
- }
-return 0;
+static int send_udp (char *nmeastring, size_t ind)
+{
+ char message [255];
+ char *buffer;
+ int channel;
+ ssize_t status;
+
+ /* if string length is unknow make a copy and compute it */
+ if (ind == 0) {
+ /* compute message size and add 0x0a 0x0d */
+ for (ind=0; nmeastring [ind] != '\0'; ind ++) {
+ if (ind > sizeof(message)) {
+ fprintf(stderr, "gps2udp: too big [%s] \n", nmeastring);
+ return -1;
+ }
+ message[ind] = nmeastring[ind];
+ }
+ buffer = message;
+ } else {
+ /* use directly nmeastring but change terminition */
+ buffer = nmeastring;
+ ind = ind-1;
+ }
+ /* Add termination to NMEA feed for AISHUB */
+ buffer[ind] = '\n'; ind++;
+ buffer[ind] = '\r'; ind++;
+ buffer[ind] = '\0';
+
+ /* send message on udp channel */
+ /*@-type@*/
+ for (channel=0; channel < udpchannel; channel ++) {
+ status = sendto(sock[channel],
+ buffer,
+ ind,
+ 0,
+ &remote[channel],
+ (int)sizeof(remote));
+ if (status < (ssize_t)ind) {
+ (void)fprintf(stderr, "gps2udp: failed to send [%s] \n", nmeastring);
+ return -1;
+ }
+ }
+ /*@=type@*/
+ return 0;
}
@@ -117,39 +130,41 @@ static int open_udp(char **hostport)
struct hostent *hp;
char *hostname = NULL;
char *portname = NULL;
- int portnum, chanel;
-
- for (chanel=0; chanel <udpchanel; chanel ++) {
-
- /* parse argement */
- hostname = strsep(&hostport[chanel], ":");
- portname = strsep(&hostport[chanel], ":");
- if ((hostname == NULL) || (portname == NULL)) {
- fprintf(stderr, "gps2udp: syntaxe is [-u hostname:port]\n");
- return (-1);
- }
-
- portnum= strtol (portname,NULL,0);
- if (errno != 0) {
- fprintf(stderr, "gps2udp: syntaxe is [-u hostname:port] [%s] is not a valid port number\n",portname);
- return (-1);
- }
-
- sock[chanel]= socket(AF_INET, SOCK_DGRAM, 0);
- if (sock[chanel] < 0) {
- fprintf(stderr, "gps2udp: error creating UDP socket\n");
- return (-1);
- }
-
- remote[chanel].sin_family = AF_INET;
- hp = gethostbyname(hostname);
- if (hp==NULL) {
- fprintf(stderr, "gps2udp: syntaxe is [-u hostname:port] [%s] is not a valid hostnamer\n",hostname);
- return (-1);
- }
-
- bcopy((char *)hp->h_addr, (char *)&remote[chanel].sin_addr, hp->h_length);
- remote[chanel].sin_port = htons(portnum);
+ int portnum, channel;
+
+ for (channel=0; channel <udpchannel; channel ++)
+ {
+ /* parse argument */
+ /*@-unrecog@*/
+ hostname = strsep(&hostport[channel], ":");
+ portname = strsep(&hostport[channel], ":");
+ /*@=unrecog@*/
+ if ((hostname == NULL) || (portname == NULL)) {
+ (void)fprintf(stderr, "gps2udp: syntax is [-u hostname:port]\n");
+ return (-1);
+ }
+
+ portnum = atoi(portname);
+ if (errno != 0) {
+ (void)fprintf(stderr, "gps2udp: syntax is [-u hostname:port] [%s] is not a valid port number\n",portname);
+ return (-1);
+ }
+
+ sock[channel]= socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock[channel] < 0) {
+ fprintf(stderr, "gps2udp: error creating UDP socket\n");
+ return (-1);
+ }
+
+ remote[channel].sin_family = (sa_family_t)AF_INET;
+ hp = gethostbyname(hostname);
+ if (hp==NULL) {
+ fprintf(stderr, "gps2udp: syntaxe is [-u hostname:port] [%s] is not a valid hostnamer\n",hostname);
+ return (-1);
+ }
+
+ bcopy((char *)hp->h_addr, (char *)&remote[channel].sin_addr, hp->h_length);
+ remote[channel].sin_port = htons((in_port_t)portnum);
}
return (0);
}
@@ -171,186 +186,205 @@ static void usage(void)
);
}
-/* loop until we connect with GPSd */
-static void connect2gpsd (int restart) {
- int delay,status;
+static void connect2gpsd(bool restart)
+/* loop until we connect with gpsd */
+{
+ int status;
+ unsigned int delay;
if (restart) {
- gps_close (&gpsdata);
- if (debug > 0) fprintf(stdout, "gps2udp [%s] reset gpsd connection\n", time2string());
-
+ (void)gps_close(&gpsdata);
+ if (debug > 0)
+ (void)fprintf(stdout,
+ "gps2udp [%s] reset gpsd connection\n",
+ time2string());
}
/* loop until we reach GPSd */
- for (delay=10;;delay=delay*2) {
+ for (delay = 10; ; delay = delay*2) {
status = gps_open(gpsd_source.server, gpsd_source.port, &gpsdata);
if (status != 0) {
- fprintf(stderr, "gps2udp [%s] connection failed at %s:%s\n",
- time2string(), gpsd_source.server, gpsd_source.port);
- sleep (delay);
+ (void)fprintf(stderr,
+ "gps2udp [%s] connection failed at %s:%s\n",
+ time2string(), gpsd_source.server, gpsd_source.port);
+ (void)sleep(delay);
} else {
- if (debug > 0) fprintf(stdout, "gps2udp [%s] connect to gpsd %s:%s\n",
- time2string(), gpsd_source.server, gpsd_source.port);
- break;
+ if (debug > 0)
+ (void)fprintf(stdout, "gps2udp [%s] connect to gpsd %s:%s\n",
+ time2string(), gpsd_source.server, gpsd_source.port);
+ break;
}
}
/* select the right set of gps data */
- gps_stream(&gpsdata, flags, gpsd_source.device);
+ (void)gps_stream(&gpsdata, flags, gpsd_source.device);
}
-/* get date from gpsd */
-static int read_gpsd (char *message, int len) {
-
- struct timeval tv;
- fd_set fds,master;
- int result,ind;
- char c;
- int retry=0;
+/*@+voidabstract@*/
+static ssize_t read_gpsd(char *message, size_t len)
+/* get data from gpsd */
+{
+ struct timeval tv;
+ fd_set fds,master;
+ int result, ind;
+ char c;
+ int retry=0;
// prepare select structure */
FD_ZERO(&master);
FD_SET(gpsdata.gps_fd, &master);
-
- /* loop until we get some data or an error */
- for (ind=0; ind<len;) {
-
+ /* loop until we get some data or an error */
+ for (ind = 0; ind < (int)len;) {
/* prepare for a blocking read with a 10s timeout */
tv.tv_sec = 10;
tv.tv_usec = 0;
- memcpy(&fds,&master,sizeof(fd_set));
+ memcpy(&fds, &master, sizeof(fd_set));
result = select(gpsdata.gps_fd+1, &fds, NULL, NULL, &tv);
- switch (result) {
- case 1: /* we have data waiting let's process them */
-
- result = (int)read(gpsdata.gps_fd, &c, 1);
-
- /* If we lost gpsd connection reset it */
- if (result != 1) {
- connect2gpsd (true);
- }
+ switch (result)
+ {
+ case 1: /* we have data waiting, let's process them */
+ result = (int)read(gpsdata.gps_fd, &c, 1);
+
+ /* If we lost gpsd connection reset it */
+ if (result != 1) {
+ connect2gpsd (true);
+ }
- if ((c == '\n') || (c == '\r')){
- message[ind]='\0';
-
- if (ind > 0) {
- if (retry > 0) {
- if (debug ==1) fprintf (stdout,"\r");
- if (debug > 1) fprintf (stdout," [%s] No Data for: %ds\n",time2string(), retry*10);
- }
-
- if (aisonly && message[0] != '!') {
- if (debug >1) fprintf (stdout,".... [%s %d] %s\n", time2string(), ind, message);
- return (0);
- }
- }
+ if ((c == '\n') || (c == '\r')){
+ message[ind]='\0';
+
+ if (ind > 0) {
+ if (retry > 0) {
+ if (debug ==1)
+ (void)fprintf (stdout,"\r");
+ if (debug > 1)
+ (void)fprintf(stdout,
+ " [%s] No Data for: %ds\n",
+ time2string(), retry*10);
+ }
+
+ if (aisonly && message[0] != '!') {
+ if (debug >1)
+ (void)fprintf(stdout,
+ ".... [%s %d] %s\n", time2string(),
+ ind, message);
+ return(0);
+ }
+ }
- return (ind+1);
- } else {
- message[ind]= c;
- ind ++;
- }
- break;
-
- case 0: /* no data fail in timeout */
- retry ++;
- /* if too many empty packet are received reset gpsd connection */
- if (retry > MAX_GPSD_RETRY) {
- connect2gpsd (true);
- retry=0;
- }
- if (debug > 0) (void)write (1,".",1);
-
- break;
-
- default:/* we lost connection with gpsd */
- connect2gpsd (true);
- break;
+ return ((ssize_t)ind+1);
+ } else {
+ message[ind]= c;
+ ind++;
+ }
+ break;
+
+ case 0: /* no data fail in timeout */
+ retry++;
+ /* if too many empty packets are received reset gpsd connection */
+ if (retry > MAX_GPSD_RETRY)
+ {
+ connect2gpsd(true);
+ retry = 0;
+ }
+ if (debug > 0)
+ (void)write (1, ".", 1);
+ break;
+
+ default: /* we lost connection with gpsd */
+ connect2gpsd(true);
+ break;
}
- }
- message [ind]='\0';
- fprintf (stderr,"\n gps2udp: message to big [%s]\n", message);
- return (-1);
+ }
+ message[ind] = '\0';
+ (void)fprintf (stderr,"\n gps2udp: message too big [%s]\n", message);
+ return(-1);
}
+/*@=voidabstract@*/
+
+static unsigned char AISto6bit(unsigned char c)
+/* 6 bits decoding of AIS payload */
+{
+ unsigned char cp = c;
-// 6 bits decoding of AIS payload
-static unsigned char AISto6bit(char c) {
- if(c < 0x30)
+ if(c < (unsigned char)0x30)
return (unsigned char)-1;
- if(c > 0x77)
+ if(c > (unsigned char)0x77)
return (unsigned char)-1;
- if((0x57 < c) && (c < 0x60))
+ if(((unsigned char)0x57 < c) && (c < (unsigned char)0x60))
return (unsigned char)-1;
- unsigned char cp = c;
- cp += 0x28;
+ cp += (unsigned char)0x28;
- if(cp > 0x80)
- cp += 0x20;
+ if(cp > (unsigned char)0x80)
+ cp += (unsigned char)0x20;
else
- cp += 0x28;
- return (unsigned char)(cp & 0x3f);
+ cp += (unsigned char)0x28;
+ return (unsigned char)(cp & (unsigned char)0x3f);
}
-// get mmsi from ais bit string
-static int AISGetInt(unsigned char* bitbytes, int sp, int len) {
- int acc = 0;
- int s0p = sp-1; // to zero base
- int cp, cx, c0, i, cs;
+static unsigned int AISGetInt(unsigned char *bitbytes, unsigned int sp, unsigned int len)
+/* get MMSI from AIS bit string */
+{
+ unsigned int acc = 0;
+ unsigned int s0p = sp-1; // to zero base
+ unsigned int cp, cx, c0, i;
for(i=0 ; i<len ; i++)
{
acc = acc << 1;
cp = (s0p + i) / 6;
- cx = (int)bitbytes[cp]; // what if cp >= byte_length?
- cs = 5 - ((s0p + i) % 6);
+ cx = (unsigned int)bitbytes[cp]; // what if cp >= byte_length?
c0 = (cx >> (5 - ((s0p + i) % 6))) & 1;
acc |= c0;
}
return acc;
-
}
-
-int main(int argc, char **argv) {
+/*@-compdef -usedef@*/
+int main(int argc, char **argv)
+{
bool daemonize = false;
long count = -1;
int option, status;
char *udphostport[MAX_UDP_DEST];
flags = WATCH_ENABLE;
- while ((option = getopt(argc, argv, "?habnjcvl:u:d:")) != -1) {
-
+ while ((option = getopt(argc, argv, "?habnjcvl:u:d:")) != -1)
+ {
switch (option) {
case 'd':
- debug= strtol(optarg, 0, 0);
+ debug = atoi(optarg);
break;
case 'n':
- if (debug >0) fprintf (stdout, "NMEA selected\n");
+ if (debug >0)
+ (void)fprintf(stdout, "NMEA selected\n");
flags |= WATCH_NMEA;
break;
case 'j':
- if (debug >0) fprintf (stdout, "JASON selected\n");
+ if (debug >0)
+ (void)fprintf(stdout, "JSON selected\n");
flags |= WATCH_JSON;
break;
case 'a':
- aisonly=1;
+ aisonly = true;
break;
case 'c':
- count = strtol(optarg, 0, 0);
+ count = atol(optarg);
break;
case 'b':
daemonize = true;
break;
case 'u':
- if (udpchanel > MAX_UDP_DEST) {
- fprintf (stderr, "gps2udp: to many UDP destination (max=%d)\n",MAX_UDP_DEST);
+ if (udpchannel > MAX_UDP_DEST) {
+ (void)fprintf(stderr,
+ "gps2udp: too many UDP destinations (max=%d)\n",
+ MAX_UDP_DEST);
} else {
- udphostport [udpchanel]= optarg;
- udpchanel ++;
+ udphostport[udpchannel++] = optarg;
}
break;
case 'v':
@@ -366,83 +400,98 @@ int main(int argc, char **argv) {
}
/* Grok the server, port, and device. */
- if (optind < argc) gpsd_source_spec(argv[optind], &gpsd_source);
- else gpsd_source_spec(NULL, &gpsd_source);
- if (gpsd_source.device != NULL) flags |= WATCH_DEVICE;
+ if (optind < argc)
+ gpsd_source_spec(argv[optind], &gpsd_source);
+ else
+ gpsd_source_spec(NULL, &gpsd_source);
+ if (gpsd_source.device != NULL)
+ flags |= WATCH_DEVICE;
/* check before going background if we can connect to gpsd */
- connect2gpsd (false);
+ connect2gpsd(false);
/* Open UDP port */
- if (udpchanel > 0) {
+ if (udpchannel > 0) {
status = open_udp(udphostport);
if (status !=0) exit (1);
}
/* Daemonize if the user requested it. */
+ /*@-unrecog@*/
if (daemonize) {
if (daemon(0, 0) != 0) {
- fprintf(stderr, "gps2udp: demonization failed: %s\n", strerror(errno));
+ (void)fprintf(stderr,
+ "gps2udp: demonization failed: %s\n",
+ strerror(errno));
}
}
+ /*@=unrecog@*/
- /* Infinit loop to get date from GPSd and push them to AIShub */
- for (;;) {
-
- char buffer [512];
- int len;
+ /* infinite loop to get data from gpsd and push them to aggregators */
+ for (;;)
+ {
+ char buffer[512];
+ ssize_t len;
- len = read_gpsd (buffer, sizeof (buffer));
+ len = read_gpsd(buffer, sizeof(buffer));
- /* ignore empty message */
- if (len > 3) {
- if (debug > 0) {
- fprintf (stdout,"---> [%s] -- %s",time2string(),buffer);
-
- // Try to extract MMSI from AIS payload
- if (strncmp (buffer,"!AIVDM",6) == 0) {
- #define MAX_INFO 6
- char packet [512];
- char *adrpkt=packet;
- char *info [MAX_INFO];
- int i,j;
- unsigned int mmsi;
- unsigned char bitstrings [255];
-
- // strtok break original string
- strncpy (packet,buffer,sizeof(packet));
- for (j=0; j<MAX_INFO; j++) {
- info [j] = strsep (&adrpkt, ",");
- }
-
- for(i=0 ; i<(int)strlen(info[5]); i++) {
- if (i > (int) sizeof (bitstrings)) break;
- bitstrings[i] = AISto6bit(info[5][i]);
- }
-
- mmsi=AISGetInt (bitstrings, 9, 30);
- fprintf (stdout," MMSI=%9d", mmsi);
-
- }
- fprintf (stdout,"\n");
-
- }
-
- // send to all UDP destination
- if (udpchanel > 0) send_udp (buffer, len);
-
- // if we count messages check it now
- if (count >= 0) {
- if (count-- == 0) {
- /* completed count */
- fprintf (stderr, "gpsd2udp normal exit after [%d] packets\n",(int)count);
- exit (0);
+ /* ignore empty message */
+ if (len > 3)
+ {
+ if (debug > 0)
+ {
+ (void)fprintf (stdout,"---> [%s] -- %s",time2string(),buffer);
+
+ // Try to extract MMSI from AIS payload
+ if (strncmp (buffer,"!AIVDM",6) == 0)
+ {
+#define MAX_INFO 6
+ int i,j;
+ unsigned char packet[512];
+ unsigned char *adrpkt = packet;
+ unsigned char *info[MAX_INFO];
+ unsigned int mmsi;
+ unsigned char bitstrings [255];
+
+ // strtok break original string
+ (void)strncpy((char *)packet, buffer, sizeof(packet));
+ for (j=0; j<MAX_INFO; j++) {
+ info[j] = strsep(&adrpkt, ",");
+ }
+
+ for(i=0 ; i < (int)strlen((char *)info[5]); i++) {
+ if (i > (int) sizeof (bitstrings)) break;
+ bitstrings[i] = AISto6bit(info[5][i]);
+ }
+
+ mmsi=AISGetInt (bitstrings, 9, 30);
+ (void)fprintf(stdout," MMSI=%9u", mmsi);
+
+ }
+ fprintf(stdout,"\n");
}
- } // end count
+
+ // send to all UDP destinations
+ if (udpchannel > 0)
+ (void)send_udp(buffer, (size_t)len);
+
+ // if we count messages check it now
+ if (count >= 0) {
+ if (count-- == 0) {
+ /* completed count */
+ (void)fprintf(stderr,
+ "gpsd2udp: normal exit after %ld packets\n",count);
+ exit (0);
+ }
+ } // end count
} // end len > 3
- } // end for (;;)
+ } // end for (;;)
-// This is an infinite loop, should never be here
-fprintf (stderr, "gpsd2udp ERROR abnormal exit\n");
-exit (-1);
+ // This is an infinite loop, should never be here
+ /*@-unreachable@*/
+ fprintf (stderr, "gpsd2udp ERROR abnormal exit\n");
+ exit (-1);
}
+/*@=compdef =usedef@*/
+
+/* end */