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 <gps.h> 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, &gps_data); 314 315 (void) gps_stream(&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(&gps_data, 500)) { 319 errno = 0; 320 if (gps_read(&gps_data, NULL, 0) == -1) { 321 ... 322 } else { 323 /* Display data from the GPS receiver. */ 324 if (gps_data.set & ... 325 } 326 } 327 328 /* When you are done... */ 329 (void) gps_stream(&gps_data, WATCH_DISABLE, NULL); 330 (void) gps_close (&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 <esr@thyrsus.com>, 392 C sample code Charles Curley <charlescurley@charlescurley.com></para> 393</refsect1> 394</refentry> 395 396