summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2004-08-15 21:16:17 +0000
committerEric S. Raymond <esr@thyrsus.com>2004-08-15 21:16:17 +0000
commited60908bf533ca9580b3b0eb8be3a5d4dae7258e (patch)
tree4cf38982ac44dff1e165bc9d43a16251b2c43335
parentb2252400bd5438c8ab012830ed67f77b933a46a7 (diff)
downloadgpsd-ed60908bf533ca9580b3b0eb8be3a5d4dae7258e.tar.gz
Code now consistently uses timestamp objects; the old cflags are gone.
-rw-r--r--README3
-rw-r--r--display.c4
-rw-r--r--em.c4
-rw-r--r--gps.c5
-rw-r--r--gpsd.c15
-rw-r--r--gpsd.h17
-rw-r--r--gpsd.xml15
-rw-r--r--nmea_parse.c48
8 files changed, 57 insertions, 54 deletions
diff --git a/README b/README
index 5c9e319d..bfbc4a75 100644
--- a/README
+++ b/README
@@ -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
diff --git a/display.c b/display.c
index d2a2580b..4d31442a 100644
--- a/display.c
+++ b/display.c
@@ -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);
diff --git a/em.c b/em.c
index 15c75527..5ca8d0f1 100644
--- a/em.c
+++ b/em.c
@@ -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)
diff --git a/gps.c b/gps.c
index dfa4a0ae..d79eeb24 100644
--- a/gps.c
+++ b/gps.c
@@ -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;
}
/**************************************************
diff --git a/gpsd.c b/gpsd.c
index 9a2cdc6b..f488c15c 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -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");
diff --git a/gpsd.h b/gpsd.h
index f7b46be2..1deb9ffc 100644
--- a/gpsd.h
+++ b/gpsd.h
@@ -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;
diff --git a/gpsd.xml b/gpsd.xml
index 5656b8a1..8165c57d 100644
--- a/gpsd.xml
+++ b/gpsd.xml
@@ -186,7 +186,8 @@ errors in meters &mdash; 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 &mdash;
+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);
}
/* ----------------------------------------------------------------------- */