GPS NMEA Frames via Serial

The built-in GPS Function is TCP/IP only. If you want to retrieve the GPS NMEA frames over the serial interface of a Netmodule Router you can use this SDK script.

Script Summary

This Script connects to the GPS server and forwards the data to the first serial interface. GPS must be enabled and in RAW mode. The default serial parameters for GPS are 4800 8N1 (8 databit, no parity, 1 stop bit, no flow controll). This parameter can be configured at the begining of the script. Please use if possible a higher data rate e.g. 115200.

Pre Requierments

To use this script you need to enable the GNSS Interface on the Router to your needs. Please use the “raw-mode” with this SDK script.

Also assign the serial interface to the SDK

Installation

Detailed step by step instructions how to install a sdk script can be found on this wiki page

Please combine this script with the “system-startup” trigger to get a job.

The Script

gps-to-serial.are
/* Options to configure by user*/
SER_SPEED = 4800;	/* Serial Baud Rate 4800, 9600, 19200, 38400, 57600, 115200 */
SER_DATABIT = 8;	/*  number of data bits (5, 6, 7, 8) */
SER_STOPBIT = 1;	/*  number of stop bits (1, 2) */	
SER_PARITY = 0;		/* parity (0=no parity, 1=odd parity, 2=even parity) */
SER_FLOW = 0;		/*  flow control (0=none, 1=xon/xoff, 2=hardware) */
DEV = "SERIAL1";	/*  name of the Serial Interface */
 
/* GPS Deamon Parameters */
HOST = "127.0.0.1";	/* local host */
PORT = (int) nb_config_get("gpsd.0.port");
 
void usage() {
    nb_syslog("Usage: gps2serial.are\n");
    exit(1);
}
 
int start_serial() {
	if (nb_config_get("serial.0.status") != "2") {
    	nb_syslog("serial not assinged to SDK\n");
        exit(2);
    }
    // printf("set serial attributes\n");
    if ((rc = nb_serial_setattr(DEV, SER_SPEED, SER_DATABIT, SER_STOPBIT, SER_PARITY, SER_FLOW)) != 0) {
        nb_syslog("ERROR: unable to set serial attributes (rc %d) to %s\n", rc, DEV);
        return -1;
    }
    // nb_syslog("Open serial device %s\n", DEV);
    if ((fd = nb_serial_open(DEV)) < 0) {
        nb_syslog("ERROR: can't open serial port %s\n", DEV);
        return -1;
    }
    return fd;
}
 
int connect_gpsd()	
{
    if (nb_config_get("gpsd.0.status") != "1" || nb_config_get("gpsd.0.cmode") != "1") {
    	nb_syslog("gpsd not enabled or not in RAW mode\n");
        exit(3);
    }
    while (1) {
        sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sock < 0)
            nb_syslog("Unable to create socket\n");
        else if (connect(sock, HOST, PORT) < 0){
            nb_syslog("Could not connect to GPS daemon\n");
            close(sock);
        } else {
            nb_syslog("Successfully connected to GPS daemon\n");
            return sock;
        }
      	sleep(10);
    }
    /* no return */
}
 
 
nb_syslog("starting serial");
if ((serial_fd = start_serial()) < 0 ) {
    nb_syslog("Could not start serial, exiting\n");
    exit(4);
}
// printf("connect to gpsd\n");
gpsd = connect_gpsd();
 
// printf("Processing NMEA data\n"); 
while (1) {
    // printf("wait for data\n");
    if ((rv = select(gpsd, 10)) == 0) {
		// printf("Select timed out\n"); 
      	continue;
	}
    if (rv < 0 || ( data = recv(gpsd)) == "") {
        nb_syslog("Select or recv failed, re-connecting to GPS daemon\n");
	close(gpsd);
        if ((gpsd = connect_gpsd()) < 0)
            exit(5);	/* can't connect */
        continue;
    }
    len = strlen(data);
	// printf("write data to serial <%s> [%i]\n", data, len);
    if (write(serial_fd, data, len) != len)
       nb_syslog("Unable to send message via Serial, data %s, len: %i\n", data, len);
}
 
close(gpsd);
close(serial_fd);
exit(6);