/* DESC: This script sends the local GPS NMEA stream (incl. serial/checksum) to a remote UDP server. * Copyright (C) 2013-2015 NetModule AG, Switzerland */ void usage() { nb_syslog("Usage: gps-udp-client.are <server> <port>"); exit(1); } int connect_gpsd () { for (attempt = 0; attempt < 60; attempt++) { sleep(1); sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) { nb_syslog("Unable to create socket"); continue; } nb_syslog("Connecting to GPS daemon"); if (connect(sock, "127.0.0.1", 2947) < 0){ nb_syslog("Could not connect to GPS daemon"); close(sock); continue; } nb_syslog("Requesting raw NMEA stream"); if (send(sock, "R\n") < 0) { nb_syslog("Unable to request raw NMEA stream"); close(sock); continue; } nb_syslog("Successfully connected to GPS daemon"); return sock; } return -1; } if (argc < 2) { usage(); } SERVER = trim((string) argv[1]); PORT = (int) argv[2]; SERIAL = struct_get(nb_status("system"), "SERIAL_NUMBER"); if (SERIAL == "") { nb_syslog("Unable to obtain serial number"); exit(1); } gpsd = connect_gpsd(); if (gpsd < 0) { exit(1); } /* open UDP server socket */ server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (server < 0) { nb_syslog("Unable to open server socket"); close(gpsd); exit(1); } /* process NMEA stream */ nb_syslog("Processing NMEA data"); while (1) { /* wait for socket data */ rv = select(gpsd, 10); if (rv > 0) { data = recv(gpsd); len = strlen(data); } else if (rv < 0) { nb_syslog("select failed"); len = -1; } else { nb_syslog("nothing received"); len = -1; } if (len <= 0) { nb_syslog("Receive failed, re-connecting to GPS daemon"); close(gpsd); gpsd = connect_gpsd(); if (gpsd < 0) { exit(1); } } else { str = strcat("PNMID,", SERIAL); chars = explode(str); checksum = 0; for (i = 0; i < length(chars); i++) { c = ord(chars[i]); checksum ^= c; } sentence = sprintf("$%s*%02X\r\n", str, checksum); data = strcat(data, sentence); len = strlen(data); if (len > 0) { sent = sendto(server, data, SERVER, PORT); if (sent != len) { nb_syslog("Unable to send message to %s:%d", SERVER, PORT); } } } } close(gpsd); close(server); exit(0);