1<?xml version="1.0" encoding="ISO-8859-1"?>
2<!--
3This file is Copyright (c) 2010 by the GPSD project
4SPDX-License-Identifier: BSD-2-clause
5-->
6<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
7                   "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
8<refentry>
9<refentryinfo><date>4 Feb 2019</date></refentryinfo>
10<refmeta>
11<refentrytitle>libgps</refentrytitle>
12<manvolnum>3</manvolnum>
13<refmiscinfo class="source">The GPSD Project</refmiscinfo>
14<refmiscinfo class="manual">GPSD Documentation</refmiscinfo>
15</refmeta>
16<refnamediv id='name'>
17<refname>libgps</refname>
18<refpurpose>C service library for communicating with the GPS daemon</refpurpose>
19</refnamediv>
20<refsynopsisdiv id='synopsis'>
21<funcsynopsis>
22<funcsynopsisinfo>
23
24C:
25
26#include &lt;gps.h&gt;
27
28</funcsynopsisinfo>
29<funcprototype>
30<funcdef>int <function>gps_open</function></funcdef>
31    <paramdef>char *<parameter>server</parameter></paramdef>
32    <paramdef>char *<parameter>port</parameter></paramdef>
33    <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
34</funcprototype>
35<funcprototype>
36<funcdef>int <function>gps_send</function></funcdef>
37    <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
38    <paramdef>char *<parameter>fmt</parameter>...</paramdef>
39</funcprototype>
40<funcprototype>
41<funcdef>int <function>gps_read</function></funcdef>
42    <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
43    <paramdef>char *<parameter>message</parameter></paramdef>
44    <paramdef>int <parameter>message_size</parameter></paramdef>
45</funcprototype>
46<funcprototype>
47<funcdef>bool <function>gps_waiting</function></funcdef>
48    <paramdef>const struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
49    <paramdef>int <parameter>timeout</parameter></paramdef>
50</funcprototype>
51<funcprototype>
52<funcdef>char *<function>gps_data</function></funcdef>
53    <paramdef>const struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
54</funcprototype>
55<funcprototype>
56<funcdef>int <function>gps_unpack</function></funcdef>
57    <paramdef>char *<parameter>buf</parameter></paramdef>
58    <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
59</funcprototype>
60<funcprototype>
61<funcdef>int <function>gps_close</function></funcdef>
62    <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
63</funcprototype>
64<funcprototype>
65<funcdef>int <function>gps_stream</function></funcdef>
66    <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
67    <paramdef>unsigned int<parameter>flags</parameter></paramdef>
68    <paramdef>void *<parameter>data</parameter></paramdef>
69</funcprototype>
70<funcprototype>
71<funcdef>int <function>gps_mainloop</function></funcdef>
72    <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
73    <paramdef>int <parameter>timeout</parameter></paramdef>
74    <paramdef>void (*<parameter>hook</parameter>)(struct gps_data_t *gpsdata)</paramdef>
75</funcprototype>
76<funcprototype>
77<funcdef>const char *<function>gps_errstr</function></funcdef>
78    <paramdef>int <parameter>err</parameter></paramdef>
79</funcprototype>
80<funcsynopsisinfo>
81
82Python:
83
84import gps
85
86session = gps.gps(host="localhost", port="2947")
87
88session.stream(flags=gps.WATCH_JSON)
89
90for report in session:
91    process(report)
92
93del session
94
95</funcsynopsisinfo>
96</funcsynopsis>
97</refsynopsisdiv>
98
99<refsect1 id='description'><title>DESCRIPTION</title>
100
101<para><emphasis remap='B'>libgps</emphasis> is a service library which
102supports communicating with an instance of the
103<citerefentry><refentrytitle>gpsd</refentrytitle><manvolnum>8</manvolnum>
104</citerefentry>; link it with the linker option -lgps.</para>
105
106<warning><para>Take care to conditionalize your code on the major and
107minor API version symbols in <filename>gps.h</filename>; ideally,
108force a compilation failure if GPSD_API_MAJOR_VERSION is not a version
109you recognize.  See the GPSD project website for more information on
110the protocol and API changes.</para></warning>
111
112<para>Calling <function>gps_open()</function> initializes a GPS-data
113structure to hold the data collected by the GPS, and sets up access to
114<citerefentry><refentrytitle>gpsd</refentrytitle><manvolnum>1</manvolnum>
115</citerefentry>
116via either the socket or shared-memory export. The shared-memory
117export is faster, but does not carry information about device
118activation and deactivation events and will not allow you to monitor
119device packet traffic.</para>
120
121<para><function>gps_open()</function> returns 0 on success, -1 on
122errors and is re-entrant.  errno is set depending on the error
123returned from the socket or shared-memory interface; see
124<filename>gps.h</filename> for values and explanations; also see
125<function>gps_errstr()</function>. The host address may be a DNS name,
126an IPv4 dotted quad, an IPV6 address, or the special value
127<constant>GPSD_SHARED_MEMORY</constant> referring to the
128shared-memory export; the library will do the right thing for any of
129these.</para>
130
131<para><function>gps_close()</function> ends the session and should only be
132called after a successful <function>gps_open()</function>.
133It returns 0 on success, -1 on errors.  The shared-memory interface
134close always returns 0, whereas a socket close can result in an error.
135For a socket close error it will have set an errno from the call to the
136system's <function>close()</function>. </para>
137
138<para><function>gps_send()</function> writes a command to the daemon.
139It does nothing when using the shared-memory export.
140The second argument must be a format string containing elements from
141the command set documented at
142<citerefentry><refentrytitle>gpsd</refentrytitle><manvolnum>1</manvolnum>
143</citerefentry>.
144It may have % elements as for
145<citerefentry><refentrytitle>sprintf</refentrytitle><manvolnum>3</manvolnum>
146</citerefentry>,
147which will be filled in from any following arguments.  This function
148returns a -1 if there was a Unix-level write error, otherwise
1490. Please read the LIMITATIONS section for additional information and
150cautions. See <function>gps_stream()</function> as a possible
151alternative.</para>
152
153<para><function>gps_read()</function> accepts a response, or sequence
154of responses, from the daemon and interprets.  This function does
155either a nonblocking read for data from the daemon or a fetch from
156shared memory; it returns a count of bytes read for success, -1 with
157errno set on a Unix-level read error, -1 with errno not set if the
158socket to the daemon has closed or if the shared-memory segment was
159unavailable, and 0 if no data is available.</para>
160
161<para><function>gps_waiting()</function> can be used to check whether
162there is new data from the daemon. The second argument is the maximum
163amount of time to wait (in microseconds) on input before returning.
164It returns true if there is input waiting, false on timeout (no data
165waiting) or error condition. When using the socket export, this
166function is a convenience wrapper around a
167<citerefentry><refentrytitle>select</refentrytitle><manvolnum>2</manvolnum>
168</citerefentry>
169call, and zeros <varname>errno</varname> on entry; you can test
170<varname>errno</varname> after exit to get more information about
171error conditions.  Warning: under the shared-memory interface there is
172a tiny race window between <function>gps_waiting()</function> and a
173following <function>gps_read()</function>; in that context, because the
174latter does not block, it is probably better to write a simple read
175loop.</para>
176
177<para><function>gps_mainloop()</function> enables the provided hook
178function to be continually called whenever there is gpsd data.
179The second argument is the maximum amount of time to wait (in microseconds)
180on input before exiting the loop (and return a value of -1).
181It will also return a negative value on various errors.
182</para>
183
184<para><function>gps_unpack()</function> parses JSON from the argument
185buffer into the target of the session structure pointer argument.
186Included in case your application wishes to manage socket I/O
187itself.</para>
188
189<para><function>gps_data()</function> returns the contents of the
190client data buffer (it returns NULL when using the shared-memory
191export). Use with care; this may fail to be a NUL-terminated string if
192WATCH_RAW is enabled.</para>
193
194<para><function>gps_stream()</function> asks
195<application>gpsd</application> to stream the reports it has at you,
196to be made available when you poll (not available when using the
197shared-memory export). The second argument is a flag mask that sets
198various policy bits; see the list below.  Calling
199<function>gps_stream()</function> more than once with different flag
200masks is allowed.</para>
201
202<variablelist>
203<varlistentry>
204<term>WATCH_DISABLE</term>
205<listitem>
206<para>Disable the reporting modes specified by the other WATCH_ flags.</para>
207</listitem>
208</varlistentry>
209<varlistentry>
210<term>WATCH_ENABLE</term>
211<listitem>
212<para>Disable the reporting modes specified by the other WATCH_ flags.
213This is the default.</para>
214</listitem>
215</varlistentry>
216<varlistentry>
217<term>WATCH_JSON</term>
218<listitem>
219<para>Enable JSON reporting of data. If WATCH_ENABLE is set, and no
220other WATCH flags are set, this is the default.</para>
221</listitem>
222</varlistentry>
223<varlistentry>
224<term>WATCH_NMEA</term>
225<listitem>
226<para>Enable generated pseudo-NMEA reporting on binary devices.</para>
227</listitem>
228</varlistentry>
229<varlistentry>
230<term>WATCH_RARE</term>
231<listitem>
232<para>Enable reporting of binary packets in encoded hex.</para>
233</listitem>
234</varlistentry>
235<varlistentry>
236<term>WATCH_RAW</term>
237<listitem>
238<para>Enable literal passthrough of binary packets.</para>
239</listitem>
240</varlistentry>
241<varlistentry>
242<term>WATCH_SCALED</term>
243<listitem>
244<para>When reporting AIS or Subframe data, scale integer quantities to
245floats if they have a divisor or rendering formula associated with them.</para>
246</listitem>
247</varlistentry>
248<varlistentry>
249<term>WATCH_NEWSTYLE</term>
250<listitem>
251<para>Force issuing a JSON initialization and getting new-style
252responses. This is the default. </para>
253</listitem>
254</varlistentry>
255<varlistentry>
256<term>WATCH_OLDSTYLE</term>
257<listitem>
258<para>Force issuing a W or R command and getting old-style
259responses. Warning: this flag (and the capability) will be removed
260in a future release.</para>
261</listitem>
262</varlistentry>
263<varlistentry>
264<term>WATCH_DEVICE</term>
265<listitem>
266<para>Restrict watching to a specified device, path given as second
267argument.</para>
268</listitem>
269</varlistentry>
270</variablelist>
271
272<para><function>gps_errstr()</function> returns an ASCII string (in
273English) describing the error indicated by a nonzero return value from
274<function>gps_open()</function>.</para>
275
276<para>Consult <filename>gps.h</filename> to learn more about the data
277members and associated timestamps.  Note that information will
278accumulate in the session structure over time, and the 'valid' field
279is not automatically zeroed by each <function>gps_read()</function>.
280It is up to the client to zero that field when appropriate and to keep
281an eye on the fix and sentence timestamps.</para>
282
283<para>The Python implementation supports the same facilities as the
284socket-export calls in the C library; there is no shared-memory
285interface. <function>gps_open()</function> is replaced by the
286initialization of a gps session object; the other calls are methods of
287that object, and have the same names as the corresponding C functions.
288However, it is simpler just to use the session object as an iterator,
289as in the example given below.  Resources within the session object
290will be properly released when it is garbage-collected.</para>
291</refsect1>
292
293<refsect1 id='environment'><title>ENVIRONMENT VARIABLES</title>
294
295<para>By setting the environment variable <envar>GPSD_SHM_KEY</envar>,
296you can control the key value used to create shared-memory segment
297used for communication with <application>gpsd</application>.  This
298will be useful mainly when isolating test instances of
299<application>gpsd</application> from production ones.</para>
300
301</refsect1>
302
303<refsect1 id='example'><title>CODE EXAMPLE</title>
304
305<para>The following is an excerpted and simplified version of the
306libgps interface code from
307<citerefentry><refentrytitle>cgps</refentrytitle><manvolnum>1</manvolnum>
308</citerefentry>.</para>
309
310<programlisting>
311    struct gps_data_t gps_data;
312
313    ret = gps_open(hostName, hostPort, &amp;gps_data);
314
315    (void) gps_stream(&amp;gps_data, WATCH_ENABLE | WATCH_JSON, NULL);
316
317    /* Put this in a loop with a call to a high resolution sleep () in it. */
318    if (gps_waiting(&amp;gps_data, 500)) {
319        errno = 0;
320        if (gps_read(&amp;gps_data, NULL, 0) == -1) {
321            ...
322        } else {
323            /* Display data from the GPS receiver. */
324            if (gps_data.set &amp; ...
325        }
326    }
327
328    /* When you are done... */
329    (void) gps_stream(&amp;gps_data, WATCH_DISABLE, NULL);
330    (void) gps_close (&amp;gps_data);
331</programlisting>
332
333</refsect1>
334
335<refsect1 id='limitations'><title>LIMITATIONS</title>
336
337<para>On some systems (those which do not support implicit linking in
338libraries) you may need to add -lm to your link line when you link libgps.
339It is always safe to do this.</para>
340
341<para>In the C API, incautious use of <function>gps_send()</function>
342may lead to subtle bugs. In order to not bloat <structname>struct
343gps_data_t</structname> with space used by responses that are not
344expected to be shipped in close sequence with each other, the storage
345for fields associated with certain responses are combined in a
346union.</para>
347
348<para>The risky set of responses includes VERSION, DEVICELIST, RTCM2,
349RTCM3, SUBFRAME, AIS, GST, and ERROR; it may not be limited to that
350set.  The logic of the daemon's watcher mode is careful to avoid
351dangerous sequences, but you should read and understand the layout of
352<structname>struct gps_data_t</structname> before using
353<function>gps_send()</function> to request any of these
354responses.</para>
355
356</refsect1>
357
358<refsect1 id='compatibility'><title>COMPATIBILITY</title>
359
360<para>The <function>gps_query()</function> supported in major versions
3611 and 2 of this library has been removed.  With the new
362streaming-oriented wire protocol behind this library, it is extremely
363unwise to assume that the first transmission from the daemon after a
364command is shipped to it will be the response to command.</para>
365
366<para>If you must send commands to the daemon explicitly, use
367<function>gps_send()</function> but beware that this ties your code to
368the GPSD wire protocol. It is not recommended.</para>
369
370<para>In earlier versions of the API <function>gps_read()</function> was
371a blocking call and there was a POLL_NONBLOCK option to make it nonblocking.
372<function>gps_waiting()</function> was added to reduce the number of
373wrong ways to code a polling loop.</para>
374
375<para>See the comment above the symbol GPSD_API_MAJOR_VERSION
376in <filename>gps.h</filename> for recent changes.</para>
377</refsect1>
378
379<refsect1 id='see_also'><title>SEE ALSO</title>
380<para>
381<citerefentry><refentrytitle>gpsd</refentrytitle><manvolnum>8</manvolnum>
382</citerefentry>,
383<citerefentry><refentrytitle>gps</refentrytitle><manvolnum>1</manvolnum>
384</citerefentry>,
385<citerefentry><refentrytitle>libgpsmm</refentrytitle><manvolnum>3</manvolnum>
386</citerefentry>.
387</para>
388</refsect1>
389
390<refsect1 id='author'><title>AUTHOR</title>
391<para>Eric S. Raymond &lt;esr@thyrsus.com&gt;,
392 C sample code Charles Curley &lt;charlescurley@charlescurley.com&gt;</para>
393</refsect1>
394</refentry>
395
396