diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2009-08-22 21:54:06 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2009-08-22 21:54:06 +0000 |
commit | 894add2589562cf783f444ca7e83943045ffae43 (patch) | |
tree | 4918891d9e81d255e3349538ec8848754a7358f5 | |
parent | 0d626154f000d430f7434657e4001fd41969ae23 (diff) | |
download | gpsd-894add2589562cf783f444ca7e83943045ffae43.tar.gz |
Add flags argument to gps_stream().
Document how to translate old-protocol commands to new ones.
-rw-r--r-- | gps.h | 7 | ||||
-rwxr-xr-x | gps.py | 15 | ||||
-rw-r--r-- | libgps.c | 26 | ||||
-rw-r--r-- | libgps.xml | 6 | ||||
-rw-r--r-- | www/protocol-transition.txt (renamed from www/proto-transition.txt) | 57 |
5 files changed, 95 insertions, 16 deletions
@@ -956,11 +956,16 @@ struct gps_data_t { void (*thread_hook)(struct gps_data_t *, char *, size_t len, int level);/* Thread-callback hook for GPS data. */ }; +/* mode flags for gps_stream() */ +#define WATCH_RAW 0x01u +#define WATCH_NOJITTER 0x02u +#define WATCH_SCALED 0x04u + extern /*@null@*/ struct gps_data_t *gps_open(const char *host, const char *port); int gps_close(struct gps_data_t *); int gps_query(struct gps_data_t *gpsdata, const char *fmt, ... ); int gps_poll(struct gps_data_t *gpsdata); -int gps_stream(struct gps_data_t *gpsdata); +int gps_stream(struct gps_data_t *gpsdata, unsigned int flags); void gps_set_raw_hook(struct gps_data_t *gpsdata, void (*hook)(struct gps_data_t *sentence, char *buf, size_t len, int level)); 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); int gps_del_callback(struct gps_data_t *gpsdata, pthread_t *handler); @@ -52,6 +52,10 @@ MODE_3D = 3 MAXCHANNELS = 12 SIGNAL_STRENGTH_UNKNOWN = NaN +WATCH_RAW = 0x01 +WATCH_NOJITTER = 0x02 +WATCH_SCALED = 0x04 + # The spec says 82, but some receivers (TN-200, GSW 2.3.2) output 86 characters NMEA_MAX = 86 @@ -412,12 +416,13 @@ class gps(gpsdata): self.send(commands) return self.poll() - def stream(self): + def stream(self, flags=0): "Ask gpsd to stream reports at your client." - if self.raw_hook: - arg = 'w+r+' - else: - arg = 'w+' + arg = "w+x" + if self.raw_hook or (flags & WATCH_RAW): + arg += 'r+' + if self.raw_hook or (flags & WATCH_NOJITTER): + arg += 'j+' return self.query(arg) # some multipliers for interpreting GPS output @@ -493,20 +493,28 @@ int gps_query(struct gps_data_t *gpsdata, const char *fmt, ... ) return gps_poll(gpsdata); } -int gps_stream(struct gps_data_t *gpsdata) +int gps_stream(struct gps_data_t *gpsdata, unsigned int flags) /* ask gpsd to stream reports at you, hiding the command details */ { + char buf[GPS_JSON_COMMAND_MAX]; + #ifdef OLDSTYLE_ENABLE - if (gpsdata->raw_hook != NULL) - return gps_query(gpsdata, "w+r+x"); - else - return gps_query(gpsdata, "w+x"); + (void)strlcpy(buf, "w+x", sizeof(buf)); + if (gpsdata->raw_hook != NULL || (flags & WATCH_RAW)) + (void)strlcat(buf, "r+", sizeof(buf)); + if (flags & WATCH_NOJITTER) + (void)strlcat(buf, "j+", sizeof(buf)); #else - if (gpsdata->raw_hook != NULL) - return gps_query(gpsdata, "?WATCH={\"raw\":1}"); - else - return gps_query(gpsdata, "?WATCH={}"); + (void)strlcpy(buf, "?WATCH={", sizeof(buf)); + if (gpsdata->raw_hook != NULL || (flags & WATCH_RAW)) + (void)strlcat(buf, "\"raw\":1", sizeof(buf)); + if (flags & WATCH_NOJITTER) + (void)strlcat(buf, "\"buffer_policy\"=1", sizeof(buf)); + if (flags & WATCH_SCALED) + (void)strlcat(buf, "\"buffer_policy\"=1", sizeof(buf)); + (void)strlcat(buf, "};", sizeof(buf)); #endif + return gps_query(gpsdata, buf); } #ifdef HAVE_LIBPTHREAD @@ -64,6 +64,7 @@ C: <funcprototype> <funcdef>int <function>gps_stream</function></funcdef> <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef> + <paramdef>unsigned int<parameter>flags</parameter></paramdef> </funcprototype> <funcsynopsisinfo> @@ -149,7 +150,10 @@ to be made available whenn you poll. It is preferable to the older-style (pre-2.39) way of doing this, <function>gps_query()</function> with a "w+" argument, because it insulates your code from whether your client library and your -<application>gpsd</application> are using old or new protocol.</para> +<application>gpsd</application> are using old or new protocol. +The second argument is a flag mask that sets various policy bits; +see gps.h for description. Calling <function>gps_stream()</function> +more than once with different flag masks is allowed. </para> <para><function>gps_set_raw_hook()</function> takes a function you specify and run it (synchronously) on the raw data pulled by a diff --git a/www/proto-transition.txt b/www/protocol-transition.txt index a9e7669e..4e910bfb 100644 --- a/www/proto-transition.txt +++ b/www/protocol-transition.txt @@ -199,3 +199,60 @@ example) mixed GPS and AIS data. In the future, the stream from gpsd could include other kinds of data, such as the take from a digital compass, water-temperature sensors, or even aircraft transponders. + +== How the command set has changed == + +If your code issues old-protocol commands A, D, E, M, P, T, U, or V, +it is a wretched hive of scum and villainy that probably hasn't +changed since before the introduction of "w". You are using the +oldest single-shot commands and will have to rewrite your interface +significantly, as the new protocol does not support equivalents. Use +libgps. + +If your code issues B, C, or N commands, they need to change to +?CONFIGDEV commands. See the protocol reference for details. + +The old 'F' and 'G' commands do not have equivalents. It would be +possible to implement these, but we probably won't do it unless there is +actual demand. Consider teaching your client to ignore fix updates +when they don't have a specified "device" or "class" tag, respectively. + +The old 'I' command has no equivalent. You probably issued it as part +of an initialization string, hoping that a subtype string would later +show up in gps_id so you could post it somewhere. In the new +protocol, when a device sends back subtype information the daemon +ships the client an object of class DEVICE with a device tag and +subtype fields. Watch for that and process appropriately. + +The old 'J' command has been replaced by an optional attribute in +?WATCH. Include the WATCH_NOJITTER mask in the argument of +gps_stream(). + +The old 'K' command is replaced by ?DEVICES. + +The old 'L' command is replaced by ?VERSION. + +The old 'O' command is replaced by ?TPV'. Note: it is possible +this command will be removed in the final version of the new +protocol. Do not rely on it. + +The old 'Q' and 'S' commands doe not have exact equivalents. We will +implement an option to have the TPV response include DOPS and status +if there is demand for them. + +The old 'R' command has been replaced by an optional attribute in +?WATCH. Include the WATCH_RAW mask in the argument of +gps_stream(), or set a raw hook before alling gps_stream(). + +The old 'W' command has been replaced by ?WATCH. Calll gps_stream() +with whatever option you want to set. + +The old 'X' command is gone. Instead, you will see an object of +class DEVICE from the daemon whenever a device is opened or closes. + +The old 'Y' command is replaced by ?SKY. Note: it is possible +this command will be removed in the final version of the new +protocol. Do not rely on it. + +The old 'Z' and '$' commands, used by the developers for profiling, +have no equivalents. We'll implement them if we need them. |