summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2009-08-22 21:54:06 +0000
committerEric S. Raymond <esr@thyrsus.com>2009-08-22 21:54:06 +0000
commit894add2589562cf783f444ca7e83943045ffae43 (patch)
tree4918891d9e81d255e3349538ec8848754a7358f5
parent0d626154f000d430f7434657e4001fd41969ae23 (diff)
downloadgpsd-894add2589562cf783f444ca7e83943045ffae43.tar.gz
Add flags argument to gps_stream().
Document how to translate old-protocol commands to new ones.
-rw-r--r--gps.h7
-rwxr-xr-xgps.py15
-rw-r--r--libgps.c26
-rw-r--r--libgps.xml6
-rw-r--r--www/protocol-transition.txt (renamed from www/proto-transition.txt)57
5 files changed, 95 insertions, 16 deletions
diff --git a/gps.h b/gps.h
index 5a566c55..0d119a67 100644
--- a/gps.h
+++ b/gps.h
@@ -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);
diff --git a/gps.py b/gps.py
index fb890785..6c8df0f4 100755
--- a/gps.py
+++ b/gps.py
@@ -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
diff --git a/libgps.c b/libgps.c
index c3e0ef72..f74f6dfc 100644
--- a/libgps.c
+++ b/libgps.c
@@ -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
diff --git a/libgps.xml b/libgps.xml
index 053f8e9d..0b6756ee 100644
--- a/libgps.xml
+++ b/libgps.xml
@@ -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.