[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gpsd-users] AIVDM sentence buffering

From: Jonathan Fewtrell
Subject: [gpsd-users] AIVDM sentence buffering
Date: Thu, 19 Jan 2012 15:38:46 +0800

I am developing an Objective C wrapper for libgps for use on OS X, which I will 
open source if I get it to work.

I have a concern about the buffering of AIVDM sentences. I hope someone here 
will be able to help.

Reading the documentation ( and, I am worried that if a read picks up 
multiple AIVDM sentences only the most recent one will be reflected in the 
ais_t struct.

My code follows the approach recommended at (I think): 

1. Connect to the daemon using gps_open().
2. Start streaming using gps_stream().
3. Launch a background thread operation which:
  (i) Calls gps_waiting() with a timeout of 5s
  (ii) If gps_waiting() returns before timeout, calls gps_read()
  (iii) Interrogates the gps_data_t struct to see if there is valid GPS and/or 
AIS data, and if so passes it back to the main thread for action.
  (iv) Launches another background thread operation at 3 and then dies.

My concern is that if gps_read() picked up say 10 AIVDM messages at 3(ii), only 
one of them would be reflected in the struct at 3(iii). The other 9 would be 
effectively lost. That is my interpretation of the quote below. Have I 

I noticed that gpspipe reads directly from the socket rather than using the 
gps_waiting()/gps_read() mechanism. Reading the code, I think this would output 
all 10 sentences. Is that right?

I did a simultaneous run of gpspipe and my own code (which uses a repeating 
timer to read the accumulated data in a serial port every (say) 1 second), and 
both seemed to output the same. That encourages me to think that AIVDM 
sentences are not being dropped by gps_waiting()/gps_read(). But I would like 
to be sure. Any insight would be appreciated.

The tricky part is interpreting what you get from the blocking 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 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 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 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.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]