Skip to content

Commit

Permalink
More H1 matching (#163)
Browse files Browse the repository at this point in the history
Attempts to decode H1 messages from c-band. If decode is not successful, it will try the next possible decoder

- cleanup of unit tests
- remove 'fullyDecoded' flags being passed around in H1Helper
  • Loading branch information
makrsmark authored Oct 17, 2024
1 parent ace8f5f commit 2e52c28
Show file tree
Hide file tree
Showing 16 changed files with 1,122 additions and 1,430 deletions.
52 changes: 26 additions & 26 deletions lib/MessageDecoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,10 @@ export class MessageDecoder {
this.registerPlugin(new Plugins.Label_44_POS(this));
this.registerPlugin(new Plugins.Label_4N(this));
this.registerPlugin(new Plugins.Label_B6_Forwardslash(this));
this.registerPlugin(new Plugins.Label_H1_FPN(this));
this.registerPlugin(new Plugins.Label_H1_FLR(this));
this.registerPlugin(new Plugins.Label_H1_FTX(this));
this.registerPlugin(new Plugins.Label_H1_INI(this));
this.registerPlugin(new Plugins.Label_H1_OHMA(this));
this.registerPlugin(new Plugins.Label_H1_POS(this));
this.registerPlugin(new Plugins.Label_H1_WRN(this));
this.registerPlugin(new Plugins.Label_H1(this));
this.registerPlugin(new Plugins.Label_HX(this));
this.registerPlugin(new Plugins.Label_80(this));
this.registerPlugin(new Plugins.Label_83(this));
Expand Down Expand Up @@ -106,29 +103,32 @@ export class MessageDecoder {
console.log(usablePlugins);
}

let result : DecodeResult;
if (usablePlugins.length > 0) {
const plugin: DecoderPluginInterface = usablePlugins[0];
let result: DecodeResult = {
decoded: false,
error: 'No known decoder plugin for this message',
decoder: {
name: 'none',
type: 'none',
decodeLevel: 'none',
},
message: message,
remaining: {
text: message.text,
},
raw: {},
formatted: {
description: 'Not Decoded',
items: [],
},
};

// for-in is not happy. doing it the old way
for (let i = 0; i < usablePlugins.length; i++) {
const plugin = usablePlugins[i];
result = plugin.decode(message);
} else {
result = {
decoded: false,
error: 'No known decoder plugin for this message',
decoder: {
name: 'none',
type: 'none',
decodeLevel: 'none',
},
message: message,
remaining: {
text: message.text,
},
raw: {},
formatted: {
description: 'Not Decoded',
items: [],
},
};
if (result.decoded) {
break;
}
}

if (options.debug) {
Expand Down
33 changes: 33 additions & 0 deletions lib/plugins/Label_H1.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { MessageDecoder } from '../MessageDecoder';
import { Label_H1 } from './Label_H1';

describe('Label_H1 INI', () => {

let plugin: Label_H1;

beforeEach(() => {
const decoder = new MessageDecoder();
plugin = new Label_H1(decoder);
});


test('matches Label H1 Preamble FLR qualifiers', () => {
expect(plugin.decode).toBeDefined();
expect(plugin.name).toBe('label-h1');
expect(plugin.qualifiers).toBeDefined();
expect(plugin.qualifiers()).toEqual({
labels: ['H1'],
});
});

test('INI <invalid>', () => {

const text = 'Bogus message';
const decodeResult = plugin.decode({ text: text });

expect(decodeResult.decoded).toBe(false);
expect(decodeResult.decoder.decodeLevel).toBe('none');
expect(decodeResult.formatted.description).toBe('Unknown H1 Message');
expect(decodeResult.message.text).toBe(text);
});
});
21 changes: 19 additions & 2 deletions lib/plugins/Label_H1.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
import { DecoderPlugin } from '../DecoderPlugin';
import { DecodeResult, Message, Options } from '../DecoderPluginInterface';
import { H1Helper } from '../utils/h1_helper';

export class Label_H1 extends DecoderPlugin {
name = 'label-h1';
qualifiers() { // eslint-disable-line class-methods-use-this
return {
labels: ['H1'],
};
}

decode(message: Message, options: Options = {}) : DecodeResult {
const decodeResult = this.defaultResult();
// console.log('DECODER: H1 detected');
let decodeResult = this.defaultResult();
decodeResult.decoder.name = this.name;
decodeResult.message = message;
decodeResult.remaining.text = '';

const msg = message.text.replace(/\n|\r/g, "");
const decoded = H1Helper.decodeH1Message(decodeResult, msg);
decodeResult.decoded = decoded;

decodeResult.decoder.decodeLevel = decodeResult.remaining.text.length===0 ? 'full' : 'partial';
if (decodeResult.formatted.items.length === 0) {
if (options.debug) {
console.log(`Decoder: Unknown H1 message: ${message.text}`);
}
decodeResult.remaining.text = message.text;
decodeResult.decoded = false;
decodeResult.decoder.decodeLevel = 'none';
}
return decodeResult;
}
}
Expand Down
538 changes: 247 additions & 291 deletions lib/plugins/Label_H1_FPN.test.ts

Large diffs are not rendered by default.

38 changes: 0 additions & 38 deletions lib/plugins/Label_H1_FPN.ts

This file was deleted.

110 changes: 50 additions & 60 deletions lib/plugins/Label_H1_FTX.test.ts
Original file line number Diff line number Diff line change
@@ -1,72 +1,62 @@
import { MessageDecoder } from '../MessageDecoder';
import { Label_H1_FTX } from './Label_H1_FTX';
import { Label_H1 } from './Label_H1';

describe('Label_H1_FTX', () => {
let plugin: Label_H1_FTX;
describe('Label_H1 FPN', () => {

beforeEach(() => {
const decoder = new MessageDecoder();
plugin = new Label_H1_FTX(decoder);
});

test('matches Label H1 Preamble FTX qualifiers', () => {
expect(plugin.decode).toBeDefined();
expect(plugin.name).toBe('label-h1-ftx');
expect(plugin.qualifiers).toBeDefined();
expect(plugin.qualifiers()).toEqual({
labels: ['H1'],
preambles: ['FTX', '- #MDFTX'],
});
});
let plugin: Label_H1;

beforeEach(() => {
const decoder = new MessageDecoder();
plugin = new Label_H1(decoder);
});

test('decodes Label H1 Preamble FTX valid', () => {
// https://app.airframes.io/messages/3402014738
const text = 'FTX/ID23544S,HIFI21,7VZ007B1S276/MR2,/FXFYI .. TAF KSUX 021720Z 0218 0318 20017G28KT P6SM SKC FM022200 22012G18KT P6SM SKC .. PUTS YOUR CXWIND AT 26KT ON RWY 13 .. REDUCES TO 18KT AT 22Z4FEF'
const decodeResult = plugin.decode({ text: text });

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.flight_number).toBe('HIFI21');
expect(decodeResult.raw.mission_number).toBe('7VZ007B1S276');
expect(decodeResult.formatted.items.length).toBe(3);
expect(decodeResult.formatted.items[0].label).toBe('Tail');
expect(decodeResult.formatted.items[0].value).toBe('23544S');
expect(decodeResult.formatted.items[1].label).toBe('Free Text');
expect(decodeResult.formatted.items[1].value).toBe('FYI .. TAF KSUX 021720Z 0218 0318 20017G28KT P6SM SKC FM022200 22012G18KT P6SM SKC .. PUTS YOUR CXWIND AT 26KT ON RWY 13 .. REDUCES TO 18KT AT 22Z');
expect(decodeResult.formatted.items[2].label).toBe('Message Checksum');
expect(decodeResult.formatted.items[2].value).toBe('0x4fef');
expect(decodeResult.remaining.text).toBe('/MR2,');
});

test('decodes Label H1 Preamble - #MDFTX valid', () => {
// https://app.airframes.io/messages/3400555283
const text = '- #MDFTX/ID77170A,RCH836,ABZ01G6XH273/MR2,/FXIRAN IS LAUNCHING MISSILES TOWARDS ISRAEL. YOUR FLIGHT PATH IS CURRENTLY NORTH OF PROJECTED MISSILE TRACKS. EXERCIZE EXTREME CAUTION.4A99'
const decodeResult = plugin.decode({ text: text });
test('decodes Label H1 Preamble FTX valid', () => {
// https://app.airframes.io/messages/3402014738
const text = 'FTX/ID23544S,HIFI21,7VZ007B1S276/MR2,/FXFYI .. TAF KSUX 021720Z 0218 0318 20017G28KT P6SM SKC FM022200 22012G18KT P6SM SKC .. PUTS YOUR CXWIND AT 26KT ON RWY 13 .. REDUCES TO 18KT AT 22Z4FEF'
const decodeResult = plugin.decode({ text: text });

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.flight_number).toBe('HIFI21');
expect(decodeResult.raw.mission_number).toBe('7VZ007B1S276');
expect(decodeResult.formatted.items.length).toBe(3);
expect(decodeResult.formatted.items[0].label).toBe('Tail');
expect(decodeResult.formatted.items[0].value).toBe('23544S');
expect(decodeResult.formatted.items[1].label).toBe('Free Text');
expect(decodeResult.formatted.items[1].value).toBe('FYI .. TAF KSUX 021720Z 0218 0318 20017G28KT P6SM SKC FM022200 22012G18KT P6SM SKC .. PUTS YOUR CXWIND AT 26KT ON RWY 13 .. REDUCES TO 18KT AT 22Z');
expect(decodeResult.formatted.items[2].label).toBe('Message Checksum');
expect(decodeResult.formatted.items[2].value).toBe('0x4fef');
expect(decodeResult.remaining.text).toBe('/MR2,');
});

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.flight_number).toBe('RCH836');
expect(decodeResult.raw.mission_number).toBe('ABZ01G6XH273');
expect(decodeResult.formatted.items.length).toBe(3);
expect(decodeResult.formatted.items[0].label).toBe('Tail');
expect(decodeResult.formatted.items[0].value).toBe('77170A');
expect(decodeResult.formatted.items[1].label).toBe('Free Text');
expect(decodeResult.formatted.items[1].value).toBe('IRAN IS LAUNCHING MISSILES TOWARDS ISRAEL. YOUR FLIGHT PATH IS CURRENTLY NORTH OF PROJECTED MISSILE TRACKS. EXERCIZE EXTREME CAUTION.');
expect(decodeResult.formatted.items[2].label).toBe('Message Checksum');
expect(decodeResult.formatted.items[2].value).toBe('0x4a99');
expect(decodeResult.remaining.text).toBe('- #MDF/MR2,'); // FIXME - should be `- #MD/`
test('decodes Label H1 Preamble - #MDFTX valid', () => {
// https://app.airframes.io/messages/3400555283
const text = '- #MDFTX/ID77170A,RCH836,ABZ01G6XH273/MR2,/FXIRAN IS LAUNCHING MISSILES TOWARDS ISRAEL. YOUR FLIGHT PATH IS CURRENTLY NORTH OF PROJECTED MISSILE TRACKS. EXERCIZE EXTREME CAUTION.4A99'
const decodeResult = plugin.decode({ text: text });

expect(decodeResult.decoded).toBe(true);
expect(decodeResult.decoder.decodeLevel).toBe('partial');
expect(decodeResult.raw.flight_number).toBe('RCH836');
expect(decodeResult.raw.mission_number).toBe('ABZ01G6XH273');
expect(decodeResult.formatted.items.length).toBe(3);
expect(decodeResult.formatted.items[0].label).toBe('Tail');
expect(decodeResult.formatted.items[0].value).toBe('77170A');
expect(decodeResult.formatted.items[1].label).toBe('Free Text');
expect(decodeResult.formatted.items[1].value).toBe('IRAN IS LAUNCHING MISSILES TOWARDS ISRAEL. YOUR FLIGHT PATH IS CURRENTLY NORTH OF PROJECTED MISSILE TRACKS. EXERCIZE EXTREME CAUTION.');
expect(decodeResult.formatted.items[2].label).toBe('Message Checksum');
expect(decodeResult.formatted.items[2].value).toBe('0x4a99');
expect(decodeResult.remaining.text).toBe('- #MD/MR2,');
});

test('decodes Label H1 Preamble POS <invalid>', () => {
test('decodes Label H1 Preamble POS <invalid>', () => {

const text = 'FTX Bogus message';
const decodeResult = plugin.decode({ text: text });
const text = 'FTX Bogus message';
const decodeResult = plugin.decode({ text: text });

expect(decodeResult.decoded).toBe(false);
expect(decodeResult.decoder.decodeLevel).toBe('none');
expect(decodeResult.decoder.name).toBe('label-h1-ftx');
expect(decodeResult.formatted.description).toBe('Free Text');
expect(decodeResult.message.text).toBe(text);
});
expect(decodeResult.decoded).toBe(false);
expect(decodeResult.decoder.decodeLevel).toBe('none');
expect(decodeResult.formatted.description).toBe('Free Text');
expect(decodeResult.message.text).toBe(text);
});
});
37 changes: 0 additions & 37 deletions lib/plugins/Label_H1_FTX.ts

This file was deleted.

Loading

0 comments on commit 2e52c28

Please sign in to comment.