[Top][All Lists]

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

[gpsd-dev] AIS: IMO236/289 Met/hydro message

From: christian Gagneraud
Subject: [gpsd-dev] AIS: IMO236/289 Met/hydro message
Date: Sat, 19 May 2012 15:40:55 +0100
User-agent: Mozilla/5.0 (X11; Linux i686; rv:11.0) Gecko/20120327 Thunderbird/11.0.1

Hi all,

I'm currently working on getting gpsd parse correctly these 2 types of messages. I've spotted some errors in the data structure and in the decoding that are easy to fix. But as I'm moving forward, I'm facing a dilemma. The dac1fid31 data structure is shared between IMO236 (FID=11) and IMO289 (FID=31), which at first makes sense as they are very similar, but as you start looking at the lowest level details, there's some differences that make awkward if not impossible to manage these 2 messages with a common structure.

So first, let's review the differences:
1) Only in IMO289:
 - Position accuracy bit
 - Greater visibility bit
=> No big deal, the IMO236 always set them to false

2) Long/Lat:
 - IMO236: latitude comes first, followed by longitude
 - IMO289: longitude comes first, followed by latitude
=> No problems, managed in driver_ais.c, where code is not shared

3) Signed vs unsigned:
 - IMO236: signedness is achieved by subtracting offset on unsigned values
 - IMO289: uses 2's complement for signed value (except water level)
=> Ditto.

4) Data not available:
 - IMO236: all the bits are sets.
 - IMO289: special values are used (usually incompatible with IMO236).
=> That's where the problems start, see below

5) Units/Precision:
 - Water level: 0.1m on 9bits for IMO236, 0.01m on 12 bits for IMO289
=> Managed in driver_ais.c, not a real concern

And now, lets look at which code is currently shared or not:

1) driver_ais.c
Not shared due to message structure incompatibility, IMO236 needs a couple of minor fixes, I'm suspecting the IMO289 to require more work.

2) gps_json.c
Code is shared, the non scaled code seems OK as it passes the raw data, but the scaled code is wrong because it doesn't deal with the special "data not available" values and would happily scale anything, resulting in crazy values.

3) ais_json.c
Code is shared, but it uses the IMO289 definitions for "data not available", which definitely breaks the IMO236 message.

4) gps.h
The "data not available" codes for IMO236 are missing

So finally, of all these differences, the biggest problem is the "data not available" stuff. To fix this problem, I see 2 different approaches:

1) Make the IMO236 low-level code in driver_ais.c mimic the IMO289 one, so that the upper layers code can easily be shared.
for example, in driver_ais.c, for IMO236:
ais->type8.dac1fid31.airtemp    = UBITS(153, 11)
/* IMO236: 1447 => IMO289: -1024 */
if (ais->type8.dac1fid31.airtemp == DAC1FID11_AIRTEMP_NOT_AVAILABLE)
   ais->type8.dac1fid31.airtemp = DAC1FID31_AIRTEMP_NOT_AVAILABLE;

* pros: Easy to do, allow to maximize the shared code in the upper layer
* cons: The IMO236 structure is actually an IMO236/IMO289 bastard, in that it doesn't fully follow the IMO236 specs.

2) Define a new dac1fid11 structure, and have different code at all levels

* pros: Both IMO236 and IMO289 stick to the specs
* cons: More code to write/read/maintain, with some similarities but subtle differences.

So the question of the day is: which way should be taken to address this issue? I personally think that the #2 is cleaner, but i would have no problem taking the path #1

FYI, attached is a diff that illustrates my point (with some minor fixes to the IMO236 decoding). As long as I deal with available data and look only at raw values, I managed to validate the decoding of live IMO236 met/hydro message against known-good decodings.


Attachment: ais-imo.diff
Description: Text Data

reply via email to

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