diff options
-rw-r--r-- | gps/__init__.py | 4 | ||||
-rw-r--r-- | gps/fake.py | 2 | ||||
-rwxr-xr-x | gps/gps.py | 2 | ||||
-rw-r--r-- | gpsctl.c | 2 | ||||
-rwxr-xr-x | gpsprof | 8 | ||||
-rw-r--r-- | libgps.xml | 33 | ||||
-rw-r--r-- | libgpsmm.cpp | 2 | ||||
-rw-r--r-- | libgpsmm.h | 2 | ||||
-rw-r--r-- | www/client-howto.txt | 55 | ||||
-rwxr-xr-x | xgps | 2 | ||||
-rwxr-xr-x | xgpsspeed | 2 |
11 files changed, 55 insertions, 59 deletions
diff --git a/gps/__init__.py b/gps/__init__.py index 8766f7c0..cb73669c 100644 --- a/gps/__init__.py +++ b/gps/__init__.py @@ -3,8 +3,8 @@ # This file is Copyright (c) 2010 by the GPSD project # BSD terms apply: see the file COPYING in the distribution root for details. -api_major_version = 4 # bumped on incompatible changes -api_minor_version = 1 # bumped on compatible changes +api_major_version = 5 # bumped on incompatible changes +api_minor_version = 0 # bumped on compatible changes from gps import * from misc import * diff --git a/gps/fake.py b/gps/fake.py index 9d742f2e..2ff5627d 100644 --- a/gps/fake.py +++ b/gps/fake.py @@ -529,7 +529,7 @@ class TestSession: chosen.send(chosen.enqueued) chosen.enqueued = "" while chosen.waiting(): - chosen.poll() + chosen.read() if chosen.valid & gps.PACKET_SET: self.reporter(chosen.response) had_output = True @@ -297,7 +297,7 @@ class gps(gpsdata, gpsjson): self.data["c_decode"] = time.time() self.timings = self.data - def poll(self): + def read(self): "Read and interpret data from the daemon." status = gpscommon.read(self) if status <= 0: @@ -263,7 +263,7 @@ int main(int argc, char **argv) } /*@-nullpass@*/ - /* ^ someday, add out annotation to the gpspoll() param and remove */ + /* ^ someday, add out annotation to the gps_poll() param and remove */ if (!lowlevel) { /* OK, there's a daemon instance running. Do things the easy way */ struct devconfig_t *devlistp; @@ -395,12 +395,12 @@ def plotframe(await, fname, speed, threshold, title): sys.stderr.write("gpsprof: gpsd unreachable.\n") sys.exit(1) # Initialize - session.poll() + session.read() if session.version == None: print >>sys.stderr, "gpsprof: requires gpsd to speak new protocol." sys.exit(1) session.send("?DEVICES;") - while session.poll() != -1: + while session.read() != -1: if session.data["class"] == "DEVICES": break if len(session.data.devices) != 1: @@ -416,7 +416,7 @@ def plotframe(await, fname, speed, threshold, title): # Set parameters if speed: session.send('?DEVICE={"path":"%s","bps:":%d}' % (path, speed)) - session.poll() + session.read() if session.baudrate != speed: sys.stderr.write("gpsprof: baud rate change failed.\n") options = "" @@ -429,7 +429,7 @@ def plotframe(await, fname, speed, threshold, title): countdown = await basetime = time.time() while countdown > 0: - if session.poll() == -1: + if session.read() == -1: sys.stderr.write("gpsprof: gpsd has vanished.\n") sys.exit(1) baton.twirl() @@ -44,7 +44,7 @@ C: char *buf, size_t len)</paramdef> </funcprototype> <funcprototype> -<funcdef>int <function>gps_poll</function></funcdef> +<funcdef>int <function>gps_read</function></funcdef> <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef> </funcprototype> <funcprototype> @@ -126,14 +126,13 @@ returns a -1 if there was a Unix-level write error, otherwise 0. Please read the LIMITATIONS section for additional information and cautions.</para> -<para><function>gps_poll()</function> accepts a response, or sequence +<para><function>gps_read()</function> accepts a response, or sequence of responses, from the daemon and interprets it as though it were a -query response (the return value is as for a query). -<function>gps_poll()</function> returns the validity mask of the -received structure. This function does a blocking read waiting for -data from the daemon; it returns 0 for success, -1 with errno set on a -Unix-level read error, -1 with errno not set if the socket to -the daemon has closed. </para> +query response (the return value is as for a query). This function +does a blocking read waiting for data from the daemon; it returns a +count of bytes read for success, -1 with errno set on a Unix-level +read error, -1 with errno not set if the socket to the daemon has +closed. </para> <para><function>gps_waiting()</function> can be used to check whether there is data from the daemon. It returns true if there is, @@ -223,9 +222,9 @@ argument.</para> <varlistentry> <term>POLL_NONBLOCK</term> <listitem> -<para>Normally <function>gps_poll()</function> blocks until +<para>Normally <function>gps_read()</function> blocks until either there is a read error or some data is received from tha -daemon. In this mode, <function>gps_poll()</function> returns +daemon. In this mode, <function>gps_read()</function> returns immediately with a value of 0 if there is no input waiting.</para> </listitem> </varlistentry> @@ -233,7 +232,7 @@ immediately with a value of 0 if there is no input waiting.</para> <para><function>gps_set_raw_hook()</function> takes a function you specify and run it (synchronously) on the raw data pulled by a -<function>gps_query()</function> or <function>gps_poll()</function> +<function>gps_query()</function> or <function>gps_read()</function> call. The arguments passed to this hook will be a pointer to a structure containing parsed data, and a buffer containining the raw <application>gpsd</application> response.</para> @@ -242,12 +241,12 @@ raw <application>gpsd</application> response.</para> English) describing the error indicated by a nonzero return value from <function>gps_open()</function>.</para> -<para>Consult <filename>gps.h</filename> to learn more about the data members -and associated timestamps. Note that information will accumulate -in the session structure over time, and the 'valid' field is not -automatically zeroed by each poll. It is up to the client to -zero that field when appropriate and to keep an eye on the fix -and sentence timestamps.</para> +<para>Consult <filename>gps.h</filename> to learn more about the data +members and associated timestamps. Note that information will +accumulate in the session structure over time, and the 'valid' field +is not automatically zeroed by each <function>gps_read()</function>. +It is up to the client to zero that field when appropriate and to keep +an eye on the fix and sentence timestamps.</para> <para>The Python implementation supports the same facilities as the C library. <function>gps_open()</function> is replaced by the diff --git a/libgpsmm.cpp b/libgpsmm.cpp index c1e5391f..b03db6e1 100644 --- a/libgpsmm.cpp +++ b/libgpsmm.cpp @@ -45,7 +45,7 @@ struct gps_data_t* gpsmm::send(const char *request) { } } -struct gps_data_t* gpsmm::poll(void) { +struct gps_data_t* gpsmm::read(void) { if (gps_read(gps_data)<=0) { // we return null if there was a read() error or connection is cloed by gpsd return NULL; @@ -24,7 +24,7 @@ class LIBQGPSMMSHARED_EXPORT gpsmm { struct gps_data_t* open(void); //open() with default values struct gps_data_t* send(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 + struct gps_data_t* read(void); //block until gpsd returns new data, then return the updated struct int close(void); // close the GPS bool waiting(void); //nonblocking check for data waitin void clear_fix(void); diff --git a/www/client-howto.txt b/www/client-howto.txt index dd1fe454..f9669bf3 100644 --- a/www/client-howto.txt +++ b/www/client-howto.txt @@ -1,6 +1,6 @@ = GPSD Client HOWTO = Eric S. Raymond <esr@thyrsus.com> -v1.1, April 2010 +v1.2, April 2010 This document is mastered in asciidoc format. If you are reading it in HTML, you can find the original at @@ -290,7 +290,8 @@ Each library has the following entry points: * Nonblocking check to see if data from the daemon is waiting. Named something like "waiting()". -* Blocking poll for data from the daemon. Named something like "poll()". +* Blocking read for data from the daemon. Named something like "read()" + (this was "poll()" in older versions). * Close the session socket. Named something like "close()". @@ -305,8 +306,6 @@ Here is a complete table of the binding entry points: Function |gps_open() |gpsmm.gpsmm() |gps.\_\_init__() | In OO languages the client class initializer opens the daemon socket. -|gps_open_r() | | | -The C library, only, has an open variant that is re-entrant. |gps_set_raw_hook() | |gps.set_raw_hook() | Set a hook function to be executed on each raw packet as it arrives. |gps_send() |gpsmm.send() |gps.send() | @@ -315,8 +314,8 @@ Send wire-protocol commands to the daemon. Deprecated and unstable. Set watch policy. What you should use instead of send(). |gps_waiting() |gpsmm.waiting() |gps.waiting() | Nonblocking check to see in input is waiting. -|gps_poll() |gpsmm.poll() |gps.poll() | -Blocking poll for data from the daemon. +|gps_read() |gpsmm.read() |gps.read() | +Blocking read for data from the daemon. |gps_close() |gpsmm.close() |gps.close() | Close the daemon socket and end the session. |gps_enable_debug() |gpsmm_enable_debug() | | @@ -326,31 +325,31 @@ Clear the contents of the fix structure. |======================================================================== The tricky part is interpreting what you get from the blocking -poll. The reason it's tricky is that you're not guaranteed that -every poll will pick up exactly one complete JSON object from the +read. The reason it's tricky is that you're not guaranteed that +every read will pick up exactly one complete JSON object from the daemon. It may grab one response object, or more than one, or part of one, or one or more followed by a fragment. -What the library does on each poll is this: get what it can from the +What the library does on each read is this: get what it can from the socket, append that to a private buffer, and then consume as many JSON objects from the front of the buffer as it can. Any incomplete JSON is left in the private buffer to be completed and unpacked on a later go-round. In C, the library "consumes" a JSON object by unpacking its content -into a blackboard structure passed to the poll entry point by +into a blackboard structure passed to the read entry point by address. The structure contains a state-flag mask that you can (and should!) check so you'll know which parts of the structure contain valid data. It is safe to do nothing unless the PACKET_SET mask bit is on, which is the library's way of telling you that at least one -complete JSON response has arrived since the last poll. +complete JSON response has arrived since the last read. Data may accumulate on the blackboard over multiple reads, with new TPV reports overwriting old ones;it is guaranteed that overwrites are not partial. Expect this pattern to be replicated in any compiled language with only fixed-extent structures. -In Python and Perl the poll entry point returns an object containing +In Python and Perl the read entry point returns an object containing accumulated data. The state-flag mask is still useful for telling you which parts contain data, and there is still a PACKET_SET bit. Expect this pattern to be replicated in other dynamic OO languages when we @@ -359,18 +358,18 @@ support them. The C++ binding is a very thin wrapper around the C. You get back an object, but it's just a reference to the C blackboard structure. -All bindings will throw a recognizable error from the poll entry +All bindings will throw a recognizable error from the read entry point when the socket is closed from the daemon side. == C Examples == -The source distribution includes three example clients in C; -gpxlogger.c, cgps.c, and xgpsspeed.c. +The source distribution includes two example clients in C; +gpxlogger.c and cgps.c. gpxlogger.c illustrates the simplest possible program flow; open, -followed by stream, followed by blocking polls forever. The use of +followed by stream, followed by blocking reads forever. The use of select is not strictly necessary, but illustrates how to wait for data -from the daemon; it would work even if the poll were +from the daemon; it would work even if the read were non-blocking. This would only be appropriate for a batch-mode report generator. @@ -378,29 +377,27 @@ cgps.c shows what an interactive application using the library and also processing user commands works. Observe the use of select(2) to wait on either data from the daemon or a keystroke. -xgpsspeed.c is a simple C client using X for display. It doesn't need -to use a select(2) or the gps_waiting() library entry point because -it's tied into the X main event loop, which is watching the daemon -socket. - == Python examples == There's a very simple Python example analogous to gpxlogger attached to the source code for the gps.py library. -For a more interesting example integrated with X and GTK, see xgps. +For more interesting example integrated with X and GTK, see xgps and +xgpsspeed. -== Future Changes == +== Backward Incompatibility and Future Changes == The C/C++ binding makes available two preprocessor symbols, GPSD_API_MAJOR_VERSION and GPSD_API_MINOR_VERSION, in gps.h. The Python module has corresponding symbols. -At some point in the foreseeable (but not near) future, the value of -the GPSD_API_MAJOR_VERSION symbol will be bumped and the API -redesigned to discard historical baggage from the old protocol. -You will be able to use the version symbols to make your code -work with either version. +In major versions before 5: + +* gps_open() didn't take a third argument; instead, it returned malloc storage. + +* The 'read()' method in various bindings was named 'poll()' and had + a different return convention. The name 'poll()' will at some point + be reintroduced as an interface to the wire-protocol POLL command. See http://gpsd.berlios.de/future.html#api_cleanup[Client API Cleanup] for details. @@ -596,7 +596,7 @@ class Base: def handle_response(self, source, condition): "Handle ordinary I/O ready condition from the daemon." - if self.daemon.poll() == -1: + if self.daemon.read() == -1: self.handle_hangup(source, condition) if self.daemon.valid & gps.PACKET_SET: if self.device and self.device != self.daemon.data["device"]: @@ -320,7 +320,7 @@ class Main(object): return True def handle_response(self, source, condition): - if self.daemon.poll() == -1: + if self.daemon.read() == -1: self.handle_hangup(source, condition) if self.daemon.data['class'] == 'TPV': self.update_speed(self.daemon.data) |