diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2004-08-11 21:10:11 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2004-08-11 21:10:11 +0000 |
commit | ea16011ee24a62547a1a2ef42ba7295c0b45ae0d (patch) | |
tree | 16e7d1e269166e429baef566e33d5cb47c0b7429 | |
parent | 36208f433acb9826c6d46d9d145eb06910f49577 (diff) | |
download | gpsd-ea16011ee24a62547a1a2ef42ba7295c0b45ae0d.tar.gz |
ESR's gpsd patch #4: This is the one that nukes globals.
There is exactly one (1) global variable left after this patch.
It is called "session", and is a per-GPS-session object that looks like this:
struct session_t
{
int debug;
struct longlat initpos;
int device_type;
struct OUTDATA gNMEAdata;
};
The next step is for the device-type field to stop being an enum and
become an object pointer -- or as close to an object pointer as you get
in C, anyway. It will refer to a driver object.
-rw-r--r-- | TODO | 9 | ||||
-rw-r--r-- | display.c | 35 | ||||
-rw-r--r-- | em.c | 172 | ||||
-rw-r--r-- | gps.c | 104 | ||||
-rw-r--r-- | gpsd.c | 158 | ||||
-rw-r--r-- | gpsd.h | 18 | ||||
-rw-r--r-- | gpsd.xml | 4 | ||||
-rw-r--r-- | gpsplay.c | 58 | ||||
-rw-r--r-- | netlib.c | 2 | ||||
-rw-r--r-- | nmea.h | 9 | ||||
-rw-r--r-- | nmea_parse.c | 146 | ||||
-rw-r--r-- | outdata.h | 11 | ||||
-rw-r--r-- | send_nmea.c | 2 | ||||
-rw-r--r-- | serial.c | 11 | ||||
-rw-r--r-- | tm.c | 88 | ||||
-rw-r--r-- | xgpsspeed.c | 16 |
16 files changed, 415 insertions, 428 deletions
@@ -1 +1,10 @@ fix formatting in (gpsd.c)handle_request(). the sprintfs... + +Bug complaints from the Kismet author: + * No error output to the user if /dev/gps doesn't exist or if theres an + IO error + * No satellite positional info. Everything that needs to know + individual sat map stuff uses debug mode and parses NMEA itself, this + is redundant + * Corruption - I haven't seen this too often, but it has a tendency to + blat out illegal coordinates when it gets confused @@ -25,10 +25,11 @@ #include <X11/Shell.h> #include <math.h> -#include "nmea.h" #include "outdata.h" +#include "nmea.h" #include "gps.h" + #define XCENTER (double)(width/2) #define YCENTER (double)(height/2) #define SCALE (double)(diameter/2) @@ -38,11 +39,13 @@ #undef min #define min(a,b) ((a) < (b) ? (a) : (b)) -Widget draww; -GC drawGC; -Dimension width, height; -int diameter; -Pixmap pixmap; +extern struct session_t session; + +static Widget draww; +static GC drawGC; +static Dimension width, height; +static int diameter; +static Pixmap pixmap; void set_color(String color) { @@ -109,15 +112,15 @@ int get_status(int satellite) int i; int s; - if (gNMEAdata.ZCHseen) { + if (session.gNMEAdata.ZCHseen) { for (i = 0; i < 12; i++) - if (satellite == gNMEAdata.Zs[i]) - return gNMEAdata.Zv[i]; + if (satellite == session.gNMEAdata.Zs[i]) + return session.gNMEAdata.Zv[i]; return 0; } else { for (i = 0; i < 12; i++) - if (satellite == gNMEAdata.PRN[i]) { - s = gNMEAdata.ss[i]; + if (satellite == session.gNMEAdata.PRN[i]) { + s = session.gNMEAdata.ss[i]; if (s<20) return 1; if (s<40) return 2; @@ -135,7 +138,7 @@ void draw_graphics() double x, y; char buf[20]; - if (gNMEAdata.cmask & (C_SAT | C_ZCH)) { + if (session.gNMEAdata.cmask & (C_SAT | C_ZCH)) { i = min(width, height); @@ -157,10 +160,10 @@ void draw_graphics() draw_arc(width / 2, height / 2, i - RM); /* Now draw the satellites... */ - for (i = 0; i < gNMEAdata.in_view; i++) { - pol2cart(gNMEAdata.azimuth[i], gNMEAdata.elevation[i], &x, &y); + for (i = 0; i < session.gNMEAdata.in_view; i++) { + pol2cart(session.gNMEAdata.azimuth[i], session.gNMEAdata.elevation[i], &x, &y); - switch (get_status(gNMEAdata.PRN[i]) & 7) { + switch (get_status(session.gNMEAdata.PRN[i]) & 7) { case 0: case 1: set_color("Grey"); @@ -183,7 +186,7 @@ void draw_graphics() 11, 11, /* width, height */ 0, 360 * 64 /* angle1, angle2 */ ); - sprintf(buf, "%02d", gNMEAdata.PRN[i]); + sprintf(buf, "%02d", session.gNMEAdata.PRN[i]); set_color("Blue"); XDrawString(XtDisplay(draww), pixmap, drawGC, (int) x + 0, (int) y + 17, buf, 2); @@ -17,16 +17,12 @@ #include <syslog.h> #include <unistd.h> -#include "gpsd.h" -#include "nmea.h" #include "outdata.h" +#include "nmea.h" +#include "gpsd.h" #define BUFSIZE 4096 -extern int debug; -extern char *latitude; -extern char *longitude; -extern char latd; -extern char lond; +extern struct session_t session; #define PI 3.14159265358979323846 @@ -100,9 +96,9 @@ static void em_spew(int type, unsigned short *dat, int dlen) h.ndata = dlen - 1; h.csum = em_checksum((unsigned short *) &h, 4); - if (gNMEAdata.fdout != -1) { - end_write(gNMEAdata.fdout, &h, sizeof(h)); - end_write(gNMEAdata.fdout, dat, sizeof(unsigned short) * dlen); + if (session.gNMEAdata.fdout != -1) { + end_write(session.gNMEAdata.fdout, &h, sizeof(h)); + end_write(session.gNMEAdata.fdout, dat, sizeof(unsigned short) * dlen); } } @@ -129,7 +125,7 @@ static void em_init() eminit = 0; - if (latitude && longitude) { + if (session.initpos.latitude && session.initpos.longitude) { t = time(NULL); tm = gmtime(&t); @@ -148,8 +144,8 @@ static void em_init() data[8] = tm->tm_hour; data[9] = tm->tm_min; data[10] = tm->tm_sec; - *(long *) (data + 11) = putlong(latitude, (latd == 'S') ? 1 : 0); - *(long *) (data + 13) = putlong(longitude, (lond == 'W') ? 1 : 0); + *(long *) (data + 11) = putlong(session.initpos.latitude, (session.initpos.latd == 'S') ? 1 : 0); + *(long *) (data + 13) = putlong(session.initpos.longitude, (session.initpos.lond == 'W') ? 1 : 0); data[15] = data[16] = 0; data[17] = data[18] = data[19] = data[20] = 0; data[21] = em_checksum(data, 21); @@ -192,7 +188,7 @@ int em_send_rtcm(char *rtcmbuf, int rtcmbytes) void do_eminit() { /* Make sure these are zero before 1002 handler called */ - gNMEAdata.pdop = gNMEAdata.hdop = gNMEAdata.vdop = 0; + session.gNMEAdata.pdop = session.gNMEAdata.hdop = session.gNMEAdata.vdop = 0; eminit = 1; } @@ -245,58 +241,58 @@ static void handle1000(unsigned short *p) fprintf(stderr, "Separation: %f\n", (p[O(33)] / 100)); #endif - sprintf(gNMEAdata.utc, "%02d/%02d/%d %02d:%02d:%02d", + sprintf(session.gNMEAdata.utc, "%02d/%02d/%d %02d:%02d:%02d", p[O(19)], p[O(20)], p[O(21)], p[O(22)], p[O(23)], p[O(24)]); - gNMEAdata.mag_var = p[O(37)] * 180 / (PI * 10000); /* degrees */ + session.gNMEAdata.mag_var = p[O(37)] * 180 / (PI * 10000); /* degrees */ - gNMEAdata.course = p[O(36)] * 180 / (PI * 1000); /* degrees */ + session.gNMEAdata.course = p[O(36)] * 180 / (PI * 1000); /* degrees */ - gNMEAdata.satellites = p[O(12)]; + session.gNMEAdata.satellites = p[O(12)]; - gNMEAdata.hours = p[O(22)]; + session.gNMEAdata.hours = p[O(22)]; - gNMEAdata.minutes = p[O(23)]; + session.gNMEAdata.minutes = p[O(23)]; - gNMEAdata.seconds = p[O(24)]; + session.gNMEAdata.seconds = p[O(24)]; - gNMEAdata.year = p[O(21)]; + session.gNMEAdata.year = p[O(21)]; - gNMEAdata.month = p[O(20)]; + session.gNMEAdata.month = p[O(20)]; - gNMEAdata.day = p[O(19)]; + session.gNMEAdata.day = p[O(19)]; - gNMEAdata.latitude = 180.0 / (PI / ((double) getlong(p + O(27)) / 100000000)); - gNMEAdata.longitude = 180.0 / (PI / ((double) getlong(p + O(29)) / 100000000)); - gNMEAdata.speed = ((double) getulong(p + O(34)) / 100.0) * 1.94387; - gNMEAdata.altitude = (double) getlong(p + O(31)) / 100.0; + session.gNMEAdata.latitude = 180.0 / (PI / ((double) getlong(p + O(27)) / 100000000)); + session.gNMEAdata.longitude = 180.0 / (PI / ((double) getlong(p + O(29)) / 100000000)); + session.gNMEAdata.speed = ((double) getulong(p + O(34)) / 100.0) * 1.94387; + session.gNMEAdata.altitude = (double) getlong(p + O(31)) / 100.0; - gNMEAdata.status = (p[O(10)] & 0x1c) ? 0 : 1; + session.gNMEAdata.status = (p[O(10)] & 0x1c) ? 0 : 1; - if (gNMEAdata.status) { - gNMEAdata.mode = (p[O(10)] & 1) ? 2 : 3; + if (session.gNMEAdata.status) { + session.gNMEAdata.mode = (p[O(10)] & 1) ? 2 : 3; } else { - gNMEAdata.mode = 1; + session.gNMEAdata.mode = 1; } - gNMEAdata.ts_status = gNMEAdata.last_update; - gNMEAdata.cmask |= C_STATUS; - gNMEAdata.ts_mode = gNMEAdata.last_update; - gNMEAdata.cmask |= C_MODE; + session.gNMEAdata.ts_status = session.gNMEAdata.last_update; + session.gNMEAdata.cmask |= C_STATUS; + session.gNMEAdata.ts_mode = session.gNMEAdata.last_update; + session.gNMEAdata.cmask |= C_MODE; - gNMEAdata.separation = p[O(33)] / 100; /* meters */ + session.gNMEAdata.separation = p[O(33)] / 100; /* meters */ } static void handle1002(unsigned short *p) { int i, j; - gNMEAdata.ZCHseen = 1; + session.gNMEAdata.ZCHseen = 1; for (j = 0; j < 12; j++) { - gNMEAdata.used[j] = 0; + session.gNMEAdata.used[j] = 0; } for (i = 0; i < 12; i++) { - gNMEAdata.Zs[i] = p[O(16 + (3 * i))]; - gNMEAdata.Zv[i] = (p[O(15 + (3 * i))] & 0xf); + session.gNMEAdata.Zs[i] = p[O(16 + (3 * i))]; + session.gNMEAdata.Zv[i] = (p[O(15 + (3 * i))] & 0xf); #if 0 fprintf(stderr, "Sat%02d:", i); fprintf(stderr, " used:%d", (p[O(15 + (3 * i))] & 1) ? 1 : 0); @@ -307,10 +303,10 @@ static void handle1002(unsigned short *p) fprintf(stderr, " C/No:%d\n", p[O(17 + (3 * i))]); #endif for (j = 0; j < 12; j++) { - if (gNMEAdata.PRN[j] != p[O(16 + (3 * i))]) + if (session.gNMEAdata.PRN[j] != p[O(16 + (3 * i))]) continue; - gNMEAdata.used[j] = (p[O(15 + (3 * i))] & 1); - gNMEAdata.ss[j] = p[O(17 + (3 * i))]; + session.gNMEAdata.used[j] = (p[O(15 + (3 * i))] & 1); + session.gNMEAdata.ss[j] = p[O(17 + (3 * i))]; break; } } @@ -320,16 +316,16 @@ static void handle1003(unsigned short *p) { int j; - gNMEAdata.pdop = p[O(10)]; - gNMEAdata.hdop = p[O(11)]; - gNMEAdata.vdop = p[O(12)]; - gNMEAdata.in_view = p[O(14)]; + session.gNMEAdata.pdop = p[O(10)]; + session.gNMEAdata.hdop = p[O(11)]; + session.gNMEAdata.vdop = p[O(12)]; + session.gNMEAdata.in_view = p[O(14)]; for (j = 0; j < 12; j++) { - if (j < gNMEAdata.in_view) { - gNMEAdata.PRN[j] = p[O(15 + (3 * j))]; - gNMEAdata.azimuth[j] = p[O(16 + (3 * j))] * 180 / (PI * 10000); - gNMEAdata.elevation[j] = p[O(17 + (3 * j))] * 180 / (PI * 10000); + if (j < session.gNMEAdata.in_view) { + session.gNMEAdata.PRN[j] = p[O(15 + (3 * j))]; + session.gNMEAdata.azimuth[j] = p[O(16 + (3 * j))] * 180 / (PI * 10000); + session.gNMEAdata.elevation[j] = p[O(17 + (3 * j))] * 180 / (PI * 10000); #if 0 fprintf(stderr, "Sat%02d:", i); fprintf(stderr, " PRN:%d", p[O(15 + (3 * i))]); @@ -338,9 +334,9 @@ static void handle1003(unsigned short *p) fprintf(stderr, "\n"); #endif } else { - gNMEAdata.PRN[j] = 0; - gNMEAdata.azimuth[j] = 0.0; - gNMEAdata.elevation[j] = 0.0; + session.gNMEAdata.PRN[j] = 0; + session.gNMEAdata.azimuth[j] = 0.0; + session.gNMEAdata.elevation[j] = 0.0; } } } @@ -377,47 +373,47 @@ static void analyze(struct header *h, unsigned short *p, fd_set * afds, fd_set * int i = 0, j = 0, nmea = 0; if (p[h->ndata] == em_checksum(p, h->ndata)) { - if (debug > 5) + if (session.debug > 5) fprintf(stderr, "id %d\n", h->id); switch (h->id) { case 1000: handle1000(p); bufp = buf; - if (gNMEAdata.mode > 1) { + if (session.gNMEAdata.mode > 1) { sprintf(bufp, "$GPGGA,%02d%02d%02d,%f,%c,%f,%c,%d,%02d,%.2f,%.1f,%c,%f,%c,%s,%s*", - gNMEAdata.hours, gNMEAdata.minutes, gNMEAdata.seconds, - degtodm(fabs(gNMEAdata.latitude)), - ((gNMEAdata.latitude > 0) ? 'N' : 'S'), - degtodm(fabs(gNMEAdata.longitude)), - ((gNMEAdata.longitude > 0) ? 'E' : 'W'), - gNMEAdata.mode, gNMEAdata.satellites, gNMEAdata.hdop, - gNMEAdata.altitude, 'M', gNMEAdata.separation, 'M', "", ""); + session.gNMEAdata.hours, session.gNMEAdata.minutes, session.gNMEAdata.seconds, + degtodm(fabs(session.gNMEAdata.latitude)), + ((session.gNMEAdata.latitude > 0) ? 'N' : 'S'), + degtodm(fabs(session.gNMEAdata.longitude)), + ((session.gNMEAdata.longitude > 0) ? 'E' : 'W'), + session.gNMEAdata.mode, session.gNMEAdata.satellites, session.gNMEAdata.hdop, + session.gNMEAdata.altitude, 'M', session.gNMEAdata.separation, 'M', "", ""); add_checksum(bufp + 1); bufp = bufp + strlen(bufp); } sprintf(bufp, "$GPRMC,%02d%02d%02d,%c,%f,%c,%f,%c,%f,%f,%02d%02d%02d,%02f,%c*", - gNMEAdata.hours, gNMEAdata.minutes, gNMEAdata.seconds, - gNMEAdata.status ? 'A' : 'V', degtodm(fabs(gNMEAdata.latitude)), - ((gNMEAdata.latitude > 0) ? 'N' : 'S'), - degtodm(fabs(gNMEAdata.longitude)), - ((gNMEAdata.longitude > 0) ? 'E' : 'W'), gNMEAdata.speed, - gNMEAdata.course, gNMEAdata.day, gNMEAdata.month, - (gNMEAdata.year % 100), gNMEAdata.mag_var, - (gNMEAdata.mag_var > 0) ? 'E' : 'W'); + session.gNMEAdata.hours, session.gNMEAdata.minutes, session.gNMEAdata.seconds, + session.gNMEAdata.status ? 'A' : 'V', degtodm(fabs(session.gNMEAdata.latitude)), + ((session.gNMEAdata.latitude > 0) ? 'N' : 'S'), + degtodm(fabs(session.gNMEAdata.longitude)), + ((session.gNMEAdata.longitude > 0) ? 'E' : 'W'), session.gNMEAdata.speed, + session.gNMEAdata.course, session.gNMEAdata.day, session.gNMEAdata.month, + (session.gNMEAdata.year % 100), session.gNMEAdata.mag_var, + (session.gNMEAdata.mag_var > 0) ? 'E' : 'W'); add_checksum(bufp + 1); nmea = 1000; break; case 1002: handle1002(p); bufp2 = bufp = buf; - sprintf(bufp, "$GPGSA,%c,%d,", 'A', gNMEAdata.mode); + sprintf(bufp, "$GPGSA,%c,%d,", 'A', session.gNMEAdata.mode); j = 0; for (i = 0; i < 12; i++) { - if (gNMEAdata.used[i]) { + if (session.gNMEAdata.used[i]) { bufp = bufp + strlen(bufp); - sprintf(bufp, "%02d,", gNMEAdata.PRN[i]); + sprintf(bufp, "%02d,", session.gNMEAdata.PRN[i]); j++; } } @@ -426,14 +422,14 @@ static void analyze(struct header *h, unsigned short *p, fd_set * afds, fd_set * sprintf(bufp, ","); } bufp = bufp + strlen(bufp); - sprintf(bufp, "%.2f,%.2f,%.2f*", gNMEAdata.pdop, gNMEAdata.hdop, - gNMEAdata.vdop); + sprintf(bufp, "%.2f,%.2f,%.2f*", session.gNMEAdata.pdop, session.gNMEAdata.hdop, + session.gNMEAdata.vdop); add_checksum(bufp2 + 1); bufp2 = bufp = bufp + strlen(bufp); sprintf(bufp, "$PRWIZCH"); bufp = bufp + strlen(bufp); for (i = 0; i < 12; i++) { - sprintf(bufp, ",%02d,%X", gNMEAdata.Zs[i], gNMEAdata.Zv[i]); + sprintf(bufp, ",%02d,%X", session.gNMEAdata.Zs[i], session.gNMEAdata.Zv[i]); bufp = bufp + strlen(bufp); } sprintf(bufp, "*"); @@ -444,17 +440,17 @@ static void analyze(struct header *h, unsigned short *p, fd_set * afds, fd_set * case 1003: handle1003(p); bufp2 = bufp = buf; - j = (gNMEAdata.in_view / 4) + (((gNMEAdata.in_view % 4) > 0) ? 1 : 0); + j = (session.gNMEAdata.in_view / 4) + (((session.gNMEAdata.in_view % 4) > 0) ? 1 : 0); while (i < 12) { if (i % 4 == 0) - sprintf(bufp, "$GPGSV,%d,%d,%02d", j, (i / 4) + 1, gNMEAdata.in_view); + sprintf(bufp, "$GPGSV,%d,%d,%02d", j, (i / 4) + 1, session.gNMEAdata.in_view); bufp += strlen(bufp); - if (i <= gNMEAdata.in_view && gNMEAdata.elevation[i]) - sprintf(bufp, ",%02d,%02d,%03d,%02d", gNMEAdata.PRN[i], - gNMEAdata.elevation[i], gNMEAdata.azimuth[i], gNMEAdata.ss[i]); + if (i <= session.gNMEAdata.in_view && session.gNMEAdata.elevation[i]) + sprintf(bufp, ",%02d,%02d,%03d,%02d", session.gNMEAdata.PRN[i], + session.gNMEAdata.elevation[i], session.gNMEAdata.azimuth[i], session.gNMEAdata.ss[i]); else - sprintf(bufp, ",%02d,00,000,%02d,", gNMEAdata.PRN[i], - gNMEAdata.ss[i]); + sprintf(bufp, ",%02d,00,000,%02d,", session.gNMEAdata.PRN[i], + session.gNMEAdata.ss[i]); bufp += strlen(bufp); if (i % 4 == 3) { sprintf(bufp, "*"); @@ -472,7 +468,7 @@ static void analyze(struct header *h, unsigned short *p, fd_set * afds, fd_set * } } if (nmea > 0) { - if (debug > 4) + if (session.debug > 4) fprintf(stderr, "%s", buf); send_nmea(afds, nmea_fds, buf); @@ -513,8 +509,8 @@ static void em_eat(unsigned char c, fd_set * afds, fd_set * nmea_fds) case EM_HUNT_A: /* A better be right after E */ - if ((c == 'A') && (gNMEAdata.fdout != -1)) - write(gNMEAdata.fdout, "EARTHA\r\n", 8); + if ((c == 'A') && (session.gNMEAdata.fdout != -1)) + write(session.gNMEAdata.fdout, "EARTHA\r\n", 8); state = EM_HUNT_FF; break; @@ -42,43 +42,35 @@ #include <sys/filio.h> #endif -#include "nmea.h" #include "outdata.h" +#include "nmea.h" #include "gps.h" +struct session_t session; + void update_display(char *message); /* global variables */ -Widget lxbApp; -Widget form_6; -Widget list_7; -Widget list_8; -Widget drawingArea_8; -Widget rowColumn_10; -Widget rowColumn_11; -Widget rowColumn_12; -Widget rowColumn_13; -Widget rowColumn_14; -Widget rowColumn_15; -Widget rowColumn_16; -Widget pushButton_11; -Widget text_1, text_2, text_3, text_4, text_5; -Widget label_1, label_2, label_3, label_4, label_5; -Widget status; - - /* command line options */ -int debug = 0; -int device_type; -int device_speed = B4800; -char *device_name = 0; -char *latitude = 0; -char *longitude = 0; -char latd = 'N'; -char lond = 'W'; - /* command line option defaults */ -char *default_device_name = "localhost:2947"; -char *default_latitude = "3600.000"; -char *default_longitude = "12300.000"; +static Widget lxbApp; +static Widget form_6; +static Widget list_7; +static Widget list_8; +static Widget drawingArea_8; +static Widget rowColumn_10; +static Widget rowColumn_11; +static Widget rowColumn_12; +static Widget rowColumn_13; +static Widget rowColumn_14; +static Widget rowColumn_15; +static Widget rowColumn_16; +static Widget pushButton_11; +static Widget text_1, text_2, text_3, text_4, text_5; +static Widget label_1, label_2, label_3, label_4, label_5; +static Widget status; + +static int device_speed = B4800; +static char *device_name = 0; +static char *default_device_name = "localhost:2947"; String fallback_resources[] = { @@ -328,12 +320,12 @@ void update_display(char *message) XmTextFieldSetString(status, message); /* This is for the satellite status display */ - if (gNMEAdata.cmask & C_SAT) { + if (session.gNMEAdata.cmask & C_SAT) { for (i = 0; i < 12; i++) { - if (i < gNMEAdata.in_view) { - sprintf(s, "%2d %02d %03d %02d", gNMEAdata.PRN[i], - gNMEAdata.elevation[i], - gNMEAdata.azimuth[i], gNMEAdata.ss[i]); + if (i < session.gNMEAdata.in_view) { + sprintf(s, "%2d %02d %03d %02d", session.gNMEAdata.PRN[i], + session.gNMEAdata.elevation[i], + session.gNMEAdata.azimuth[i], session.gNMEAdata.ss[i]); } else sprintf(s, " "); string[i] = XmStringCreateSimple(s); @@ -342,9 +334,9 @@ void update_display(char *message) for (i = 0; i < 12; i++) XmStringFree(string[i]); } - if (gNMEAdata.cmask & C_ZCH) { + if (session.gNMEAdata.cmask & C_ZCH) { for (i = 0; i < 12; i++) { - sprintf(s, "%2d %02x", gNMEAdata.Zs[i], gNMEAdata.Zv[i]); + sprintf(s, "%2d %02x", session.gNMEAdata.Zs[i], session.gNMEAdata.Zv[i]); string[i] = XmStringCreateSimple(s); } XmListReplaceItemsPos(list_8, string, 12, 1); @@ -353,20 +345,20 @@ void update_display(char *message) } /* here now the value fields */ - XmTextFieldSetString(text_1, gNMEAdata.utc); - sprintf(s, "%f", gNMEAdata.latitude); + XmTextFieldSetString(text_1, session.gNMEAdata.utc); + sprintf(s, "%f", session.gNMEAdata.latitude); XmTextFieldSetString(text_2, s); - sprintf(s, "%f", gNMEAdata.longitude); + sprintf(s, "%f", session.gNMEAdata.longitude); XmTextFieldSetString(text_3, s); - sprintf(s, "%f", gNMEAdata.altitude); + sprintf(s, "%f", session.gNMEAdata.altitude); XmTextFieldSetString(text_4, s); - switch (gNMEAdata.mode) { + switch (session.gNMEAdata.mode) { case 2: - sprintf(s, "2D %sFIX", (gNMEAdata.status==2) ? "DIFF ": ""); + sprintf(s, "2D %sFIX", (session.gNMEAdata.status==2) ? "DIFF ": ""); break; case 3: - sprintf(s, "3D %sFIX", (gNMEAdata.status==2) ? "DIFF ": ""); + sprintf(s, "3D %sFIX", (session.gNMEAdata.status==2) ? "DIFF ": ""); break; default: sprintf(s, "NO FIX"); @@ -375,7 +367,7 @@ void update_display(char *message) XmTextFieldSetString(text_5, s); draw_graphics(); - gNMEAdata.cmask = 0; + session.gNMEAdata.cmask = 0; } /************************************************** @@ -386,10 +378,10 @@ static void open_input(XtAppContext app) int input = 0; XtInputId input_id; - input = serial_open(); + input = serial_open(device_name, device_speed); - gNMEAdata.fdin = input; - gNMEAdata.fdout = input; + session.gNMEAdata.fdin = input; + session.gNMEAdata.fdout = input; input_id = XtAppAddInput(app, input, (XtPointer) XtInputReadMask, handle_input, NULL); @@ -428,10 +420,10 @@ int main(int argc, char *argv[]) case 'T': switch (*optarg) { case 't': - device_type = DEVICE_TRIPMATE; + session.device_type = DEVICE_TRIPMATE; break; case 'e': - device_type = DEVICE_EARTHMATE; + session.device_type = DEVICE_EARTHMATE; break; default: fprintf(stderr,"Invalide device type \"%c\"\n" @@ -440,7 +432,7 @@ int main(int argc, char *argv[]) } break; case 'D': - debug = (int) strtol(optarg, 0, 0); + session.debug = (int) strtol(optarg, 0, 0); break; case 'p': if (device_name) @@ -481,14 +473,10 @@ int main(int argc, char *argv[]) } if (!device_name) device_name = default_device_name; - if (!latitude) - latitude = default_latitude; - if (!longitude) - longitude = default_longitude; - if (debug > 0) { + if (session.debug > 0) { fprintf(stderr, "command line options:\n"); - fprintf(stderr, " debug level: %d\n", debug); + fprintf(stderr, " debug level: %d\n", session.debug); fprintf(stderr, " gps device name: %s\n", device_name); fprintf(stderr, " gps device speed: %d\n", device_speed); } @@ -42,31 +42,23 @@ #include <sys/time.h> #endif +#include "outdata.h" #include "nmea.h" #include "gpsd.h" -#include "outdata.h" #include "version.h" #define QLEN 5 #define BUFSIZE 4096 -#define GPS_TIMEOUT 5 /* Consider GPS connection loss after 5 sec */ - -int gps_timeout = GPS_TIMEOUT; -int debug = 0; -int device_speed = B4800; -int device_type; -char *device_name = 0; -char *latitude = 0; -char *longitude = 0; -char latd = 'N'; -char lond = 'W'; -char *default_device_name = "/dev/gps"; +#define GPS_TIMEOUT 5 /* Consider GPS connection loss after 5 sec */ -int nfds, dsock; -int verbose = 1; -int bincount; +struct session_t session; -int reopen = 0; +static int gps_timeout = GPS_TIMEOUT; +static int device_speed = B4800; +static char *device_name = 0; +static char *default_device_name = "/dev/gps"; +static int nfds, dsock; +static int reopen = 0; static int handle_input(int input, fd_set * afds, fd_set * nmea_fds); static int handle_request(int fd, fd_set * fds); @@ -118,8 +110,8 @@ static void send_dgps() { char buf[BUFSIZE]; - sprintf(buf, "R %0.8f %0.8f %0.2f\r\n", gNMEAdata.latitude, - gNMEAdata.longitude, gNMEAdata.altitude); + sprintf(buf, "R %0.8f %0.8f %0.2f\r\n", session.gNMEAdata.latitude, + session.gNMEAdata.longitude, session.gNMEAdata.altitude); write(dsock, buf, strlen(buf)); } @@ -182,7 +174,7 @@ static int set_device_type(char what) static void print_settings(char *service, char *dgpsserver, char *dgpsport) { fprintf(stderr, "command line options:\n"); - fprintf(stderr, " debug level: %d\n", debug); + fprintf(stderr, " debug level: %d\n", session.debug); fprintf(stderr, " gps device name: %s\n", device_name); fprintf(stderr, " gps device speed: %d\n", device_speed); fprintf(stderr, " gpsd port: %s\n", service); @@ -190,9 +182,9 @@ static void print_settings(char *service, char *dgpsserver, char *dgpsport) fprintf(stderr, " dgps server: %s\n", dgpsserver); fprintf(stderr, " dgps port: %s\n", dgpsport); } - if (latitude && longitude) { - fprintf(stderr, " latitude: %s%c\n", latitude, latd); - fprintf(stderr, " longitude: %s%c\n", longitude, lond); + if (session.initpos.latitude && session.initpos.longitude) { + fprintf(stderr, " latitude: %s%c\n", session.initpos.latitude, session.initpos.latd); + fprintf(stderr, " longitude: %s%c\n", session.initpos.longitude, session.initpos.lond); } } @@ -201,12 +193,12 @@ static int handle_dgps() char buf[BUFSIZE]; int rtcmbytes, cnt; - if ((rtcmbytes=read(dsock, buf, BUFSIZE))>0 && (gNMEAdata.fdout!=-1)) { + if ((rtcmbytes=read(dsock, buf, BUFSIZE))>0 && (session.gNMEAdata.fdout!=-1)) { - if (device_type == DEVICE_EARTHMATEb) + if (session.device_type == DEVICE_EARTHMATEb) cnt = em_send_rtcm(buf, rtcmbytes); else - cnt = write(gNMEAdata.fdout, buf, rtcmbytes); + cnt = write(session.gNMEAdata.fdout, buf, rtcmbytes); if (cnt<=0) syslog(LOG_WARNING, "Write to rtcm sink failed"); @@ -220,26 +212,26 @@ static int handle_dgps() static void deactivate() { - gNMEAdata.fdin = -1; - gNMEAdata.fdout = -1; + session.gNMEAdata.fdin = -1; + session.gNMEAdata.fdout = -1; serial_close(); - if (device_type == DEVICE_EARTHMATEb) - device_type = DEVICE_EARTHMATE; + if (session.device_type == DEVICE_EARTHMATEb) + session.device_type = DEVICE_EARTHMATE; syslog(LOG_NOTICE, "Closed gps"); - gNMEAdata.mode = 1; - gNMEAdata.status = 0; + session.gNMEAdata.mode = 1; + session.gNMEAdata.status = 0; } static int activate() { int input; - if ((input = serial_open()) < 0) + if ((input = serial_open(device_name, device_speed)) < 0) errexit("Exiting - serial open"); syslog(LOG_NOTICE, "Opened gps"); - gNMEAdata.fdin = input; - gNMEAdata.fdout = input; + session.gNMEAdata.fdin = input; + session.gNMEAdata.fdout = input; return input; } @@ -266,10 +258,10 @@ int main(int argc, char *argv[]) while ((option = getopt(argc, argv, "D:L:S:T:hncl:p:s:d:r:t:")) != -1) { switch (option) { case 'T': - device_type = set_device_type(*optarg); + session.device_type = set_device_type(*optarg); break; case 'D': - debug = (int) strtol(optarg, 0, 0); + session.debug = (int) strtol(optarg, 0, 0); break; case 'S': service = optarg; @@ -293,12 +285,12 @@ int main(int argc, char *argv[]) "gpsd: longitude field is invalid; must end in E or W.\n"); else { *colon = '\0'; - latitude = optarg; - latd = toupper(optarg[strlen(latitude) - 1]); - latitude[strlen(latitude) - 1] = '\0'; - longitude = colon+1; - lond = toupper(longitude[strlen(longitude)-1]); - longitude[strlen(longitude)-1] = '\0'; + session.initpos.latitude = optarg; + session.initpos.latd = toupper(optarg[strlen(session.initpos.latitude) - 1]); + session.initpos.latitude[strlen(session.initpos.latitude) - 1] = '\0'; + session.initpos.longitude = colon+1; + session.initpos.lond = toupper(session.initpos.longitude[strlen(session.initpos.longitude)-1]); + session.initpos.longitude[strlen(session.initpos.longitude)-1] = '\0'; } break; case 'p': @@ -326,10 +318,10 @@ int main(int argc, char *argv[]) else service = default_service; } - if (debug > 0) + if (session.debug > 0) print_settings(service, dgpsserver, dgpsport); - if (debug < 2) + if (session.debug < 2) daemonize(); /* Handle some signals */ @@ -371,14 +363,14 @@ int main(int argc, char *argv[]) /* mark fds closed */ input = -1; - gNMEAdata.fdin = input; - gNMEAdata.fdout = input; + session.gNMEAdata.fdin = input; + session.gNMEAdata.fdout = input; - gNMEAdata.v_latlon = gps_timeout; - gNMEAdata.v_alt = gps_timeout; - gNMEAdata.v_speed = gps_timeout; - gNMEAdata.v_status = gps_timeout; - gNMEAdata.v_mode = gps_timeout; + session.gNMEAdata.v_latlon = gps_timeout; + session.gNMEAdata.v_alt = gps_timeout; + session.gNMEAdata.v_speed = gps_timeout; + session.gNMEAdata.v_status = gps_timeout; + session.gNMEAdata.v_mode = gps_timeout; while (1) { struct timeval tv; @@ -419,14 +411,14 @@ int main(int argc, char *argv[]) } if (input >= 0 && FD_ISSET(input, &rfds)) { - gNMEAdata.last_update = time(NULL); - if (device_type == DEVICE_EARTHMATEb) + session.gNMEAdata.last_update = time(NULL); + if (session.device_type == DEVICE_EARTHMATEb) handle_EMinput(input, &afds, &nmea_fds); else handle_input(input, &afds, &nmea_fds); } - if (gNMEAdata.status > 0) + if (session.gNMEAdata.status > 0) fixcnt++; if (fixcnt > 10) { @@ -469,21 +461,21 @@ static int validate_sm(time_t cur_time) int ostatus, omode; int status = 0; - ostatus = gNMEAdata.status; - omode = gNMEAdata.mode; + ostatus = session.gNMEAdata.status; + omode = session.gNMEAdata.mode; /* status: 0 = no fix, 1 = fix, 2 = dgps fix */ /* mode: 1 = no fix, 2 = 2D, 3 = 3D */ /* always slave mode to status, consider mode only if status is valid */ - if (debug>1) fprintf(stderr, "status=%d, mode=%d\n", + if (session.debug>1) fprintf(stderr, "status=%d, mode=%d\n", ostatus, omode); - if ((gNMEAdata.ts_status + gNMEAdata.v_status) >= cur_time) { + if ((session.gNMEAdata.ts_status + session.gNMEAdata.v_status) >= cur_time) { status = ostatus; - if (debug>1) fprintf(stderr, "status is valid!\n"); - if ((gNMEAdata.ts_mode + gNMEAdata.v_mode) >= cur_time) { + if (session.debug>1) fprintf(stderr, "status is valid!\n"); + if ((session.gNMEAdata.ts_mode + session.gNMEAdata.v_mode) >= cur_time) { switch (ostatus) { case 0: if (omode != 1) invalidate = 1; @@ -499,15 +491,15 @@ static int validate_sm(time_t cur_time) } } else { - gNMEAdata.ts_mode = 0; /* invalidate mode */ + session.gNMEAdata.ts_mode = 0; /* invalidate mode */ } - gNMEAdata.cmask &= ~(C_STATUS|C_MODE); + session.gNMEAdata.cmask &= ~(C_STATUS|C_MODE); if (invalidate) { syslog(LOG_ERR, "Impossible status(%d)/mode(%d) reason(%d)\n", ostatus, omode, invalidate); - gNMEAdata.ts_status = 0; - gNMEAdata.ts_mode = 0; + session.gNMEAdata.ts_status = 0; + session.gNMEAdata.ts_mode = 0; status = 0; } return status; @@ -537,27 +529,27 @@ static int handle_request(int fd, fd_set * fds) switch (*p) { case 'P': case 'p': - if ((gNMEAdata.ts_latlon + gNMEAdata.v_latlon) >= cur_time) { + if ((session.gNMEAdata.ts_latlon + session.gNMEAdata.v_latlon) >= cur_time) { sprintf(reply + strlen(reply), ",P=%f %f", - gNMEAdata.latitude, - gNMEAdata.longitude); + session.gNMEAdata.latitude, + session.gNMEAdata.longitude); } break; case 'A': case 'a': - if ((gNMEAdata.ts_alt + gNMEAdata.v_alt) >= cur_time) { + if ((session.gNMEAdata.ts_alt + session.gNMEAdata.v_alt) >= cur_time) { sprintf(reply + strlen(reply), ",A=%f", - gNMEAdata.altitude); + session.gNMEAdata.altitude); } break; case 'V': case 'v': - if ((gNMEAdata.ts_speed + gNMEAdata.v_speed) >= cur_time) { + if ((session.gNMEAdata.ts_speed + session.gNMEAdata.v_speed) >= cur_time) { sprintf(reply + strlen(reply), ",V=%f", - gNMEAdata.speed); + session.gNMEAdata.speed); } break; } @@ -568,7 +560,7 @@ static int handle_request(int fd, fd_set * fds) case 'd': sprintf(reply + strlen(reply), ",D=%s", - gNMEAdata.utc); + session.gNMEAdata.utc); break; case 'X': case 'x': @@ -607,26 +599,26 @@ static int handle_request(int fd, fd_set * fds) break; case 'S': case 's': - if ((gNMEAdata.ts_status + gNMEAdata.v_status) >= cur_time) { + if ((session.gNMEAdata.ts_status + session.gNMEAdata.v_status) >= cur_time) { sprintf(reply + strlen(reply), ",S=%d", - gNMEAdata.status); + session.gNMEAdata.status); } break; case 'M': case 'm': - if ((gNMEAdata.ts_mode + gNMEAdata.v_mode) >= cur_time) { + if ((session.gNMEAdata.ts_mode + session.gNMEAdata.v_mode) >= cur_time) { sprintf(reply + strlen(reply), ",M=%d", - gNMEAdata.mode); + session.gNMEAdata.mode); } break; case 'Q': case 'q': sprintf(reply + strlen(reply), ",Q=%d %d %f %f %f", - gNMEAdata.in_view, gNMEAdata.satellites, - gNMEAdata.pdop, gNMEAdata.hdop, gNMEAdata.vdop); + session.gNMEAdata.in_view, session.gNMEAdata.satellites, + session.gNMEAdata.pdop, session.gNMEAdata.hdop, session.gNMEAdata.vdop); break; case 'I': case 'i': @@ -636,12 +628,12 @@ static int handle_request(int fd, fd_set * fds) q = p; i = (int)strtol(p+1, &q, 10); - if (i>=0 && i<gNMEAdata.in_view) { - fprintf(stderr, "i=%d in view=%d\n", i, gNMEAdata.in_view); + if (i>=0 && i<session.gNMEAdata.in_view) { + fprintf(stderr, "i=%d in view=%d\n", i, session.gNMEAdata.in_view); sprintf(reply + strlen(reply), ",I=%d %d %d %d", - gNMEAdata.PRN[i], gNMEAdata.azimuth[i], - gNMEAdata.elevation[i], gNMEAdata.ss[i]); + session.gNMEAdata.PRN[i], session.gNMEAdata.azimuth[i], + session.gNMEAdata.elevation[i], session.gNMEAdata.ss[i]); } else sprintf(reply + strlen(reply), ",I=-1 -1 -1 -1"); if (q!=p) p = q-1; @@ -2,8 +2,24 @@ enum { DEVICE_GENERIC, DEVICE_TRIPMATE, DEVICE_EARTHMATE, DEVICE_EARTHMATEb }; +struct longlat +{ + char *latitude; + char *longitude; + char latd; + char lond; +}; + +struct session_t +{ + int debug; + struct longlat initpos; + int device_type; + struct OUTDATA gNMEAdata; +}; + void send_nmea(fd_set *afds, fd_set *nmea_fds, char *buf); -int serial_open(); +int serial_open(char *device_name, int device_speed); void serial_close(); void handle_message(char *sentence); void errexit(char *s); @@ -200,6 +200,10 @@ the replies. Examples:</para> reply: "GPSD,V=0.000000,A=37.900000\r\n" </screen> +<para>If the GPS stops sending updates to gpsd, gpsd will continue +presenting the last data it got, except that after 5 seconds the +status (S) and mode (M) responses will bothe go to zero.</para> + </refsect2> <refsect2><title>gps</title> @@ -42,30 +42,24 @@ #include <sys/time.h> #endif -#include "nmea.h" #include "outdata.h" +#include "nmea.h" #include "gpsd.h" #include "version.h" #define QLEN 5 #define BUFSIZE 4096 -int debug = 0; -char *device_name = 0; -char *latitude = 0; -char *longitude = 0; -char latd = 'N'; -char lond = 'W'; -int device_type; + +struct session_t session; char *default_device_name = "/tmp/gpslog"; -int nfds, dsock; -int verbose = 1; -int bincount; +static int nfds, dsock; +static char *device_name; static int ttyfd = -1; static FILE *fp = 0; -int reopen = 0; +static int reopen = 0; static int handle_input(int input, fd_set * afds, fd_set * nmea_fds); static int handle_request(int fd, fd_set * fds); @@ -150,19 +144,19 @@ static void usage() static void print_settings(char *service) { fprintf(stderr, "command line options:\n"); - fprintf(stderr, " debug level: %d\n", debug); + fprintf(stderr, " debug level: %d\n", session.debug); fprintf(stderr, " gps device name: %s\n", device_name); fprintf(stderr, " gpsd port: %s\n", service); } static void deactivate() { - gNMEAdata.fdin = -1; - gNMEAdata.fdout = -1; + session.gNMEAdata.fdin = -1; + session.gNMEAdata.fdout = -1; gpslog_close(); syslog(LOG_NOTICE, "Closed gps"); - gNMEAdata.mode = 1; - gNMEAdata.status = 0; + session.gNMEAdata.mode = 1; + session.gNMEAdata.status = 0; } static int activate() @@ -172,8 +166,8 @@ static int activate() if ((input = gpslog_open()) < 0) errexit("gpslog open: "); syslog(LOG_NOTICE, "Opened gps"); - gNMEAdata.fdin = input; - gNMEAdata.fdout = -1; + session.gNMEAdata.fdin = input; + session.gNMEAdata.fdout = -1; return input; } @@ -197,7 +191,7 @@ int main(int argc, char *argv[]) while ((option = getopt(argc, argv, "D:S:hp:")) != -1) { switch (option) { case 'D': - debug = (int) strtol(optarg, 0, 0); + session.debug = (int) strtol(optarg, 0, 0); break; case 'S': service = optarg; @@ -221,10 +215,10 @@ int main(int argc, char *argv[]) else service = default_service; } - if (debug > 0) + if (session.debug > 0) print_settings(service); - if (debug < 2) + if (session.debug < 2) daemonize(); /* Handle some signals */ @@ -249,8 +243,8 @@ int main(int argc, char *argv[]) /* mark fds closed */ input = -1; - gNMEAdata.fdin = input; - gNMEAdata.fdout = -1; + session.gNMEAdata.fdin = input; + session.gNMEAdata.fdout = -1; while (1) { struct timeval tv; @@ -289,7 +283,7 @@ int main(int argc, char *argv[]) handle_input(input, &afds, &nmea_fds); } - if (gNMEAdata.status > 0) + if (session.gNMEAdata.status > 0) fixcnt++; for (fd = 0; fd < nfds; fd++) { @@ -338,26 +332,26 @@ static int handle_request(int fd, fd_set * fds) case 'p': sprintf(reply + strlen(reply), ",P=%f %f", - gNMEAdata.latitude, - gNMEAdata.longitude); + session.gNMEAdata.latitude, + session.gNMEAdata.longitude); break; case 'D': case 'd': sprintf(reply + strlen(reply), ",D=%s", - gNMEAdata.utc); + session.gNMEAdata.utc); break; case 'A': case 'a': sprintf(reply + strlen(reply), ",A=%f", - gNMEAdata.altitude); + session.gNMEAdata.altitude); break; case 'V': case 'v': sprintf(reply + strlen(reply), ",V=%f", - gNMEAdata.speed); + session.gNMEAdata.speed); break; case 'R': case 'r': @@ -375,13 +369,13 @@ static int handle_request(int fd, fd_set * fds) case 's': sprintf(reply + strlen(reply), ",S=%d", - gNMEAdata.status); + session.gNMEAdata.status); break; case 'M': case 'm': sprintf(reply + strlen(reply), ",M=%d", - gNMEAdata.mode); + session.gNMEAdata.mode); break; case '\r': case '\n': @@ -17,6 +17,8 @@ #include <sys/param.h> #endif +#include "outdata.h" +#include "nmea.h" #include "gpsd.h" @@ -10,13 +10,6 @@ /* prototypes */ extern void doNMEA(short refNum); -extern void processGPVTG(char *sentence); -extern void processGPRMC(char *sentence); -extern void processGPGGA(char *sentence); -extern void processGPGSV(char *sentence); -extern void processGPGSA(char *sentence); -extern void processPRWIZCH(char *sentence); -extern void processPMGNST(char *sentence); +extern int process_NMEA_message(char *sentence, struct OUTDATA *outdata); extern void add_checksum(char *sentence); extern short checksum(char *sentence); -extern struct OUTDATA gNMEAdata; diff --git a/nmea_parse.c b/nmea_parse.c index 996a9aa8..57a98593 100644 --- a/nmea_parse.c +++ b/nmea_parse.c @@ -2,16 +2,15 @@ #include <stdio.h> #include <math.h> #include <string.h> -#include "nmea.h" #include "outdata.h" +#include "nmea.h" -extern struct OUTDATA gNMEAdata; -static void do_lat_lon(char *sentence, int begin); +static void do_lat_lon(char *sentence, int begin, struct OUTDATA *out); static char *field(char *sentence, short n); -static void update_field_i(char *sentence, int fld, int *dest, int mask); +static void update_field_i(char *sentence, int fld, int *dest, int mask, struct OUTDATA *out); #if 0 -static void update_field_f(char *sentence, int fld, double *dest, int mask); +static void update_field_f(char *sentence, int fld, double *dest, int mask, struct OUTDATA *out); #endif /* ----------------------------------------------------------------------- */ @@ -24,7 +23,7 @@ static void update_field_f(char *sentence, int fld, double *dest, int mask); 01234567890123456789 */ -void processGPRMC(char *sentence) +static void processGPRMC(char *sentence, struct OUTDATA *out) { char s[20], d[10]; int tmp; @@ -56,19 +55,19 @@ void processGPRMC(char *sentence) s[13] = s[16] = ':'; s[19] = '\0'; - strcpy(gNMEAdata.utc, s); + strcpy(out->utc, s); /* A = valid, V = invalid */ if (strcmp(field(sentence, 2), "V") == 0) - gNMEAdata.status = 0; + out->status = 0; - sscanf(field(sentence, 7), "%lf", &gNMEAdata.speed); + sscanf(field(sentence, 7), "%lf", &out->speed); #if GPRMC_TRACK - sscanf(field(sentence, 8), "%lf", &gNMEAdata.track); + sscanf(field(sentence, 8), "%lf", &out->track); #endif - do_lat_lon(sentence, 3); + do_lat_lon(sentence, 3, out); } /* @@ -86,7 +85,7 @@ where: *40 checksum */ -void processPMGNST(char *sentence) +void processPMGNST(char *sentence, struct OUTDATA *out) { int tmp1; char foo; @@ -96,80 +95,80 @@ void processPMGNST(char *sentence) sscanf(field(sentence, 2), "%d", &tmp1); sscanf(field(sentence, 3), "%c", &foo); - if (!(gNMEAdata.cmask&C_STATUS)) { + if (!(out->cmask&C_STATUS)) { if (foo == 'T') { - gNMEAdata.status = 1; - gNMEAdata.mode = tmp1; + out->status = 1; + out->mode = tmp1; } else { - gNMEAdata.status = 0; - gNMEAdata.mode = 1; + out->status = 0; + out->mode = 1; } - gNMEAdata.ts_status = gNMEAdata.last_update; - gNMEAdata.cmask |= C_STATUS; - gNMEAdata.ts_mode = gNMEAdata.last_update; - gNMEAdata.cmask |= C_MODE; + out->ts_status = out->last_update; + out->cmask |= C_STATUS; + out->ts_mode = out->last_update; + out->cmask |= C_MODE; } } /* ----------------------------------------------------------------------- */ -void processGPVTG(char *sentence) +void processGPVTG(char *sentence, struct OUTDATA *out) { - sscanf(field(sentence, 3), "%lf", &gNMEAdata.speed); + sscanf(field(sentence, 3), "%lf", &out->speed); #if GPRMC_TRACK - sscanf(field(sentence, 1), "%lf", &gNMEAdata.track); + sscanf(field(sentence, 1), "%lf", &out->track); #endif } /* ----------------------------------------------------------------------- */ -void processGPGGA(char *sentence) +void processGPGGA(char *sentence, struct OUTDATA *out) { - do_lat_lon(sentence, 2); + do_lat_lon(sentence, 2, out); /* 0 = none, 1 = normal, 2 = diff */ - sscanf(field(sentence, 6), "%d", &gNMEAdata.status); - gNMEAdata.ts_status = gNMEAdata.last_update; - gNMEAdata.cmask |= C_STATUS; - sscanf(field(sentence, 7), "%d", &gNMEAdata.satellites); - sscanf(field(sentence, 9), "%lf", &gNMEAdata.altitude); - gNMEAdata.ts_alt = gNMEAdata.last_update; + sscanf(field(sentence, 6), "%d", &out->status); + out->ts_status = out->last_update; + out->cmask |= C_STATUS; + sscanf(field(sentence, 7), "%d", &out->satellites); + sscanf(field(sentence, 9), "%lf", &out->altitude); + out->ts_alt = out->last_update; } /* ----------------------------------------------------------------------- */ -void processGPGSA(char *sentence) +void processGPGSA(char *sentence, struct OUTDATA *out) { /* 1 = none, 2 = 2d, 3 = 3d */ - sscanf(field(sentence, 2), "%d", &gNMEAdata.mode); - gNMEAdata.ts_mode = gNMEAdata.last_update; - gNMEAdata.cmask |= C_MODE; - sscanf(field(sentence, 15), "%lf", &gNMEAdata.pdop); - sscanf(field(sentence, 16), "%lf", &gNMEAdata.hdop); - sscanf(field(sentence, 17), "%lf", &gNMEAdata.vdop); + sscanf(field(sentence, 2), "%d", &out->mode); + out->ts_mode = out->last_update; + out->cmask |= C_MODE; + sscanf(field(sentence, 15), "%lf", &out->pdop); + sscanf(field(sentence, 16), "%lf", &out->hdop); + sscanf(field(sentence, 17), "%lf", &out->vdop); } /* ----------------------------------------------------------------------- */ -void processGPGSV(char *sentence) +void processGPGSV(char *sentence, struct OUTDATA *out) { int n, m, f = 4; if (sscanf(field(sentence, 2), "%d", &n) < 1) return; - update_field_i(sentence, 3, &gNMEAdata.in_view, C_SAT); + update_field_i(sentence, 3, &out->in_view, C_SAT, out); n = (n - 1) * 4; m = n + 4; - while (n < gNMEAdata.in_view && n < m) { - update_field_i(sentence, f++, &gNMEAdata.PRN[n], C_SAT); - update_field_i(sentence, f++, &gNMEAdata.elevation[n], C_SAT); - update_field_i(sentence, f++, &gNMEAdata.azimuth[n], C_SAT); + while (n < out->in_view && n < m) { + update_field_i(sentence, f++, &out->PRN[n], C_SAT, out); + update_field_i(sentence, f++, &out->elevation[n], C_SAT, out); + update_field_i(sentence, f++, &out->azimuth[n], C_SAT, out); if (*(field(sentence, f))) - update_field_i(sentence, f, &gNMEAdata.ss[n], C_SAT); + update_field_i(sentence, f, &out->ss[n], C_SAT, out); f++; n++; } @@ -177,20 +176,20 @@ void processGPGSV(char *sentence) /* ----------------------------------------------------------------------- */ -void processPRWIZCH(char *sentence) +static void processPRWIZCH(char *sentence, struct OUTDATA *out) { int i; for (i = 0; i < 12; i++) { - update_field_i(sentence, 2 * i + 1, &gNMEAdata.Zs[i], C_ZCH); - update_field_i(sentence, 2 * i + 2, &gNMEAdata.Zv[i], C_ZCH); + update_field_i(sentence, 2 * i + 1, &out->Zs[i], C_ZCH, out); + update_field_i(sentence, 2 * i + 2, &out->Zv[i], C_ZCH, out); } - gNMEAdata.ZCHseen = 1; + out->ZCHseen = 1; } /* ----------------------------------------------------------------------- */ -static void do_lat_lon(char *sentence, int begin) +static void do_lat_lon(char *sentence, int begin, struct OUTDATA *out) { double lat, lon, d, m; char str[20], *p; @@ -205,9 +204,9 @@ static void do_lat_lon(char *sentence, int begin) p = field(sentence, begin + 1); if (*p == 'S') lat = -lat; - if (gNMEAdata.latitude != lat) { - gNMEAdata.latitude = lat; - gNMEAdata.cmask |= C_LATLON; + if (out->latitude != lat) { + out->latitude = lat; + out->cmask |= C_LATLON; } updated++; } @@ -220,19 +219,19 @@ static void do_lat_lon(char *sentence, int begin) p = field(sentence, begin + 3); if (*p == 'W') lon = -lon; - if (gNMEAdata.longitude != lon) { - gNMEAdata.longitude = lon; - gNMEAdata.cmask |= C_LATLON; + if (out->longitude != lon) { + out->longitude = lon; + out->cmask |= C_LATLON; } updated++; } if (updated == 2) - gNMEAdata.ts_latlon = time(NULL); + out->ts_latlon = time(NULL); } /* ----------------------------------------------------------------------- */ -static void update_field_i(char *sentence, int fld, int *dest, int mask) +static void update_field_i(char *sentence, int fld, int *dest, int mask, struct OUTDATA *out) { int tmp; @@ -240,12 +239,12 @@ static void update_field_i(char *sentence, int fld, int *dest, int mask) if (tmp != *dest) { *dest = tmp; - gNMEAdata.cmask |= mask; + out->cmask |= mask; } } #if 0 -static void update_field_f(char *sentence, int fld, double *dest, int mask) +static void update_field_f(char *sentence, int fld, double *dest, int mask, struct OUTDATA *out) { double tmp; @@ -253,7 +252,7 @@ static void update_field_f(char *sentence, int fld, double *dest, int mask) if (tmp != *dest) { *dest = tmp; - gNMEAdata.cmask |= mask; + out->cmask |= mask; } } #endif @@ -306,3 +305,26 @@ static char *field(char *sentence, short n) *p = '\0'; return result; } + +int process_NMEA_message(char *sentence, struct OUTDATA *outdata) +{ + if (checksum(sentence)) { + if (strncmp(GPRMC, sentence, 5) == 0) { + processGPRMC(sentence, outdata); + } else if (strncmp(GPGGA, sentence, 5) == 0) { + processGPGGA(sentence, outdata); + } else if (strncmp(GPVTG, sentence, 5) == 0) { + processGPVTG(sentence, outdata); + } else if (strncmp(GPGSA, sentence, 5) == 0) { + processGPGSA(sentence, outdata); + } else if (strncmp(GPGSV, sentence, 5) == 0) { + processGPGSV(sentence, outdata); + } else if (strncmp(PRWIZCH, sentence, 7) == 0) { + processPRWIZCH(sentence, outdata); + } else { + return -1; + } + } + return 0; +} + @@ -6,6 +6,8 @@ #define C_STATUS 8 #define C_MODE 16 +#define MAXSATS 12 + struct OUTDATA { int fdin; int fdout; @@ -15,10 +17,12 @@ struct OUTDATA { long cmask; /* Change flag, set by backend. Reset by app. */ - char utc[20]; /* UTC date / time in format "mm/dd/yy hh:mm:ss" */ + char utc[20]; /* UTC date/time as "mm/dd/yy hh:mm:ss" */ time_t ts_utc; /* UTC last updated time stamp */ - double latitude; /* Latitude and longitude in format "d.ddddd" */ + + /* location */ + double latitude; /* Latitude/longitude in format "d.ddddd" */ double longitude; time_t ts_latlon; /* Update time stamp */ int v_latlon; /* Valid for v_latlon seconds */ @@ -27,10 +31,12 @@ struct OUTDATA { time_t ts_alt; int v_alt; + /* velocity */ double speed; /* Speed over ground, knots */ time_t ts_speed; int v_speed; + /* status and precision of fix */ int status; /* 0 = no fix, 1 = fix, 2 = dgps fix */ int mode; /* 1 = no fix, 2 = 2D, 3 = 3D */ time_t ts_mode; @@ -42,6 +48,7 @@ struct OUTDATA { double hdop; /* Horizontal dilution of precision */ double vdop; /* Vertical dilution of precision */ + /* satellite status */ int in_view; /* # of satellites in view */ int satellites; /* Number of satellites used in solution */ int PRN[12]; /* PRN of satellite */ diff --git a/send_nmea.c b/send_nmea.c index 2a106f18..cf921b10 100644 --- a/send_nmea.c +++ b/send_nmea.c @@ -1,4 +1,6 @@ #include <sys/types.h> +#include "outdata.h" +#include "nmea.h" #include "gpsd.h" @@ -15,20 +15,17 @@ #endif #endif +#include "outdata.h" +#include "nmea.h" #include "gpsd.h" #define DEFAULTPORT "2947" -extern int debug; -extern char *device_name; -extern int device_speed; - - /* define global variables */ static int ttyfd = -1; static struct termios ttyset, ttyset_old; -int serial_open() +int serial_open(char *device_name, int device_speed) { char *temp; char *p; @@ -43,8 +40,6 @@ int serial_open() *p = '\0'; /* temp now holds the HOSTNAME portion and port the port number. */ - if (debug > 5) - fprintf(stderr, "Host: %s Port: %s\n", temp, port); ttyfd = connectTCP(temp, port); port = 0; @@ -1,7 +1,7 @@ /* - * Handle the proprietary extensions to NMEA 0183 supported by thr TripMATE GPS. - * Also, if requested, intialize it with longitude, latitude, and local time. - * This will speed up its first fix. + * Handle the proprietary extensions to NMEA 0183 supported by the + * TripMATE GPS. Also, if requested, intialize it with longitude, + * latitude, and local time. This will speed up its first fix. */ #include "config.h" #include <stdio.h> @@ -10,46 +10,11 @@ #include <fcntl.h> #include <string.h> #include <syslog.h> -#include "gpsd.h" -#include "nmea.h" #include "outdata.h" +#include "nmea.h" +#include "gpsd.h" - -struct OUTDATA gNMEAdata; - -extern char *latitude; -extern char *longitude; - -extern int debug; -extern int device_type; -extern char latd; -extern char lond; - -void process_message(char *sentence) -{ - if (checksum(sentence)) { - if (strncmp(PMGNST, sentence, 6) == 0) { - processPMGNST(sentence); - } else if (strncmp(GPRMC, sentence, 5) == 0) { - processGPRMC(sentence); - } else if (strncmp(GPGGA, sentence, 5) == 0) { - processGPGGA(sentence); - } else if (strncmp(GPVTG, sentence, 5) == 0) { - processGPVTG(sentence); - } else if (strncmp(GPGSA, sentence, 5) == 0) { - processGPGSA(sentence); - } else if (strncmp(GPGSV, sentence, 5) == 0) { - processGPGSV(sentence); - } else if (strncmp(PRWIZCH, sentence, 7) == 0) { - processPRWIZCH(sentence); - } else { - if (debug > 1) { - fprintf(stderr, "Unknown sentence: \"%s\"\n", - sentence); - } - } - } -} +extern struct session_t session; void send_init() { @@ -57,7 +22,7 @@ void send_init() time_t t; struct tm *tm; - if (latitude && longitude) { + if (session.initpos.latitude && session.initpos.longitude) { t = time(NULL); tm = gmtime(&t); @@ -66,13 +31,14 @@ void send_init() sprintf(buf, "$PRWIINIT,V,,,%s,%c,%s,%c,100.0,0.0,M,0.0,T,%02d%02d%02d,%02d%02d%02d*", - latitude, latd, longitude, lond, + session.initpos.latitude, session.initpos.latd, + session.initpos.longitude, session.initpos.lond, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_mday, tm->tm_mon + 1, tm->tm_year); add_checksum(buf + 1); /* add c-sum + cr/lf */ - if (gNMEAdata.fdout != -1) - write(gNMEAdata.fdout, buf, strlen(buf)); - if (debug > 1) { + if (session.gNMEAdata.fdout != -1) + write(session.gNMEAdata.fdout, buf, strlen(buf)); + if (session.debug > 1) { fprintf(stderr, "Sending: %s", buf); } } @@ -92,17 +58,17 @@ void do_init() void process_exception(char *sentence) { - if (strncmp("ASTRAL", sentence, 6) == 0 && isatty(gNMEAdata.fdout)) { - write(gNMEAdata.fdout, "$IIGPQ,ASTRAL*73\r\n", 18); + if (strncmp("ASTRAL", sentence, 6) == 0 && isatty(session.gNMEAdata.fdout)) { + write(session.gNMEAdata.fdout, "$IIGPQ,ASTRAL*73\r\n", 18); syslog(LOG_NOTICE, "Found a TripMate, initializing..."); do_init(); } else if ((strncmp("EARTHA", sentence, 6) == 0 - && isatty(gNMEAdata.fdout))) { - write(gNMEAdata.fdout, "EARTHA\r\n", 8); - device_type = DEVICE_EARTHMATEb; + && isatty(session.gNMEAdata.fdout))) { + write(session.gNMEAdata.fdout, "EARTHA\r\n", 8); + session.device_type = DEVICE_EARTHMATEb; syslog(LOG_NOTICE, "Found an EarthMate (id)."); do_eminit(); - } else if (debug > 1) { + } else if (session.debug > 1) { fprintf(stderr, "Unknown exception: \"%s\"", sentence); } @@ -110,22 +76,22 @@ void process_exception(char *sentence) void handle_message(char *sentence) { - if (debug > 5) + if (session.debug > 5) fprintf(stderr, "%s\n", sentence); if (*sentence == '$') - process_message(sentence + 1); + process_NMEA_message(sentence + 1, &session.gNMEAdata); else process_exception(sentence); - if (debug > 2) { + if (session.debug > 2) { fprintf(stderr, "Lat: %f Lon: %f Alt: %f Sat: %d Mod: %d Time: %s\n", - gNMEAdata.latitude, - gNMEAdata.longitude, - gNMEAdata.altitude, - gNMEAdata.satellites, - gNMEAdata.mode, - gNMEAdata.utc); + session.gNMEAdata.latitude, + session.gNMEAdata.longitude, + session.gNMEAdata.altitude, + session.gNMEAdata.satellites, + session.gNMEAdata.mode, + session.gNMEAdata.utc); } } diff --git a/xgpsspeed.c b/xgpsspeed.c index 59fcb963..659a94e5 100644 --- a/xgpsspeed.c +++ b/xgpsspeed.c @@ -11,23 +11,21 @@ #include "xgpsspeed.h" #include "xgpsspeed.icon" -#include "nmea.h" #include "outdata.h" +#include "nmea.h" #include "gpsd.h" #define BUFSIZE 4096 #define DEFAULTPORT "2947" -char latd, lond; -double latitude, longitude; -int device_type; -int debug = 0; #if defined(ultrix) || defined(SOLARIS) extern double rint(); #endif -Widget toplevel, base; -Widget tacho, label, title; +struct session_t session; + +static Widget toplevel, base; +static Widget tacho, label; static XrmOptionDescRec options[] = { {"-rv", "*reverseVideo", XrmoptionNoArg, "TRUE"}, @@ -139,9 +137,9 @@ void Usage() void update_display() { - int new = rint(gNMEAdata.speed * 6076.12 / 5280); + int new = rint(session.gNMEAdata.speed * 6076.12 / 5280); #if 0 - fprintf(stderr, "gNMEAspeed %f scaled %f %d\n", gNMEAdata.speed, rint(gNMEAdata.speed * 5208/6706.12), (int)rint(gNMEAdata.speed * 5208/6706.12)); + fprintf(stderr, "gNMEAspeed %f scaled %f %d\n", session.gNMEAdata.speed, rint(session.gNMEAdata.speed * 5208/6706.12), (int)rint(session.gNMEAdata.speed * 5208/6706.12)); #endif if (new > 100) new = 100; |