This is an old revision of the document!
Send the local GPS NMEA stream to a remote UDP server
Goal
This script sends the local GPS NMEA stream to a remote UDP server. In addition, the GNSS frames are extended with a sentence (PNMID) and the serial number from the router. If Telit modules have been installed for the router, a GPRMC frame is searched for and provided from a GNSS data block using a regex rule.
Prerequisites
NetModule Wireless Router with wireless connection
NetModule wireless router with a GNSS module
-
Not available for legacy products NB1600, NB2700, NB3700, NB3710
The wiki was tested with router software version 5.0.0.101.
1. Set up the SDK script on the router
In the first step, the SDK function is activated and further options are specified.
The function is activated under point 1.
Under
point 2, we free up memory for the execution of the script. For this SDK script, 100
MB is sufficient; only a few variables are stored temporarily for the execution of the program.
Under point 3, we activate monitoring to check whether the script is still being processed correctly. We use the router's core function in the program. Monitoring makes sense here.
In the second step, we store the SDK script in Job Management.
First, we store the SDK script under Job Management. Using the plus button under point 3, we add a script.
After pressing the plus button, a new window opens with settings.
First, assign a name to the SDK process. In the second step, you can insert the SDK script using the “upload” function. You can open the script by clicking on the “show code” button in the WIKI and then download the “GPS_TRACKING.are” file. Once you have saved the file on your computer, you can search for it in step 3 using Browse and select it. The last step, “Apply“, saves everything to the router.
show code
- GPS_TRACKING.are
/* 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=flase; # Enable debugging with true or disable with false
DEBUGALL=flase; # Enable debugging with true or disable with false
###############################################################################
release_point = 0;
void usage()
{
nb_syslog("usage: gps-broadcast.are <server> <port>");
printf("No server IP address or port was entered <server> <port>\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);