diff --git a/lib/MessageDecoder.ts b/lib/MessageDecoder.ts index b40f43a..ebf5493 100644 --- a/lib/MessageDecoder.ts +++ b/lib/MessageDecoder.ts @@ -78,6 +78,7 @@ const pluginClasses = [ Plugins.Label_QQ, Plugins.Label_QR, Plugins.Label_QS, + Plugins.Label_A3_PDC, ]; export class MessageDecoder { diff --git a/lib/plugins/Label_A3_PDC.ts b/lib/plugins/Label_A3_PDC.ts new file mode 100644 index 0000000..efacb8b --- /dev/null +++ b/lib/plugins/Label_A3_PDC.ts @@ -0,0 +1,325 @@ +import { DecoderPlugin } from '../DecoderPlugin'; +import { DecodeResult, Message, Options } from '../DecoderPluginInterface'; +import { ResultFormatter } from '../utils/result_formatter'; +import { DateTimeUtils } from '../DateTimeUtils'; + +/** + * Label A3 — Pre-Departure Clearance (PDC) + * + * ATC-issued departure clearance delivered via D-ATIS / datalink, confirming + * routing, runway, squawk, frequencies, and ATIS code to the flight crew + * before pushback. + * + * Wire format (single concatenated text with embedded newlines or spaces): + * + * RIOCGYA.DC1.CLD 2227 260419 SBGR PDC 692 + * IBE0272 CLRD TO LEMD OFF 10L VIA AMVUL6A + * AMVUL6A/NUXEL/F350/NUXEL UZ23 OGSOO DCT EVTOR ... + * ... Z409 TLD + * SQUAWK 4447 ADT 2220 NEXT FREQ 126.900 ATIS Z + * APP 120.454 D02 + * + * Header tokens: + * FACILITY — originating ATC datalink facility (e.g. RIOCGYA = Rio/Galeão) + * DC — Departure Clearance message subtype (DC1, DC2, ...) + * CLD — Clearance message type + * HHMM — UTC time of clearance + * DDMMYY — date of clearance + * ICAO — departure airport + * PDC — message format keyword + * SEQ — facility-local PDC sequence number + * + * Body: + * CALLSIGN CLRD TO OFF VIA + * + * + * Trailer (any order): + * SQUAWK + * ADT — target/actual departure time (interpreted) + * NEXT FREQ — next ATC sector frequency + * ATIS — required ATIS information code + * APP D — undocumented trailing field, raw only + * + * Per the analyst's "ignore wild-guesses" guidance, the trailing + * `APP ... D02` token is exposed verbatim as a raw string with no + * interpretation. + */ +export class Label_A3_PDC extends DecoderPlugin { + name = 'label-a3-pdc'; + + qualifiers() { + return { + labels: ['A3'], + }; + } + + decode(message: Message, options: Options = {}): DecodeResult { + const decodeResult = this.initResult( + message, + 'Pre-Departure Clearance (PDC)', + ); + + const text = (message.text || '').replace(/\r/g, '').trim(); + if (!text) { + this.setDecodeLevel(decodeResult, false); + return decodeResult; + } + + // ── Header: FACILITY.DC[./]CLD HHMM YYMMDD ICAO PDC SEQ ── + // Separator between SUBTYPE and MSGTYPE is either `.` (e.g. SBGR form) + // or `/` (e.g. EDDF/Frankfurt form). A leading `/` in front of the + // facility is optional. + const headerRe = + /\/?(?[A-Z0-9]+)\.(?DC\d+)[./](?[A-Z]{2,4})\s+(?