>From 4aaa3aaad2ec2424f25cd942f006329607c5a4c7 Mon Sep 17 00:00:00 2001
From: Fulup Ar Foll
Date: Fri, 1 Mar 2013 18:20:20 +0100
Subject: [PATCH 1/2] =?UTF-8?q?=20Committer:=20Fulup=20Ar=20Foll=20?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
gps2udp push gpsd data to multiple UDP host:port destination
It can send AIS data to: ais-hub, shipfinder, marinetraffic,....
---
SConstruct | 11 ++++++++---
leapseconds.cache | 34 +++++++++++++++++-----------------
2 files changed, 25 insertions(+), 20 deletions(-)
diff --git a/SConstruct b/SConstruct
index e5d1f54..506eb60 100644
--- a/SConstruct
+++ b/SConstruct
@@ -947,6 +947,9 @@ env.Depends(gpsmon, [compiled_gpsdlib, compiled_gpslib])
gpspipe = env.Program('gpspipe', ['gpspipe.c'], parse_flags=gpslibs)
env.Depends(gpspipe, compiled_gpslib)
+gps2udp = env.Program('gps2udp', ['gps2udp.c'], parse_flags=gpslibs)
+env.Depends(gps2udp, compiled_gpslib)
+
gpxlogger = env.Program('gpxlogger', ['gpxlogger.c'], parse_flags=gpslibs)
env.Depends(gpxlogger, compiled_gpslib)
@@ -956,7 +959,7 @@ env.Depends(lcdgps, compiled_gpslib)
cgps = env.Program('cgps', ['cgps.c'], parse_flags=gpslibs + ncurseslibs)
env.Depends(cgps, compiled_gpslib)
-binaries = [gpsd, gpsdecode, gpsctl, gpsdctl, gpspipe, gpxlogger, lcdgps]
+binaries = [gpsd, gpsdecode, gpsctl, gpsdctl, gpspipe, gps2udp, gpxlogger, lcdgps]
if ncurseslibs:
binaries += [cgps, gpsmon]
@@ -1175,6 +1178,7 @@ base_manpages = {
"gpsctl.1" : "gpsctl.xml",
"gpsdctl.8" : "gpsdctl.xml",
"gpspipe.1" : "gpspipe.xml",
+ "gps2udp.1" : "gps2udp.xml",
"gpsdecode.1" : "gpsdecode.xml",
"srec.5" : "srec.xml",
}
@@ -1220,7 +1224,7 @@ headerinstall = [ env.Install(installdir('includedir'), x) for x in ("libgpsmm.h
binaryinstall = []
binaryinstall.append(env.Install(installdir('sbindir'), [gpsd, gpsdctl]))
-binaryinstall.append(env.Install(installdir('bindir'), [gpsdecode, gpsctl, gpspipe, gpxlogger, lcdgps]))
+binaryinstall.append(env.Install(installdir('bindir'), [gpsdecode, gpsctl, gpspipe, gps2udp, gpxlogger, lcdgps]))
if ncurseslibs:
binaryinstall.append(env.Install(installdir('bindir'), [cgps, gpsmon]))
binaryinstall.append(LibraryInstall(env, installdir('libdir'), compiled_gpslib))
@@ -1326,6 +1330,7 @@ splint_table = [
('splint-gpsdctl',['gpsdctl.c'],'gpsdctl', ['']),
('splint-gpsmon',gpsmon_sources,'gpsmon', ['-exportlocal']),
('splint-gpspipe',['gpspipe.c'],'gpspipe', ['']),
+ ('splint-gps2udp',['gps2udp.c'],'gps2udp', ['']),
('splint-gpsdecode',['gpsdecode.c'],'gpsdecode', ['']),
('splint-gpxlogger',['gpxlogger.c'],'gpxlogger', ['']),
('splint-test_packet',['test_packet.c'],'test_packet test harness', ['']),
@@ -1569,7 +1574,7 @@ env.Alias('testregress', check)
webpages = Split('''www/installation.html
www/gpscat.html www/gpsctl.html www/gpsdecode.html
www/gpsd.html www/gpsd_json.html www/gpsfake.html www/gpsmon.html
- www/gpspipe.html www/gpsprof.html www/gps.html
+ www/gpspipe.html www/gps2udp.html www/gpsprof.html www/gps.html
www/libgpsd.html www/libgpsmm.html www/libgps.html
www/srec.html
www/AIVDM.html www/NMEA.html
diff --git a/leapseconds.cache b/leapseconds.cache
index 4d8e7f2..f7f9f49 100644
--- a/leapseconds.cache
+++ b/leapseconds.cache
@@ -1,17 +1,17 @@
-315532800
-362793599
-394329599
-425865599
-489023999
-567993600
-631152000
-662688000
-709948799
-741484799
-773020799
-820454400
-867715199
-915148800
-1136073600
-1230768000
-1341100799
+315532800 # ('1979-12-31T23:59:60')
+362793599 # ('1981-06-30T23:59:59')
+394329599 # ('1982-06-30T23:59:59')
+425865599 # ('1983-06-30T23:59:59')
+489023999 # ('1985-06-30T23:59:59')
+567993600 # ('1987-12-31T23:59:60')
+631152000 # ('1989-12-31T23:59:60')
+662688000 # ('1990-12-31T23:59:60')
+709948799 # ('1992-06-30T23:59:59')
+741484799 # ('1993-06-30T23:59:59')
+773020799 # ('1994-06-30T23:59:59')
+820454400 # ('1995-12-31T23:59:60')
+867715199 # ('1997-06-30T23:59:59')
+915148800 # ('1998-12-31T23:59:60')
+1136073600 # ('2005-12-31T23:59:60')
+1230768000 # ('2008-12-31T23:59:60')
+1341100799 # ('2012-06-30T23:59:59')
--
1.7.10.4
>From 1d1f9cfa90f7eb7518ade532b41aca032018c346 Mon Sep 17 00:00:00 2001
From: "Fulup.ArFoll"
Date: Fri, 1 Mar 2013 18:28:40 +0100
Subject: [PATCH 2/2] added gps2udp to support AIS push on aishub,
marintraffic, shipfinder, ...
---
gps2udp.c | 338 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
gps2udp.xml | 114 ++++++++++++++++++++
2 files changed, 452 insertions(+)
create mode 100644 gps2udp.c
create mode 100644 gps2udp.xml
diff --git a/gps2udp.c b/gps2udp.c
new file mode 100644
index 0000000..033f0da
--- /dev/null
+++ b/gps2udp.c
@@ -0,0 +1,338 @@
+/*
+ * gps2udp
+ *
+ * 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
+ *
+ * This file is Copyright (c) 2010 by the GPSD project
+ * BSD terms apply: see the file COPYING in the distribution root for details.
+ *
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifndef S_SPLINT_S
+#include
+#endif /* S_SPLINT_S */
+
+#include "gpsd.h"
+#include "gpsdclient.h"
+#include "revision.h"
+
+#include
+#include
+#include
+#include
+
+
+static struct gps_data_t gpsdata;
+
+/* UDP socket variables */
+#define MAX_UDP_DEST 5
+static struct sockaddr_in remote[MAX_UDP_DEST];
+static int sock[MAX_UDP_DEST];
+static int udpchanel;
+
+/* gpsclient source */
+static struct fixsource_t gpsd_source;
+static int flags;
+static int debug=0;
+static int aisonly=0;
+
+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 last 2 byte */
+ buffer = nmeastring;
+ ind=ind-2;
+ }
+ /* 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 open_udp(char **hostport)
+/* Open and bind udp socket to host */
+{
+ struct hostent *hp;
+ char *hostname = NULL;
+ char *portname = NULL;
+ int portnum, chanel;
+
+ for (chanel=0; chanel h_addr, (char *)&remote[chanel].sin_addr, hp->h_length);
+ remote[chanel].sin_port = htons(portnum);
+ }
+return (0);
+}
+
+static void usage(void)
+{
+ (void)fprintf(stderr,
+ "Usage: gps2udp [OPTIONS] [server[:port[:device]]]\n\n"
+ "-h Show this help.\n"
+ "-u Send UDP NMEA/JASON feed to host:port [multiple -u host:port accepted]"
+ "-n Feed NMEA.\n"
+ "-j Feed Jason.\n"
+ "-a Select !AISDM message only.\n"
+ "-c [count] exit after count packets.\n"
+ "-b Run in background as a daemon.\n"
+ "-d debug display packets.\n"
+ "-v Print version and exit.\n\n"
+ "You must specify one, or more, of -r, -R, or -w\n"
+ );
+}
+
+/* loop until we connect with GPSd */
+static void connect2gpsd (int restart) {
+ int delay,status;
+
+ if (restart) gps_close (&gpsdata);
+
+ /* loop until we reach GPSd */
+ for (delay=10;;delay=delay*2) {
+ status = gps_open(gpsd_source.server, gpsd_source.port, &gpsdata);
+ if (status != 0) {
+ fprintf(stderr, "gps2udp: lost gpsd connection at %s:%s\n",
+ gpsd_source.server, gpsd_source.port);
+ sleep (delay);
+ } else {
+ if (debug > 0) fprintf(stdout, "gps2udp: connected to gpsd %s:%s\n",
+ gpsd_source.server, gpsd_source.port);
+ break;
+ }
+ }
+ /* select the right set of gps data */
+ 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;
+
+ // 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 0) && (debug > 0)) fprintf (stdout," Retry=%d\n",retry);
+
+ if (aisonly && message[0] != '!') {
+ if (debug >0) fprintf (stdout,"info [%d] %s\n", ind, message);
+ return (0);
+ }
+
+ return (ind+1);
+ } else {
+ message[ind]= c;
+ }
+ break;
+
+ case 0: /* no data fail in timeout */
+ retry ++;
+ if (debug > 0) 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);
+}
+
+
+int main(int argc, char **argv) {
+ bool daemonize = false;
+ long count = 0;
+ int option, status;
+
+ char *udphostport[MAX_UDP_DEST];
+
+ flags = WATCH_ENABLE;
+ while ((option = getopt(argc, argv, "?habnjcdvl:u:")) != -1) {
+
+ switch (option) {
+ case 'd':
+ debug=1;
+ break;
+ case 'n':
+ if (debug >0) fprintf (stdout, "NMEA selected\n");
+ flags |= WATCH_NMEA;
+ break;
+ case 'j':
+ if (debug >0) fprintf (stdout, "JASON selected\n");
+ flags |= WATCH_JSON;
+ break;
+ case 'a':
+ aisonly=1;
+ break;
+ case 'c':
+ count = strtol(optarg, 0, 0);
+ 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);
+ } else {
+ udphostport [udpchanel]= optarg;
+ udpchanel ++;
+ }
+ break;
+ case 'v':
+ (void)fprintf(stderr, "%s: %s (revision %s)\n",
+ argv[0], VERSION, REVISION);
+ exit(0);
+ case '?':
+ case 'h':
+ default:
+ usage();
+ exit(1);
+ }
+ }
+
+ /* 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;
+
+ /* check before going background if we can connect to gpsd */
+ connect2gpsd (false);
+
+ /* Open UDP port */
+ if (udpchanel > 0) {
+ status = open_udp(udphostport);
+ if (status !=0) exit (1);
+ }
+
+ /* Daemonize if the user requested it. */
+ if (daemonize) {
+ if (daemon(0, 0) != 0) {
+ fprintf(stderr, "gps2udp: demonization failed: %s\n", strerror(errno));
+ }
+ }
+
+ /* Infinit loop to get date from GPSd and push them to AIShub */
+ for (;;) {
+ char buffer [1024];
+ int len;
+
+ len = read_gpsd (buffer, sizeof (buffer));
+
+ /* ignore empty message */
+ if (len > 3) {
+ if (debug > 0) fprintf (stdout,"---> [%d] -- %s\n", len,buffer);
+ if (udpchanel > 0) send_udp (buffer, len);
+ }
+
+ if (count > 0) {
+ if (count-- < 0) {
+ /* completed count */
+ fprintf (stderr, "gpsd2udp normal exit after [%d] packets\n",(int)count);
+ break;
+ }
+ }
+ }
+
+exit (0);
+}
diff --git a/gps2udp.xml b/gps2udp.xml
new file mode 100644
index 0000000..46ea69c
--- /dev/null
+++ b/gps2udp.xml
@@ -0,0 +1,114 @@
+
+
+
+
+01 Marc 2013
+
+gps2udp
+1
+The GPSD Project
+GPSD Documentation
+
+
+gps2udp
+tool to connect to gpsd and push sentences to aishub, marinetraffic, ....
+
+
+
+
+ gps2udp
+ -h
+ -n
+ -j
+ -a
+ -u hostname:udpport
+ -c count
+ -d
+ -v
+
+ server
+ :port
+ :device
+
+
+
+
+
+DESCRIPTION
+
+gps2udp is a tool to connect
+to gpsd and output the received
+sentences to one or many UDP host:port destinations. This makes the program useful to feed AIS information from gpsd to aishub, marinetraffic, shipfinder,...
+
+gps2udp does not require root
+privileges, and can be run concurrently with other tools connecting
+to the local gpsd without causing problems.
+
+The output will consist of one or both of NMEA (-n option) or Jason (-j option)
+gpsd sentences. The output are sent to one or many destinations host through a UDP network socket (-u host:port options) .
+
+Optionally a server, TCP/IP port number and remote device can be given.
+If omitted, gps2udp connects to localhost on
+the default port (2947) and watches all devices opened by
+gpsd.
+
+gps2udp may be run as a daemon (-b option).
+
+gps2udp is design to run smoothly in background, it reconnecte automatically to gpsd is ever this one is restarted. For debug perporse, there is an option to exit gracefully after a given count of packets (-c option).
+
+
+OPTIONS
+
+-h makes gps2udp print
+a usage message and exit.
+
+-n causes NMEA sentences to be output.
+-j causes JASON sentences to be output.
+-u host:port UDP destination for output sentenses (up to five destinations).
+
+-a output only AIS messages.
+-b causes gps2udp to run as a daemon.
+-n [count] causes [count] sentences to be output.
+gps2udp will then exit gracefully.
+
+-d prints sent packet on stdout.
+-v prints the version, then exits.
+
+
+
+EXAMPLE
+With a running gpsd accessible on the network
+
+gps2udp -d -n -u data.aishub.net:2222
+ will collect data from localhost:gpsd display them on stdout and send a copy to test aishub in NMEA format.
+
+gps2udp -a -n -b -u data.aishub.net 2222 -u 5.9.207.224 5321 -u 109.200.19.151 4001 vz-fulup.vpn:2947 will collect data from a remote gpsd located on vz-fulup.vpn host, will filter AIS messages and send them to 3 destination [aishub, marinetraffic, shipfinder] in NMEA format, command is running in background mode
+
+
+SEE ALSO
+
+gpsd8,
+gps1,
+libgps3,
+libgpsd3,
+gpsprof1,
+gpsfake1,
+gpsctl1,
+gpscat1.
+gpsmon1.
+
+
+
+AUTHOR
+
+Fulup Ar Foll fulup (Ã ) sinagot.net.
+
+
+
+
+
--
1.7.10.4