Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message type 24 (Class B static data) does not detect and correctly decode part B #7

Open
astuder opened this issue Apr 1, 2024 · 4 comments

Comments

@astuder
Copy link
Contributor

astuder commented Apr 1, 2024

Message type 24 comes in two variants, called "part A" and "part B". simpleais always returns both sets of fields.

Example message: !AIVDM,1,1,,B,H5NhCmTN7B=400500000001P0004,0*56

Decoded by simpleais:

type 24
repeat 0
mmsi 367793110
partno 1
shipname G!4#Q@@AP@@@@@@@X
ignored-160 4
shiptype Fishing
vendorid GRM
model 1
serial 5
callsign
to_bow 12
to_stern 0
to_port 0
to_starboard 0
mothership_mmsi 25165824
ignored-162 4
text None

Correct decoding (via Maritec):

type 24
repeat 0
mmsi 367793110
part_no 1
type fishing
vendorid GRMD@@E
callsign @@@@@@@
to_bow 12
to_stern 0
to_port 0
to_starboard 0
spare 4

The output for shipname may be uninitialized memory, at one occasion I got C: DRIVE - Edit: Never mind, there's a ship with that name :)

This type may require some custom handling as the documentation for AIVDM merged both definitions into the same table:
https://gpsd.gitlab.io/gpsd/AIVDM.html#_type_24_static_data_report

@astuder
Copy link
Contributor Author

astuder commented Apr 2, 2024

Message types 22, 25 and 26 have a similar issue with the broadcast/addressed bit indicating different field decoding.

My first idea was to have an optional "type decoders" to post-process the message, that are invoked based on message type. The type decoders could be managed as a list in MessageDecoder similar to the field decoders.

But simpleais enumerating/decoding fields on access complicates things a bit..

How about a "subtype" structure in the MessageDecoder class with:

type
subtype_field_name
subtype_fields [subtype_values][fields]

For example for msg type 24:

type = 24
subtype_field_name = partno
subtype_fields = [
    [shipname, spare],
    [shiptype, vendorid, model, serial, callsign, to_bow, to_stern, to_port, to_starboard, mothership_mmsi, spare]
]

and then query that in the iterators and getters to only return applicable fields:

if requested_field_name in subtypes[field(subtype_field_name)].sub_type_fields:
    # field exists for this subtype
else:
    # field does not exist

caveat, mothership is even more complicated and overlaps with dimensions:

Interpretation of the 30 bits 132-162 in Part B is variable. If the MMSI at 8-37 is that of an auxiliary craft, the entry is taken to refer to a small attached auxiliary vessel and these 30 bits are read as the MMSI of the mother ship. Otherwise the 30 bits describe vessel dimensions as in Message Type 5.

According to [MMSI], an MMSI is associated with an auxiliary craft when it is of the form 98XXXYYYY, where (1) the '98' in positions 1 and 2 is required to designate an auxiliary craft, (2) the digits XXX in the 3, 4 and 5 positions are the MID (the three-digit country code as described in [ITU-MID]) and (3) YYYY is any decimal literal from 0000 to 9999.

@wpietri
Copy link
Owner

wpietri commented Apr 2, 2024

Thanks for mentioning this. Just to understand the priority, is this something you actively need? Or is it more a desire to have everything correct?

@astuder
Copy link
Contributor Author

astuder commented Apr 2, 2024

I can work around it with a few lines of Python code.

But for the common msg type 24 (sent by pleasure boats), it's a bit jarring to see the invalid names when using aist. Though that might be an oversight in aist as I now see that you already check for partno in there.

@astuder
Copy link
Contributor Author

astuder commented Apr 4, 2024

I implemented a fix in astuder@6105c45

It introduces the concept of subtypes, where the value of one field controls the decoding of other fields. Each unique subtype creates a trimmed instance of MessageDecoder, which is requested by the constructor of Sentence if applicable.

This fixes the issue with overlapping field definitions when decoding type 22 (channel management) and type 24 (static data report):

Sentence 1:
          text: !AIVDM,1,1,,B,H5Nv6n058TDj0tJ1HT=@u8T4000,2*3E
        length: 160
          type: 24
        repeat: 0
          mmsi: 368019160
        partno: 0
      shipname: ARIEL OF VICTORIA
   ignored-160: -

Sentence 2:
          text: !AIVDM,1,1,,B,H5Nv6n4T0000000G4:pojh1h5130,0*62
        length: 168
          type: 24
        repeat: 0
          mmsi: 368019160
        partno: 1
      shiptype: Sailing
      vendorid: 
         model: 0
        serial: 0
      callsign: WDJ8720
        to_bow: 14
      to_stern: 5
       to_port: 1
  to_starboard: 3
  mothership_mmsi: 29380675
   ignored-162: 0

mothership_mmsi still is a problem as its handling requires more complex rules depending on mmsi field. I haven't seen this in use in the wild yet.

This fix also improves support for dest_mmsi in type 25/26 (single/multiple slot binary message), but those messages probably still won't return the data field. Though, according to AIVDM documentation, these message types haven't been seen in the wild.

This branch also fixes warnings about escaping of backslashes in aivdm_translate.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants