client-howto.adoc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. = GPSD Client HOWTO
  2. Eric S. Raymond <esr@thyrsus.com>
  3. v1.21, Feb 2021
  4. :author: Eric S. Raymond
  5. :date: 22 Februrary 2021
  6. :description: This document is a guide to interfacing client applications with GPSD.
  7. :email: <esr@thyrsus.com>
  8. :keywords: time, GPSD, NTP, time, precision, 1PPS, PPS, stratum, jitter
  9. :sectlinks:
  10. :toc: macro
  11. include::inc-menu.adoc[]
  12. == Introduction
  13. This document is a guide to interfacing client applications with GPSD.
  14. It surveys the available bindings and their use cases. It also explains
  15. some sharp edges in the client API which, unfortunately, are fundamental
  16. results of the way GPS sensor devices operate, and suggests tactics
  17. for avoiding being cut.
  18. == Sensor behavior matters
  19. GPSD handles two main kinds of sensors: GPS receivers and AIS
  20. receivers. It has rudimentary support for some other kinds of
  21. specialized geolocation-related sensors as well, notably compass and
  22. yaw/pitch/roll, but those sensors are usually combined with GPS/AIS
  23. receivers and behave like them.
  24. In an ideal world, GPS/AIS sensors would be oracles that you could
  25. poll at any time to get clean data. But despite the existence of some
  26. vendor-specific query and control strings on some devices, a GPS/AIS
  27. sensor is not a synchronous device you can query for specified data
  28. and count on getting a response back from in a fixed period of time.
  29. It gets radio data on its own schedule (usually once per second for a
  30. GPS), and emits the reports it feels like reporting asynchronously
  31. with variable lag during the following second. *If* it supports query
  32. strings, reports from these are intermixed with the regular
  33. reports, and usually scheduled at a lower priority (often with a lag
  34. of more than a second).
  35. A GPS/AIS receiver, or any sensor that behaves like one, is in effect
  36. a datagram emitter similar to a UDP data source; you get no guarantees
  37. about sequence or timing at finer resolution than "TPV roughly once
  38. per second" (or whatever the main type of report and report interval
  39. is).
  40. The only way to simulate synchronous querying of such a sensor is to
  41. have an agent between you and it that caches the data coming out of
  42. the device; you can then query the agent and expect a reasonably
  43. synchronous response from the cache (we support this for
  44. GPSs). However, note that this doesn't work for a freshly opened
  45. device - there's no cached data.
  46. Consider what this implies for GPses, in particular:
  47. * You can't actually poll them. They report to you over a serial
  48. (RS232 or USB-serial) interface at a fixed interval, usually once
  49. per second.
  50. * They don't always have a fix to report, because they can only
  51. get one when they have satellite lock.
  52. * They may fail to have satellite lock when your skyview is poor.
  53. If you are moving through uneven terrain or anywhere with trees
  54. or buildings, your skyview can degrade in an instant.
  55. * They may also fail to have lock because they're initially powering
  56. on (cold start), or waking from a power-conserving sleep mode (warm
  57. start). While most modern GPSs with a good skyview can get
  58. satellite lock in 30 seconds from a warm start, a GPS that has
  59. been off for a while can take 15 minutes or more to acquire lock
  60. Time to fix after a power-on matters because in many use cases for
  61. GPSs they're running off a battery, and you can't afford to keep them
  62. powered when you don't actually need location data. This is why GPS
  63. sensors are sometimes designed to go to a low-power mode when you close
  64. the serial port they're attached to.
  65. AIS receivers have a simpler set of constraints. They report
  66. navigational and ID information from any AIS transmitter in line of
  67. sight; there are no skyview issues, and they're ready instantly when
  68. powered up. Furthermore, they're not normally battery constrained.
  69. However, you don't poll them either; they receive information
  70. packets over the air and ship them to you at unpredictable intervals
  71. over a serial port.
  72. The design of the GPSD reporting protocol surrenders to reality. Its data
  73. packets translate the GPS's stream of datagrams into
  74. device-type-independent datagrams, but it can't impose timing and
  75. sequencing regularities on them that the underlying device doesn't
  76. already obey.
  77. == What GPSD does, and what it cannot do
  78. GPSD solves some of the problems with GPS/AIS sensors. First:
  79. multiplexing; it allows multiple applications to get sensor data
  80. without having to contend for a single serial device. Second:
  81. coping with the hideous gallimaufry of badly-designed protocols these
  82. devices use -- regardless of device type, you will get data in a single
  83. well-documented format. Third: on operating systems with a hotplug
  84. facility (like Linux udev), GPSD will handle all the device
  85. management as USB devices are plugged in and unplugged.
  86. What GPSD can't do is pull fix data out of thin air when your
  87. device hasn't reported any. Nor is it a magic power supply,
  88. so its device management has to be designed around keeping the
  89. attached sensors open only when a client application actually
  90. needs a fix.
  91. As you'll see, these constraints explain most of the design of the GPSD
  92. wire protocol, and of the library APIs your client application
  93. will be using.
  94. == How the GPSD wire protocol works
  95. While GPSD project ships several library bindings that will hide the
  96. details of the wire protocol from you, you'll understand the library APIs
  97. better by knowing what a wire-protocol session looks like. After
  98. reading this section, you can forget the details about commands and
  99. responses and attributes as long as you hold on to the basic
  100. logical flow of a session.
  101. Your client library's open function is going to connect a socket to
  102. port 2947 on the host your sensors are attached to, usually
  103. localhost. On connection, the gpsd daemon will ship a banner that
  104. looks something like this:
  105. -----------------------------------------------------------------------------
  106. {"class":"VERSION","release":"2.93","rev":"2010-03-30T12:18:17",
  107. "proto_major":3,"proto_minor":2}
  108. -----------------------------------------------------------------------------
  109. There's nothing mysterious here. Your server daemon is identifying
  110. itself with information that may allow a client library to work
  111. around bugs or potential incompatibilities produced by upgrades.
  112. To get data from the attached sensors, you need to explicitly tell the
  113. daemon you want it. (Remember that it's trying to minimize the amount
  114. of time the devices are held open and in a fully powered state.) You
  115. do this by issuing a WATCH command:
  116. -----------------------------------------------------------------------------
  117. ?WATCH={"enable":true,"json":true}
  118. -----------------------------------------------------------------------------
  119. This tells the daemon to watch all devices and to issue reports in
  120. JSON. It can ship some other protocols as well (notably, NMEA 0183)
  121. but JSON is the most capable and usually what you want.
  122. A side effect of the WATCH command is that the daemon will ship you
  123. back some information on available devices.
  124. -----------------------------------------------------------------------------
  125. {"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyUSB0",
  126. "activated":1269959537.20,"native":0,"bps":4800,"parity":"N",
  127. "stopbits":1,"cycle":1.00}]}
  128. {"class":"WATCH","enable":true,"json":true,"nmea":false,"raw":0,
  129. "scaled":false,"timing":false,"pps":false}
  130. -----------------------------------------------------------------------------
  131. The DEVICES response tells you what devices are available to the
  132. daemon; this list is maintained in a way you as the application
  133. designer don't have to care about. The WATCH response will
  134. immediately follow and tells you what all your watch request settings
  135. are.
  136. Up to this point, nothing has been dependent on the state of the
  137. sensors. At this time, it may well be that none of those devices is
  138. fully powered up yet. In fact, they won't be, unless another
  139. GPSD-enabled application is already watching when you open your
  140. connection. If that's the case, you will start seeing data
  141. immediately.
  142. For now, though, let's go back to the case where gpsd has to fire up
  143. the sensors. After issuing the WATCH response, the daemon opens all of
  144. them and watches for incoming packets that it can recognize. *After
  145. a variable delay*, it will ship a notification that looks something
  146. like this:
  147. -----------------------------------------------------------------------------
  148. {"class":"DEVICE","path":"/dev/ttyUSB0","activated":1269960793.97,
  149. "driver":"SiRF binary","native":1,"bps":4800,
  150. "parity":"N","stopbits":1,"cycle":1.00}
  151. -----------------------------------------------------------------------------
  152. This is the daemon telling you that it has recognized a SiRF binary
  153. GPS on /dev/ttyUSB0 shipping report packets at 4800 bits per second.
  154. This notification is not delayed by the time it takes to achieve
  155. satellite lock; the GPS will cheerfully ship packets before that. But
  156. it will be delayed by the time required for the daemon to sync up with
  157. the GPS.
  158. The GPSD daemon is designed so it doesn't have to know anything about the
  159. sensor in advance - not which of a dozen reporting protocols it uses,
  160. and not even the baud rate of the serial device. The reason for this
  161. agnosticism is so the daemon can adapt properly to anything a hotplug
  162. event night throw at it. If you unplug your GPS while your
  163. application is running, and then plug in one of a different type, the
  164. daemon will cope. Your application won't know the difference unless
  165. you have told it to notice device types.
  166. You can even start your application, have it issue a WATCH, realize
  167. you forgot to plug in a GPS, and do that. The hotplug event will
  168. tell gpsd, which will add the new device to the watched-devices list
  169. of every client that has issued a ?WATCH.
  170. In order to make this work, gpsd has a packet sniffer inside it that
  171. does autobauding and packet-protocol detection. Normally the packet
  172. sniffer will achieve sync in well under a second (my measured times
  173. range from 0.10 to 0.53 sec at 4800bps), but it can take longer if
  174. your serial traffic is degraded by dodgy cables or electrical noise,
  175. or if the GPS is configured to run at an unusual speed/parity/stopbit
  176. configuration.
  177. The real point here is that the delay is *variable*. The client
  178. library, and your application, can't assume a neat lockstep of
  179. request and instant response.
  180. Once you do get your device(s) synced, things become more predictable.
  181. The sensor will start shipping fix reports at a constant interval,
  182. usually every second, and the daemon will massage them into JSON and
  183. pass them up the client to your application.
  184. However, until the sensor achieves satellite lock, those fixes will be
  185. "mode 1" - no valid data (mode 2 is a 2D fix, mode 3 is a 3D fix).
  186. Here's what that looks like:
  187. -----------------------------------------------------------------------------
  188. {"class":"TPV","device":"/dev/ttyUSB0",
  189. "time":"2010-04-30T11:47:43.28Z","ept":0.005,"mode":1}
  190. -----------------------------------------------------------------------------
  191. Occasionally you'll get another kind of sentence, SKY, that reports a
  192. satellite skyview. But TPV is the important one. Here's what it
  193. looks like when the sensor has a fix to report:
  194. -----------------------------------------------------------------------------
  195. {"class":"TPV","time":"2010-04-30T11:48:20.10Z","ept":0.005,
  196. "lat":46.498204497,"lon":7.568061439,"alt":1327.689,
  197. "epx":15.319,"epy":17.054,"epv":124.484,"track":10.3797,
  198. "speed":0.091,"climb":-0.085,"eps":34.11,"mode":3}
  199. -----------------------------------------------------------------------------
  200. Note the "mode":3 at the end. This is how you tell that the GPS is
  201. reporting a full 3D fix with altitude.
  202. If you have an AIS receiver attached, it too will have been opened
  203. and autobauded and protocol-sniffed after your WATCH. The stream of
  204. JSON objects will then include things like this:
  205. -----------------------------------------------------------------------------
  206. {"class":"AIS","type":5,"repeat":0,"mmsi":351759000,"scaled":true,
  207. "imo":9134270,"ais_version":0,"callsign":"3FOF8",
  208. "shipname":"EVER DIADEM",
  209. "shiptype":"Cargo - all ships of this type",
  210. "to_bow":225,
  211. "to_stern":70,"to_port":1,"to_starboard":31,"draught":12.2,
  212. "epfd":"GPS","eta":"05-15T14:00Z",
  213. "destination":"NEW YORK","dte":0}
  214. -----------------------------------------------------------------------------
  215. When your application shuts down, it can cancel its watch:
  216. -----------------------------------------------------------------------------
  217. ?WATCH={"enable":false}
  218. -----------------------------------------------------------------------------
  219. This will enable the daemon to close devices and conserve
  220. power. Supposing you don't do this, the daemon will time out devices
  221. with no listeners, so canceling your watch is not strictly necessary.
  222. But it is good manners.
  223. Another way to use the daemon is with the ?POLL command To do this, issue
  224. -----------------------------------------------------------------------------
  225. ?WATCH={"enable":true}
  226. -----------------------------------------------------------------------------
  227. This activates all devices without enabling streaming of reports. You
  228. can then say "?POLL;" to poll gpsd's recorded data.
  229. -----------------------------------------------------------------------------
  230. ?POLL;
  231. {"class":"POLL","time":"2012-04-05T15:00:01.501Z","active":1,
  232. "tpv":[{"class":"TPV","device":"/dev/ttyUSB0","mode":3,"time":"2012-04-05T15:00:00.000Z","ept":0.005,"lat":40.035083522,"lon":-75.519982905,"alt":166.145,"epx":9.125,"epy":17.778,"epv":34.134,"track":0.0000,"speed":0.000,"climb":0.000,"eps":36.61}],"gst":[{"class":"GST","device":"/dev/ttyUSB0","time":"1970-01-01T00:00:00.000Z","rms":0.000,"major":0.000,"minor":0.000,"orient":0.000,"lat":0.000,"lon":0.000,"alt":0.000}],
  233. "sky":[{"class":"SKY","device":"/dev/ttyUSB0","time":"2012-04-05T15:00:00.000Z","xdop":0.61,"ydop":1.19,"vdop":1.48,"tdop":1.14,"hdop":1.40,"gdop":2.30,"pdop":1.99,"satellites":[{"PRN":26,"el":15,"az":49,"ss":29,"used":true},{"PRN":18,"el":62,"az":315,"ss":31,"used":true},{"PRN":15,"el":60,"az":43,"ss":44,"used":true},{"PRN":21,"el":71,"az":237,"ss":0,"used":false},{"PRN":27,"el":52,"az":94,"ss":40,"used":true},{"PRN":9,"el":48,"az":136,"ss":33,"used":true},{"PRN":22,"el":21,"az":291,"ss":36,"used":true},{"PRN":3,"el":8,"az":303,"ss":25,"used":true}]}]}
  234. -----------------------------------------------------------------------------
  235. This interface is intended for use with applications like CGI scripts
  236. that cannot wait on output from the daemon but must poke it into responding.
  237. If you're a clever sort, you're already wondering what the daemon does
  238. if the application at the other end of the client socket doesn't read data
  239. out of it as fast as gpsd is shipping it upwards. And the answer is
  240. this: eventually the socket buffer fills up, a write from the daemon
  241. throws an error, and the daemon shuts down that client socket.
  242. From the point of view of the application, it reads all the buffered
  243. data and then gets a read return indicating the socket shutdown. We'll
  244. return to this in the discussion of client libraries, but the thing
  245. for you to know right now is that this edge case is actually quite
  246. difficult to fall afoul of. Total data volume on these sockets is not
  247. high. As long as your application checks for and reads socket data no
  248. less often than once a second, you won't -- and a second is a *lot* of
  249. time in which to come back around your main loop.
  250. == Interfacing from the client side
  251. The gpsd daemon exports data in three different ways: via a sockets
  252. interface, via DBUS broadcasts, and via a shared-memory interface,
  253. It is possible one or more of these may be configured out in your
  254. installation.
  255. === The sockets interface
  256. The GPSD project provides client-side libraries in C, C++, and Python
  257. that exercise the sockets export. A Perl module is separately
  258. available from CPAN. While the details of these libraries vary, they
  259. all have the same two purposes and the same limitations.
  260. One purpose of the libraries is to handle the details of unpacking
  261. JSON-based wire-protocol objects into whatever native structure/record
  262. feature your application language has. This is particularly important
  263. in the C and C++ libraries, because those languages don't have
  264. good native support for JSON.
  265. Another purpose is to hide the details of the wire protocol from the
  266. application. This gives the GPSD developers room to improve extend
  267. the protocol without breaking every client application. Depend
  268. on wire-protocol details only at your own risk!
  269. The limitations the libraries have to cope with are the nature of
  270. the data flow from the sensors, and the simple fact that they're
  271. not necessarily delivering fixes at any given time.
  272. For details of the libraries' APIs, see their reference
  273. documentation; the objective of the rest of this section is to teach
  274. you the general model of client-side interfacing that they all have to
  275. follow because of the way the daemon works.
  276. Each library has the following entry points:
  277. * Open a session socket to the daemon. Named something like "open()".
  278. * Set watch policy. Named something like "stream()"
  279. * Send wire-protocol commands to the daemon. Deprecated; makes your
  280. code dependent on the wire protocol. There is no longer a real
  281. use case for this entry point; if you think you need no use it,
  282. you have probably failed to understand the rest of the interface.
  283. * Blocking check to see if data from the daemon is waiting. Named
  284. something like "waiting()" and taking a wait timeout as argument.
  285. Note that choosing a wait timeout of less than twice the cycle time
  286. of your device will be hazardous, as the receiver will probably not
  287. supply input often enough to prevent a spurious error indication.
  288. For the typical 1-second cycle time of GPSes this implies a minimum
  289. 2-second timeout.
  290. * Blocking read for data from the daemon. Named something like "read()"
  291. (this was "poll()" in older versions).
  292. * Close the session socket. Named something like "close()".
  293. * Enable debugging trace messages
  294. The fact that the data-waiting check and the read both block means
  295. that, if your application has to deal with other input sources than
  296. the GPS, you will probably have to isolate the read loop in a thread with
  297. a mutex lock on the gps_data structure.
  298. Here is a complete table of the binding entry points:
  299. .Entry points in client bindings
  300. [frame="topbot",options="header"]
  301. |========================================================================
  302. |C |C++ |Python |
  303. Function
  304. |gps_open() |gpsmm.gpsmm() |gps.\_\_init__() |
  305. In OO languages the client class initializer opens the daemon socket.
  306. |gps_send() |gpsmm.send() |gps.send() |
  307. Send wire-protocol commands to the daemon. Deprecated and unstable.
  308. |gps_stream() |gpsmm.stream() |gps.stream() |
  309. Set watch policy. What you should use instead of send().
  310. |gps_waiting() |gpsmm.waiting() |gps.waiting() |
  311. Blocking check with timeout to see if input is waiting.
  312. |gps_read() |gpsmm.read() |gps.read() |
  313. Read data from the daemon. Usually blocking.
  314. |gps_unpack() | |gps.unpack() |
  315. Parse JSON from a specified buffer into a session structure
  316. |gps_close() |gpsmm.~gpsmm() |gps.close() |
  317. Close the daemon socket and end the session.
  318. |gps_data() |gpsmm.data() |gps.data() |
  319. Get the contents of the client buffer.
  320. |gps_enable_debug() |gpsmm_enable_debug() | |
  321. Enable debug tracing. Only useful for GPSD developers.
  322. |gps_clear_fix() |gpsmm.clear_fix() | |
  323. Clear the contents of the fix structure.
  324. |========================================================================
  325. The tricky part is interpreting what you get from the blocking
  326. read. The reason it's tricky is that you're not guaranteed that
  327. every read will pick up exactly one complete JSON object from the
  328. daemon. It may grab one response object, or more than one, or
  329. part of one, or one or more followed by a fragment.
  330. What the library does on each read is this: get what it can from the
  331. socket, append that to a private buffer, and then consume as many JSON
  332. objects from the front of the buffer as it can. Any incomplete JSON
  333. is left in the private buffer to be completed and unpacked on a later
  334. go-round.
  335. In C, the library "consumes" a JSON object by unpacking its content
  336. into a blackboard structure passed to the read entry point by
  337. address. The structure contains a state-flag mask that you can (and
  338. should!) check so you'll know which parts of the structure contain
  339. valid data. It is safe to do nothing unless the PACKET_SET mask bit
  340. is on, which is the library's way of telling you that at least one
  341. complete JSON response has arrived since the last read.
  342. Data may accumulate on the blackboard over multiple reads,
  343. with new TPV reports overwriting old ones; it is guaranteed that
  344. overwrites are not partial. Expect this pattern to be replicated
  345. in any compiled language with only fixed-extent structures.
  346. In Python and Perl the read entry point returns an object containing
  347. accumulated data. The state-flag mask is still useful for telling you
  348. which parts contain data, and there is still a PACKET_SET bit. Expect
  349. this pattern to be replicated in other dynamic OO languages when we
  350. support them.
  351. The C++ binding is a very thin wrapper around the C. You get back an
  352. object, but it's just a reference to the C blackboard structure. There's
  353. no unpack() method because it doesn't fit the gpsmm object's RAII model.
  354. All bindings will throw a recognizable error from the read entry
  355. point when the socket is closed from the daemon side.
  356. [WARNING]
  357. The timing of your read loop is important. When it has satellite lock,
  358. the daemon will be writing into its end of the socket once per
  359. whatever the normal reporting-cycle time of your device is - for a GPS
  360. normally one peer second. *You must poll the socket more often that
  361. that.*
  362. If necessary, spawn a worker thread to do this, mutex-locking the
  363. structure where it outs the reports. If you don't do this, data
  364. will back up in your socket buffers and position reports will be
  365. more and more delayed until the socket FIFO fills, at which point the
  366. daemon will conclude the client has died and drop the connection.
  367. AIVDM clients have a longer maximum allowable poll interval, but a
  368. problem of a different kind. you have the problem that later sentences
  369. of (say) Type 1 don't obsolete the data in earlier ones. This is a
  370. problem, because the library is designed so that read calls pull any
  371. JSON reports waiting from the daemon and interpret them all.
  372. To avoid losing data, you want to poll the daemon more often than once
  373. per two seconds (that being the minimum transmission period for the
  374. most frequently shipped sentences, Type 1/2/3). That way the read
  375. buffer will never contain both a message and a later message of the
  376. same type that steps on it.
  377. === Shared-memory interface
  378. Whenever gpsd recognizes a packet from any attached device, it writes
  379. the accumulated state from that device to a shared memory segment. The
  380. C and C++ client libraries shipped with GPSD can read this segment.
  381. The API for reading the segment uses the same gps_open(), gps_read()
  382. and gps_close() entry points as the sockets interface. To enable using
  383. shared memory instead, it is only necessary to use the macro constant
  384. GPSD_SHARED_MEMORY as the host argument of gps_open().
  385. The gps_stream(), gps_send(), gps_waiting(), and gps_data() entry
  386. points are not available with this interface. You cannot set a device
  387. filter on it. You will not get device activation or deactivation
  388. notices through it. And, of course, it is only good for local and not
  389. networked access. Its main advantage is that it is very fast and
  390. lightweight, especially suitable for use in low-power embedded
  391. deployments with a single device on a fixed port and the sockets
  392. interface configured out.
  393. Under the shared-memory interface, gps_read() after a successful
  394. gps_open() will always return with data; its return is the size of a
  395. struct gps_data_t in bytes. The 'gps_fd' member of the struct gpsdata
  396. instance handed to you will always be -1. The PACKET_SET flag will
  397. always be asserted. The other flag bits in the 'set' member will tell
  398. you what data is updated in the instance, just as in the sockets
  399. interface.
  400. The shared-memory interface is not yet available from Python.
  401. === D-Bus broadcasts
  402. If your system supports D-Bus, gpsd broadcasts a signal with path /org/gpsd,
  403. interface "org.gpsd", and name "fix" whenever it received a position
  404. report from any device attached to it. See the gpsd(8) manual page for
  405. details of the binary payload layout.
  406. == C Examples
  407. The source distribution includes two example clients in C;
  408. gpxlogger.c and cgps.c.
  409. gpxlogger.c illustrates the simplest possible program flow; open,
  410. followed by stream, followed by the library main loop.
  411. cgps.c shows what an interactive application using the library and
  412. also hw processing user commands works. Note the use of the curses
  413. nodelay function to ensure that wgetch() does not block the GPS
  414. polling loop.
  415. == C++ examples
  416. The following code skeleton implements a C++ client:
  417. ----------------------------------------------------------------------
  418. int main(void)
  419. {
  420. gpsmm gps_rec("localhost", DEFAULT_GPSD_PORT);
  421. if (gps_rec.stream(WATCH_ENABLE|WATCH_JSON) == NULL) {
  422. cerr << "No GPSD running.\n";
  423. return 1;
  424. }
  425. for (;;) {
  426. struct gps_data_t* newdata;
  427. if (!gps_rec.waiting(50000000))
  428. continue;
  429. if ((newdata = gps_rec.read()) == NULL) {
  430. cerr << "Read error.\n";
  431. return 1;
  432. } else {
  433. PROCESS(newdata);
  434. }
  435. }
  436. return 0;
  437. }
  438. ----------------------------------------------------------------------
  439. Note the absence of explicit open and close methods. The object
  440. interface is designed on the RAII (Resource Acquisition Is
  441. Initialization) model; you close it by deallocating it.
  442. Look at test_gpsmm.cpp in the distribution for a full example.
  443. == Python examples
  444. There's a very simple Python example analogous to gpxlogger attached
  445. to the source code for the gps.py library.
  446. The heart of it is this code:
  447. -----------------------------------------------------------------------------
  448. session = gps(**opts)
  449. session.stream(WATCH_ENABLE|WATCH_NEWSTYLE)
  450. for report in session:
  451. print report
  452. -----------------------------------------------------------------------------
  453. If you need to intersperse other processing in a main event loop,
  454. like this:
  455. ----------------------------------------------------------------------
  456. session = gps(mode=WATCH_ENABLE)
  457. try:
  458. while True:
  459. # Do stuff
  460. report = session.next()
  461. # Check report class for 'DEVICE' messages from gpsd. If
  462. # we're expecting messages from multiple devices we should
  463. # inspect the message to determine which device
  464. # has just become available. But if we're just listening
  465. # to a single device, this may do.
  466. if report['class'] == 'DEVICE':
  467. # Clean up our current connection.
  468. session.close()
  469. # Tell gpsd we're ready to receive messages.
  470. session = gps(mode=WATCH_ENABLE)
  471. # Do more stuff
  472. except StopIteration:
  473. print "GPSD has terminated"
  474. ----------------------------------------------------------------------
  475. Each call to the iterator yields a report structure until the daemon
  476. terminates, at which point the iterator next() method will raise
  477. StopIteration and the loop will terminate.
  478. The report object returned by next() can be accessed either as a dictionary
  479. or as an object. As a dictionary, it is the raw contents of the last
  480. JSON response re-encoded in plain ASCII. For convenience, you may
  481. also access it as an object with members for each attribute in the
  482. dictionary. It is especially useful to know that the object will
  483. always have a "class" member giving the response type (TPV, SKY,
  484. DEVICE, etc.) as a string.
  485. For more interesting examples integrated with X and GTK, see xgps and
  486. xgpsspeed.
  487. == Other Client Bindings
  488. There are a couple of client bindings for GPSD that are maintained
  489. separately from the GPSD distribution. We don't try to document their
  490. APIs here, but just provide pointers to them.
  491. == Java
  492. There is a Java binding, described at http://gpsd4java.forge.hoegergroup.de/
  493. This binding is available at maven central. See that web page for how
  494. to use it in a maven build.
  495. == Perl
  496. There's a Perl client library at http://search.cpan.org/dist/Net-GPSD3/
  497. == Backward Incompatibility and Future Changes
  498. The C/C++ binding makes available two preprocessor symbols,
  499. GPSD_API_MAJOR_VERSION and GPSD_API_MINOR_VERSION, in gps.h.
  500. The Python module has corresponding symbols.
  501. In major versions before 5:
  502. * gps_open() didn't take a third argument; instead, it returned malloc storage.
  503. * The 'read()' method in various bindings was named 'poll()', blocked
  504. waiting for input, and had a different return convention. The name
  505. 'poll()' will at some point be reintroduced as an interface to the
  506. wire-protocol POLL command.
  507. * Clients needed to define a hook for client-side logging if they
  508. didn't want code in netlib.c and libgps_core.c to occasionally send
  509. messages to stderr. This requirement is now gone.
  510. * There was a set_raw_hook() method in the C and Python bindings, now gone.
  511. C clients should call gps_data(); the buffer is available directly in Python,
  512. both as str (response) and bytes (bresponse). The distinction matters
  513. in Python 3.
  514. //end