diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2004-08-15 21:16:17 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2004-08-15 21:16:17 +0000 |
commit | ed60908bf533ca9580b3b0eb8be3a5d4dae7258e (patch) | |
tree | 4cf38982ac44dff1e165bc9d43a16251b2c43335 | |
parent | b2252400bd5438c8ab012830ed67f77b933a46a7 (diff) | |
download | gpsd-ed60908bf533ca9580b3b0eb8be3a5d4dae7258e.tar.gz |
Code now consistently uses timestamp objects; the old cflags are gone.
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | display.c | 4 | ||||
-rw-r--r-- | em.c | 4 | ||||
-rw-r--r-- | gps.c | 5 | ||||
-rw-r--r-- | gpsd.c | 15 | ||||
-rw-r--r-- | gpsd.h | 17 | ||||
-rw-r--r-- | gpsd.xml | 15 | ||||
-rw-r--r-- | nmea_parse.c | 48 |
8 files changed, 57 insertions, 54 deletions
@@ -99,6 +99,9 @@ New features include: * New y and z commands support signal-status reporting and satellite location -- it should no longer ever be necessary for clients to go to raw mode unless they want to monitor and log the GPS stream. + * New 'w' command toggles 'watcher' mode. In watcher mode gpsd ships + a gpsd-style response for each incoming sentence as if the client + had just sent all commands that asked for data contained in the sentence. * Massive refactoring -- one main loop now calls a self-contained driver object for each type. * The GPS-bashing code this program uses can now be directly linked as a @@ -112,7 +112,7 @@ int get_status(int satellite) int i; int s; - if (session.gNMEAdata.cmask & C_ZCH) { + if (SEEN(session.gNMEAdata.signal_quality_stamp)) { for (i = 0; i < 12; i++) if (satellite == session.gNMEAdata.Zs[i]) return session.gNMEAdata.Zv[i]; @@ -138,7 +138,7 @@ void draw_graphics() double x, y; char buf[20]; - if (session.gNMEAdata.cmask & (C_SAT | C_ZCH)) { + if (SEEN(session.gNMEAdata.satellite_stamp) || SEEN(session.gNMEAdata.signal_quality_stamp)) { i = min(width, height); @@ -271,9 +271,7 @@ static void handle1000(struct gpsd_t *session, unsigned short *p) session->gNMEAdata.mode = 1; } REFRESH(session->gNMEAdata.status_stamp); - session->gNMEAdata.cmask |= C_STATUS; REFRESH(session->gNMEAdata.mode_stamp); - session->gNMEAdata.cmask |= C_MODE; session->gNMEAdata.separation = p[O(33)] / 100; /* meters */ } @@ -305,7 +303,7 @@ static void handle1002(struct gpsd_t *session, unsigned short *p) break; } } - session->gNMEAdata.cmask |= C_ZCH; + REFRESH(session->gNMEAdata.signal_quality_stamp); } static void handle1003(struct gpsd_t *session, unsigned short *p) @@ -319,7 +319,7 @@ void update_display(char *message) XmTextFieldSetString(status, message); /* This is for the satellite status display */ - if (session.gNMEAdata.cmask & C_SAT) { + if (SEEN(session.gNMEAdata.satellite_stamp)) { for (i = 0; i < 12; i++) { if (i < session.gNMEAdata.in_view) { sprintf(s, "%2d %02d %03d %02d", session.gNMEAdata.PRN[i], @@ -333,7 +333,7 @@ void update_display(char *message) for (i = 0; i < 12; i++) XmStringFree(string[i]); } - if (session.gNMEAdata.cmask & C_ZCH) { + if (SEEN(session.gNMEAdata.signal_quality_stamp)) { for (i = 0; i < 12; i++) { sprintf(s, "%2d %02x", session.gNMEAdata.Zs[i], session.gNMEAdata.Zv[i]); string[i] = XmStringCreateSimple(s); @@ -366,7 +366,6 @@ void update_display(char *message) XmTextFieldSetString(text_5, s); draw_graphics(); - session.gNMEAdata.cmask = 0; } /************************************************** @@ -310,14 +310,14 @@ static int handle_request(int fd, char *buf, int buflen) case 'Y': case 'y': sc = 0; - if (session.gNMEAdata.cmask & C_SAT) + if (SEEN(session.gNMEAdata.satellite_stamp)) for (i = 0; i < MAXCHANNELS; i++) if (session.gNMEAdata.PRN[i]) sc++; sprintf(reply + strlen(reply), ",Y=%d ", sc); - for (i = 0; i < MAXCHANNELS; i++) - if (session.gNMEAdata.cmask & C_SAT) + if (SEEN(session.gNMEAdata.satellite_stamp)) + for (i = 0; i < MAXCHANNELS; i++) if (session.gNMEAdata.PRN[i]) sprintf(reply + strlen(reply),"%d %2d %2d ", session.gNMEAdata.PRN[i], @@ -327,13 +327,13 @@ static int handle_request(int fd, char *buf, int buflen) case 'Z': case 'z': sc = 0; - if (session.gNMEAdata.cmask & C_SAT) + if (SEEN(session.gNMEAdata.satellite_stamp)) { for (i = 0; i < MAXCHANNELS; i++) if (session.gNMEAdata.PRN[i]) sc++; } - else if (session.gNMEAdata.cmask & C_ZCH) + else if (SEEN(session.gNMEAdata.signal_quality_stamp)) { for (i = 0; i < MAXCHANNELS; i++) if (session.gNMEAdata.Zs[i]) @@ -342,14 +342,14 @@ static int handle_request(int fd, char *buf, int buflen) sprintf(reply + strlen(reply), ",Z=%d ", sc); for (i = 0; i < MAXCHANNELS; i++) - if (session.gNMEAdata.cmask & C_SAT) + if (SEEN(session.gNMEAdata.satellite_stamp)) { if (session.gNMEAdata.PRN[i]) sprintf(reply + strlen(reply),"%d %02d ", session.gNMEAdata.PRN[i], session.gNMEAdata.ss[i]); } - else + else if (SEEN(session.gNMEAdata.signal_quality_stamp)) { if (session.gNMEAdata.Zs[i]) sprintf(reply + strlen(reply),"%d %02d ", @@ -392,6 +392,7 @@ static void raw_hook(char *sentence) /* some listeners may be in push mode */ int ok = 1; + ++sentence; #define PUBLISH(fd, cmds) handle_request(fd, cmds, sizeof(cmds)-1) if (strncmp(GPRMC, sentence, 5) == 0) { ok = PUBLISH(fd, "pvs"); @@ -3,12 +3,6 @@ #include <sys/types.h> #include <time.h> -#define C_LATLON 1 -#define C_SAT 2 -#define C_ZCH 4 -#define C_STATUS 8 -#define C_MODE 16 - #define MAXCHANNELS 12 struct life_t @@ -20,10 +14,10 @@ struct life_t #define INIT(stamp, now, tl) stamp.time_to_live=tl; stamp.last_refresh=now #define REFRESH(stamp) stamp.last_refresh = time(NULL) #define FRESH(stamp, t) stamp.last_refresh + stamp.time_to_live >= t +#define CHANGED(stamp, now) stamp.last_refresh == now +#define SEEN(stamp) stamp.last_refresh != 0 struct OUTDATA { - long cmask; /* Change flag, set by backend. Reset by app. */ - char utc[20]; /* UTC date/time as "mm/dd/yy hh:mm:ss" */ time_t ts_utc; /* UTC last updated time stamp */ @@ -38,25 +32,26 @@ struct OUTDATA { /* velocity */ double speed; /* Speed over ground, knots */ - struct life_t speed_stamp; double mag_var; /* magnetic variation in degrees */ double course; /* course made good */ + struct life_t speed_stamp; /* status and precision of fix */ int status; #define STATUS_NO_FIX 0 #define STATUS_FIX 1 #define STATUS_DGPS_FIX 2 + struct life_t status_stamp; int mode; #define MODE_NO_FIX 1 #define MODE_2D 2 #define MODE_3D 3 struct life_t mode_stamp; - struct life_t status_stamp; double pdop; /* Position dilution of precision, meters */ double hdop; /* Horizontal dilution of precision, meters */ double vdop; /* Vertical dilution of precision, meters */ double separation; /* geoidal separation */ + struct life_t fix_quality_stamp; /* satellite status */ int in_view; /* # of satellites in view */ @@ -66,10 +61,12 @@ struct OUTDATA { int azimuth[MAXCHANNELS]; /* azimuth */ int ss[MAXCHANNELS]; /* signal strength */ int used[MAXCHANNELS]; /* used in solution */ + struct life_t satellite_stamp; /* Zodiac chipset channel status from PRWIZCH */ int Zs[MAXCHANNELS]; /* satellite PRNs */ int Zv[MAXCHANNELS]; /* signal values (0-7) */ + struct life_t signal_quality_stamp; int year; int month; @@ -186,7 +186,8 @@ errors in meters — position, horizontal, and vertical.</para> <varlistentry> <term>r</term> <listitem><para>Toggles 'raw' mode. Return "R=0" or "R=1". In raw mode -you read the unfiltered data stream from the GPS</para></listitem> +you read the NMEA data stream from the GPS. (Non-NMEA GPSes get +their communication format translated to NMEA on the fly.)</para></listitem> </varlistentry> <varlistentry> @@ -201,6 +202,18 @@ you read the unfiltered data stream from the GPS</para></listitem> </varlistentry> <varlistentry> +<term>w</term> +<listitem><para>Toggles 'watcher' mode. Return "W=0" or "W=1". In +watcher mode gpsd ships a line of data to the client each time the the GPS +sends a sentence, but rather than being raw NMEA the line is a gpsd +response as if the user had just sent some set of gpsd commands. That set of +commands is the minimum for which the incoming sentence is relevant — +e.g., a GPRMC sentence ships a "pvs" response because it contains +position, velocity and GPS status data. +</para></listitem> +</varlistentry> + +<varlistentry> <term>y</term> <listitem> <para>Returns Y= followed by a count not more than 12, followed by diff --git a/nmea_parse.c b/nmea_parse.c index 37392a50..3906f9c1 100644 --- a/nmea_parse.c +++ b/nmea_parse.c @@ -47,7 +47,6 @@ static void do_lat_lon(char *sentence, int begin, struct OUTDATA *out) lat = -lat; if (out->latitude != lat) { out->latitude = lat; - out->cmask |= C_LATLON; } updated++; } @@ -62,7 +61,6 @@ static void do_lat_lon(char *sentence, int begin, struct OUTDATA *out) lon = -lon; if (out->longitude != lon) { out->longitude = lon; - out->cmask |= C_LATLON; } updated++; } @@ -80,29 +78,19 @@ static void do_lat_lon(char *sentence, int begin, struct OUTDATA *out) /* ----------------------------------------------------------------------- */ -static void update_field_i(char *sentence, int fld, int *dest, int mask, struct OUTDATA *out) +static void update_field_i(char *sentence, int fld, int *dest, struct OUTDATA *out) { int tmp; sscanf(field(sentence, fld), "%d", &tmp); - - if (tmp != *dest) { - *dest = tmp; - out->cmask |= mask; - } } #if 0 -static void update_field_f(char *sentence, int fld, double *dest, int mask, struct OUTDATA *out) +static void update_field_f(char *sentence, int fld, double *dest, struct OUTDATA *out) { double tmp; scanf(field(sentence, fld), "%lf", &tmp); - - if (tmp != *dest) { - *dest = tmp; - out->cmask |= mask; - } } #endif @@ -169,15 +157,19 @@ static void processGPRMC(char *sentence, struct OUTDATA *out) do_lat_lon(sentence, 3, out); /* A = valid, V = invalid */ - if (strcmp(field(sentence, 2), "V") == 0) + if (strcmp(field(sentence, 2), "A") == 0) + out->status = STATUS_FIX; + else { gpscli_report(2, "Invalid GPRMC zeroes status.\n"); - out->status = 0; + out->status = STATUS_NO_FIX; } + REFRESH(out->speed_stamp); sscanf(field(sentence, 7), "%lf", &out->speed); sscanf(field(sentence, 8), "%lf", &out->course); + REFRESH(out->speed_stamp); } /* ----------------------------------------------------------------------- */ @@ -284,6 +276,7 @@ static void processGPVTG(char *sentence, struct OUTDATA *out) sscanf(field(sentence, 5), "%lf", &out->speed); else sscanf(field(sentence, 3), "%lf", &out->speed); + REFRESH(out->speed_stamp); } /* ----------------------------------------------------------------------- */ @@ -314,7 +307,6 @@ static void processGPGGA(char *sentence, struct OUTDATA *out) sscanf(field(sentence, 6), "%d", &out->status); REFRESH(out->status_stamp); gpscli_report(2, "GPGGA sets status %d\n", out->status); - out->cmask |= C_STATUS; sscanf(field(sentence, 7), "%d", &out->satellites); sscanf(field(sentence, 9), "%lf", &out->altitude); REFRESH(out->altitude_stamp); @@ -344,11 +336,11 @@ static void processGPGSA(char *sentence, struct OUTDATA *out) sscanf(field(sentence, 2), "%d", &out->mode); REFRESH(out->mode_stamp); - out->cmask |= C_MODE; gpscli_report(2, "GPGSA sets mode %d\n", out->mode); sscanf(field(sentence, 15), "%lf", &out->pdop); sscanf(field(sentence, 16), "%lf", &out->hdop); sscanf(field(sentence, 17), "%lf", &out->vdop); + REFRESH(out->signal_quality_stamp); } /* ----------------------------------------------------------------------- */ @@ -374,20 +366,21 @@ static void processGPGSV(char *sentence, struct OUTDATA *out) if (sscanf(field(sentence, 2), "%d", &n) < 1) return; - update_field_i(sentence, 3, &out->in_view, C_SAT, out); + update_field_i(sentence, 3, &out->in_view, out); n = (n - 1) * 4; m = n + 4; 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); + update_field_i(sentence, f++, &out->PRN[n], out); + update_field_i(sentence, f++, &out->elevation[n], out); + update_field_i(sentence, f++, &out->azimuth[n], out); if (*(field(sentence, f))) - update_field_i(sentence, f, &out->ss[n], C_SAT, out); + update_field_i(sentence, f, &out->ss[n], out); f++; n++; } + REFRESH(out->satellite_stamp); } /* ----------------------------------------------------------------------- */ @@ -420,7 +413,7 @@ static void processPMGNST(char *sentence, struct OUTDATA *out) sscanf(field(sentence, 2), "%d", &tmp1); sscanf(field(sentence, 3), "%c", &foo); - if (!(out->cmask&C_STATUS)) { + if (!SEEN(out->status_stamp)) { if (foo == 'T') { out->status = 1; out->mode = tmp1; @@ -430,9 +423,7 @@ static void processPMGNST(char *sentence, struct OUTDATA *out) out->mode = 1; } REFRESH(out->status_stamp); - out->cmask |= C_STATUS; REFRESH(out->mode_stamp); - out->cmask |= C_MODE; gpscli_report(2, "PMGNST sets status %d, mode %d\n", out->status, out->mode); } } @@ -453,9 +444,10 @@ static void processPRWIZCH(char *sentence, struct OUTDATA *out) int i; for (i = 0; i < 12; i++) { - 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); + update_field_i(sentence, 2 * i + 1, &out->Zs[i], out); + update_field_i(sentence, 2 * i + 2, &out->Zv[i], out); } + REFRESH(out->signal_quality_stamp); } /* ----------------------------------------------------------------------- */ |