@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.mjs
CHANGED
|
@@ -590,8 +590,11 @@ var ResultFormatter = class {
|
|
|
590
590
|
value: decodeResult.raw.fuel_remaining.toString()
|
|
591
591
|
});
|
|
592
592
|
}
|
|
593
|
+
static checksumAlgorithm(decodeResult, value) {
|
|
594
|
+
decodeResult.raw.checksum_algorithm = value;
|
|
595
|
+
}
|
|
593
596
|
static checksum(decodeResult, value) {
|
|
594
|
-
decodeResult.raw.checksum =
|
|
597
|
+
decodeResult.raw.checksum = value;
|
|
595
598
|
decodeResult.formatted.items.push({
|
|
596
599
|
type: "message_checksum",
|
|
597
600
|
code: "CHECKSUM",
|
|
@@ -1975,9 +1978,14 @@ function addCompanyRoute(decodeResult, value) {
|
|
|
1975
1978
|
// lib/utils/h1_helper.ts
|
|
1976
1979
|
var H1Helper = class _H1Helper {
|
|
1977
1980
|
static decodeH1Message(decodeResult, message) {
|
|
1978
|
-
const checksum = message.slice(-4);
|
|
1981
|
+
const checksum = parseInt(message.slice(-4), 16);
|
|
1979
1982
|
const data = message.slice(0, message.length - 4);
|
|
1980
|
-
|
|
1983
|
+
let checksumAlgorithmUsed = "";
|
|
1984
|
+
if (crc16IbmSdlcRev(data) === checksum) {
|
|
1985
|
+
checksumAlgorithmUsed = "IBM-SDLC reversed";
|
|
1986
|
+
} else if (crc16Genibus(data) === checksum) {
|
|
1987
|
+
checksumAlgorithmUsed = "GENIBUS";
|
|
1988
|
+
} else {
|
|
1981
1989
|
decodeResult.decoded = false;
|
|
1982
1990
|
decodeResult.decoder.decodeLevel = "none";
|
|
1983
1991
|
return false;
|
|
@@ -2054,6 +2062,9 @@ var H1Helper = class _H1Helper {
|
|
|
2054
2062
|
case "RN":
|
|
2055
2063
|
ResultFormatter.routeNumber(decodeResult, data2);
|
|
2056
2064
|
break;
|
|
2065
|
+
case "RW":
|
|
2066
|
+
processRunway(decodeResult, data2.split(":"));
|
|
2067
|
+
break;
|
|
2057
2068
|
case "SN":
|
|
2058
2069
|
decodeResult.raw.serial_number = data2;
|
|
2059
2070
|
break;
|
|
@@ -2079,6 +2090,7 @@ var H1Helper = class _H1Helper {
|
|
|
2079
2090
|
ResultFormatter.unknown(decodeResult, fields[i], "/");
|
|
2080
2091
|
}
|
|
2081
2092
|
}
|
|
2093
|
+
ResultFormatter.checksumAlgorithm(decodeResult, checksumAlgorithmUsed);
|
|
2082
2094
|
ResultFormatter.checksum(decodeResult, checksum);
|
|
2083
2095
|
return true;
|
|
2084
2096
|
}
|
|
@@ -2193,29 +2205,42 @@ function processIdentification(decodeResult, data) {
|
|
|
2193
2205
|
}
|
|
2194
2206
|
}
|
|
2195
2207
|
function processDT(decodeResult, data) {
|
|
2196
|
-
if (
|
|
2197
|
-
ResultFormatter.
|
|
2198
|
-
|
|
2199
|
-
|
|
2208
|
+
if (data.length === 9) {
|
|
2209
|
+
ResultFormatter.unknown(decodeResult, data[0]);
|
|
2210
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
2211
|
+
ResultFormatter.arrivalAirport(decodeResult, data[1]);
|
|
2212
|
+
}
|
|
2213
|
+
ResultFormatter.arrivalRunway(decodeResult, data[2]);
|
|
2214
|
+
ResultFormatter.currentFuel(decodeResult, parseInt(data[3], 10));
|
|
2215
|
+
ResultFormatter.eta(
|
|
2216
|
+
decodeResult,
|
|
2217
|
+
DateTimeUtils.convertHHMMSSToTod(data[4])
|
|
2218
|
+
);
|
|
2219
|
+
ResultFormatter.unknown(decodeResult, data[5]);
|
|
2220
|
+
ResultFormatter.position(
|
|
2221
|
+
decodeResult,
|
|
2222
|
+
CoordinateUtils.decodeStringCoordinates(data[6])
|
|
2223
|
+
);
|
|
2224
|
+
ResultFormatter.unknown(decodeResult, data[7]);
|
|
2225
|
+
ResultFormatter.unknown(decodeResult, data[8]);
|
|
2226
|
+
return;
|
|
2200
2227
|
}
|
|
2201
|
-
if (data.length
|
|
2228
|
+
if (data.length === 4 || data.length === 5) {
|
|
2229
|
+
if (!decodeResult.raw.arrival_icao) {
|
|
2230
|
+
ResultFormatter.arrivalAirport(decodeResult, data[0]);
|
|
2231
|
+
}
|
|
2202
2232
|
ResultFormatter.arrivalRunway(decodeResult, data[1]);
|
|
2203
|
-
|
|
2204
|
-
if (data.length > 2) {
|
|
2205
|
-
ResultFormatter.currentFuel(decodeResult, Number(data[2]));
|
|
2206
|
-
}
|
|
2207
|
-
if (data.length > 3) {
|
|
2233
|
+
ResultFormatter.currentFuel(decodeResult, parseInt(data[2], 10));
|
|
2208
2234
|
ResultFormatter.eta(
|
|
2209
2235
|
decodeResult,
|
|
2210
2236
|
DateTimeUtils.convertHHMMSSToTod(data[3])
|
|
2211
2237
|
);
|
|
2238
|
+
if (data.length > 4) {
|
|
2239
|
+
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
2240
|
+
}
|
|
2241
|
+
return;
|
|
2212
2242
|
}
|
|
2213
|
-
|
|
2214
|
-
ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
|
|
2215
|
-
}
|
|
2216
|
-
if (data.length > 5) {
|
|
2217
|
-
ResultFormatter.unknownArr(decodeResult, data);
|
|
2218
|
-
}
|
|
2243
|
+
ResultFormatter.unknownArr(decodeResult, data, ",");
|
|
2219
2244
|
}
|
|
2220
2245
|
function processLandingReport(decodeResult, data) {
|
|
2221
2246
|
if (data.length === 19) {
|
|
@@ -2279,7 +2304,9 @@ function processMessageType(decodeResult, type) {
|
|
|
2279
2304
|
} else if (type === "FTX") {
|
|
2280
2305
|
decodeResult.formatted.description = "Free Text";
|
|
2281
2306
|
} else if (type === "INI") {
|
|
2282
|
-
decodeResult.formatted.description = "
|
|
2307
|
+
decodeResult.formatted.description = "Initial Report";
|
|
2308
|
+
} else if (type === "LDI") {
|
|
2309
|
+
decodeResult.formatted.description = "Load Distribution Information";
|
|
2283
2310
|
} else if (type === "PER") {
|
|
2284
2311
|
decodeResult.formatted.description = "Performance Report";
|
|
2285
2312
|
} else if (type === "POS") {
|
|
@@ -2344,11 +2371,14 @@ function processWindData(decodeResult, message) {
|
|
|
2344
2371
|
const flightLevel = Number(message.slice(0, 3));
|
|
2345
2372
|
const fields = message.slice(4).split(".");
|
|
2346
2373
|
fields.forEach((field) => {
|
|
2374
|
+
if (field.length < 4) {
|
|
2375
|
+
return;
|
|
2376
|
+
}
|
|
2347
2377
|
const data = field.split(",");
|
|
2348
2378
|
const waypoint = { name: data[0] };
|
|
2349
2379
|
const windData = data[1];
|
|
2350
|
-
const windDirection =
|
|
2351
|
-
const windSpeed =
|
|
2380
|
+
const windDirection = parseInt(windData.slice(0, 3), 10);
|
|
2381
|
+
const windSpeed = parseInt(windData.slice(3), 10);
|
|
2352
2382
|
if (data.length === 3) {
|
|
2353
2383
|
const tempData = data[2];
|
|
2354
2384
|
const tempFlightLevel = Number(tempData.slice(0, 3));
|
|
@@ -2375,7 +2405,16 @@ function processWindData(decodeResult, message) {
|
|
|
2375
2405
|
});
|
|
2376
2406
|
ResultFormatter.windData(decodeResult, wind);
|
|
2377
2407
|
}
|
|
2378
|
-
function
|
|
2408
|
+
function processRunway(decodeResult, data) {
|
|
2409
|
+
const parts = data[0].split(".");
|
|
2410
|
+
const more = parts[0].split(",");
|
|
2411
|
+
ResultFormatter.departureRunway(decodeResult, more[0]);
|
|
2412
|
+
ResultFormatter.unknownArr(decodeResult, more.slice(1), ",");
|
|
2413
|
+
ResultFormatter.unknownArr(decodeResult, parts.slice(1), ".");
|
|
2414
|
+
ResultFormatter.departureAirport(decodeResult, data[1].split(",")[0]);
|
|
2415
|
+
ResultFormatter.unknownArr(decodeResult, data[1].split(",").slice(1), ",");
|
|
2416
|
+
}
|
|
2417
|
+
function crc16IbmSdlcRev(data) {
|
|
2379
2418
|
let crc = 65535;
|
|
2380
2419
|
const bytes = Buffer.from(data, "ascii");
|
|
2381
2420
|
for (const byte of bytes) {
|
|
@@ -2393,7 +2432,23 @@ function calculateChecksum(data) {
|
|
|
2393
2432
|
const nibble2 = crc >> 8 & 15;
|
|
2394
2433
|
const nibble3 = crc >> 4 & 15;
|
|
2395
2434
|
const nibble4 = crc & 15;
|
|
2396
|
-
return
|
|
2435
|
+
return nibble4 << 12 | nibble3 << 8 | nibble2 << 4 | nibble1;
|
|
2436
|
+
}
|
|
2437
|
+
function crc16Genibus(data) {
|
|
2438
|
+
let crc = 65535;
|
|
2439
|
+
const polynomial = 4129;
|
|
2440
|
+
const bytes = Buffer.from(data, "ascii");
|
|
2441
|
+
for (const byte of bytes) {
|
|
2442
|
+
crc ^= byte << 8;
|
|
2443
|
+
for (let i = 0; i < 8; i++) {
|
|
2444
|
+
if ((crc & 32768) !== 0) {
|
|
2445
|
+
crc = (crc << 1 ^ polynomial) & 65535;
|
|
2446
|
+
} else {
|
|
2447
|
+
crc = crc << 1 & 65535;
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
return (crc ^ 65535) & 65535;
|
|
2397
2452
|
}
|
|
2398
2453
|
|
|
2399
2454
|
// lib/plugins/Label_1J_2J_FTX.ts
|
|
@@ -3992,7 +4047,7 @@ var Label_4N = class extends DecoderPlugin {
|
|
|
3992
4047
|
if (fields[12].length > 1) {
|
|
3993
4048
|
ResultFormatter.alternateRunway(decodeResult, fields[12].split("/")[0]);
|
|
3994
4049
|
}
|
|
3995
|
-
ResultFormatter.checksum(decodeResult, fields[32]);
|
|
4050
|
+
ResultFormatter.checksum(decodeResult, parseInt(fields[32], 16));
|
|
3996
4051
|
ResultFormatter.unknownArr(
|
|
3997
4052
|
decodeResult,
|
|
3998
4053
|
[...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter(
|
|
@@ -4501,7 +4556,7 @@ var Label_H1 = class extends DecoderPlugin {
|
|
|
4501
4556
|
} else if (parts.length === 1) {
|
|
4502
4557
|
decoded = H1Helper.decodeH1Message(decodeResult, msg);
|
|
4503
4558
|
} else if (parts.length == 2) {
|
|
4504
|
-
const offset = isNaN(parseInt(parts[1][1])) ? 3 : 4;
|
|
4559
|
+
const offset = parts[0] === "- " || isNaN(parseInt(parts[1][1])) ? 3 : 4;
|
|
4505
4560
|
decoded = H1Helper.decodeH1Message(
|
|
4506
4561
|
decodeResult,
|
|
4507
4562
|
msg.slice(parts[0].length + offset)
|
|
@@ -4722,6 +4777,66 @@ var Label_H1_OHMA = class extends DecoderPlugin {
|
|
|
4722
4777
|
}
|
|
4723
4778
|
};
|
|
4724
4779
|
|
|
4780
|
+
// lib/plugins/Label_H1_Paren.ts
|
|
4781
|
+
var Label_H1_Paren = class extends DecoderPlugin {
|
|
4782
|
+
name = "label-h1-paren";
|
|
4783
|
+
qualifiers() {
|
|
4784
|
+
return {
|
|
4785
|
+
labels: ["H1"],
|
|
4786
|
+
preambles: ["("]
|
|
4787
|
+
};
|
|
4788
|
+
}
|
|
4789
|
+
decode(message) {
|
|
4790
|
+
let decodeResult = this.defaultResult();
|
|
4791
|
+
decodeResult.decoder.name = this.name;
|
|
4792
|
+
decodeResult.message = message;
|
|
4793
|
+
if (!message.text || !message.text.startsWith("(")) {
|
|
4794
|
+
decodeResult.decoded = false;
|
|
4795
|
+
return decodeResult;
|
|
4796
|
+
}
|
|
4797
|
+
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})\)/;
|
|
4798
|
+
const match = message.text.match(regex);
|
|
4799
|
+
if (match && match.groups) {
|
|
4800
|
+
decodeResult.decoded = true;
|
|
4801
|
+
decodeResult.decoder.decodeLevel = "partial";
|
|
4802
|
+
decodeResult.formatted.description = "Position Report";
|
|
4803
|
+
ResultFormatter.flightNumber(decodeResult, match.groups.flight);
|
|
4804
|
+
ResultFormatter.position(decodeResult, {
|
|
4805
|
+
latitude: parseLat(match.groups.lat),
|
|
4806
|
+
longitude: parseLon(match.groups.lon)
|
|
4807
|
+
});
|
|
4808
|
+
ResultFormatter.time_of_day(
|
|
4809
|
+
decodeResult,
|
|
4810
|
+
DateTimeUtils.convertHHMMSSToTod(match.groups.timestamp)
|
|
4811
|
+
);
|
|
4812
|
+
ResultFormatter.altitude(
|
|
4813
|
+
decodeResult,
|
|
4814
|
+
parseInt(match.groups.alt, 10) * 100
|
|
4815
|
+
);
|
|
4816
|
+
ResultFormatter.currentFuel(decodeResult, parseFloat(match.groups.fuel));
|
|
4817
|
+
ResultFormatter.mach(decodeResult, parseFloat(match.groups.mach));
|
|
4818
|
+
ResultFormatter.unknown(decodeResult, "RMK");
|
|
4819
|
+
}
|
|
4820
|
+
return decodeResult;
|
|
4821
|
+
}
|
|
4822
|
+
};
|
|
4823
|
+
function parseLat(latStr) {
|
|
4824
|
+
const match = latStr.match(/(-?)(\d{2})(\d{2})([NS])/);
|
|
4825
|
+
if (!match) return NaN;
|
|
4826
|
+
let deg = parseInt(match[2]);
|
|
4827
|
+
let min = parseInt(match[3]);
|
|
4828
|
+
let sign = match[4] === "S" ? -1 : 1;
|
|
4829
|
+
return sign * (deg + min / 60);
|
|
4830
|
+
}
|
|
4831
|
+
function parseLon(lonStr) {
|
|
4832
|
+
const match = lonStr.match(/(\d{3})(\d{2})([EW])/);
|
|
4833
|
+
if (!match) return NaN;
|
|
4834
|
+
let deg = parseInt(match[1]);
|
|
4835
|
+
let min = parseInt(match[2]);
|
|
4836
|
+
let sign = match[3] === "W" ? -1 : 1;
|
|
4837
|
+
return sign * (deg + min / 60);
|
|
4838
|
+
}
|
|
4839
|
+
|
|
4725
4840
|
// lib/plugins/Label_H1_StarPOS.ts
|
|
4726
4841
|
var Label_H1_StarPOS = class extends DecoderPlugin {
|
|
4727
4842
|
name = "label-h1-star-pos";
|
|
@@ -6117,6 +6232,7 @@ var MessageDecoder = class {
|
|
|
6117
6232
|
this.registerPlugin(new Label_H2_02E(this));
|
|
6118
6233
|
this.registerPlugin(new Label_H1_FLR(this));
|
|
6119
6234
|
this.registerPlugin(new Label_H1_OHMA(this));
|
|
6235
|
+
this.registerPlugin(new Label_H1_Paren(this));
|
|
6120
6236
|
this.registerPlugin(new Label_H1_WRN(this));
|
|
6121
6237
|
this.registerPlugin(new Label_H1(this));
|
|
6122
6238
|
this.registerPlugin(new Label_H1_StarPOS(this));
|