Skip to content

utils/dsc/constants.py lookup tables disagree with spec-verified values in decoder.py #244

Description

@jimarndt

Following up on #241 — found a related but separate issue while testing. utils/dsc/constants.py has its own independent lookup tables (FORMAT_CODES, DISTRESS_NATURE_CODES, TELECOMMAND_CODES) that weren't touched by #241 and disagree with the spec-verified values already used in decoder.py's _try_decode_message(). Confirmed via GUI testing — wrong nature-of-distress labels were displayed for known messages.

Most serious: FORMAT_CODES has format 120 and 112 swapped. constants.py currently maps 120: "DISTRESS", but per the spec (and per decoder.py's own verified table), 112 is DISTRESS and 120 is INDIVIDUAL. As it stands this misclassifies a routine individual call as a mayday and vice versa.

python

Spec-verified (matches decoder.py), vs. current constants.py:

FORMAT_CODES = {
102: "GEOGRAPHIC_AREA", # constants.py has: 102: "ALL_SHIPS"
112: "DISTRESS", # constants.py has: 112: "INDIVIDUAL"
114: "GROUP", # constants.py has: 114: "INDIVIDUAL_ACK"
116: "ALL_SHIPS", # constants.py has: 116: "GROUP"
120: "INDIVIDUAL", # constants.py has: 120: "DISTRESS"
123: "INDIVIDUAL_SEMI_AUTO", # constants.py has: 123: "ALL_SHIPS_URGENCY_SAFETY"
}

DISTRESS_NATURE_CODES is shifted by one — constants.py has an extra 100: "UNDESIGNATED" entry that pushes every other code down by one from the spec value:

python
DISTRESS_NATURE_CODES = {
100: "FIRE_EXPLOSION",
101: "FLOODING",
102: "COLLISION",
103: "GROUNDING",
104: "LISTING_CAPSIZE_DANGER",
105: "SINKING",
106: "DISABLED_ADRIFT",
107: "UNDESIGNATED",
108: "ABANDONING_SHIP",
109: "PIRACY_ARMED_ROBBERY",
110: "MAN_OVERBOARD",
}

(constants.py also has a 112: "EPIRB" entry that isn't in decoder.py's verified table — happy to drop it or track it down against the spec separately, whichever you'd prefer.)

TELECOMMAND_CODES has a direct conflict, not just different labels. decoder.py labels 118: "TEST"; constants.py has 111: "TEST" and 118: "FREQ_ANNOUNCEMENT". decoder.py's table is also intentionally partial — only codes confirmed against spec text are included, everything else reports UNKNOWN- rather than guessing:

python
TELECOMMAND_CODES = {
100: "F3E/G3E ALL MODES TP",
101: "F3E/G3E DUPLEX TP",
118: "TEST",
121: "POSITION_OR_LOCATION_UPDATING",
126: "NO_INFORMATION",
}

constants.py's codes 102–113 and 200–201 aren't in decoder.py's verified table at all and look like guesses — want to confirm before I either source them from the spec or drop them to UNKNOWN- like decoder.py does.

Related, also found: CATEGORY_PRIORITY in constants.py is keyed on ALL_SHIPS/GROUP/INDIVIDUAL/INDIVIDUAL_ACK, but decoder.py actually emits category as DISTRESS/URGENCY/SAFETY/SHIPS_BUSINESS/ROUTINE. As-is, almost every non-distress message falls through to the default priority (10) in parser.py's get_category_priority().

Open question before I write the PR: parser.py's parse_dsc_message() re-derives format_text/nature_of_distress/telecommand*_text from its own lookup tables, but decoder.py already computes and includes format_text/nature_text/telecommand_text (and ship_in_distress_mmsi for the distress-ack/self-cancel case) directly in its JSON output. Was parser.py deliberately built to be independent of decoder.py's output (e.g. so it could parse JSON from another source someday), or is the duplication just drift? This matters for DISTRESS_ACK_OR_SELF_CANCEL specifically — format 116 is overloaded (disambiguated by peeking at the category field), so a numeric format-code lookup in parser.py can never reproduce that distinction on its own; the clean fix is for parser.py to trust decoder.py's precomputed format_text instead of recomputing it. Let me know which direction you'd prefer and I'll open the PR against that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions