'\" t .\" Title: libgps .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.79.1 .\" Date: 4 Feb 2019 .\" Manual: GPSD Documentation .\" Source: The GPSD Project .\" Language: English .\" .TH "LIBGPS" "3" "4 Feb 2019" "The GPSD Project" "GPSD Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" libgps \- C service library for communicating with the GPS daemon .SH "SYNOPSIS" .sp .ft B .nf C: #include .fi .ft .HP \w'int\ gps_open('u .BI "int gps_open(char\ *" "server" ", char\ *" "port" ", struct\ gps_data_t\ *" "gpsdata" ");" .HP \w'int\ gps_send('u .BI "int gps_send(struct\ gps_data_t\ *" "gpsdata" ", char\ *" "fmt" "\&.\&.\&.);" .HP \w'int\ gps_read('u .BI "int gps_read(struct\ gps_data_t\ *" "gpsdata" ", char\ *" "message" ", int\ " "message_size" ");" .HP \w'bool\ gps_waiting('u .BI "bool gps_waiting(const\ struct\ gps_data_t\ *" "gpsdata" ", int\ " "timeout" ");" .HP \w'char\ *gps_data('u .BI "char *gps_data(const\ struct\ gps_data_t\ *" "gpsdata" ");" .HP \w'int\ gps_unpack('u .BI "int gps_unpack(char\ *" "buf" ", struct\ gps_data_t\ *" "gpsdata" ");" .HP \w'int\ gps_close('u .BI "int gps_close(struct\ gps_data_t\ *" "gpsdata" ");" .HP \w'int\ gps_stream('u .BI "int gps_stream(struct\ gps_data_t\ *" "gpsdata" ", unsigned\ int" "flags" ", void\ *" "data" ");" .HP \w'int\ gps_mainloop('u .BI "int gps_mainloop(struct\ gps_data_t\ *" "gpsdata" ", int\ " "timeout" ", void\ (*" "hook" ")(struct\ gps_data_t\ *gpsdata));" .HP \w'const\ char\ *gps_errstr('u .BI "const char *gps_errstr(int\ " "err" ");" .sp .ft B .nf Python: import gps session = gps\&.gps(host="localhost", port="2947") session\&.stream(flags=gps\&.WATCH_JSON) for report in session: process(report) del session .fi .ft .SH "DESCRIPTION" .PP \fBlibgps\fR is a service library which supports communicating with an instance of the \fBgpsd\fR(8); link it with the linker option \-lgps\&. .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBWarning\fR .ps -1 .br .PP Take care to conditionalize your code on the major and minor API version symbols in gps\&.h; ideally, force a compilation failure if GPSD_API_MAJOR_VERSION is not a version you recognize\&. See the GPSD project website for more information on the protocol and API changes\&. .sp .5v .RE .PP Calling \fBgps_open()\fR initializes a GPS\-data structure to hold the data collected by the GPS, and sets up access to \fBgpsd\fR(1) via either the socket or shared\-memory export\&. The shared\-memory export is faster, but does not carry information about device activation and deactivation events and will not allow you to monitor device packet traffic\&. .PP \fBgps_open()\fR returns 0 on success, \-1 on errors and is re\-entrant\&. errno is set depending on the error returned from the socket or shared\-memory interface; see gps\&.h for values and explanations; also see \fBgps_errstr()\fR\&. The host address may be a DNS name, an IPv4 dotted quad, an IPV6 address, or the special value \fBGPSD_SHARED_MEMORY\fR referring to the shared\-memory export; the library will do the right thing for any of these\&. .PP \fBgps_close()\fR ends the session and should only be called after a successful \fBgps_open()\fR\&. It returns 0 on success, \-1 on errors\&. The shared\-memory interface close always returns 0, whereas a socket close can result in an error\&. For a socket close error it will have set an errno from the call to the system\*(Aqs \fBclose()\fR\&. .PP \fBgps_send()\fR writes a command to the daemon\&. It does nothing when using the shared\-memory export\&. The second argument must be a format string containing elements from the command set documented at \fBgpsd\fR(1)\&. It may have % elements as for \fBsprintf\fR(3), which will be filled in from any following arguments\&. This function returns a \-1 if there was a Unix\-level write error, otherwise 0\&. Please read the LIMITATIONS section for additional information and cautions\&. See \fBgps_stream()\fR as a possible alternative\&. .PP \fBgps_read()\fR accepts a response, or sequence of responses, from the daemon and interprets\&. This function does either a nonblocking read for data from the daemon or a fetch from shared memory; 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 or if the shared\-memory segment was unavailable, and 0 if no data is available\&. .PP \fBgps_waiting()\fR can be used to check whether there is new data from the daemon\&. The second argument is the maximum amount of time to wait (in microseconds) on input before returning\&. It returns true if there is input waiting, false on timeout (no data waiting) or error condition\&. When using the socket export, this function is a convenience wrapper around a \fBselect\fR(2) call, and zeros \fIerrno\fR on entry; you can test \fIerrno\fR after exit to get more information about error conditions\&. Warning: under the shared\-memory interface there is a tiny race window between \fBgps_waiting()\fR and a following \fBgps_read()\fR; in that context, because the latter does not block, it is probably better to write a simple read loop\&. .PP \fBgps_mainloop()\fR enables the provided hook function to be continually called whenever there is gpsd data\&. The second argument is the maximum amount of time to wait (in microseconds) on input before exiting the loop (and return a value of \-1)\&. It will also return a negative value on various errors\&. .PP \fBgps_unpack()\fR parses JSON from the argument buffer into the target of the session structure pointer argument\&. Included in case your application wishes to manage socket I/O itself\&. .PP \fBgps_data()\fR returns the contents of the client data buffer (it returns NULL when using the shared\-memory export)\&. Use with care; this may fail to be a NUL\-terminated string if WATCH_RAW is enabled\&. .PP \fBgps_stream()\fR asks gpsd to stream the reports it has at you, to be made available when you poll (not available when using the shared\-memory export)\&. The second argument is a flag mask that sets various policy bits; see the list below\&. Calling \fBgps_stream()\fR more than once with different flag masks is allowed\&. .PP WATCH_DISABLE .RS 4 Disable the reporting modes specified by the other WATCH_ flags\&. .RE .PP WATCH_ENABLE .RS 4 Disable the reporting modes specified by the other WATCH_ flags\&. This is the default\&. .RE .PP WATCH_JSON .RS 4 Enable JSON reporting of data\&. If WATCH_ENABLE is set, and no other WATCH flags are set, this is the default\&. .RE .PP WATCH_NMEA .RS 4 Enable generated pseudo\-NMEA reporting on binary devices\&. .RE .PP WATCH_RARE .RS 4 Enable reporting of binary packets in encoded hex\&. .RE .PP WATCH_RAW .RS 4 Enable literal passthrough of binary packets\&. .RE .PP WATCH_SCALED .RS 4 When reporting AIS or Subframe data, scale integer quantities to floats if they have a divisor or rendering formula associated with them\&. .RE .PP WATCH_NEWSTYLE .RS 4 Force issuing a JSON initialization and getting new\-style responses\&. This is the default\&. .RE .PP WATCH_OLDSTYLE .RS 4 Force issuing a W or R command and getting old\-style responses\&. Warning: this flag (and the capability) will be removed in a future release\&. .RE .PP WATCH_DEVICE .RS 4 Restrict watching to a specified device, path given as second argument\&. .RE .PP \fBgps_errstr()\fR returns an ASCII string (in English) describing the error indicated by a nonzero return value from \fBgps_open()\fR\&. .PP Consult gps\&.h to learn more about the data members and associated timestamps\&. Note that information will accumulate in the session structure over time, and the \*(Aqvalid\*(Aq field is not automatically zeroed by each \fBgps_read()\fR\&. It is up to the client to zero that field when appropriate and to keep an eye on the fix and sentence timestamps\&. .PP The Python implementation supports the same facilities as the socket\-export calls in the C library; there is no shared\-memory interface\&. \fBgps_open()\fR is replaced by the initialization of a gps session object; the other calls are methods of that object, and have the same names as the corresponding C functions\&. However, it is simpler just to use the session object as an iterator, as in the example given below\&. Resources within the session object will be properly released when it is garbage\-collected\&. .SH "ENVIRONMENT VARIABLES" .PP By setting the environment variable \fBGPSD_SHM_KEY\fR, you can control the key value used to create shared\-memory segment used for communication with gpsd\&. This will be useful mainly when isolating test instances of gpsd from production ones\&. .SH "CODE EXAMPLE" .PP The following is an excerpted and simplified version of the libgps interface code from \fBcgps\fR(1)\&. .sp .if n \{\ .RS 4 .\} .nf struct gps_data_t gps_data; ret = gps_open(hostName, hostPort, &gps_data); (void) gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL); /* Put this in a loop with a call to a high resolution sleep () in it\&. */ if (gps_waiting(&gps_data, 500)) { errno = 0; if (gps_read(&gps_data, NULL, 0) == \-1) { \&.\&.\&. } else { /* Display data from the GPS receiver\&. */ if (gps_data\&.set & \&.\&.\&. } } /* When you are done\&.\&.\&. */ (void) gps_stream(&gps_data, WATCH_DISABLE, NULL); (void) gps_close (&gps_data); .fi .if n \{\ .RE .\} .SH "LIMITATIONS" .PP On some systems (those which do not support implicit linking in libraries) you may need to add \-lm to your link line when you link libgps\&. It is always safe to do this\&. .PP In the C API, incautious use of \fBgps_send()\fR may lead to subtle bugs\&. In order to not bloat struct gps_data_t with space used by responses that are not expected to be shipped in close sequence with each other, the storage for fields associated with certain responses are combined in a union\&. .PP The risky set of responses includes VERSION, DEVICELIST, RTCM2, RTCM3, SUBFRAME, AIS, GST, and ERROR; it may not be limited to that set\&. The logic of the daemon\*(Aqs watcher mode is careful to avoid dangerous sequences, but you should read and understand the layout of struct gps_data_t before using \fBgps_send()\fR to request any of these responses\&. .SH "COMPATIBILITY" .PP The \fBgps_query()\fR supported in major versions 1 and 2 of this library has been removed\&. With the new streaming\-oriented wire protocol behind this library, it is extremely unwise to assume that the first transmission from the daemon after a command is shipped to it will be the response to command\&. .PP If you must send commands to the daemon explicitly, use \fBgps_send()\fR but beware that this ties your code to the GPSD wire protocol\&. It is not recommended\&. .PP In earlier versions of the API \fBgps_read()\fR was a blocking call and there was a POLL_NONBLOCK option to make it nonblocking\&. \fBgps_waiting()\fR was added to reduce the number of wrong ways to code a polling loop\&. .PP See the comment above the symbol GPSD_API_MAJOR_VERSION in gps\&.h for recent changes\&. .SH "SEE ALSO" .PP \fBgpsd\fR(8), \fBgps\fR(1), \fBlibgpsmm\fR(3)\&. .SH "AUTHOR" .PP Eric S\&. Raymond , C sample code Charles Curley