summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2009-09-17 10:16:23 +0000
committerEric S. Raymond <esr@thyrsus.com>2009-09-17 10:16:23 +0000
commit6dd560b389a7ed2dbbfcb6485342745ceedbbe91 (patch)
tree642527bb30bf0507434f018fcc0f0c8a1654a53b
parent9cdbb998794f19a64b5597002cbf8ade0938357a (diff)
downloadgpsd-6dd560b389a7ed2dbbfcb6485342745ceedbbe91.tar.gz
Disentangle the packet raw hook used on the client side...
...from the internals of gpsd. Besides being better factoring, this will give us better control of the daemon's report-generation policy in the future. All regression tests pass. Codebase splints clean.
-rw-r--r--cgps.c9
-rw-r--r--gps.h10
-rw-r--r--gpsd.c37
-rw-r--r--gpsd.h-tail2
-rw-r--r--gpxlogger.c2
-rw-r--r--lcdgps.c3
-rw-r--r--libgps.c12
-rw-r--r--libgps.xml6
-rw-r--r--libgpsd_core.c36
-rw-r--r--libgpsmm.cpp2
-rw-r--r--libgpsmm.h2
-rw-r--r--pseudonmea.c4
-rw-r--r--www/protocol-transition.txt18
-rw-r--r--xgps.c3
-rw-r--r--xgpsspeed.c2
15 files changed, 71 insertions, 77 deletions
diff --git a/cgps.c b/cgps.c
index 412efa85..65754e8e 100644
--- a/cgps.c
+++ b/cgps.c
@@ -222,8 +222,7 @@ static enum deg_str_type deg_type = deg_dd;
update_compass_panel(). */
static void update_probe(struct gps_data_t *gpsdata,
char *message,
- size_t len UNUSED ,
- int level UNUSED)
+ size_t len UNUSED)
{
/* Send an 'i' once per second until we figure out what the GPS
device is. */
@@ -401,8 +400,7 @@ static void windowsetup(void){
/* This gets called once for each new compass sentence. */
static void update_compass_panel(struct gps_data_t *gpsdata,
char *message,
- size_t len UNUSED ,
- int level UNUSED)
+ size_t len UNUSED)
{
char scr[128];
/* Print time/date. */
@@ -462,8 +460,7 @@ static void update_compass_panel(struct gps_data_t *gpsdata,
/* This gets called once for each new GPS sentence. */
static void update_gps_panel(struct gps_data_t *gpsdata,
char *message,
- size_t len UNUSED ,
- int level UNUSED)
+ size_t len UNUSED)
{
int i,n;
int newstate;
diff --git a/gps.h b/gps.h
index 11132e93..c2d3efa3 100644
--- a/gps.h
+++ b/gps.h
@@ -958,10 +958,10 @@ struct gps_data_t {
double c_recv_time; /* client receipt time (-> T2) */
double c_decode_time; /* client end-of-decode time (-> D2) */
- /* these members are private */
+ /* hook functions */
int gps_fd; /* socket or file descriptor to GPS */
- void (*raw_hook)(struct gps_data_t *, char *, size_t len, int level);/* Raw-mode hook for GPS data. */
- void (*thread_hook)(struct gps_data_t *, char *, size_t len, int level);/* Thread-callback hook for GPS data. */
+ void (*raw_hook)(struct gps_data_t *, char *, size_t len); /* Raw-mode hook for GPS data. */
+ void (*thread_hook)(struct gps_data_t *, char *, size_t len);/* Thread-callback hook for GPS data. */
};
/* mode flags for gps_stream() */
@@ -976,8 +976,8 @@ extern int gps_close(struct gps_data_t *);
extern int gps_query(struct gps_data_t *gpsdata, const char *fmt, ... );
extern int gps_poll(struct gps_data_t *gpsdata);
extern int gps_stream(struct gps_data_t *gpsdata, unsigned int flags);
-extern void gps_set_raw_hook(struct gps_data_t *gpsdata, void (*hook)(struct gps_data_t *sentence, char *buf, size_t len, int level));
-extern int gps_set_callback(struct gps_data_t *gpsdata, void (*callback)(struct gps_data_t *sentence, char *buf, size_t len, int level), pthread_t *handler);
+extern void gps_set_raw_hook(struct gps_data_t *gpsdata, void (*hook)(struct gps_data_t *sentence, char *buf, size_t len));
+extern int gps_set_callback(struct gps_data_t *gpsdata, void (*callback)(struct gps_data_t *sentence, char *buf, size_t len), pthread_t *handler);
extern int gps_del_callback(struct gps_data_t *gpsdata, pthread_t *handler);
extern char /*@observer@*/ *gps_errstr(const int);
diff --git a/gpsd.c b/gpsd.c
index 32a797ce..f032ba0c 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -600,14 +600,13 @@ static void deactivate_device(struct gps_device_t *device)
}
}
-static void raw_hook(struct gps_data_t *ud,
- char *sentence, size_t len, int level)
+static void internal_raw_hook(struct gps_data_t *ud, char *sentence, size_t len)
/* hook to be executed on each incoming packet */
{
struct channel_t *channel;
for (channel = channels; channel < channels + NITEMS(channels); channel++)
- if (channel->subscriber != NULL && channel->subscriber->policy.raw == level)
+ if (channel->subscriber != NULL)
{
struct subscriber_t *sub = channel->subscriber;
@@ -619,6 +618,33 @@ static void raw_hook(struct gps_data_t *ud,
}
}
+static void raw_hook(struct gps_device_t *session, char *data, size_t len)
+{
+ /* also copy the sentence up to clients in raw mode */
+ if (session->packet.type == NMEA_PACKET) {
+ internal_raw_hook(&session->gpsdata, data, len);
+ } else {
+ char buf2[MAX_PACKET_LENGTH*3+2];
+
+ buf2[0] = '\0';
+
+ /* Some kinds of data is automatically passed through */
+#ifdef BINARY_ENABLE
+#if defined(RTCM104V2_ENABLE) || defined(RTCM104V3_ENABLE)
+ if ((session->gpsdata.set & (RTCM2_SET | RTCM3_SET)) == 0)
+#endif /* defined(RTCM104V2_ENABLE) || defined(RTCM104V3_ENABLE) */
+ gpsd_pseudonmea_dump(session, buf2, sizeof(buf2));
+#endif /* BINARY_ENABLE */
+ if (buf2[0] != '\0') {
+ gpsd_report(LOG_IO, "<= GPS (binary) %s: %s",
+ session->gpsdata.dev.path, buf2);
+ internal_raw_hook(&session->gpsdata, buf2, strlen(buf2));
+ }
+ }
+ if (session->gpsdata.fix.mode == MODE_3D)
+ netgnss_report(session);
+}
+
/*@ -globstate @*/
/*@null@*/ /*@observer@*/static struct gps_device_t *find_device(char *device_name)
/* find the device block for an existing device name */
@@ -655,7 +681,6 @@ static bool open_device(char *device_name)
return false;
found:
gpsd_init(devp, &context, device_name);
- devp->gpsdata.raw_hook = raw_hook;
#ifdef OLDSTYLE_ENABLE
/*
* Bring the device all the way so we'll sniff packets from it and
@@ -689,7 +714,6 @@ static bool add_device(char *device_name)
for (devp = devices; devp < devices + MAXDEVICES; devp++)
if (!allocated_device(devp)) {
gpsd_init(devp, &context, device_name);
- devp->gpsdata.raw_hook = raw_hook;
gpsd_report(LOG_INF,"stashing device %s at slot %d\n",
device_name,
(int)(devp - devices));
@@ -2209,6 +2233,9 @@ int main(int argc, char *argv[])
{
gpsd_report(LOG_RAW+1, "polling %d\n", device->gpsdata.gps_fd);
changed = gpsd_poll(device);
+ raw_hook(device,
+ (char *)device->packet.outbuffer,
+ (size_t)device->packet.outbuflen);
if (changed == ERROR_SET) {
gpsd_report(LOG_WARN, "packet sniffer failed to sync up\n");
FD_CLR(device->gpsdata.gps_fd, &all_fds);
diff --git a/gpsd.h-tail b/gpsd.h-tail
index e10cf6f8..26429947 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -476,7 +476,7 @@ extern int netlib_connectsock(const char *, const char *, const char *);
extern char /*@observer@*/ *netlib_errstr(const int);
extern char /*@observer@*/ *sock2ip(int);
-extern void gpsd_binary_dump(struct gps_device_t *, char[], size_t);
+extern void gpsd_pseudonmea_dump(struct gps_device_t *, char[], size_t);
extern void ntpshm_init(struct gps_context_t *, bool);
extern int ntpshm_alloc(struct gps_context_t *);
diff --git a/gpxlogger.c b/gpxlogger.c
index a985a2d1..caaa39b0 100644
--- a/gpxlogger.c
+++ b/gpxlogger.c
@@ -266,7 +266,7 @@ static int dbus_mainloop(void)
struct fixsource_t source;
static void process(struct gps_data_t *gpsdata,
- char *buf UNUSED, size_t len UNUSED, int level UNUSED)
+ char *buf UNUSED, size_t len UNUSED)
{
/* this is where we implement source-device filtering */
if (gpsdata->dev.path[0] && source.device!=NULL && strcmp(source.device, gpsdata->dev.path) != 0)
diff --git a/lcdgps.c b/lcdgps.c
index 8964bb0f..64a40972 100644
--- a/lcdgps.c
+++ b/lcdgps.c
@@ -259,8 +259,7 @@ static enum deg_str_type deg_type = deg_dd;
/* This gets called once for each new sentence. */
static void update_lcd(struct gps_data_t *gpsdata,
char *message UNUSED,
- size_t len UNUSED,
- int level UNUSED)
+ size_t len UNUSED)
{
char tmpbuf[255];
#ifdef CLIMB
diff --git a/libgps.c b/libgps.c
index 9be3230c..9e0e1f6c 100644
--- a/libgps.c
+++ b/libgps.c
@@ -59,7 +59,7 @@ int gps_close(struct gps_data_t *gpsdata)
}
void gps_set_raw_hook(struct gps_data_t *gpsdata,
- void (*hook)(struct gps_data_t *, char *, size_t len, int level))
+ void (*hook)(struct gps_data_t *, char *, size_t len))
{
gpsdata->raw_hook = hook;
}
@@ -438,9 +438,9 @@ int gps_unpack(char *buf, struct gps_data_t *gpsdata)
/*@ -compdef @*/
if (gpsdata->raw_hook)
- gpsdata->raw_hook(gpsdata, buf, strlen(buf), 1);
+ gpsdata->raw_hook(gpsdata, buf, strlen(buf));
if (gpsdata->thread_hook)
- gpsdata->thread_hook(gpsdata, buf, strlen(buf), 1);
+ gpsdata->thread_hook(gpsdata, buf, strlen(buf));
return 0;
}
@@ -556,7 +556,7 @@ static /*@null@*/void *poll_gpsd(void *args)
}
int gps_set_callback(struct gps_data_t *gpsdata,
- void (*callback)(struct gps_data_t *sentence, char *buf, size_t len, int level),
+ void (*callback)(struct gps_data_t *sentence, char *buf, size_t len),
pthread_t *handler)
/* set an asynchronous callback and launch a thread for it */
{
@@ -651,8 +651,8 @@ static void data_dump(struct gps_data_t *collect, time_t now)
}
-static void dumpline(struct gps_data_t *ud UNUSED, char *buf,
- size_t ulen UNUSED, int level UNUSED)
+static void dumpline(struct gps_data_t *ud UNUSED,
+ char *buf, size_t ulen UNUSED)
{
puts(buf);
}
diff --git a/libgps.xml b/libgps.xml
index a13d606c..2afd7d6b 100644
--- a/libgps.xml
+++ b/libgps.xml
@@ -35,7 +35,8 @@ C:
<funcprototype>
<funcdef>void <function>gps_set_raw_hook</function></funcdef>
<paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
- <paramdef>void (*<parameter>hook</parameter>)(struct gps_data_t *, char *buf)</paramdef>
+ <paramdef>void (*<parameter>hook</parameter>)(struct gps_data_t *,
+ char *buf, size_t len)</paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>gps_poll</function></funcdef>
@@ -48,7 +49,8 @@ C:
<funcprototype>
<funcdef>void <function>gps_set_callback</function></funcdef>
<paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
- <paramdef>void (*<parameter>callback</parameter>)(struct gps_data_t *sentence, char *buf)</paramdef>
+ <paramdef>void (*<parameter>callback</parameter>)(struct
+ gps_data_t *sentence, char *buf, size_t len)</paramdef>
<paramdef>pthread_t *<parameter>handler</parameter></paramdef>
</funcprototype>
<funcprototype>
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 1d39164e..1f0c0f2f 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -520,11 +520,6 @@ gps_mask_t gpsd_poll(struct gps_device_t *session)
gpsd_report(LOG_RAW+3, "Accepted packet on %s.\n",
session->gpsdata.dev.path);
- /*@ -nullstate @*/
- if (session->gpsdata.raw_hook)
- session->gpsdata.raw_hook(&session->gpsdata,
- (char *)session->packet.outbuffer,
- (size_t)session->packet.outbuflen, 2);
/* collect profiling data */
session->gpsdata.sentence_length = session->packet.outbuflen;
@@ -583,37 +578,6 @@ gps_mask_t gpsd_poll(struct gps_device_t *session)
session->gpsdata.d_decode_time = timestamp();
- /* also copy the sentence up to clients in raw mode */
- if (session->packet.type == NMEA_PACKET) {
- if (session->gpsdata.raw_hook)
- session->gpsdata.raw_hook(&session->gpsdata,
- (char *)session->packet.outbuffer,
- strlen((char *)session->packet.outbuffer),
- 1);
- } else {
- char buf2[MAX_PACKET_LENGTH*3+2];
-
- buf2[0] = '\0';
-
- /* Some kinds of data is automatically passed through */
-#ifdef BINARY_ENABLE
-#if defined(RTCM104V2_ENABLE) || defined(RTCM104V3_ENABLE)
- if ((session->gpsdata.set & (RTCM2_SET | RTCM3_SET)) == 0)
-#endif /* defined(RTCM104V2_ENABLE) || defined(RTCM104V3_ENABLE) */
- gpsd_binary_dump(session, buf2, sizeof(buf2));
-#endif /* BINARY_ENABLE */
- if (buf2[0] != '\0') {
- gpsd_report(LOG_IO, "<= GPS (binary) %s: %s",
- session->gpsdata.dev.path, buf2);
- if (session->gpsdata.raw_hook)
- session->gpsdata.raw_hook(&session->gpsdata,
- buf2, strlen(buf2), 1);
- }
- }
-
- if (session->gpsdata.fix.mode == MODE_3D)
- netgnss_report(session);
-
return session->gpsdata.set;
}
}
diff --git a/libgpsmm.cpp b/libgpsmm.cpp
index 2961e58d..8c2d90d9 100644
--- a/libgpsmm.cpp
+++ b/libgpsmm.cpp
@@ -53,7 +53,7 @@ struct gps_data_t* gpsmm::poll(void) {
}
}
-int gpsmm::set_callback(void (*hook)(struct gps_data_t *sentence, char *buf, size_t len, int level)) {
+int gpsmm::set_callback(void (*hook)(struct gps_data_t *sentence, char *buf, size_t len)) {
handler = new pthread_t;
return gps_set_callback(gps_data,hook,handler);
}
diff --git a/libgpsmm.h b/libgpsmm.h
index 29200e93..6ccaa9fc 100644
--- a/libgpsmm.h
+++ b/libgpsmm.h
@@ -21,7 +21,7 @@ class gpsmm {
struct gps_data_t* query(const char *request); //put a command to gpsd and return the updated struct
struct gps_data_t* stream(int); //set watcher and policy flags
struct gps_data_t* poll(void); //block until gpsd returns new data, then return the updated struct
- int set_callback(void (*hook)(struct gps_data_t *sentence, char *buf, size_t len, int level)); //set a callback funcition, called each time new data arrives
+ int set_callback(void (*hook)(struct gps_data_t *sentence, char *buf, size_t len)); //set a callback funcition, called each time new data arrives
int del_callback(void); //delete the callback function
void clear_fix(void);
diff --git a/pseudonmea.c b/pseudonmea.c
index c8c5d070..96b33600 100644
--- a/pseudonmea.c
+++ b/pseudonmea.c
@@ -174,7 +174,7 @@ static void gpsd_binary_quality_dump(struct gps_device_t *session,
char *bufp2 = bufp;
bool used_valid = (session->gpsdata.set & USED_SET)!= 0;
- if ((session->gpsdata.set & MODE_SET) != 0) {
+ if (session->device_type!=NULL && (session->gpsdata.set & MODE_SET) != 0) {
(void)snprintf(bufp, len-strlen(bufp),
"$GPGSA,%c,%d,", 'A', session->gpsdata.fix.mode);
j = 0;
@@ -226,7 +226,7 @@ static void gpsd_binary_quality_dump(struct gps_device_t *session,
#undef ZEROIZE
}
-void gpsd_binary_dump(struct gps_device_t *session,
+void gpsd_pseudonmea_dump(struct gps_device_t *session,
char bufp[], size_t len)
/* the only entry point - dump a device state in pseudo-NMEA */
{
diff --git a/www/protocol-transition.txt b/www/protocol-transition.txt
index 7dec882d..c271f574 100644
--- a/www/protocol-transition.txt
+++ b/www/protocol-transition.txt
@@ -81,6 +81,9 @@ unusual configuration commands. Here are the exceptions:
fail. Later in this document you will learn how to fix these
problems.
+* You set a per-packet raw hook. This feature was documented
+ incorrectly. It no longer takes a level argument.
+
You can probably ignore the rest of this document, unless
either (a) you want to learn about gpsd's new capabilities so you
can use them in creative ways, or (b) you want to caper with unholy glee
@@ -198,11 +201,11 @@ data by command. After each request, they would need to wait until a
response came back. Then, watcher mode was added. By saying "w+",
you could ask gpsd to stream GPS reports at you whenever it got them.
-In the new protocol, streaming is almost all there is. Every
-report coming up from the daemon is tagged with its device and type.
-Instead of issuing commands and then ewaiting for specific responses,
-clients should expect any kind of report at any time and merge it
-into client-local storage (libgps does this for you).
+In the new protocol, streaming is all there is. Every report coming
+up from the daemon is tagged with its device and type. Instead of
+issuing commands and then ewaiting for specific responses, clients
+should expect any kind of report at any time and merge it into
+client-local storage (libgps does this for you).
This change is necessary to cope with devices that may send (for
example) mixed GPS and AIS data. In the future, the stream from
@@ -244,7 +247,7 @@ The old 'L' command is replaced by ?VERSION. Note that the daemon now
ships a version response to each client on connect, so it will
probably never be necessary for you to issue a ?VERSION request.
-The old 'M' command has no equivalent. Mode is reported in the TVP response.
+The old 'M' command has no equivalent. Mode is reported in the TPV response.
The old 'O' and 'Y' commands are gone. Use ?WATCH and sample the
stream instead.
@@ -294,3 +297,6 @@ Data in this structure should be considered valid only when
DEVICELIST_SET is on in the top-level set member. Storage for
pathnames is no longer dynamically allocated, but static; to save
space, it lives in a union with several other substructures.
+
+The signature of the raw_hook member has changed. It no longer takes
+the final 'leve' argument, which libgps had always set to 1.
diff --git a/xgps.c b/xgps.c
index d9e30014..a5150faa 100644
--- a/xgps.c
+++ b/xgps.c
@@ -871,8 +871,7 @@ handle_input(XtPointer client_data UNUSED, int *source UNUSED, XtInputId *id UNU
/* runs on each sentence */
static void
-update_panel(struct gps_data_t *gpsdata, char *message,
- size_t len UNUSED, int level UNUSED)
+update_panel(struct gps_data_t *gpsdata, char *message, size_t len UNUSED)
{
unsigned int i;
int newstate;
diff --git a/xgpsspeed.c b/xgpsspeed.c
index 61c38f0c..1abf835c 100644
--- a/xgpsspeed.c
+++ b/xgpsspeed.c
@@ -39,7 +39,7 @@ static Widget toplevel;
static struct fixsource_t source;
static void update_display(struct gps_data_t *gpsdata,
- char *buf UNUSED, size_t len UNUSED, int level UNUSED)
+ char *buf UNUSED, size_t len UNUSED)
{
/* this is where we implement source-device filtering */
if (gpsdata->dev.path[0]!='\0' && source.device!=NULL && strcmp(source.device, gpsdata->dev.path) != 0)