summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/util/Makefile.am7
-rw-r--r--src/util/gps_fwd.c182
2 files changed, 188 insertions, 1 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 3d87a32..3697358 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -1,7 +1,7 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS = -std=gnu99
-bin_PROGRAMS = libgsmd-tool cell_log
+bin_PROGRAMS = libgsmd-tool cell_log gps_fwd
libgsmd_tool_SOURCES = libgsmd-tool.c shell.c event.c pin.c atcmd.c \
$(top_srcdir)/src/gsmd/talloc.c
@@ -13,4 +13,9 @@ cell_log_SOURCES = cell_log.c \
cell_log_LDADD = $(top_builddir)/src/libgsmd/libgsmd.la
cell_log_LDFLAGS = -dynamic
+gps_fwd_SOURCES = gps_fwd.c \
+ $(top_srcdir)/src/gsmd/talloc.c
+gps_fwd_LDADD = $(top_builddir)/src/libgsmd/libgsmd.la
+gps_fwd_LDFLAGS = -dynamic
+
noinst_HEADERS = atcmd.h event.h pin.h shell.h
diff --git a/src/util/gps_fwd.c b/src/util/gps_fwd.c
new file mode 100644
index 0000000..3270c48
--- /dev/null
+++ b/src/util/gps_fwd.c
@@ -0,0 +1,182 @@
+/* GPS/AIS client extractor, forwad to gpsd via UDP
+ *
+ * (C) 2013 by Harald Welte <laforge@gnumonks.org>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <syslog.h>
+#include <stdint.h>
+#include <netdb.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <libgsmd/libgsmd.h>
+#include <libgsmd/event.h>
+#include <gsmd/usock.h>
+#include <gsmd/ts0705.h>
+#include <common/linux_list.h>
+
+#ifndef __GSMD__
+#define __GSMD__
+#include <gsmd/talloc.h>
+#undef __GSMD__
+#endif
+
+static int out_fd = -1;
+static FILE *outf;
+
+static int celllog_main(struct lgsm_handle *lgsmh)
+{
+ int rc;
+ char buf[8192+1];
+ fd_set readset;
+ int gsm_fd = lgsm_fd(lgsmh);
+
+ fcntl(gsm_fd, F_SETFD, O_NONBLOCK);
+ FD_ZERO(&readset);
+
+ while (1) {
+ fd_set readset;
+ FD_SET(gsm_fd, &readset);
+
+ rc = select(gsm_fd+1, &readset, NULL, NULL, NULL);
+ if (rc < 0)
+ break;
+
+ if (FD_ISSET(gsm_fd, &readset)) {
+ /* we've received something on the gsmd socket, pass it
+ * on to the library */
+ rc = read(gsm_fd, buf, sizeof(buf));
+ if (rc <= 0) {
+ syslog(LOG_ERR, "ERROR reading from gsm_fd\n");
+ break;
+ }
+ rc = lgsm_handle_packet(lgsmh, buf, rc);
+ if (rc < 0)
+ syslog(LOG_ERR, "ERROR processing packet: %d(%s)\n", rc, strerror(-rc));
+ }
+ fflush(outf);
+ }
+ return 0;
+}
+
+static int gps_handler(struct lgsm_handle *lh, int evt, struct gsmd_evt_auxdata *aux)
+{
+ int rc;
+
+ rc = fprintf(outf, "%s\r\n", aux->data);
+ if (rc < 0) {
+ syslog(LOG_ERR, "error %d during fprintf() on socket, aborting\n", rc);
+ exit(3);
+ }
+
+ return 0;
+}
+
+
+/* more or less a copy form libosmocore, we could simply make this a
+ * dependency... */
+static int out_sock_init(uint16_t family, uint16_t type, uint8_t proto,
+ const char *host, uint16_t port)
+{
+ int fd = -1, rc;
+ struct addrinfo hints, *result, *rp;
+ char portbuf[16];
+
+ sprintf(portbuf, "%u", port);
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = family;
+
+ rc = getaddrinfo(host, portbuf, &hints, &result);
+ if (rc != 0) {
+ syslog(LOG_ERR, "Error during getaddrinfo(%s:%d)\n",
+ host, port);
+ return -EINVAL;
+ }
+
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+
+ fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (fd < 0)
+ continue;
+
+ rc = connect(fd, rp->ai_addr, rp->ai_addrlen);
+ if (rc != -1 || (rc == -1 && errno == EINPROGRESS))
+ break;
+
+ close(fd);
+ }
+ freeaddrinfo(result);
+
+ if (rp == NULL) {
+ syslog(LOG_ERR, "unable to connect socket\n");
+ return -ENODEV;
+ }
+
+ return fd;
+}
+
+int main(int argc, char **argv)
+{
+ static struct lgsm_handle *lgsmh;
+ char *host;
+ int port;
+ int rc;
+
+ printf("gps_fwd - (C) 2013 by Harald Welte <laforge@gnumonks.org>.\n"
+ "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n");
+
+ if (argc < 3) {
+ fprintf(stderr, "You have to specify the remote hostname + port\n");
+ exit(2);
+ }
+
+ host = argv[1];
+ port = atoi(argv[2]);
+
+ openlog("gps_fwd", 0, LOG_LOCAL0);
+
+ lgsmh = lgsm_init(LGSMD_DEVICE_GSMD);
+ if (!lgsmh) {
+ fprintf(stderr, "Can't connect to gsmd\n");
+ exit(1);
+ }
+
+ lgsm_evt_handler_register(lgsmh, GSMD_EVT_GPS, &gps_handler);
+ lgsm_evt_handler_register(lgsmh, GSMD_EVT_AIS, &gps_handler);
+
+ out_fd = out_sock_init(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, host, port);
+ if (out_fd < 0)
+ exit(1);
+
+ outf = fdopen(out_fd, "w");
+
+ celllog_main(lgsmh);
+
+ exit(0);
+}
personal git repositories of Harald Welte. Your mileage may vary