@airframes/acars-decoder 1.8.7 → 1.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +142 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +142 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -627,8 +627,11 @@ var ResultFormatter = class {
|
|
|
627
627
|
value: decodeResult.raw.fuel_remaining.toString()
|
|
628
628
|
});
|
|
629
629
|
}
|
|
630
|
+
static checksumAlgorithm(decodeResult, value) {
|
|
631
|
+
decodeResult.raw.checksum_algorithm = value;
|
|
632
|
+
}
|
|
630
633
|
static checksum(decodeResult, value) {
|
|
631
|
-
decodeResult.raw.checksum =
|
|
634
|
+
decodeResult.raw.checksum = value;
|
|
632
635
|
decodeResult.formatted.items.push({
|
|
633
636
|
type: "message_checksum",
|
|
634
637
|
code: "CHECKSUM",
|
|
@@ -2012,9 +2015,14 @@ function addCompanyRoute(decodeResult, value) {
|
|
|
2012
2015
|
// lib/utils/h1_helper.ts
|
|
2013
2016
|
var H1Helper = class _H1Helper {
|
|
2014
2017
|
static decodeH1Message(decodeResult, message) {
|
|
2015
|
-
const checksum = message.slice(-4);
|
|
2018
|
+
const checksum = parseInt(message.slice(-4), 16);
|
|
2016
2019
|
const data = message.slice(0, message.length - 4);
|
|
2017
|
-
|
|
2020
|
+
let checksumAlgorithmUsed = "";
|
|
2021
|
+
if (crc16IbmSdlcRev(data) === checksum) {
|
|
2022
|
+
checksumAlgorithmUsed = "IBM-SDLC reversed";
|
|
2023
|
+
} else if (crc16Genibus(data) === checksum) {
|
|
2024
|
+
checksumAlgorithmUsed = "GENIBUS";
|
|
2025
|
+
} else {
|
|
2018
2026
|
decodeResult.decoded = false;
|
|
2019
2027
|
decodeResult.decoder.decodeLevel = "none";
|
|
2020
2028
|
return false;
|
|
@@ -2091,6 +2099,9 @@ var H1Helper = class _H1Helper {
|
|
|
2091
2099
|
case "RN":
|
|
2092
2100
|
ResultFormatter.routeNumber(decodeResult, data2);
|
|
2093
2101
|
break;
|
|
2102
|
+
case "RW":
|
|
2103
|
+
processRunway(decodeResult, data2.split(":"));
|
|
2104
|
+
break;
|
|
2094
2105
|
case "SN":
|
|
2095
2106
|
decodeResult.raw.serial_number = data2;
|
|
2096
2107
|
break;
|
|
@@ -2116,6 +2127,7 @@ var H1Helper = class _H1Helper {
|
|
|
2116
2127
|
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2117
2128
|
}
|
|
2118
2129
|
}
|
|
2130
|
+
ResultFormatter.checksumAlgorithm(decodeResult, checksumAlgorithmUsed);
|
|
2119
2131
|
ResultFormatter.checksum(decodeResult, checksum);
|
|
2120
2132
|
return true;
|
|
2121
2133
|
}
|
|
@@ -2230,29 +2242,42 @@ function processIdentification(decodeResult, data) {
|
|
|
2230
2242
|
}
|
|
2231
2243
|
}
|
|
2232
2244
|
function processDT(decodeResult, data) {
|
|
2233
|
-
if (
|
|
2234
|
-
ResultFormatter.
|
|
2235
|
-
|
|
2236
|
-
|
|
2245
|
+
if (data.length === 9) {
|
|
2246
|
+
ResultFormatter.unknown(decodeResult, data[0]);
|
|
2247
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
2248
|
+
ResultFormatter.arrivalAirport(decodeResult, data[1]);
|
|
2249
|
+
}
|
|
2250
|
+
ResultFormatter.arrivalRunway(decodeResult, data[2]);
|
|
2251
|
+
ResultFormatter.currentFuel(decodeResult, parseInt(data[3], 10));
|
|
2252
|
+
ResultFormatter.eta(
|
|
2253
|
+
decodeResult,
|
|
2254
|
+
DateTimeUtils.convertHHMMSSToTod(data[4])
|
|
2255
|
+
);
|
|
2256
|
+
ResultFormatter.unknown(decodeResult, data[5]);
|
|
2257
|
+
ResultFormatter.position(
|
|
2258
|
+
decodeResult,
|
|
2259
|
+
CoordinateUtils.decodeStringCoordinates(data[6])
|
|
2260
|
+
);
|
|
2261
|
+
ResultFormatter.unknown(decodeResult, data[7]);
|
|
2262
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2263
|
+
return;
|
|
2237
2264
|
}
|
|
2238
|
-
if (data.length
|
|
2265
|
+
if (data.length === 4 || data.length === 5) {
|
|
2266
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
2267
|
+
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
2268
|
+
}
|
|
2239
2269
|
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
2240
|
-
|
|
2241
|
-
if (data.length > 2) {
|
|
2242
|
-
ResultFormatter.currentFuel(decodeResult, Number(data[2]));
|
|
2243
|
-
}
|
|
2244
|
-
if (data.length > 3) {
|
|
2270
|
+
ResultFormatter.currentFuel(decodeResult, parseInt(data[2], 10));
|
|
2245
2271
|
ResultFormatter.eta(
|
|
2246
2272
|
decodeResult,
|
|
2247
2273
|
DateTimeUtils.convertHHMMSSToTod(data[3])
|
|
2248
2274
|
);
|
|
2275
|
+
if (data.length > 4) {
|
|
2276
|
+
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
2277
|
+
}
|
|
2278
|
+
return;
|
|
2249
2279
|
}
|
|
2250
|
-
|
|
2251
|
-
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
2252
|
-
}
|
|
2253
|
-
if (data.length > 5) {
|
|
2254
|
-
ResultFormatter.unknownArr(decodeResult, data);
|
|
2255
|
-
}
|
|
2280
|
+
ResultFormatter.unknownArr(decodeResult, data, ",");
|
|
2256
2281
|
}
|
|
2257
2282
|
function processLandingReport(decodeResult, data) {
|
|
2258
2283
|
if (data.length === 19) {
|
|
@@ -2316,7 +2341,9 @@ function processMessageType(decodeResult, type) {
|
|
|
2316
2341
|
} else if (type === "FTX") {
|
|
2317
2342
|
decodeResult.formatted.description = "Free Text";
|
|
2318
2343
|
} else if (type === "INI") {
|
|
2319
|
-
decodeResult.formatted.description = "
|
|
2344
|
+
decodeResult.formatted.description = "Initial Report";
|
|
2345
|
+
} else if (type === "LDI") {
|
|
2346
|
+
decodeResult.formatted.description = "Load Distribution Information";
|
|
2320
2347
|
} else if (type === "PER") {
|
|
2321
2348
|
decodeResult.formatted.description = "Performance Report";
|
|
2322
2349
|
} else if (type === "POS") {
|
|
@@ -2381,11 +2408,14 @@ function processWindData(decodeResult, message) {
|
|
|
2381
2408
|
const flightLevel = Number(message.slice(0, 3));
|
|
2382
2409
|
const fields = message.slice(4).split(".");
|
|
2383
2410
|
fields.forEach((field) => {
|
|
2411
|
+
if (field.length < 4) {
|
|
2412
|
+
return;
|
|
2413
|
+
}
|
|
2384
2414
|
const data = field.split(",");
|
|
2385
2415
|
const waypoint = { name: data[0] };
|
|
2386
2416
|
const windData = data[1];
|
|
2387
|
-
const windDirection =
|
|
2388
|
-
const windSpeed =
|
|
2417
|
+
const windDirection = parseInt(windData.slice(0, 3), 10);
|
|
2418
|
+
const windSpeed = parseInt(windData.slice(3), 10);
|
|
2389
2419
|
if (data.length === 3) {
|
|
2390
2420
|
const tempData = data[2];
|
|
2391
2421
|
const tempFlightLevel = Number(tempData.slice(0, 3));
|
|
@@ -2412,7 +2442,16 @@ function processWindData(decodeResult, message) {
|
|
|
2412
2442
|
});
|
|
2413
2443
|
ResultFormatter.windData(decodeResult, wind);
|
|
2414
2444
|
}
|
|
2415
|
-
function
|
|
2445
|
+
function processRunway(decodeResult, data) {
|
|
2446
|
+
const parts = data[0].split(".");
|
|
2447
|
+
const more = parts[0].split(",");
|
|
2448
|
+
ResultFormatter.departureRunway(decodeResult, more[0]);
|
|
2449
|
+
ResultFormatter.unknownArr(decodeResult, more.slice(1), ",");
|
|
2450
|
+
ResultFormatter.unknownArr(decodeResult, parts.slice(1), ".");
|
|
2451
|
+
ResultFormatter.departureAirport(decodeResult, data[1].split(",")[0]);
|
|
2452
|
+
ResultFormatter.unknownArr(decodeResult, data[1].split(",").slice(1), ",");
|
|
2453
|
+
}
|
|
2454
|
+
function crc16IbmSdlcRev(data) {
|
|
2416
2455
|
let crc = 65535;
|
|
2417
2456
|
const bytes = Buffer.from(data, "ascii");
|
|
2418
2457
|
for (const byte of bytes) {
|
|
@@ -2430,7 +2469,23 @@ function calculateChecksum(data) {
|
|
|
2430
2469
|
const nibble2 = crc >> 8 & 15;
|
|
2431
2470
|
const nibble3 = crc >> 4 & 15;
|
|
2432
2471
|
const nibble4 = crc & 15;
|
|
2433
|
-
return
|
|
2472
|
+
return nibble4 << 12 | nibble3 << 8 | nibble2 << 4 | nibble1;
|
|
2473
|
+
}
|
|
2474
|
+
function crc16Genibus(data) {
|
|
2475
|
+
let crc = 65535;
|
|
2476
|
+
const polynomial = 4129;
|
|
2477
|
+
const bytes = Buffer.from(data, "ascii");
|
|
2478
|
+
for (const byte of bytes) {
|
|
2479
|
+
crc ^= byte << 8;
|
|
2480
|
+
for (let i = 0; i < 8; i++) {
|
|
2481
|
+
if ((crc & 32768) !== 0) {
|
|
2482
|
+
crc = (crc << 1 ^ polynomial) & 65535;
|
|
2483
|
+
} else {
|
|
2484
|
+
crc = crc << 1 & 65535;
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
return (crc ^ 65535) & 65535;
|
|
2434
2489
|
}
|
|
2435
2490
|
|
|
2436
2491
|
// lib/plugins/Label_1J_2J_FTX.ts
|
|
@@ -4029,7 +4084,7 @@ var Label_4N = class extends DecoderPlugin {
|
|
|
4029
4084
|
if (fields[12].length > 1) {
|
|
4030
4085
|
ResultFormatter.alternateRunway(decodeResult, fields[12].split("/")[0]);
|
|
4031
4086
|
}
|
|
4032
|
-
ResultFormatter.checksum(decodeResult, fields[32]);
|
|
4087
|
+
ResultFormatter.checksum(decodeResult, parseInt(fields[32], 16));
|
|
4033
4088
|
ResultFormatter.unknownArr(
|
|
4034
4089
|
decodeResult,
|
|
4035
4090
|
[...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter(
|
|
@@ -4538,7 +4593,7 @@ var Label_H1 = class extends DecoderPlugin {
|
|
|
4538
4593
|
} else if (parts.length === 1) {
|
|
4539
4594
|
decoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
4540
4595
|
} else if (parts.length == 2) {
|
|
4541
|
-
const offset = isNaN(parseInt(parts[1][1])) ? 3 : 4;
|
|
4596
|
+
const offset = parts[0] === "- " || isNaN(parseInt(parts[1][1])) ? 3 : 4;
|
|
4542
4597
|
decoded = H1Helper.decodeH1Message(
|
|
4543
4598
|
decodeResult,
|
|
4544
4599
|
msg.slice(parts[0].length + offset)
|
|
@@ -4759,6 +4814,66 @@ var Label_H1_OHMA = class extends DecoderPlugin {
|
|
|
4759
4814
|
}
|
|
4760
4815
|
};
|
|
4761
4816
|
|
|
4817
|
+
// lib/plugins/Label_H1_Paren.ts
|
|
4818
|
+
var Label_H1_Paren = class extends DecoderPlugin {
|
|
4819
|
+
name = "label-h1-paren";
|
|
4820
|
+
qualifiers() {
|
|
4821
|
+
return {
|
|
4822
|
+
labels: ["H1"],
|
|
4823
|
+
preambles: ["("]
|
|
4824
|
+
};
|
|
4825
|
+
}
|
|
4826
|
+
decode(message) {
|
|
4827
|
+
let decodeResult = this.defaultResult();
|
|
4828
|
+
decodeResult.decoder.name = this.name;
|
|
4829
|
+
decodeResult.message = message;
|
|
4830
|
+
if (!message.text || !message.text.startsWith("(")) {
|
|
4831
|
+
decodeResult.decoded = false;
|
|
4832
|
+
return decodeResult;
|
|
4833
|
+
}
|
|
4834
|
+
const regex = /^\(POS-(?<flight>\w+)\s+(?<lat>-?\d{4,5}[NS])(?<lon>\d{5}[EW])\/(?<timestamp>\d{6})\s+F(?<alt>\d{3})\r?\nRMK\/FUEL\s+(?<fuel>\d{2,3}\.\d)\s+M(?<mach>\d\.\d{2})\)/;
|
|
4835
|
+
const match = message.text.match(regex);
|
|
4836
|
+
if (match && match.groups) {
|
|
4837
|
+
decodeResult.decoded = true;
|
|
4838
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
4839
|
+
decodeResult.formatted.description = "Position Report";
|
|
4840
|
+
ResultFormatter.flightNumber(decodeResult, match.groups.flight);
|
|
4841
|
+
ResultFormatter.position(decodeResult, {
|
|
4842
|
+
latitude: parseLat(match.groups.lat),
|
|
4843
|
+
longitude: parseLon(match.groups.lon)
|
|
4844
|
+
});
|
|
4845
|
+
ResultFormatter.time_of_day(
|
|
4846
|
+
decodeResult,
|
|
4847
|
+
DateTimeUtils.convertHHMMSSToTod(match.groups.timestamp)
|
|
4848
|
+
);
|
|
4849
|
+
ResultFormatter.altitude(
|
|
4850
|
+
decodeResult,
|
|
4851
|
+
parseInt(match.groups.alt, 10) * 100
|
|
4852
|
+
);
|
|
4853
|
+
ResultFormatter.currentFuel(decodeResult, parseFloat(match.groups.fuel));
|
|
4854
|
+
ResultFormatter.mach(decodeResult, parseFloat(match.groups.mach));
|
|
4855
|
+
ResultFormatter.unknown(decodeResult, "RMK");
|
|
4856
|
+
}
|
|
4857
|
+
return decodeResult;
|
|
4858
|
+
}
|
|
4859
|
+
};
|
|
4860
|
+
function parseLat(latStr) {
|
|
4861
|
+
const match = latStr.match(/(-?)(\d{2})(\d{2})([NS])/);
|
|
4862
|
+
if (!match) return NaN;
|
|
4863
|
+
let deg = parseInt(match[2]);
|
|
4864
|
+
let min = parseInt(match[3]);
|
|
4865
|
+
let sign = match[4] === "S" ? -1 : 1;
|
|
4866
|
+
return sign * (deg + min / 60);
|
|
4867
|
+
}
|
|
4868
|
+
function parseLon(lonStr) {
|
|
4869
|
+
const match = lonStr.match(/(\d{3})(\d{2})([EW])/);
|
|
4870
|
+
if (!match) return NaN;
|
|
4871
|
+
let deg = parseInt(match[1]);
|
|
4872
|
+
let min = parseInt(match[2]);
|
|
4873
|
+
let sign = match[3] === "W" ? -1 : 1;
|
|
4874
|
+
return sign * (deg + min / 60);
|
|
4875
|
+
}
|
|
4876
|
+
|
|
4762
4877
|
// lib/plugins/Label_H1_StarPOS.ts
|
|
4763
4878
|
var Label_H1_StarPOS = class extends DecoderPlugin {
|
|
4764
4879
|
name = "label-h1-star-pos";
|
|
@@ -6154,6 +6269,7 @@ var MessageDecoder = class {
|
|
|
6154
6269
|
this.registerPlugin(new Label_H2_02E(this));
|
|
6155
6270
|
this.registerPlugin(new Label_H1_FLR(this));
|
|
6156
6271
|
this.registerPlugin(new Label_H1_OHMA(this));
|
|
6272
|
+
this.registerPlugin(new Label_H1_Paren(this));
|
|
6157
6273
|
this.registerPlugin(new Label_H1_WRN(this));
|
|
6158
6274
|
this.registerPlugin(new Label_H1(this));
|
|
6159
6275
|
this.registerPlugin(new Label_H1_StarPOS(this));
|