diff --git a/lib/MessageDecoder.ts b/lib/MessageDecoder.ts index b40f43a..c8ee94c 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_B2_OCRA, ]; export class MessageDecoder { diff --git a/lib/plugins/Label_B2_OCRA.ts b/lib/plugins/Label_B2_OCRA.ts new file mode 100644 index 0000000..4f6926b --- /dev/null +++ b/lib/plugins/Label_B2_OCRA.ts @@ -0,0 +1,248 @@ +import { DecoderPlugin } from '../DecoderPlugin'; +import { DecodeResult, Message, Options } from '../DecoderPluginInterface'; +import { ResultFormatter } from '../utils/result_formatter'; +import { DateTimeUtils } from '../DateTimeUtils'; + +/** + * Label B2 — Oceanic Clearance Acknowledgement (OCRA / CLA) + * + * Downlink confirming that an oceanic clearance uplink (CLX) has been + * received and acknowledged by the aircraft. Carries the time, date, + * oceanic FIR, clearance number, callsign, destination, cleared route + * (random-route or named NAT track) with coordinate waypoints, entry- + * fix time, cleared flight level, and cleared Mach. + * + * Wire format: + * + * /PIKCLYA.OC1/CLA 1911 260420 EGGX CLRNCE 296 AFR012 CLRD TO KJFK VIA + * DINIM RANDOM ROUTE DINIM 5130N020W 5230N030W 5130N040W 4930N050W IBERG + * FM DINIM/2039 MNTN F400 M085 END OF MESSAGE 694F + * + * Date field: 6 digits in YYMMDD order (e.g. `260420` = 2026-04-20). + * (An earlier analyst report read this as DDMMYY; that interpretation + * is inconsistent with the real message date — corrected here.) + */ +export class Label_B2_OCRA extends DecoderPlugin { + name = 'label-b2-ocra'; + + qualifiers() { + return { + labels: ['B2'], + }; + } + + decode(message: Message, options: Options = {}): DecodeResult { + const decodeResult = this.initResult( + message, + 'Oceanic Clearance Acknowledgement (OCRA / CLA)', + ); + + const text = (message.text || '').replace(/\r/g, ' ').trim(); + if (!text) { + this.setDecodeLevel(decodeResult, false); + return decodeResult; + } + + // ── Envelope: //CLA HHMM YYMMDD FIR CLRNCE CLRD TO VIA <...> ── + const envelope = text.match( + /^\/(?[A-Z0-9]+)\.(?[A-Z0-9]+)\/(?.+)$/, + ); + let station = ''; + let channel = ''; + let body = text; + if (envelope?.groups) { + station = envelope.groups.station; + channel = envelope.groups.channel; + body = envelope.groups.rest; + } + + // ── Header ── + const headerRe = + /\bCLA\s+(?