/* DESC: This script sends the local GPS NMEA stream to a remote UDP server * (including device identity). * In addition, a Telit module is used to provide the GPRMC frame from the * GNSS data block using a regular expression. * Copyright (C) 2013-2025 NetModule AG, Switzerland */ ############################################################################### DEBUG=false; # Enable debugging with true or disable with false DEBUGALL=false; # Enable debugging with true or disable with false ############################################################################### release_point = 0; void usage() { nb_syslog("usage: gps-broadcast.are "); printf("No server IP address or port was entered \n"); exit(1); } if (argc < 2) { usage(); } SERVER = trim((string) argv[1]); PORT = (int) argv[2]; int gpsd_request (int fd) { nb_syslog("Requesting NMEA stream"); if (send(fd, "R\n") != 2) { nb_syslog("ERROR: cannot send to gpsd"); return -1; } return 0; } int gpsd_init () { /* connect to gpsd */ fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd < 0) { nb_syslog("ERROR: unable to open socket to gpsd"); return -1; } if (connect(fd, "127.0.0.1", 2947) < 0){ nb_syslog("ERROR: unable to connect to gpsd"); close(fd); return -1; } if (gpsd_request(fd) != 0) { close(fd); return -1; } return fd; } void gpsd_uninit (int fd) { if (fd >= 0) { close(fd); } } int server_init () { /* open UDP server socket */ fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { nb_syslog("ERROR: unable to open server socket"); return -1; } else { return fd; } } void server_uninit (int fd) { if (fd >= 0) { close(fd); } } int gpsd_process (int gpsd, int server) { /* process NMEA stream */ nb_syslog("Processing NMEA data"); while(1) { /* wait for client socket data */ rv = select(gpsd, 3); if (rv == -1) { nb_syslog("ERROR: select failed"); return -1; } else if (rv == 0) { /* nb_syslog("nothing received"); */ continue; } data = recv(gpsd); if(DEBUG || DEBUGALL)printf("The raw data frames from the GNSS module:\n%s\n",data); status = nb_status("wwan"); info = struct_get(status, "MOBILE1_MODULE_INFO"); info = right(info,strlen(info)-14); len = strlen(info); temp = len - 6; info = left(info,strlen(info)-temp); if(DEBUGALL)printf("Querying the modem module in the router: %s\n", info); if (info == "Telit "){ if(DEBUGALL)printf("A Telit module was installed!\n\n"); len = strlen(data); if (len > 200){ if(DEBUG || DEBUGALL)printf("The GNSS data block is larger than 200 bytes: %s bytes\n",len); data_gprmc = pcre_compile("\\$GPRMC.*\\r\\n?", 0); m = pcre_exec( data_gprmc, data, 0); len = strlen(m[0]); if(DEBUGALL)printf("Check whether the GPRMC frame is present in the GNSS data block: %s bytes\n",len); if (len != 0){ if(DEBUG || DEBUGALL)printf("The data block is searched for the GPRMC frame using a regex rule:\n%s\n", m[0]); release_point = 1; } else { if(DEBUGALL)printf("The GPRMC frame does not contain GNSS data blocks: %s bytes\n",len); } } } if (strlen(data) == 0) { nb_syslog("ERROR: no NMEA data"); return -1; } status = nb_status("system"); serial = struct_get(status, "SERIAL_NUMBER"); sentence = strcat("PNMID,", serial); sentenceLength = strlen(sentence); sentenceArray = explode(sentence); checksum = 0; for (i = 0; i < sentenceLength; i++) { currentChar = ord(sentenceArray[i]); checksum ^= currentChar; } checksum = sprintf("%02X",checksum); nmsentence = strcat("$", sentence , "*", checksum ,"\r\n"); if (release_point == 0){ data = strcat(data, nmsentence); if(DEBUG || DEBUGALL)printf("The GNSS frame has been extended with the serial number from the router:\n%s\n",data); } if (release_point == 1){ if(DEBUG || DEBUGALL)printf("Approval for the GPRMC frame: %s\n",release_point); m = strcat(m[0], nmsentence); if(DEBUG || DEBUGALL)printf("The GPRMC frame has been extended with the serial number from the router:\n%s\n",m); release_point = 0; data = m; } len = strlen(data); if (len <= 0) continue; sent = sendto(server, data, SERVER, PORT); if(DEBUG || DEBUGALL)printf("This GNSS data frame is sent: %s bytes\n\n\n",sent); if (sent != len) { nb_syslog("ERROR: unable to send to %s:%d", SERVER, PORT); return -1; } } return 0; } /* main */ while (1) { nb_syslog("Initializing connection to gpsd"); gpsd = gpsd_init(); server = server_init(); if (gpsd >= 0 && server >= 0) { gpsd_process(gpsd, server); } server_uninit(server); gpsd_uninit(gpsd); sleep(5); } exit(0);