@airframes/acars-decoder 1.8.13 → 1.9.0
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/License.md +21 -0
- package/README.md +8 -11
- package/dist/index.d.mts +154 -2
- package/dist/index.d.ts +154 -2
- package/dist/index.js +634 -681
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +634 -681
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -85,56 +85,6 @@ var IcaoDecoder = class _IcaoDecoder {
|
|
|
85
85
|
}
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
// lib/DecoderPlugin.ts
|
|
89
|
-
var DecoderPlugin = class {
|
|
90
|
-
decoder;
|
|
91
|
-
name = "unknown";
|
|
92
|
-
defaultResult() {
|
|
93
|
-
return {
|
|
94
|
-
decoded: false,
|
|
95
|
-
decoder: {
|
|
96
|
-
name: "unknown",
|
|
97
|
-
type: "pattern-match",
|
|
98
|
-
decodeLevel: "none"
|
|
99
|
-
},
|
|
100
|
-
formatted: {
|
|
101
|
-
description: "Unknown",
|
|
102
|
-
items: []
|
|
103
|
-
},
|
|
104
|
-
raw: {},
|
|
105
|
-
remaining: {}
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
options;
|
|
109
|
-
constructor(decoder, options = {}) {
|
|
110
|
-
this.decoder = decoder;
|
|
111
|
-
this.options = options;
|
|
112
|
-
}
|
|
113
|
-
id() {
|
|
114
|
-
console.log(
|
|
115
|
-
"DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!"
|
|
116
|
-
);
|
|
117
|
-
return "abstract_decoder_plugin";
|
|
118
|
-
}
|
|
119
|
-
meetsStateRequirements() {
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
// onRegister(store: Store<any>) {
|
|
123
|
-
// this.store = store;
|
|
124
|
-
// }
|
|
125
|
-
qualifiers() {
|
|
126
|
-
const labels = [];
|
|
127
|
-
return {
|
|
128
|
-
labels
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
decode(message) {
|
|
132
|
-
const decodeResult = this.defaultResult();
|
|
133
|
-
decodeResult.remaining.text = message.text;
|
|
134
|
-
return decodeResult;
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
|
|
138
88
|
// lib/utils/coordinate_utils.ts
|
|
139
89
|
var CoordinateUtils = class _CoordinateUtils {
|
|
140
90
|
/**
|
|
@@ -144,11 +94,11 @@ var CoordinateUtils = class _CoordinateUtils {
|
|
|
144
94
|
* @returns An object with latitude and longitude properties
|
|
145
95
|
*/
|
|
146
96
|
static decodeStringCoordinates(stringCoords) {
|
|
147
|
-
const firstChar = stringCoords.
|
|
148
|
-
let middleChar = stringCoords.
|
|
97
|
+
const firstChar = stringCoords.charAt(0);
|
|
98
|
+
let middleChar = stringCoords.charAt(6);
|
|
149
99
|
let longitudeChars = stringCoords.substring(7, 13);
|
|
150
|
-
if (middleChar
|
|
151
|
-
middleChar = stringCoords.
|
|
100
|
+
if (middleChar === " ") {
|
|
101
|
+
middleChar = stringCoords.charAt(7);
|
|
152
102
|
longitudeChars = stringCoords.substring(8, 14);
|
|
153
103
|
}
|
|
154
104
|
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
@@ -166,24 +116,26 @@ var CoordinateUtils = class _CoordinateUtils {
|
|
|
166
116
|
* @returns An object with latitude and longitude properties
|
|
167
117
|
*/
|
|
168
118
|
static decodeStringCoordinatesDecimalMinutes(stringCoords) {
|
|
169
|
-
const firstChar = stringCoords.
|
|
170
|
-
let middleChar = stringCoords.
|
|
119
|
+
const firstChar = stringCoords.charAt(0);
|
|
120
|
+
let middleChar = stringCoords.charAt(6);
|
|
171
121
|
let longitudeChars = stringCoords.substring(7, 13);
|
|
172
|
-
if (middleChar
|
|
173
|
-
middleChar = stringCoords.
|
|
122
|
+
if (middleChar === " ") {
|
|
123
|
+
middleChar = stringCoords.charAt(7);
|
|
174
124
|
longitudeChars = stringCoords.substring(8, 14);
|
|
175
125
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
|
|
179
|
-
const lonMin = Number(longitudeChars) % 1e3 / 10;
|
|
180
|
-
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
181
|
-
return {
|
|
182
|
-
latitude: (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar),
|
|
183
|
-
longitude: (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar)
|
|
184
|
-
};
|
|
126
|
+
if (firstChar !== "N" && firstChar !== "S" || middleChar !== "W" && middleChar !== "E") {
|
|
127
|
+
return void 0;
|
|
185
128
|
}
|
|
186
|
-
|
|
129
|
+
const latRaw = Number(stringCoords.substring(1, 6));
|
|
130
|
+
const lonRaw = Number(longitudeChars);
|
|
131
|
+
const latDeg = Math.trunc(latRaw / 1e3);
|
|
132
|
+
const latMin = latRaw % 1e3 / 10;
|
|
133
|
+
const lonDeg = Math.trunc(lonRaw / 1e3);
|
|
134
|
+
const lonMin = lonRaw % 1e3 / 10;
|
|
135
|
+
return {
|
|
136
|
+
latitude: (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar),
|
|
137
|
+
longitude: (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar)
|
|
138
|
+
};
|
|
187
139
|
}
|
|
188
140
|
static coordinateString(coords) {
|
|
189
141
|
const latDir = coords.latitude > 0 ? "N" : "S";
|
|
@@ -214,25 +166,13 @@ var DateTimeUtils = class {
|
|
|
214
166
|
// Expects a six digit date string and a four digit UTC time string
|
|
215
167
|
// (DDMMYY) (HHMM)
|
|
216
168
|
static UTCDateTimeToString(dateString, timeString) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
utcDate.setUTCHours(
|
|
225
|
-
+timeString.substr(0, 2),
|
|
226
|
-
+timeString.substr(2, 2),
|
|
227
|
-
+timeString.substr(4, 2)
|
|
228
|
-
);
|
|
229
|
-
} else {
|
|
230
|
-
utcDate.setUTCHours(
|
|
231
|
-
+timeString.substr(0, 2),
|
|
232
|
-
+timeString.substr(2, 2),
|
|
233
|
-
0
|
|
234
|
-
);
|
|
235
|
-
}
|
|
169
|
+
const day = +dateString.substr(0, 2);
|
|
170
|
+
const month = +dateString.substr(2, 2) - 1;
|
|
171
|
+
const year = dateString.length === 6 ? 2e3 + +dateString.substr(4, 2) : (/* @__PURE__ */ new Date()).getUTCFullYear();
|
|
172
|
+
const hours = +timeString.substr(0, 2);
|
|
173
|
+
const minutes = +timeString.substr(2, 2);
|
|
174
|
+
const seconds = timeString.length === 6 ? +timeString.substr(4, 2) : 0;
|
|
175
|
+
const utcDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds));
|
|
236
176
|
return utcDate.toUTCString();
|
|
237
177
|
}
|
|
238
178
|
/**
|
|
@@ -577,7 +517,7 @@ var ResultFormatter = class {
|
|
|
577
517
|
decodeResult.raw.fuel_remaining = value;
|
|
578
518
|
decodeResult.formatted.items.push({
|
|
579
519
|
type: "fuel_remaining",
|
|
580
|
-
code: "
|
|
520
|
+
code: "FUEL_REM",
|
|
581
521
|
label: "Fuel Remaining",
|
|
582
522
|
value: decodeResult.raw.fuel_remaining.toString()
|
|
583
523
|
});
|
|
@@ -971,7 +911,7 @@ var ResultFormatter = class {
|
|
|
971
911
|
type: "sequence",
|
|
972
912
|
code: "SEQ",
|
|
973
913
|
label: "Sequence Number",
|
|
974
|
-
value: decodeResult.raw.sequence_number
|
|
914
|
+
value: decodeResult.raw.sequence_number.toString()
|
|
975
915
|
});
|
|
976
916
|
}
|
|
977
917
|
static sequenceResponse(decodeResult, value) {
|
|
@@ -980,7 +920,7 @@ var ResultFormatter = class {
|
|
|
980
920
|
type: "sequence",
|
|
981
921
|
code: "SEQ_RESP",
|
|
982
922
|
label: "Sequence Response",
|
|
983
|
-
value: decodeResult.raw.sequence_response
|
|
923
|
+
value: decodeResult.raw.sequence_response.toString()
|
|
984
924
|
});
|
|
985
925
|
}
|
|
986
926
|
static unknown(decodeResult, value, sep = ",") {
|
|
@@ -992,7 +932,101 @@ var ResultFormatter = class {
|
|
|
992
932
|
}
|
|
993
933
|
};
|
|
994
934
|
|
|
935
|
+
// lib/DecoderPlugin.ts
|
|
936
|
+
var DecoderPlugin = class {
|
|
937
|
+
decoder;
|
|
938
|
+
name = "unknown";
|
|
939
|
+
defaultResult() {
|
|
940
|
+
return {
|
|
941
|
+
decoded: false,
|
|
942
|
+
decoder: {
|
|
943
|
+
name: "unknown",
|
|
944
|
+
type: "pattern-match",
|
|
945
|
+
decodeLevel: "none"
|
|
946
|
+
},
|
|
947
|
+
formatted: {
|
|
948
|
+
description: "Unknown",
|
|
949
|
+
items: []
|
|
950
|
+
},
|
|
951
|
+
raw: {},
|
|
952
|
+
remaining: {}
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Creates a DecodeResult pre-populated with the plugin name, description, and message.
|
|
957
|
+
* Replaces the common boilerplate at the start of every decode() method.
|
|
958
|
+
*/
|
|
959
|
+
initResult(message, description) {
|
|
960
|
+
const result = this.defaultResult();
|
|
961
|
+
result.decoder.name = this.name;
|
|
962
|
+
result.formatted.description = description;
|
|
963
|
+
result.message = message;
|
|
964
|
+
return result;
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Sets the decoded flag and decodeLevel on a result.
|
|
968
|
+
* If decoded is true and no explicit level is given, infers 'full' or 'partial'
|
|
969
|
+
* based on whether remaining.text is set.
|
|
970
|
+
*/
|
|
971
|
+
setDecodeLevel(result, decoded, level) {
|
|
972
|
+
result.decoded = decoded;
|
|
973
|
+
if (decoded) {
|
|
974
|
+
result.decoder.decodeLevel = level ?? (result.remaining.text ? "partial" : "full");
|
|
975
|
+
} else {
|
|
976
|
+
result.decoder.decodeLevel = "none";
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
/**
|
|
980
|
+
* Logs a debug message prefixed with the plugin name, only if options.debug is true.
|
|
981
|
+
*/
|
|
982
|
+
debug(options, ...args) {
|
|
983
|
+
if (options.debug) {
|
|
984
|
+
console.log(`[${this.name}]`, ...args);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Marks a result as a failed decode with 'none' level, sets the remaining text
|
|
989
|
+
* as unknown, and logs a debug message. Returns the result for convenient early return.
|
|
990
|
+
*/
|
|
991
|
+
failUnknown(result, text, options = {}) {
|
|
992
|
+
this.debug(options, `Unknown message: ${text}`);
|
|
993
|
+
ResultFormatter.unknown(result, text);
|
|
994
|
+
result.decoded = false;
|
|
995
|
+
result.decoder.decodeLevel = "none";
|
|
996
|
+
return result;
|
|
997
|
+
}
|
|
998
|
+
options;
|
|
999
|
+
constructor(decoder, options = {}) {
|
|
1000
|
+
this.decoder = decoder;
|
|
1001
|
+
this.options = options;
|
|
1002
|
+
}
|
|
1003
|
+
id() {
|
|
1004
|
+
console.log(
|
|
1005
|
+
"DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!"
|
|
1006
|
+
);
|
|
1007
|
+
return "abstract_decoder_plugin";
|
|
1008
|
+
}
|
|
1009
|
+
meetsStateRequirements() {
|
|
1010
|
+
return true;
|
|
1011
|
+
}
|
|
1012
|
+
// onRegister(store: Store<any>) {
|
|
1013
|
+
// this.store = store;
|
|
1014
|
+
// }
|
|
1015
|
+
qualifiers() {
|
|
1016
|
+
const labels = [];
|
|
1017
|
+
return {
|
|
1018
|
+
labels
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
decode(message, options = {}) {
|
|
1022
|
+
const decodeResult = this.defaultResult();
|
|
1023
|
+
decodeResult.remaining.text = message.text;
|
|
1024
|
+
return decodeResult;
|
|
1025
|
+
}
|
|
1026
|
+
};
|
|
1027
|
+
|
|
995
1028
|
// lib/plugins/CBand.ts
|
|
1029
|
+
var CBAND_HEADER = /^(?<msgno>[A-Z]\d{2}[A-Z])(?<airline>[A-Z0-9]{2})(?<number>[0-9]{4})/;
|
|
996
1030
|
var CBand = class extends DecoderPlugin {
|
|
997
1031
|
name = "c-band";
|
|
998
1032
|
qualifiers() {
|
|
@@ -1001,35 +1035,43 @@ var CBand = class extends DecoderPlugin {
|
|
|
1001
1035
|
};
|
|
1002
1036
|
}
|
|
1003
1037
|
decode(message, options = {}) {
|
|
1004
|
-
|
|
1038
|
+
const text = message.text;
|
|
1039
|
+
if (text.length < 10) {
|
|
1040
|
+
const result = this.defaultResult();
|
|
1041
|
+
result.decoder.name = this.name;
|
|
1042
|
+
result.message = message;
|
|
1043
|
+
return result;
|
|
1044
|
+
}
|
|
1045
|
+
const cband = CBAND_HEADER.exec(text);
|
|
1046
|
+
if (!cband?.groups) {
|
|
1047
|
+
const result = this.defaultResult();
|
|
1048
|
+
result.decoder.name = this.name;
|
|
1049
|
+
result.message = message;
|
|
1050
|
+
return result;
|
|
1051
|
+
}
|
|
1052
|
+
const decoded = this.decoder.decode(
|
|
1053
|
+
{
|
|
1054
|
+
label: message.label,
|
|
1055
|
+
sublabel: message.sublabel,
|
|
1056
|
+
text: text.substring(10)
|
|
1057
|
+
},
|
|
1058
|
+
options
|
|
1059
|
+
);
|
|
1060
|
+
const decodeResult = this.defaultResult();
|
|
1005
1061
|
decodeResult.decoder.name = this.name;
|
|
1006
1062
|
decodeResult.message = message;
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
const messageText = message.text.substring(10);
|
|
1012
|
-
const decoded = this.decoder.decode(
|
|
1013
|
-
{
|
|
1014
|
-
label: message.label,
|
|
1015
|
-
sublabel: message.sublabel,
|
|
1016
|
-
text: messageText
|
|
1017
|
-
},
|
|
1018
|
-
options
|
|
1063
|
+
if (decoded.decoded) {
|
|
1064
|
+
ResultFormatter.flightNumber(
|
|
1065
|
+
decodeResult,
|
|
1066
|
+
cband.groups.airline + Number(cband.groups.number)
|
|
1019
1067
|
);
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
decodeResult.decoder.name = this.name + "-" + decoded.decoder.name;
|
|
1028
|
-
decodeResult.raw = { ...decodeResult.raw, ...decoded.raw };
|
|
1029
|
-
decodeResult.formatted.description = decoded.formatted.description;
|
|
1030
|
-
decodeResult.formatted.items.push(...decoded.formatted.items);
|
|
1031
|
-
decodeResult.remaining = decoded.remaining;
|
|
1032
|
-
}
|
|
1068
|
+
decodeResult.decoded = true;
|
|
1069
|
+
decodeResult.decoder.decodeLevel = decoded.decoder.decodeLevel;
|
|
1070
|
+
decodeResult.decoder.name = this.name + "-" + decoded.decoder.name;
|
|
1071
|
+
decodeResult.raw = { ...decodeResult.raw, ...decoded.raw };
|
|
1072
|
+
decodeResult.formatted.description = decoded.formatted.description;
|
|
1073
|
+
decodeResult.formatted.items.push(...decoded.formatted.items);
|
|
1074
|
+
decodeResult.remaining = decoded.remaining;
|
|
1033
1075
|
}
|
|
1034
1076
|
return decodeResult;
|
|
1035
1077
|
}
|
|
@@ -1114,7 +1156,9 @@ var FlightPlanUtils = class _FlightPlanUtils {
|
|
|
1114
1156
|
label: "Route Status",
|
|
1115
1157
|
value: "Route Planned"
|
|
1116
1158
|
});
|
|
1117
|
-
|
|
1159
|
+
if (header.length > 2) {
|
|
1160
|
+
addRoute(decodeResult, header.substring(2));
|
|
1161
|
+
}
|
|
1118
1162
|
} else if (header.startsWith("RI")) {
|
|
1119
1163
|
decodeResult.raw.route_status = "RI";
|
|
1120
1164
|
decodeResult.formatted.items.push({
|
|
@@ -1212,6 +1256,11 @@ function addCompanyRoute(decodeResult, value) {
|
|
|
1212
1256
|
}
|
|
1213
1257
|
|
|
1214
1258
|
// lib/utils/arinc_702_helper.ts
|
|
1259
|
+
function asciiStringToBytes(data) {
|
|
1260
|
+
const bytes = new Uint8Array(data.length);
|
|
1261
|
+
for (let i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i) & 255;
|
|
1262
|
+
return bytes;
|
|
1263
|
+
}
|
|
1215
1264
|
var Arinc702Helper = class _Arinc702Helper {
|
|
1216
1265
|
/**
|
|
1217
1266
|
* Decodes an ARINC 702 message
|
|
@@ -1730,7 +1779,7 @@ function processSummary(decodeResult, data) {
|
|
|
1730
1779
|
}
|
|
1731
1780
|
function crc16IbmSdlcRev(data) {
|
|
1732
1781
|
let crc = 65535;
|
|
1733
|
-
const bytes =
|
|
1782
|
+
const bytes = asciiStringToBytes(data);
|
|
1734
1783
|
for (const byte of bytes) {
|
|
1735
1784
|
crc ^= byte;
|
|
1736
1785
|
for (let i = 0; i < 8; i++) {
|
|
@@ -1751,7 +1800,7 @@ function crc16IbmSdlcRev(data) {
|
|
|
1751
1800
|
function crc16Genibus(data) {
|
|
1752
1801
|
let crc = 65535;
|
|
1753
1802
|
const polynomial = 4129;
|
|
1754
|
-
const bytes =
|
|
1803
|
+
const bytes = asciiStringToBytes(data);
|
|
1755
1804
|
for (const byte of bytes) {
|
|
1756
1805
|
crc ^= byte << 8;
|
|
1757
1806
|
for (let i = 0; i < 8; i++) {
|
|
@@ -1776,6 +1825,7 @@ function processMessageReference(decodeResult, data) {
|
|
|
1776
1825
|
}
|
|
1777
1826
|
|
|
1778
1827
|
// lib/plugins/ARINC_702.ts
|
|
1828
|
+
var NEWLINE_REGEX = /[\n\r]/g;
|
|
1779
1829
|
var Arinc702 = class extends DecoderPlugin {
|
|
1780
1830
|
name = "arinc-702";
|
|
1781
1831
|
qualifiers() {
|
|
@@ -1787,7 +1837,7 @@ var Arinc702 = class extends DecoderPlugin {
|
|
|
1787
1837
|
let decodeResult = this.defaultResult();
|
|
1788
1838
|
decodeResult.decoder.name = this.name;
|
|
1789
1839
|
decodeResult.message = message;
|
|
1790
|
-
const msg = message.text.replace(
|
|
1840
|
+
const msg = message.text.replace(NEWLINE_REGEX, "");
|
|
1791
1841
|
let decoded = false;
|
|
1792
1842
|
decoded = Arinc702Helper.decodeH1Message(decodeResult, msg);
|
|
1793
1843
|
if (decoded) {
|
|
@@ -2061,19 +2111,10 @@ var Label_10_POS = class extends DecoderPlugin {
|
|
|
2061
2111
|
};
|
|
2062
2112
|
}
|
|
2063
2113
|
decode(message, options = {}) {
|
|
2064
|
-
const decodeResult = this.
|
|
2065
|
-
decodeResult.decoder.name = this.name;
|
|
2066
|
-
decodeResult.formatted.description = "Position Report";
|
|
2067
|
-
decodeResult.message = message;
|
|
2114
|
+
const decodeResult = this.initResult(message, "Position Report");
|
|
2068
2115
|
const parts = message.text.split(",");
|
|
2069
2116
|
if (parts.length !== 12) {
|
|
2070
|
-
|
|
2071
|
-
console.log(`Decoder: Unknown 10 message: ${message.text}`);
|
|
2072
|
-
}
|
|
2073
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
2074
|
-
decodeResult.decoded = false;
|
|
2075
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2076
|
-
return decodeResult;
|
|
2117
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
2077
2118
|
}
|
|
2078
2119
|
const lat = parts[1].trim();
|
|
2079
2120
|
const lon = parts[2].trim();
|
|
@@ -2088,8 +2129,7 @@ var Label_10_POS = class extends DecoderPlugin {
|
|
|
2088
2129
|
...parts.slice(3, 7),
|
|
2089
2130
|
...parts.slice(8)
|
|
2090
2131
|
]);
|
|
2091
|
-
decodeResult
|
|
2092
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2132
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
2093
2133
|
return decodeResult;
|
|
2094
2134
|
}
|
|
2095
2135
|
};
|
|
@@ -2216,19 +2256,10 @@ var Label_12_POS = class extends DecoderPlugin {
|
|
|
2216
2256
|
};
|
|
2217
2257
|
}
|
|
2218
2258
|
decode(message, options = {}) {
|
|
2219
|
-
const decodeResult = this.
|
|
2220
|
-
decodeResult.decoder.name = this.name;
|
|
2221
|
-
decodeResult.formatted.description = "Position Report";
|
|
2222
|
-
decodeResult.message = message;
|
|
2259
|
+
const decodeResult = this.initResult(message, "Position Report");
|
|
2223
2260
|
const data = message.text.substring(3).split(",");
|
|
2224
2261
|
if (!message.text.startsWith("POS") || data.length !== 12) {
|
|
2225
|
-
|
|
2226
|
-
console.log(`Decoder: Unknown 12 message: ${message.text}`);
|
|
2227
|
-
}
|
|
2228
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
2229
|
-
decodeResult.decoded = false;
|
|
2230
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2231
|
-
return decodeResult;
|
|
2262
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
2232
2263
|
}
|
|
2233
2264
|
const lat = data[0].substring(0, 8);
|
|
2234
2265
|
const lon = data[0].substring(8);
|
|
@@ -2262,8 +2293,7 @@ var Label_12_POS = class extends DecoderPlugin {
|
|
|
2262
2293
|
ResultFormatter.departureAirport(decodeResult, data[9]);
|
|
2263
2294
|
ResultFormatter.arrivalAirport(decodeResult, data[10]);
|
|
2264
2295
|
ResultFormatter.unknown(decodeResult, data[11]);
|
|
2265
|
-
decodeResult
|
|
2266
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2296
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
2267
2297
|
return decodeResult;
|
|
2268
2298
|
}
|
|
2269
2299
|
};
|
|
@@ -2376,10 +2406,7 @@ var Label_15 = class extends DecoderPlugin {
|
|
|
2376
2406
|
};
|
|
2377
2407
|
}
|
|
2378
2408
|
decode(message, options = {}) {
|
|
2379
|
-
const decodeResult = this.
|
|
2380
|
-
decodeResult.decoder.name = this.name;
|
|
2381
|
-
decodeResult.formatted.description = "Position Report";
|
|
2382
|
-
decodeResult.message = message;
|
|
2409
|
+
const decodeResult = this.initResult(message, "Position Report");
|
|
2383
2410
|
if (message.text.startsWith("(2") && message.text.endsWith("(Z")) {
|
|
2384
2411
|
const between = message.text.substring(2, message.text.length - 2);
|
|
2385
2412
|
ResultFormatter.position(
|
|
@@ -2417,16 +2444,9 @@ var Label_15 = class extends DecoderPlugin {
|
|
|
2417
2444
|
ResultFormatter.unknown(decodeResult, between.substring(26));
|
|
2418
2445
|
}
|
|
2419
2446
|
} else {
|
|
2420
|
-
|
|
2421
|
-
console.log(`Decoder: Unknown 15 message: ${message.text}`);
|
|
2422
|
-
}
|
|
2423
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
2424
|
-
decodeResult.decoded = false;
|
|
2425
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2426
|
-
return decodeResult;
|
|
2447
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
2427
2448
|
}
|
|
2428
|
-
decodeResult
|
|
2429
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2449
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
2430
2450
|
return decodeResult;
|
|
2431
2451
|
}
|
|
2432
2452
|
};
|
|
@@ -2441,10 +2461,7 @@ var Label_15_FST = class extends DecoderPlugin {
|
|
|
2441
2461
|
};
|
|
2442
2462
|
}
|
|
2443
2463
|
decode(message, options = {}) {
|
|
2444
|
-
const decodeResult = this.
|
|
2445
|
-
decodeResult.decoder.name = this.name;
|
|
2446
|
-
decodeResult.formatted.description = "Position Report";
|
|
2447
|
-
decodeResult.message = message;
|
|
2464
|
+
const decodeResult = this.initResult(message, "Position Report");
|
|
2448
2465
|
const parts = message.text.split(" ");
|
|
2449
2466
|
const header = parts[0];
|
|
2450
2467
|
const stringCoords = header.substring(13);
|
|
@@ -2460,15 +2477,12 @@ var Label_15_FST = class extends DecoderPlugin {
|
|
|
2460
2477
|
Number(stringCoords.substring(15)) * 100
|
|
2461
2478
|
);
|
|
2462
2479
|
} else {
|
|
2463
|
-
decodeResult.
|
|
2464
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2465
|
-
return decodeResult;
|
|
2480
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
2466
2481
|
}
|
|
2467
2482
|
ResultFormatter.departureAirport(decodeResult, header.substring(5, 9));
|
|
2468
2483
|
ResultFormatter.arrivalAirport(decodeResult, header.substring(9, 13));
|
|
2469
2484
|
ResultFormatter.unknownArr(decodeResult, parts.slice(1), " ");
|
|
2470
|
-
decodeResult
|
|
2471
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2485
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
2472
2486
|
return decodeResult;
|
|
2473
2487
|
}
|
|
2474
2488
|
};
|
|
@@ -2607,19 +2621,10 @@ var Label_16_POSA1 = class extends DecoderPlugin {
|
|
|
2607
2621
|
};
|
|
2608
2622
|
}
|
|
2609
2623
|
decode(message, options = {}) {
|
|
2610
|
-
const decodeResult = this.
|
|
2611
|
-
decodeResult.decoder.name = this.name;
|
|
2612
|
-
decodeResult.formatted.description = "Position Report";
|
|
2613
|
-
decodeResult.message = message;
|
|
2624
|
+
const decodeResult = this.initResult(message, "Position Report");
|
|
2614
2625
|
const fields = message.text.split(",");
|
|
2615
2626
|
if (fields.length !== 11 || !fields[0].startsWith("POSA1")) {
|
|
2616
|
-
|
|
2617
|
-
console.log(`Decoder: Unknown 16 message: ${message.text}`);
|
|
2618
|
-
}
|
|
2619
|
-
decodeResult.remaining.text = message.text;
|
|
2620
|
-
decodeResult.decoded = false;
|
|
2621
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
2622
|
-
return decodeResult;
|
|
2627
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
2623
2628
|
}
|
|
2624
2629
|
ResultFormatter.position(
|
|
2625
2630
|
decodeResult,
|
|
@@ -2637,8 +2642,7 @@ var Label_16_POSA1 = class extends DecoderPlugin {
|
|
|
2637
2642
|
{ name: nextWaypoint, time: nextTime }
|
|
2638
2643
|
]
|
|
2639
2644
|
});
|
|
2640
|
-
decodeResult
|
|
2641
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
2645
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
2642
2646
|
return decodeResult;
|
|
2643
2647
|
}
|
|
2644
2648
|
};
|
|
@@ -3020,42 +3024,31 @@ var Label_20_POS = class extends DecoderPlugin {
|
|
|
3020
3024
|
};
|
|
3021
3025
|
}
|
|
3022
3026
|
decode(message, options = {}) {
|
|
3023
|
-
const decodeResult = this.
|
|
3024
|
-
decodeResult.decoder.name = this.name;
|
|
3025
|
-
decodeResult.formatted.description = "Position Report";
|
|
3026
|
-
decodeResult.message = message;
|
|
3027
|
+
const decodeResult = this.initResult(message, "Position Report");
|
|
3027
3028
|
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
3028
3029
|
const content = message.text.substring(3);
|
|
3029
3030
|
const fields = content.split(",");
|
|
3030
3031
|
if (fields.length == 11) {
|
|
3031
|
-
|
|
3032
|
-
console.log(`DEBUG: ${this.name}: Variation 1 detected`);
|
|
3033
|
-
}
|
|
3032
|
+
this.debug(options, "Variation 1 detected");
|
|
3034
3033
|
const rawCoords = fields[0];
|
|
3035
3034
|
ResultFormatter.position(
|
|
3036
3035
|
decodeResult,
|
|
3037
3036
|
CoordinateUtils.decodeStringCoordinates(rawCoords)
|
|
3038
3037
|
);
|
|
3039
|
-
decodeResult
|
|
3040
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3038
|
+
this.setDecodeLevel(decodeResult, true, "full");
|
|
3041
3039
|
} else if (fields.length == 5) {
|
|
3042
|
-
|
|
3043
|
-
console.log(`DEBUG: ${this.name}: Variation 2 detected`);
|
|
3044
|
-
}
|
|
3040
|
+
this.debug(options, "Variation 2 detected");
|
|
3045
3041
|
const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
|
|
3046
3042
|
if (position) {
|
|
3047
3043
|
ResultFormatter.position(decodeResult, position);
|
|
3048
3044
|
}
|
|
3049
|
-
decodeResult
|
|
3050
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3045
|
+
this.setDecodeLevel(decodeResult, true, "full");
|
|
3051
3046
|
} else {
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
decodeResult.decoded = false;
|
|
3058
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3047
|
+
this.debug(
|
|
3048
|
+
options,
|
|
3049
|
+
`Unknown variation. Field count: ${fields.length}, content: ${content}`
|
|
3050
|
+
);
|
|
3051
|
+
this.setDecodeLevel(decodeResult, false);
|
|
3059
3052
|
}
|
|
3060
3053
|
return decodeResult;
|
|
3061
3054
|
}
|
|
@@ -3071,10 +3064,7 @@ var Label_21_POS = class extends DecoderPlugin {
|
|
|
3071
3064
|
};
|
|
3072
3065
|
}
|
|
3073
3066
|
decode(message, options = {}) {
|
|
3074
|
-
const decodeResult = this.
|
|
3075
|
-
decodeResult.decoder.name = this.name;
|
|
3076
|
-
decodeResult.formatted.description = "Position Report";
|
|
3077
|
-
decodeResult.message = message;
|
|
3067
|
+
const decodeResult = this.initResult(message, "Position Report");
|
|
3078
3068
|
decodeResult.raw.preamble = message.text.substring(0, 3);
|
|
3079
3069
|
const content = message.text.substring(3);
|
|
3080
3070
|
const fields = content.split(",");
|
|
@@ -3096,16 +3086,13 @@ var Label_21_POS = class extends DecoderPlugin {
|
|
|
3096
3086
|
fields[4],
|
|
3097
3087
|
fields[5]
|
|
3098
3088
|
]);
|
|
3099
|
-
decodeResult
|
|
3100
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3089
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
3101
3090
|
} else {
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
decodeResult.decoded = false;
|
|
3108
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3091
|
+
this.debug(
|
|
3092
|
+
options,
|
|
3093
|
+
`Unknown variation. Field count: ${fields.length}, content: ${content}`
|
|
3094
|
+
);
|
|
3095
|
+
this.setDecodeLevel(decodeResult, false);
|
|
3109
3096
|
}
|
|
3110
3097
|
return decodeResult;
|
|
3111
3098
|
}
|
|
@@ -3133,15 +3120,11 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
3133
3120
|
};
|
|
3134
3121
|
}
|
|
3135
3122
|
decode(message, options = {}) {
|
|
3136
|
-
const decodeResult = this.
|
|
3137
|
-
decodeResult.decoder.name = this.name;
|
|
3138
|
-
decodeResult.formatted.description = "Takeoff Report";
|
|
3139
|
-
decodeResult.message = message;
|
|
3123
|
+
const decodeResult = this.initResult(message, "Takeoff Report");
|
|
3140
3124
|
if (message.text.startsWith("OFF01")) {
|
|
3141
3125
|
const fields = message.text.substring(5).split("/");
|
|
3142
3126
|
if (fields.length != 2) {
|
|
3143
|
-
decodeResult
|
|
3144
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3127
|
+
this.setDecodeLevel(decodeResult, false);
|
|
3145
3128
|
return decodeResult;
|
|
3146
3129
|
}
|
|
3147
3130
|
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
@@ -3167,13 +3150,11 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
3167
3150
|
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22))
|
|
3168
3151
|
);
|
|
3169
3152
|
ResultFormatter.unknown(decodeResult, fields[1].substring(22));
|
|
3170
|
-
decodeResult
|
|
3171
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3153
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
3172
3154
|
} else if (message.text.startsWith("OFF02\r\n")) {
|
|
3173
3155
|
const fields = message.text.substring(7).split(",");
|
|
3174
3156
|
if (fields.length != 4) {
|
|
3175
|
-
decodeResult
|
|
3176
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3157
|
+
this.setDecodeLevel(decodeResult, false);
|
|
3177
3158
|
return decodeResult;
|
|
3178
3159
|
}
|
|
3179
3160
|
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
@@ -3183,13 +3164,11 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
3183
3164
|
DateTimeUtils.convertHHMMSSToTod(fields[2])
|
|
3184
3165
|
);
|
|
3185
3166
|
ResultFormatter.unknown(decodeResult, fields[3]);
|
|
3186
|
-
decodeResult
|
|
3187
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3167
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
3188
3168
|
} else if (message.text.startsWith("OFF02")) {
|
|
3189
3169
|
const fields = message.text.substring(5).split("/");
|
|
3190
3170
|
if (fields.length != 2) {
|
|
3191
|
-
decodeResult
|
|
3192
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3171
|
+
this.setDecodeLevel(decodeResult, false);
|
|
3193
3172
|
return decodeResult;
|
|
3194
3173
|
}
|
|
3195
3174
|
ResultFormatter.flightNumber(decodeResult, fields[0]);
|
|
@@ -3218,14 +3197,10 @@ var Label_22_OFF = class extends DecoderPlugin {
|
|
|
3218
3197
|
decodeResult,
|
|
3219
3198
|
DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40))
|
|
3220
3199
|
);
|
|
3221
|
-
decodeResult
|
|
3222
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3200
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
3223
3201
|
} else {
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
}
|
|
3227
|
-
decodeResult.decoded = false;
|
|
3228
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3202
|
+
this.debug(options, "Unknown variation.");
|
|
3203
|
+
this.setDecodeLevel(decodeResult, false);
|
|
3229
3204
|
}
|
|
3230
3205
|
return decodeResult;
|
|
3231
3206
|
}
|
|
@@ -3241,19 +3216,14 @@ var Label_22_POS = class extends DecoderPlugin {
|
|
|
3241
3216
|
};
|
|
3242
3217
|
}
|
|
3243
3218
|
decode(message, options = {}) {
|
|
3244
|
-
const decodeResult = this.
|
|
3245
|
-
decodeResult.decoder.name = this.name;
|
|
3246
|
-
decodeResult.formatted.description = "Position Report";
|
|
3247
|
-
decodeResult.message = message;
|
|
3219
|
+
const decodeResult = this.initResult(message, "Position Report");
|
|
3248
3220
|
const fields = message.text.split(",");
|
|
3249
3221
|
if (fields.length !== 11) {
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
decodeResult.decoded = false;
|
|
3256
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3222
|
+
this.debug(
|
|
3223
|
+
options,
|
|
3224
|
+
`Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`
|
|
3225
|
+
);
|
|
3226
|
+
this.setDecodeLevel(decodeResult, false);
|
|
3257
3227
|
return decodeResult;
|
|
3258
3228
|
}
|
|
3259
3229
|
const latStr = fields[0].substring(1, 8);
|
|
@@ -3270,8 +3240,7 @@ var Label_22_POS = class extends DecoderPlugin {
|
|
|
3270
3240
|
);
|
|
3271
3241
|
ResultFormatter.altitude(decodeResult, Number(fields[3]));
|
|
3272
3242
|
ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
|
|
3273
|
-
decodeResult
|
|
3274
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
3243
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
3275
3244
|
return decodeResult;
|
|
3276
3245
|
}
|
|
3277
3246
|
};
|
|
@@ -3563,218 +3532,143 @@ var Label_44_ETA = class extends DecoderPlugin {
|
|
|
3563
3532
|
};
|
|
3564
3533
|
}
|
|
3565
3534
|
decode(message, options = {}) {
|
|
3566
|
-
const
|
|
3567
|
-
decodeResult.decoder.name = this.name;
|
|
3568
|
-
decodeResult.formatted.description = "ETA Report";
|
|
3569
|
-
decodeResult.message = message;
|
|
3535
|
+
const result = this.initResult(message, "ETA Report");
|
|
3570
3536
|
const data = message.text.split(",");
|
|
3571
|
-
if (data.length
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
return
|
|
3537
|
+
if (data.length < 9) {
|
|
3538
|
+
return this.failUnknown(result, message.text, options);
|
|
3539
|
+
}
|
|
3540
|
+
this.debug(options, "ETA Report: fields", data);
|
|
3541
|
+
ResultFormatter.position(
|
|
3542
|
+
result,
|
|
3543
|
+
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
3544
|
+
);
|
|
3545
|
+
ResultFormatter.altitude(result, 100 * Number(data[2]));
|
|
3546
|
+
ResultFormatter.departureAirport(result, data[3]);
|
|
3547
|
+
ResultFormatter.arrivalAirport(result, data[4]);
|
|
3548
|
+
ResultFormatter.month(result, Number(data[5].substring(0, 2)));
|
|
3549
|
+
ResultFormatter.day(result, Number(data[5].substring(2, 4)));
|
|
3550
|
+
ResultFormatter.timestamp(
|
|
3551
|
+
result,
|
|
3552
|
+
DateTimeUtils.convertHHMMSSToTod(data[6])
|
|
3553
|
+
);
|
|
3554
|
+
ResultFormatter.eta(result, DateTimeUtils.convertHHMMSSToTod(data[7]));
|
|
3555
|
+
const fuel = Number(data[8]);
|
|
3556
|
+
if (!isNaN(fuel)) {
|
|
3557
|
+
ResultFormatter.remainingFuel(result, fuel);
|
|
3558
|
+
}
|
|
3559
|
+
if (data.length > 9) {
|
|
3560
|
+
ResultFormatter.unknownArr(result, data.slice(9));
|
|
3561
|
+
}
|
|
3562
|
+
this.setDecodeLevel(result, true, "full");
|
|
3563
|
+
return result;
|
|
3564
|
+
}
|
|
3565
|
+
};
|
|
3566
|
+
|
|
3567
|
+
// lib/plugins/Label_44_Base.ts
|
|
3568
|
+
var Label_44_Base = class extends DecoderPlugin {
|
|
3569
|
+
decode(message, options = {}) {
|
|
3570
|
+
const result = this.initResult(message, this.description);
|
|
3571
|
+
const data = message.text.split(",");
|
|
3572
|
+
if (data.length < this.minFields) {
|
|
3573
|
+
return this.failUnknown(result, message.text, options);
|
|
3574
|
+
}
|
|
3575
|
+
this.debug(options, `${this.description}: fields`, data);
|
|
3576
|
+
ResultFormatter.position(
|
|
3577
|
+
result,
|
|
3578
|
+
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
3579
|
+
);
|
|
3580
|
+
ResultFormatter.departureAirport(result, data[2]);
|
|
3581
|
+
ResultFormatter.arrivalAirport(result, data[3]);
|
|
3582
|
+
ResultFormatter.month(result, Number(data[4].substring(0, 2)));
|
|
3583
|
+
ResultFormatter.day(result, Number(data[4].substring(2, 4)));
|
|
3584
|
+
this.decodeEventFields(result, data, options);
|
|
3585
|
+
this.setDecodeLevel(result, true, "full");
|
|
3586
|
+
return result;
|
|
3587
|
+
}
|
|
3588
|
+
/**
|
|
3589
|
+
* Helper to parse a fuel value from a CSV field.
|
|
3590
|
+
* Returns undefined if the value is not a valid number.
|
|
3591
|
+
*/
|
|
3592
|
+
parseFuel(result, value) {
|
|
3593
|
+
const fuel = Number(value);
|
|
3594
|
+
if (!isNaN(fuel)) {
|
|
3595
|
+
ResultFormatter.remainingFuel(result, fuel);
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
/**
|
|
3599
|
+
* Helper to add any remaining fields as unknown.
|
|
3600
|
+
*/
|
|
3601
|
+
addRemainingFields(result, data, startIndex) {
|
|
3602
|
+
if (data.length > startIndex) {
|
|
3603
|
+
ResultFormatter.unknownArr(result, data.slice(startIndex));
|
|
3608
3604
|
}
|
|
3609
|
-
decodeResult.decoded = true;
|
|
3610
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3611
|
-
return decodeResult;
|
|
3612
3605
|
}
|
|
3613
3606
|
};
|
|
3614
3607
|
|
|
3615
3608
|
// lib/plugins/Label_44_IN.ts
|
|
3616
|
-
var Label_44_IN = class extends
|
|
3609
|
+
var Label_44_IN = class extends Label_44_Base {
|
|
3617
3610
|
name = "label-44-in";
|
|
3611
|
+
get description() {
|
|
3612
|
+
return "In Gate Report";
|
|
3613
|
+
}
|
|
3614
|
+
get minFields() {
|
|
3615
|
+
return 7;
|
|
3616
|
+
}
|
|
3618
3617
|
qualifiers() {
|
|
3619
3618
|
return {
|
|
3620
3619
|
labels: ["44"],
|
|
3621
3620
|
preambles: ["00IN01", "00IN02", "00IN03", "IN01", "IN02", "IN03"]
|
|
3622
3621
|
};
|
|
3623
3622
|
}
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
decodeResult.message = message;
|
|
3629
|
-
const data = message.text.split(",");
|
|
3630
|
-
if (data.length >= 7) {
|
|
3631
|
-
if (options.debug) {
|
|
3632
|
-
console.log("Label 44 In Air Report: groups");
|
|
3633
|
-
console.log(data);
|
|
3634
|
-
}
|
|
3635
|
-
ResultFormatter.position(
|
|
3636
|
-
decodeResult,
|
|
3637
|
-
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
3638
|
-
);
|
|
3639
|
-
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
3640
|
-
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
3641
|
-
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
3642
|
-
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
3643
|
-
ResultFormatter.in(
|
|
3644
|
-
decodeResult,
|
|
3645
|
-
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3646
|
-
);
|
|
3647
|
-
const fuel = Number(data[6]);
|
|
3648
|
-
if (!isNaN(fuel)) {
|
|
3649
|
-
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
3650
|
-
}
|
|
3651
|
-
if (data.length > 7) {
|
|
3652
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(7));
|
|
3653
|
-
}
|
|
3654
|
-
} else {
|
|
3655
|
-
if (options.debug) {
|
|
3656
|
-
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
3657
|
-
}
|
|
3658
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
3659
|
-
decodeResult.decoded = false;
|
|
3660
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3661
|
-
return decodeResult;
|
|
3662
|
-
}
|
|
3663
|
-
decodeResult.decoded = true;
|
|
3664
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3665
|
-
return decodeResult;
|
|
3623
|
+
decodeEventFields(result, data, _options) {
|
|
3624
|
+
ResultFormatter.in(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
|
|
3625
|
+
this.parseFuel(result, data[6]);
|
|
3626
|
+
this.addRemainingFields(result, data, 7);
|
|
3666
3627
|
}
|
|
3667
3628
|
};
|
|
3668
3629
|
|
|
3669
3630
|
// lib/plugins/Label_44_OFF.ts
|
|
3670
|
-
var Label_44_OFF = class extends
|
|
3631
|
+
var Label_44_OFF = class extends Label_44_Base {
|
|
3671
3632
|
name = "label-44-off";
|
|
3633
|
+
get description() {
|
|
3634
|
+
return "Off Runway Report";
|
|
3635
|
+
}
|
|
3636
|
+
get minFields() {
|
|
3637
|
+
return 8;
|
|
3638
|
+
}
|
|
3672
3639
|
qualifiers() {
|
|
3673
3640
|
return {
|
|
3674
3641
|
labels: ["44"],
|
|
3675
3642
|
preambles: ["00OFF01", "00OFF02", "00OFF03", "OFF01", "OFF02", "OFF03"]
|
|
3676
3643
|
};
|
|
3677
3644
|
}
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
const data = message.text.split(",");
|
|
3684
|
-
if (data.length >= 8) {
|
|
3685
|
-
if (options.debug) {
|
|
3686
|
-
console.log("Label 44 Off Runway Report: groups");
|
|
3687
|
-
console.log(data);
|
|
3688
|
-
}
|
|
3689
|
-
ResultFormatter.position(
|
|
3690
|
-
decodeResult,
|
|
3691
|
-
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
3692
|
-
);
|
|
3693
|
-
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
3694
|
-
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
3695
|
-
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
3696
|
-
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
3697
|
-
ResultFormatter.off(
|
|
3698
|
-
decodeResult,
|
|
3699
|
-
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3700
|
-
);
|
|
3701
|
-
ResultFormatter.eta(
|
|
3702
|
-
decodeResult,
|
|
3703
|
-
DateTimeUtils.convertHHMMSSToTod(data[6])
|
|
3704
|
-
);
|
|
3705
|
-
const fuel = Number(data[7]);
|
|
3706
|
-
if (!isNaN(fuel)) {
|
|
3707
|
-
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
3708
|
-
}
|
|
3709
|
-
if (data.length > 8) {
|
|
3710
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(8));
|
|
3711
|
-
}
|
|
3712
|
-
} else {
|
|
3713
|
-
if (options.debug) {
|
|
3714
|
-
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
3715
|
-
}
|
|
3716
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
3717
|
-
decodeResult.decoded = false;
|
|
3718
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3719
|
-
return decodeResult;
|
|
3720
|
-
}
|
|
3721
|
-
decodeResult.decoded = true;
|
|
3722
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3723
|
-
return decodeResult;
|
|
3645
|
+
decodeEventFields(result, data, _options) {
|
|
3646
|
+
ResultFormatter.off(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
|
|
3647
|
+
ResultFormatter.eta(result, DateTimeUtils.convertHHMMSSToTod(data[6]));
|
|
3648
|
+
this.parseFuel(result, data[7]);
|
|
3649
|
+
this.addRemainingFields(result, data, 8);
|
|
3724
3650
|
}
|
|
3725
3651
|
};
|
|
3726
3652
|
|
|
3727
3653
|
// lib/plugins/Label_44_ON.ts
|
|
3728
|
-
var Label_44_ON = class extends
|
|
3654
|
+
var Label_44_ON = class extends Label_44_Base {
|
|
3729
3655
|
name = "label-44-on";
|
|
3656
|
+
get description() {
|
|
3657
|
+
return "On Runway Report";
|
|
3658
|
+
}
|
|
3659
|
+
get minFields() {
|
|
3660
|
+
return 7;
|
|
3661
|
+
}
|
|
3730
3662
|
qualifiers() {
|
|
3731
3663
|
return {
|
|
3732
3664
|
labels: ["44"],
|
|
3733
3665
|
preambles: ["00ON01", "00ON02", "00ON03", "ON01", "ON02", "ON03"]
|
|
3734
3666
|
};
|
|
3735
3667
|
}
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
decodeResult.message = message;
|
|
3741
|
-
const data = message.text.split(",");
|
|
3742
|
-
if (data.length >= 7) {
|
|
3743
|
-
if (options.debug) {
|
|
3744
|
-
console.log("Label 44 On Runway Report: groups");
|
|
3745
|
-
console.log(data);
|
|
3746
|
-
}
|
|
3747
|
-
ResultFormatter.position(
|
|
3748
|
-
decodeResult,
|
|
3749
|
-
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1])
|
|
3750
|
-
);
|
|
3751
|
-
ResultFormatter.departureAirport(decodeResult, data[2]);
|
|
3752
|
-
ResultFormatter.arrivalAirport(decodeResult, data[3]);
|
|
3753
|
-
ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
|
|
3754
|
-
ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
|
|
3755
|
-
ResultFormatter.on(
|
|
3756
|
-
decodeResult,
|
|
3757
|
-
DateTimeUtils.convertHHMMSSToTod(data[5])
|
|
3758
|
-
);
|
|
3759
|
-
const fuel = Number(data[6]);
|
|
3760
|
-
if (!isNaN(fuel)) {
|
|
3761
|
-
ResultFormatter.remainingFuel(decodeResult, Number(fuel));
|
|
3762
|
-
}
|
|
3763
|
-
if (data.length > 7) {
|
|
3764
|
-
ResultFormatter.unknownArr(decodeResult, data.slice(7));
|
|
3765
|
-
}
|
|
3766
|
-
} else {
|
|
3767
|
-
if (options.debug) {
|
|
3768
|
-
console.log(`Decoder: Unknown 44 message: ${message.text}`);
|
|
3769
|
-
}
|
|
3770
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
3771
|
-
decodeResult.decoded = false;
|
|
3772
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3773
|
-
return decodeResult;
|
|
3774
|
-
}
|
|
3775
|
-
decodeResult.decoded = true;
|
|
3776
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3777
|
-
return decodeResult;
|
|
3668
|
+
decodeEventFields(result, data, _options) {
|
|
3669
|
+
ResultFormatter.on(result, DateTimeUtils.convertHHMMSSToTod(data[5]));
|
|
3670
|
+
this.parseFuel(result, data[6]);
|
|
3671
|
+
this.addRemainingFields(result, data, 7);
|
|
3778
3672
|
}
|
|
3779
3673
|
};
|
|
3780
3674
|
|
|
@@ -3788,17 +3682,11 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
3788
3682
|
};
|
|
3789
3683
|
}
|
|
3790
3684
|
decode(message, options = {}) {
|
|
3791
|
-
const decodeResult = this.
|
|
3792
|
-
decodeResult.decoder.name = this.name;
|
|
3793
|
-
decodeResult.formatted.description = "Position Report";
|
|
3794
|
-
decodeResult.message = message;
|
|
3685
|
+
const decodeResult = this.initResult(message, "Position Report");
|
|
3795
3686
|
const regex = /^.*,(?<unsplit_coords>.*),(?<flight_level_or_ground>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
|
|
3796
3687
|
const results = message.text.match(regex);
|
|
3797
3688
|
if (results?.groups) {
|
|
3798
|
-
|
|
3799
|
-
console.log("Label 44 Position Report: groups");
|
|
3800
|
-
console.log(results.groups);
|
|
3801
|
-
}
|
|
3689
|
+
this.debug(options, "Position Report: groups", results.groups);
|
|
3802
3690
|
ResultFormatter.position(
|
|
3803
3691
|
decodeResult,
|
|
3804
3692
|
CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
@@ -3831,10 +3719,10 @@ var Label_44_POS = class extends DecoderPlugin {
|
|
|
3831
3719
|
);
|
|
3832
3720
|
ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
|
|
3833
3721
|
ResultFormatter.altitude(decodeResult, flight_level * 100);
|
|
3722
|
+
this.setDecodeLevel(decodeResult, true, "full");
|
|
3723
|
+
return decodeResult;
|
|
3834
3724
|
}
|
|
3835
|
-
decodeResult.
|
|
3836
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3837
|
-
return decodeResult;
|
|
3725
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
3838
3726
|
}
|
|
3839
3727
|
};
|
|
3840
3728
|
|
|
@@ -3912,10 +3800,7 @@ var Label_4A = class extends DecoderPlugin {
|
|
|
3912
3800
|
};
|
|
3913
3801
|
}
|
|
3914
3802
|
decode(message, options = {}) {
|
|
3915
|
-
const decodeResult = this.
|
|
3916
|
-
decodeResult.decoder.name = this.name;
|
|
3917
|
-
decodeResult.message = message;
|
|
3918
|
-
decodeResult.formatted.description = "Latest New Format";
|
|
3803
|
+
const decodeResult = this.initResult(message, "Latest New Format");
|
|
3919
3804
|
decodeResult.decoded = true;
|
|
3920
3805
|
const fields = message.text.split(",");
|
|
3921
3806
|
if (fields.length === 11) {
|
|
@@ -3929,7 +3814,8 @@ var Label_4A = class extends DecoderPlugin {
|
|
|
3929
3814
|
ResultFormatter.arrivalAirport(decodeResult, fields[5]);
|
|
3930
3815
|
ResultFormatter.unknownArr(decodeResult, fields.slice(8));
|
|
3931
3816
|
} else if (fields.length === 6) {
|
|
3932
|
-
|
|
3817
|
+
const f0 = fields[0];
|
|
3818
|
+
if (f0.length > 0 && (f0[0] === "N" || f0[0] === "S")) {
|
|
3933
3819
|
ResultFormatter.position(
|
|
3934
3820
|
decodeResult,
|
|
3935
3821
|
CoordinateUtils.decodeStringCoordinates(fields[0].substring(0, 13))
|
|
@@ -3971,13 +3857,7 @@ var Label_4A = class extends DecoderPlugin {
|
|
|
3971
3857
|
decodeResult.decoded = false;
|
|
3972
3858
|
ResultFormatter.unknown(decodeResult, message.text);
|
|
3973
3859
|
}
|
|
3974
|
-
|
|
3975
|
-
if (!decodeResult.remaining.text)
|
|
3976
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
3977
|
-
else decodeResult.decoder.decodeLevel = "partial";
|
|
3978
|
-
} else {
|
|
3979
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
3980
|
-
}
|
|
3860
|
+
this.setDecodeLevel(decodeResult, decodeResult.decoded);
|
|
3981
3861
|
return decodeResult;
|
|
3982
3862
|
}
|
|
3983
3863
|
};
|
|
@@ -3992,10 +3872,7 @@ var Label_4A_01 = class extends DecoderPlugin {
|
|
|
3992
3872
|
};
|
|
3993
3873
|
}
|
|
3994
3874
|
decode(message, options = {}) {
|
|
3995
|
-
const decodeResult = this.
|
|
3996
|
-
decodeResult.decoder.name = this.name;
|
|
3997
|
-
decodeResult.message = message;
|
|
3998
|
-
decodeResult.formatted.description = "Latest New Format";
|
|
3875
|
+
const decodeResult = this.initResult(message, "Latest New Format");
|
|
3999
3876
|
decodeResult.decoded = true;
|
|
4000
3877
|
let rgx = message.text.match(
|
|
4001
3878
|
/^01([A-Z]{2})([A-Z]{2})\s*(\w+)\/(\d{6})([A-Z]{4})([A-Z]{4})\r\n([+-]\s*\d+)(\d{3}\.\d)([+-]\s*\d+\.\d)/
|
|
@@ -4016,13 +3893,7 @@ var Label_4A_01 = class extends DecoderPlugin {
|
|
|
4016
3893
|
decodeResult.decoded = false;
|
|
4017
3894
|
ResultFormatter.unknown(decodeResult, message.text);
|
|
4018
3895
|
}
|
|
4019
|
-
|
|
4020
|
-
if (!decodeResult.remaining.text)
|
|
4021
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
4022
|
-
else decodeResult.decoder.decodeLevel = "partial";
|
|
4023
|
-
} else {
|
|
4024
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
4025
|
-
}
|
|
3896
|
+
this.setDecodeLevel(decodeResult, decodeResult.decoded);
|
|
4026
3897
|
return decodeResult;
|
|
4027
3898
|
}
|
|
4028
3899
|
};
|
|
@@ -4037,10 +3908,7 @@ var Label_4A_DIS = class extends DecoderPlugin {
|
|
|
4037
3908
|
};
|
|
4038
3909
|
}
|
|
4039
3910
|
decode(message, options = {}) {
|
|
4040
|
-
const decodeResult = this.
|
|
4041
|
-
decodeResult.decoder.name = this.name;
|
|
4042
|
-
decodeResult.message = message;
|
|
4043
|
-
decodeResult.formatted.description = "Latest New Format";
|
|
3911
|
+
const decodeResult = this.initResult(message, "Latest New Format");
|
|
4044
3912
|
decodeResult.decoded = true;
|
|
4045
3913
|
const fields = message.text.split(",");
|
|
4046
3914
|
ResultFormatter.timestamp(
|
|
@@ -4049,13 +3917,7 @@ var Label_4A_DIS = class extends DecoderPlugin {
|
|
|
4049
3917
|
);
|
|
4050
3918
|
ResultFormatter.callsign(decodeResult, fields[2]);
|
|
4051
3919
|
ResultFormatter.text(decodeResult, fields.slice(3).join(""));
|
|
4052
|
-
|
|
4053
|
-
if (!decodeResult.remaining.text)
|
|
4054
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
4055
|
-
else decodeResult.decoder.decodeLevel = "partial";
|
|
4056
|
-
} else {
|
|
4057
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
4058
|
-
}
|
|
3920
|
+
this.setDecodeLevel(decodeResult, decodeResult.decoded);
|
|
4059
3921
|
return decodeResult;
|
|
4060
3922
|
}
|
|
4061
3923
|
};
|
|
@@ -4070,10 +3932,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
|
|
|
4070
3932
|
};
|
|
4071
3933
|
}
|
|
4072
3934
|
decode(message, options = {}) {
|
|
4073
|
-
const decodeResult = this.
|
|
4074
|
-
decodeResult.decoder.name = this.name;
|
|
4075
|
-
decodeResult.message = message;
|
|
4076
|
-
decodeResult.formatted.description = "Latest New Format";
|
|
3935
|
+
const decodeResult = this.initResult(message, "Latest New Format");
|
|
4077
3936
|
decodeResult.decoded = true;
|
|
4078
3937
|
const fields = message.text.split(" ");
|
|
4079
3938
|
if (fields.length === 3) {
|
|
@@ -4090,13 +3949,7 @@ var Label_4A_DOOR = class extends DecoderPlugin {
|
|
|
4090
3949
|
decodeResult.decoded = false;
|
|
4091
3950
|
ResultFormatter.unknown(decodeResult, message.text);
|
|
4092
3951
|
}
|
|
4093
|
-
|
|
4094
|
-
if (!decodeResult.remaining.text)
|
|
4095
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
4096
|
-
else decodeResult.decoder.decodeLevel = "partial";
|
|
4097
|
-
} else {
|
|
4098
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
4099
|
-
}
|
|
3952
|
+
this.setDecodeLevel(decodeResult, decodeResult.decoded);
|
|
4100
3953
|
return decodeResult;
|
|
4101
3954
|
}
|
|
4102
3955
|
};
|
|
@@ -4343,6 +4196,9 @@ var Label_4T_ETA = class extends DecoderPlugin {
|
|
|
4343
4196
|
};
|
|
4344
4197
|
|
|
4345
4198
|
// lib/plugins/Label_80.ts
|
|
4199
|
+
var POS_REGEX = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
|
|
4200
|
+
var WS_REGEX = /\s+/;
|
|
4201
|
+
var NEWLINE_REGEX2 = /\r?\n/;
|
|
4346
4202
|
var Label_80 = class extends DecoderPlugin {
|
|
4347
4203
|
name = "label-80";
|
|
4348
4204
|
qualifiers() {
|
|
@@ -4352,10 +4208,11 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4352
4208
|
};
|
|
4353
4209
|
}
|
|
4354
4210
|
decode(message, options = {}) {
|
|
4355
|
-
const decodeResult = this.
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4211
|
+
const decodeResult = this.initResult(
|
|
4212
|
+
message,
|
|
4213
|
+
"Airline Defined Position Report"
|
|
4214
|
+
);
|
|
4215
|
+
const lines = message.text.split(NEWLINE_REGEX2);
|
|
4359
4216
|
if (lines.length === 1 && lines[0].includes(",")) {
|
|
4360
4217
|
this.parseCsvFormat(lines[0], decodeResult);
|
|
4361
4218
|
} else {
|
|
@@ -4380,8 +4237,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4380
4237
|
}
|
|
4381
4238
|
}
|
|
4382
4239
|
if (decodeResult.formatted.items.length > 0) {
|
|
4383
|
-
decodeResult
|
|
4384
|
-
decodeResult.decoder.decodeLevel = decodeResult.remaining.text === void 0 ? "full" : "partial";
|
|
4240
|
+
this.setDecodeLevel(decodeResult, true);
|
|
4385
4241
|
}
|
|
4386
4242
|
return decodeResult;
|
|
4387
4243
|
}
|
|
@@ -4391,7 +4247,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4391
4247
|
ResultFormatter.unknown(results, header, "/");
|
|
4392
4248
|
return;
|
|
4393
4249
|
}
|
|
4394
|
-
const msgInfo = fields[0].split(
|
|
4250
|
+
const msgInfo = fields[0].split(WS_REGEX);
|
|
4395
4251
|
if (msgInfo.length === 3) {
|
|
4396
4252
|
ResultFormatter.unknownArr(results, msgInfo.slice(0, 2), " ");
|
|
4397
4253
|
ResultFormatter.flightNumber(results, msgInfo[2]);
|
|
@@ -4399,14 +4255,14 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4399
4255
|
ResultFormatter.unknown(results, header, "/");
|
|
4400
4256
|
return;
|
|
4401
4257
|
}
|
|
4402
|
-
const otherInfo1 = fields[1].split(
|
|
4258
|
+
const otherInfo1 = fields[1].split(WS_REGEX);
|
|
4403
4259
|
if (otherInfo1.length === 2) {
|
|
4404
4260
|
ResultFormatter.day(results, parseInt(otherInfo1[0], 10));
|
|
4405
4261
|
ResultFormatter.departureAirport(results, otherInfo1[1]);
|
|
4406
4262
|
} else {
|
|
4407
4263
|
ResultFormatter.unknownArr(results, otherInfo1, " ");
|
|
4408
4264
|
}
|
|
4409
|
-
const otherInfo2 = fields[2].split(
|
|
4265
|
+
const otherInfo2 = fields[2].split(WS_REGEX);
|
|
4410
4266
|
if (otherInfo2.length === 2) {
|
|
4411
4267
|
ResultFormatter.arrivalAirport(results, otherInfo2[0]);
|
|
4412
4268
|
ResultFormatter.tail(results, otherInfo2[1].replace(".", ""));
|
|
@@ -4418,7 +4274,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4418
4274
|
}
|
|
4419
4275
|
}
|
|
4420
4276
|
parseTags(part, results) {
|
|
4421
|
-
const kvPair = part.split(
|
|
4277
|
+
const kvPair = part.split(WS_REGEX);
|
|
4422
4278
|
if (kvPair.length < 2) {
|
|
4423
4279
|
ResultFormatter.unknown(results, part, "/");
|
|
4424
4280
|
return;
|
|
@@ -4426,9 +4282,8 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4426
4282
|
const tag = kvPair[0];
|
|
4427
4283
|
const val = kvPair.slice(1).join(" ");
|
|
4428
4284
|
switch (tag) {
|
|
4429
|
-
case "POS":
|
|
4430
|
-
const
|
|
4431
|
-
const posResult = val.match(posRegex);
|
|
4285
|
+
case "POS": {
|
|
4286
|
+
const posResult = POS_REGEX.exec(val);
|
|
4432
4287
|
const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.latd === "S" ? -1 : 1);
|
|
4433
4288
|
const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
|
|
4434
4289
|
const position = {
|
|
@@ -4437,6 +4292,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4437
4292
|
};
|
|
4438
4293
|
ResultFormatter.position(results, position);
|
|
4439
4294
|
break;
|
|
4295
|
+
}
|
|
4440
4296
|
case "ALT":
|
|
4441
4297
|
ResultFormatter.altitude(results, parseInt(val.replace("+", ""), 10));
|
|
4442
4298
|
break;
|
|
@@ -4469,10 +4325,11 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4469
4325
|
DateTimeUtils.convertHHMMSSToTod(val)
|
|
4470
4326
|
);
|
|
4471
4327
|
break;
|
|
4472
|
-
case "ETA":
|
|
4328
|
+
case "ETA": {
|
|
4473
4329
|
const hhmm = val.split(".")[0].replace(":", "");
|
|
4474
4330
|
ResultFormatter.eta(results, DateTimeUtils.convertHHMMSSToTod(hhmm));
|
|
4475
4331
|
break;
|
|
4332
|
+
}
|
|
4476
4333
|
case "HDG":
|
|
4477
4334
|
ResultFormatter.heading(results, parseInt(val, 10));
|
|
4478
4335
|
break;
|
|
@@ -4496,7 +4353,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4496
4353
|
if (csvParts.length !== 9) {
|
|
4497
4354
|
return;
|
|
4498
4355
|
}
|
|
4499
|
-
const header = csvParts[0].trim().split(
|
|
4356
|
+
const header = csvParts[0].trim().split(WS_REGEX);
|
|
4500
4357
|
ResultFormatter.unknown(results, header[0], " ");
|
|
4501
4358
|
ResultFormatter.unknown(results, header[1], " ");
|
|
4502
4359
|
ResultFormatter.position(
|
|
@@ -4519,6 +4376,9 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4519
4376
|
};
|
|
4520
4377
|
|
|
4521
4378
|
// lib/plugins/Label_83.ts
|
|
4379
|
+
var WS_REGEX2 = /\s+/;
|
|
4380
|
+
var ALL_WS_REGEX = /\s/g;
|
|
4381
|
+
var ALL_DOTS_REGEX = /\./g;
|
|
4522
4382
|
var Label_83 = class extends DecoderPlugin {
|
|
4523
4383
|
name = "label-83";
|
|
4524
4384
|
qualifiers() {
|
|
@@ -4533,8 +4393,8 @@ var Label_83 = class extends DecoderPlugin {
|
|
|
4533
4393
|
decodeResult.formatted.description = "Airline Defined";
|
|
4534
4394
|
decodeResult.decoded = true;
|
|
4535
4395
|
const text = message.text;
|
|
4536
|
-
if (text.
|
|
4537
|
-
const fields = text.split(
|
|
4396
|
+
if (text.startsWith("4DH3 ETAT2")) {
|
|
4397
|
+
const fields = text.split(WS_REGEX2);
|
|
4538
4398
|
if (fields[2].length > 5) {
|
|
4539
4399
|
decodeResult.raw.day = fields[2].substring(5);
|
|
4540
4400
|
}
|
|
@@ -4542,15 +4402,15 @@ var Label_83 = class extends DecoderPlugin {
|
|
|
4542
4402
|
const subfields = fields[3].split("/");
|
|
4543
4403
|
ResultFormatter.departureAirport(decodeResult, subfields[0]);
|
|
4544
4404
|
ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
|
|
4545
|
-
ResultFormatter.tail(decodeResult, fields[4].replace(
|
|
4405
|
+
ResultFormatter.tail(decodeResult, fields[4].replace(ALL_DOTS_REGEX, ""));
|
|
4546
4406
|
ResultFormatter.eta(
|
|
4547
4407
|
decodeResult,
|
|
4548
4408
|
DateTimeUtils.convertHHMMSSToTod(fields[6] + "00")
|
|
4549
4409
|
);
|
|
4550
|
-
} else if (text.
|
|
4410
|
+
} else if (text.startsWith("001PR")) {
|
|
4551
4411
|
decodeResult.raw.day = text.substring(5, 7);
|
|
4552
4412
|
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
4553
|
-
text.substring(13, 28).replace(
|
|
4413
|
+
text.substring(13, 28).replace(ALL_DOTS_REGEX, "")
|
|
4554
4414
|
);
|
|
4555
4415
|
if (position) {
|
|
4556
4416
|
ResultFormatter.position(decodeResult, position);
|
|
@@ -4558,15 +4418,15 @@ var Label_83 = class extends DecoderPlugin {
|
|
|
4558
4418
|
ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
|
|
4559
4419
|
ResultFormatter.unknown(decodeResult, text.substring(33));
|
|
4560
4420
|
} else {
|
|
4561
|
-
const fields = text.replace(
|
|
4421
|
+
const fields = text.replace(ALL_WS_REGEX, "").split(",");
|
|
4562
4422
|
if (fields.length === 9) {
|
|
4563
4423
|
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
4564
4424
|
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
4565
4425
|
decodeResult.raw.day = fields[2].substring(0, 2);
|
|
4566
4426
|
decodeResult.raw.time = fields[2].substring(2);
|
|
4567
4427
|
ResultFormatter.position(decodeResult, {
|
|
4568
|
-
latitude: Number(fields[3]
|
|
4569
|
-
longitude: Number(fields[4]
|
|
4428
|
+
latitude: Number(fields[3]),
|
|
4429
|
+
longitude: Number(fields[4])
|
|
4570
4430
|
});
|
|
4571
4431
|
ResultFormatter.altitude(decodeResult, Number(fields[5]));
|
|
4572
4432
|
ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
|
|
@@ -4630,13 +4490,15 @@ var Label_B6_Forwardslash = class extends DecoderPlugin {
|
|
|
4630
4490
|
};
|
|
4631
4491
|
}
|
|
4632
4492
|
decode(message, options = {}) {
|
|
4633
|
-
const decodeResult = this.
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4493
|
+
const decodeResult = this.initResult(message, "CPDLC Message");
|
|
4494
|
+
const body = message.text.substring(1);
|
|
4495
|
+
if (body.length > 0) {
|
|
4496
|
+
ResultFormatter.text(decodeResult, body);
|
|
4497
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
4498
|
+
} else {
|
|
4499
|
+
this.setDecodeLevel(decodeResult, false);
|
|
4639
4500
|
}
|
|
4501
|
+
this.debug(options, "CPDLC body:", body);
|
|
4640
4502
|
return decodeResult;
|
|
4641
4503
|
}
|
|
4642
4504
|
};
|
|
@@ -4907,10 +4769,7 @@ var Label_H1_FLR = class extends DecoderPlugin {
|
|
|
4907
4769
|
};
|
|
4908
4770
|
}
|
|
4909
4771
|
decode(message, options = {}) {
|
|
4910
|
-
|
|
4911
|
-
decodeResult.decoder.name = this.name;
|
|
4912
|
-
decodeResult.formatted.description = "Fault Log Report";
|
|
4913
|
-
decodeResult.message = message;
|
|
4772
|
+
const decodeResult = this.initResult(message, "Fault Log Report");
|
|
4914
4773
|
const parts = message.text.split("/FR");
|
|
4915
4774
|
if (parts.length > 1) {
|
|
4916
4775
|
const fields = parts[0].split("/");
|
|
@@ -4934,15 +4793,9 @@ var Label_H1_FLR = class extends DecoderPlugin {
|
|
|
4934
4793
|
label: "Fault Report",
|
|
4935
4794
|
value: decodeResult.raw.fault_message
|
|
4936
4795
|
});
|
|
4937
|
-
decodeResult
|
|
4938
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
4796
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
4939
4797
|
} else {
|
|
4940
|
-
|
|
4941
|
-
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
4942
|
-
}
|
|
4943
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
4944
|
-
decodeResult.decoded = false;
|
|
4945
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
4798
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
4946
4799
|
}
|
|
4947
4800
|
return decodeResult;
|
|
4948
4801
|
}
|
|
@@ -4957,30 +4810,21 @@ var Label_H1_M_POS = class extends DecoderPlugin {
|
|
|
4957
4810
|
};
|
|
4958
4811
|
}
|
|
4959
4812
|
decode(message, options = {}) {
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4813
|
+
const decodeResult = this.initResult(
|
|
4814
|
+
message,
|
|
4815
|
+
"M-Series Periodic Position Report"
|
|
4816
|
+
);
|
|
4964
4817
|
const headerRegex = /^M(\d{2})A([A-Z]{2})(\d{4})/;
|
|
4965
4818
|
const headerMatch = message.text.match(headerRegex);
|
|
4966
4819
|
if (!headerMatch) {
|
|
4967
|
-
|
|
4968
|
-
console.log(`Decoder: Unknown H1 M-POS message: ${message.text}`);
|
|
4969
|
-
}
|
|
4970
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
4971
|
-
decodeResult.decoded = false;
|
|
4972
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
4973
|
-
return decodeResult;
|
|
4820
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
4974
4821
|
}
|
|
4975
4822
|
const airline = headerMatch[2];
|
|
4976
4823
|
const flightNum = headerMatch[3];
|
|
4977
4824
|
const afterHeader = message.text.substring(headerMatch[0].length);
|
|
4978
4825
|
const fields = afterHeader.split(",");
|
|
4979
4826
|
if (fields.length < 7) {
|
|
4980
|
-
|
|
4981
|
-
decodeResult.decoded = false;
|
|
4982
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
4983
|
-
return decodeResult;
|
|
4827
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
4984
4828
|
}
|
|
4985
4829
|
ResultFormatter.flightNumber(decodeResult, `${airline}${flightNum}`);
|
|
4986
4830
|
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
@@ -5004,15 +4848,48 @@ var Label_H1_M_POS = class extends DecoderPlugin {
|
|
|
5004
4848
|
if (fields.length > 7) {
|
|
5005
4849
|
ResultFormatter.unknownArr(decodeResult, fields.slice(7));
|
|
5006
4850
|
}
|
|
5007
|
-
|
|
5008
|
-
|
|
4851
|
+
this.setDecodeLevel(
|
|
4852
|
+
decodeResult,
|
|
4853
|
+
true,
|
|
4854
|
+
fields.length > 7 ? "partial" : "full"
|
|
4855
|
+
);
|
|
5009
4856
|
return decodeResult;
|
|
5010
4857
|
}
|
|
5011
4858
|
};
|
|
5012
4859
|
|
|
4860
|
+
// lib/utils/compression.ts
|
|
4861
|
+
import * as pako from "pako";
|
|
4862
|
+
function inflateData(data, raw) {
|
|
4863
|
+
const chunks = [];
|
|
4864
|
+
const inflator = new pako.Inflate({ windowBits: raw ? -15 : 15 });
|
|
4865
|
+
inflator.onData = (chunk) => {
|
|
4866
|
+
chunks.push(chunk);
|
|
4867
|
+
};
|
|
4868
|
+
inflator.push(data, 2);
|
|
4869
|
+
if (chunks.length === 0) return void 0;
|
|
4870
|
+
if (chunks.length === 1) return chunks[0];
|
|
4871
|
+
const totalLen = chunks.reduce((sum, c) => sum + c.length, 0);
|
|
4872
|
+
const result = new Uint8Array(totalLen);
|
|
4873
|
+
let offset = 0;
|
|
4874
|
+
for (const chunk of chunks) {
|
|
4875
|
+
result.set(chunk, offset);
|
|
4876
|
+
offset += chunk.length;
|
|
4877
|
+
}
|
|
4878
|
+
return result;
|
|
4879
|
+
}
|
|
4880
|
+
function base64ToUint8Array(base64) {
|
|
4881
|
+
const cleaned = base64.replace(/-/g, "+").replace(/_/g, "/").replace(/[^A-Za-z0-9+/]/g, "");
|
|
4882
|
+
const padded = cleaned + "=".repeat((4 - cleaned.length % 4) % 4);
|
|
4883
|
+
const binary = atob(padded);
|
|
4884
|
+
const bytes = new Uint8Array(binary.length);
|
|
4885
|
+
for (let i = 0; i < binary.length; i++) {
|
|
4886
|
+
bytes[i] = binary.charCodeAt(i);
|
|
4887
|
+
}
|
|
4888
|
+
return bytes;
|
|
4889
|
+
}
|
|
4890
|
+
|
|
5013
4891
|
// lib/plugins/Label_H1_OHMA.ts
|
|
5014
|
-
|
|
5015
|
-
import { Buffer as Buffer2 } from "buffer";
|
|
4892
|
+
var textDecoder = new TextDecoder();
|
|
5016
4893
|
var Label_H1_OHMA = class extends DecoderPlugin {
|
|
5017
4894
|
name = "label-h1-ohma";
|
|
5018
4895
|
qualifiers() {
|
|
@@ -5028,12 +4905,12 @@ var Label_H1_OHMA = class extends DecoderPlugin {
|
|
|
5028
4905
|
decodeResult.message = message;
|
|
5029
4906
|
const data = message.text.split("OHMA")[1];
|
|
5030
4907
|
try {
|
|
5031
|
-
const compressedBuffer =
|
|
5032
|
-
const
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
const jsonText = result
|
|
4908
|
+
const compressedBuffer = base64ToUint8Array(data);
|
|
4909
|
+
const result = inflateData(compressedBuffer, false);
|
|
4910
|
+
if (!result || result.length === 0) {
|
|
4911
|
+
throw new Error("Decompression produced no output");
|
|
4912
|
+
}
|
|
4913
|
+
const jsonText = textDecoder.decode(result);
|
|
5037
4914
|
let formattedMsg;
|
|
5038
4915
|
let jsonMessage;
|
|
5039
4916
|
try {
|
|
@@ -5363,10 +5240,7 @@ var Label_H1_WRN = class extends DecoderPlugin {
|
|
|
5363
5240
|
};
|
|
5364
5241
|
}
|
|
5365
5242
|
decode(message, options = {}) {
|
|
5366
|
-
|
|
5367
|
-
decodeResult.decoder.name = this.name;
|
|
5368
|
-
decodeResult.formatted.description = "Warning Message";
|
|
5369
|
-
decodeResult.message = message;
|
|
5243
|
+
const decodeResult = this.initResult(message, "Warning Message");
|
|
5370
5244
|
const parts = message.text.split("/WN");
|
|
5371
5245
|
if (parts.length > 1) {
|
|
5372
5246
|
const fields = parts[0].split("/");
|
|
@@ -5387,15 +5261,9 @@ var Label_H1_WRN = class extends DecoderPlugin {
|
|
|
5387
5261
|
label: "Warning Message",
|
|
5388
5262
|
value: decodeResult.raw.warning_message
|
|
5389
5263
|
});
|
|
5390
|
-
decodeResult
|
|
5391
|
-
decodeResult.decoder.decodeLevel = "partial";
|
|
5264
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
5392
5265
|
} else {
|
|
5393
|
-
|
|
5394
|
-
console.log(`Decoder: Unknown H1 message: ${message.text}`);
|
|
5395
|
-
}
|
|
5396
|
-
ResultFormatter.unknown(decodeResult, message.text);
|
|
5397
|
-
decodeResult.decoded = false;
|
|
5398
|
-
decodeResult.decoder.decodeLevel = "none";
|
|
5266
|
+
return this.failUnknown(decodeResult, message.text, options);
|
|
5399
5267
|
}
|
|
5400
5268
|
return decodeResult;
|
|
5401
5269
|
}
|
|
@@ -5447,10 +5315,47 @@ var Label_HX = class extends DecoderPlugin {
|
|
|
5447
5315
|
}
|
|
5448
5316
|
};
|
|
5449
5317
|
|
|
5318
|
+
// lib/utils/ascii85.ts
|
|
5319
|
+
function ascii85Decode(input) {
|
|
5320
|
+
let str = input;
|
|
5321
|
+
if (str.startsWith("<~")) str = str.slice(2);
|
|
5322
|
+
if (str.endsWith("~>")) str = str.slice(0, -2);
|
|
5323
|
+
str = str.replace(/\s/g, "");
|
|
5324
|
+
if (str.length === 0) return new Uint8Array(0);
|
|
5325
|
+
const output = [];
|
|
5326
|
+
let i = 0;
|
|
5327
|
+
while (i < str.length) {
|
|
5328
|
+
if (str[i] === "z") {
|
|
5329
|
+
output.push(0, 0, 0, 0);
|
|
5330
|
+
i++;
|
|
5331
|
+
continue;
|
|
5332
|
+
}
|
|
5333
|
+
const remaining = str.length - i;
|
|
5334
|
+
const chunkLen = Math.min(5, remaining);
|
|
5335
|
+
if (chunkLen === 1) break;
|
|
5336
|
+
let padded = str.slice(i, i + chunkLen);
|
|
5337
|
+
while (padded.length < 5) padded += "u";
|
|
5338
|
+
let value = 0;
|
|
5339
|
+
for (let j = 0; j < 5; j++) {
|
|
5340
|
+
const digit = padded.charCodeAt(j) - 33;
|
|
5341
|
+
if (digit < 0 || digit > 84) return null;
|
|
5342
|
+
value = value * 85 + digit;
|
|
5343
|
+
}
|
|
5344
|
+
if (chunkLen === 5 && value > 4294967295) return null;
|
|
5345
|
+
const v = value >>> 0;
|
|
5346
|
+
const numBytes = chunkLen === 5 ? 4 : chunkLen - 1;
|
|
5347
|
+
if (numBytes >= 1) output.push(v >>> 24 & 255);
|
|
5348
|
+
if (numBytes >= 2) output.push(v >>> 16 & 255);
|
|
5349
|
+
if (numBytes >= 3) output.push(v >>> 8 & 255);
|
|
5350
|
+
if (numBytes >= 4) output.push(v & 255);
|
|
5351
|
+
i += chunkLen;
|
|
5352
|
+
}
|
|
5353
|
+
return new Uint8Array(output);
|
|
5354
|
+
}
|
|
5355
|
+
|
|
5450
5356
|
// lib/utils/miam.ts
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
import { Buffer as Buffer3 } from "buffer";
|
|
5357
|
+
var textDecoder2 = new TextDecoder();
|
|
5358
|
+
var textEncoder = new TextEncoder();
|
|
5454
5359
|
var MIAMVersion = /* @__PURE__ */ ((MIAMVersion2) => {
|
|
5455
5360
|
MIAMVersion2[MIAMVersion2["V1"] = 1] = "V1";
|
|
5456
5361
|
MIAMVersion2[MIAMVersion2["V2"] = 2] = "V2";
|
|
@@ -5537,7 +5442,7 @@ var MIAMCoreUtils = class {
|
|
|
5537
5442
|
error: "Empty MIAM message header"
|
|
5538
5443
|
};
|
|
5539
5444
|
}
|
|
5540
|
-
let hdr =
|
|
5445
|
+
let hdr = ascii85Decode("<~" + rawHdr + "~>");
|
|
5541
5446
|
if (!hdr || hdr.length < hpad) {
|
|
5542
5447
|
return {
|
|
5543
5448
|
decoded: false,
|
|
@@ -5549,17 +5454,24 @@ var MIAMCoreUtils = class {
|
|
|
5549
5454
|
if (rawBody.length > 0) {
|
|
5550
5455
|
if ("0123".indexOf(bpad) >= 0) {
|
|
5551
5456
|
const bpadValue = parseInt(bpad);
|
|
5552
|
-
|
|
5553
|
-
if (
|
|
5457
|
+
const decoded = ascii85Decode("<~" + rawBody + "~>");
|
|
5458
|
+
if (decoded === null) {
|
|
5459
|
+
return {
|
|
5460
|
+
decoded: false,
|
|
5461
|
+
error: "Ascii85 decode failed for MIAM message body"
|
|
5462
|
+
};
|
|
5463
|
+
}
|
|
5464
|
+
body = decoded;
|
|
5465
|
+
if (body.length >= bpadValue) {
|
|
5554
5466
|
body = body.subarray(0, body.length - bpadValue);
|
|
5555
5467
|
}
|
|
5556
5468
|
} else if (bpad === "-") {
|
|
5557
|
-
body =
|
|
5469
|
+
body = textEncoder.encode(rawBody);
|
|
5558
5470
|
}
|
|
5559
5471
|
}
|
|
5560
5472
|
hdr = hdr.subarray(0, hdr.length - hpad);
|
|
5561
|
-
const version = hdr
|
|
5562
|
-
const pduType = hdr
|
|
5473
|
+
const version = hdr[0] & 15;
|
|
5474
|
+
const pduType = hdr[0] >> 4 & 15;
|
|
5563
5475
|
if (isMIAMVersion(version) && isMIAMCorePdu(pduType)) {
|
|
5564
5476
|
const versionPduHandler = this.VersionPduHandlerTable[version][pduType];
|
|
5565
5477
|
return versionPduHandler(hdr, body);
|
|
@@ -5856,7 +5768,7 @@ var MIAMCoreUtils = class {
|
|
|
5856
5768
|
];
|
|
5857
5769
|
let crc = (seed || 0) & 65535;
|
|
5858
5770
|
for (let i = 0; i < buf.length; i++) {
|
|
5859
|
-
crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 8 ^ buf
|
|
5771
|
+
crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 8 ^ buf[i]) >>> 0 & 255]) >>> 0;
|
|
5860
5772
|
}
|
|
5861
5773
|
return crc & 65535;
|
|
5862
5774
|
}
|
|
@@ -6121,7 +6033,7 @@ var MIAMCoreUtils = class {
|
|
|
6121
6033
|
];
|
|
6122
6034
|
let crc = seed || 0;
|
|
6123
6035
|
for (let i = 0; i < buf.length; i++) {
|
|
6124
|
-
crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 24 ^ buf
|
|
6036
|
+
crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 24 ^ buf[i]) >>> 0]) >>> 0;
|
|
6125
6037
|
}
|
|
6126
6038
|
return crc;
|
|
6127
6039
|
}
|
|
@@ -6158,7 +6070,7 @@ var MIAMCoreUtils = class {
|
|
|
6158
6070
|
let msgNum = 0;
|
|
6159
6071
|
let ackOptions = 0;
|
|
6160
6072
|
if (version === 1 /* V1 */) {
|
|
6161
|
-
pduSize = hdr
|
|
6073
|
+
pduSize = hdr[1] << 16 | hdr[2] << 8 | hdr[3];
|
|
6162
6074
|
const msgSize = hdr.length + (body === void 0 ? 0 : body.length);
|
|
6163
6075
|
if (pduSize > msgSize) {
|
|
6164
6076
|
pduIsComplete = false;
|
|
@@ -6167,17 +6079,17 @@ var MIAMCoreUtils = class {
|
|
|
6167
6079
|
);
|
|
6168
6080
|
}
|
|
6169
6081
|
hdr = hdr.subarray(4);
|
|
6170
|
-
tail = hdr.subarray(0, 7)
|
|
6082
|
+
tail = textDecoder2.decode(hdr.subarray(0, 7));
|
|
6171
6083
|
hdr = hdr.subarray(7);
|
|
6172
6084
|
} else if (version === 2 /* V2 */) {
|
|
6173
6085
|
hdr = hdr.subarray(1);
|
|
6174
6086
|
}
|
|
6175
|
-
msgNum = hdr
|
|
6176
|
-
ackOptions = hdr
|
|
6087
|
+
msgNum = hdr[0] >> 1 & 127;
|
|
6088
|
+
ackOptions = hdr[0] & 1;
|
|
6177
6089
|
hdr = hdr.subarray(1);
|
|
6178
|
-
pduCompression = (hdr
|
|
6179
|
-
pduEncoding = hdr
|
|
6180
|
-
pduAppType = hdr
|
|
6090
|
+
pduCompression = (hdr[0] << 2 | hdr[1] >> 6 & 3) & 7;
|
|
6091
|
+
pduEncoding = hdr[1] >> 4 & 3;
|
|
6092
|
+
pduAppType = hdr[1] & 15;
|
|
6181
6093
|
hdr = hdr.subarray(2);
|
|
6182
6094
|
let appIdLen;
|
|
6183
6095
|
if (isMIAMCoreApp(pduAppType)) {
|
|
@@ -6203,12 +6115,12 @@ var MIAMCoreUtils = class {
|
|
|
6203
6115
|
error: "Header too short for v" + version + " appType: " + pduAppType
|
|
6204
6116
|
};
|
|
6205
6117
|
}
|
|
6206
|
-
pduAppId = hdr.subarray(0, appIdLen)
|
|
6118
|
+
pduAppId = textDecoder2.decode(hdr.subarray(0, appIdLen));
|
|
6207
6119
|
hdr = hdr.subarray(appIdLen);
|
|
6208
6120
|
if (crcLen === 4) {
|
|
6209
|
-
pduCrc = hdr
|
|
6121
|
+
pduCrc = hdr[0] << 24 | hdr[1] << 16 | hdr[2] << 8 | hdr[3];
|
|
6210
6122
|
} else if (crcLen === 2) {
|
|
6211
|
-
pduCrc = hdr
|
|
6123
|
+
pduCrc = hdr[0] << 8 | hdr[1];
|
|
6212
6124
|
}
|
|
6213
6125
|
hdr = hdr.subarray(crcLen);
|
|
6214
6126
|
if (body !== void 0 && body.length > 0) {
|
|
@@ -6216,10 +6128,12 @@ var MIAMCoreUtils = class {
|
|
|
6216
6128
|
pduCompression
|
|
6217
6129
|
) >= 0) {
|
|
6218
6130
|
try {
|
|
6219
|
-
const
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6131
|
+
const inflated = inflateData(body, true);
|
|
6132
|
+
if (inflated === void 0) {
|
|
6133
|
+
pduErrors.push("Inflation produced no output for body");
|
|
6134
|
+
} else {
|
|
6135
|
+
pduData = inflated;
|
|
6136
|
+
}
|
|
6223
6137
|
} catch (e) {
|
|
6224
6138
|
pduErrors.push("Inflation failed for body: " + e);
|
|
6225
6139
|
}
|
|
@@ -6277,12 +6191,12 @@ var MIAMCoreUtils = class {
|
|
|
6277
6191
|
label,
|
|
6278
6192
|
...sublabel ? { sublabel } : {},
|
|
6279
6193
|
...mfi ? { mfi } : {},
|
|
6280
|
-
...pduData ? { text:
|
|
6194
|
+
...pduData ? { text: textDecoder2.decode(pduData) } : {}
|
|
6281
6195
|
};
|
|
6282
6196
|
} else {
|
|
6283
6197
|
pdu.non_acars = {
|
|
6284
6198
|
appId: pduAppId,
|
|
6285
|
-
...pduData ? { text:
|
|
6199
|
+
...pduData ? { text: textDecoder2.decode(pduData) } : {}
|
|
6286
6200
|
};
|
|
6287
6201
|
}
|
|
6288
6202
|
return {
|
|
@@ -6403,12 +6317,11 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
6403
6317
|
};
|
|
6404
6318
|
}
|
|
6405
6319
|
decode(message, options = {}) {
|
|
6406
|
-
const decodeResult = this.
|
|
6407
|
-
decodeResult.decoder.name = this.name;
|
|
6320
|
+
const decodeResult = this.initResult(message, "Ground Station Squitter");
|
|
6408
6321
|
decodeResult.raw.preamble = message.text.substring(0, 4);
|
|
6409
|
-
decodeResult.raw.version = message.text.substring(1, 2);
|
|
6322
|
+
decodeResult.raw.version = Number(message.text.substring(1, 2));
|
|
6410
6323
|
decodeResult.raw.network = message.text.substring(3, 4);
|
|
6411
|
-
if (decodeResult.raw.version ===
|
|
6324
|
+
if (decodeResult.raw.version === 2) {
|
|
6412
6325
|
const regex = /0(\d)X(?<org>\w)(?<iata>\w\w\w)(?<icao>\w\w\w\w)(?<station>\d)(?<lat>\d+)(?<latd>[NS])(?<lng>\d+)(?<lngd>[EW])V(?<vfreq>\d+)\/.*/;
|
|
6413
6326
|
const result = message.text.match(regex);
|
|
6414
6327
|
if (result?.groups && result.length >= 8) {
|
|
@@ -6424,7 +6337,6 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
6424
6337
|
decodeResult.raw.vdlFrequency = Number(result.groups.vfreq) / 1e3;
|
|
6425
6338
|
}
|
|
6426
6339
|
}
|
|
6427
|
-
decodeResult.formatted.description = "Ground Station Squitter";
|
|
6428
6340
|
var formattedNetwork = "Unknown";
|
|
6429
6341
|
if (decodeResult.raw.network == "A") {
|
|
6430
6342
|
formattedNetwork = "ARINC";
|
|
@@ -6442,7 +6354,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
6442
6354
|
type: "version",
|
|
6443
6355
|
code: "VER",
|
|
6444
6356
|
label: "Version",
|
|
6445
|
-
value: decodeResult.raw.version
|
|
6357
|
+
value: String(decodeResult.raw.version)
|
|
6446
6358
|
}
|
|
6447
6359
|
];
|
|
6448
6360
|
if (decodeResult.raw.groundStation) {
|
|
@@ -6495,8 +6407,7 @@ var Label_SQ = class extends DecoderPlugin {
|
|
|
6495
6407
|
value: `${decodeResult.raw.vdlFrequency} MHz`
|
|
6496
6408
|
});
|
|
6497
6409
|
}
|
|
6498
|
-
decodeResult
|
|
6499
|
-
decodeResult.decoder.decodeLevel = "full";
|
|
6410
|
+
this.setDecodeLevel(decodeResult, true, "full");
|
|
6500
6411
|
return decodeResult;
|
|
6501
6412
|
}
|
|
6502
6413
|
};
|
|
@@ -6648,103 +6559,130 @@ var Label_QQ = class extends DecoderPlugin {
|
|
|
6648
6559
|
};
|
|
6649
6560
|
|
|
6650
6561
|
// lib/MessageDecoder.ts
|
|
6562
|
+
var pluginClasses = [
|
|
6563
|
+
CBand,
|
|
6564
|
+
Arinc702,
|
|
6565
|
+
Label_ColonComma,
|
|
6566
|
+
Label_5Z_Slash,
|
|
6567
|
+
Label_10_LDR,
|
|
6568
|
+
Label_10_POS,
|
|
6569
|
+
Label_10_Slash,
|
|
6570
|
+
Label_12_N_Space,
|
|
6571
|
+
Label_12_POS,
|
|
6572
|
+
Label_13Through18_Slash,
|
|
6573
|
+
Label_15,
|
|
6574
|
+
Label_15_FST,
|
|
6575
|
+
Label_16_Honeywell,
|
|
6576
|
+
Label_16_N_Space,
|
|
6577
|
+
Label_16_POSA1,
|
|
6578
|
+
Label_16_TOD,
|
|
6579
|
+
Label_1L_3Line,
|
|
6580
|
+
Label_1L_070,
|
|
6581
|
+
Label_1L_660,
|
|
6582
|
+
Label_1L_Slash,
|
|
6583
|
+
Label_20_POS,
|
|
6584
|
+
Label_21_POS,
|
|
6585
|
+
Label_22_OFF,
|
|
6586
|
+
Label_22_POS,
|
|
6587
|
+
Label_24_Slash,
|
|
6588
|
+
Label_2P_FM3,
|
|
6589
|
+
Label_2P_FM4,
|
|
6590
|
+
Label_2P_FM5,
|
|
6591
|
+
Label_30_Slash_EA,
|
|
6592
|
+
Label_44_ETA,
|
|
6593
|
+
Label_44_IN,
|
|
6594
|
+
Label_44_OFF,
|
|
6595
|
+
Label_44_ON,
|
|
6596
|
+
Label_44_POS,
|
|
6597
|
+
Label_44_Slash,
|
|
6598
|
+
Label_4A,
|
|
6599
|
+
Label_4A_01,
|
|
6600
|
+
Label_4A_DIS,
|
|
6601
|
+
Label_4A_DOOR,
|
|
6602
|
+
Label_4A_Slash_01,
|
|
6603
|
+
Label_4N,
|
|
6604
|
+
Label_4T_AGFSR,
|
|
6605
|
+
Label_4T_ETA,
|
|
6606
|
+
Label_B6_Forwardslash,
|
|
6607
|
+
Label_H2_02E,
|
|
6608
|
+
Label_H1_ATIS,
|
|
6609
|
+
Label_H1_EZF,
|
|
6610
|
+
Label_H1_FLR,
|
|
6611
|
+
Label_H1_M_POS,
|
|
6612
|
+
Label_H1_OHMA,
|
|
6613
|
+
Label_H1_OFP,
|
|
6614
|
+
Label_H1_Paren,
|
|
6615
|
+
Label_H1_WRN,
|
|
6616
|
+
Label_H1_StarPOS,
|
|
6617
|
+
Label_HX,
|
|
6618
|
+
Label_58,
|
|
6619
|
+
Label_80,
|
|
6620
|
+
Label_83,
|
|
6621
|
+
Label_8E,
|
|
6622
|
+
Label_1M_Slash,
|
|
6623
|
+
Label_MA,
|
|
6624
|
+
Label_SQ,
|
|
6625
|
+
Label_QP,
|
|
6626
|
+
Label_QQ,
|
|
6627
|
+
Label_QR,
|
|
6628
|
+
Label_QS
|
|
6629
|
+
];
|
|
6651
6630
|
var MessageDecoder = class {
|
|
6652
6631
|
name;
|
|
6653
6632
|
plugins;
|
|
6654
6633
|
debug;
|
|
6634
|
+
/** Maps a label string to the candidate entries (wildcard + label-specific) in registration order. */
|
|
6635
|
+
candidatesByLabel = /* @__PURE__ */ new Map();
|
|
6636
|
+
/** Wildcard entries (plugins that register the '*' label). */
|
|
6637
|
+
wildcardEntries = [];
|
|
6638
|
+
/** Membership set for wildcard entries to dedupe when a plugin also registers a specific label. */
|
|
6639
|
+
wildcardSet = /* @__PURE__ */ new Set();
|
|
6655
6640
|
constructor() {
|
|
6656
6641
|
this.name = "acars-decoder-typescript";
|
|
6657
6642
|
this.plugins = [];
|
|
6658
6643
|
this.debug = false;
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
this.registerPlugin(new Label_5Z_Slash(this));
|
|
6663
|
-
this.registerPlugin(new Label_10_LDR(this));
|
|
6664
|
-
this.registerPlugin(new Label_10_POS(this));
|
|
6665
|
-
this.registerPlugin(new Label_10_Slash(this));
|
|
6666
|
-
this.registerPlugin(new Label_12_N_Space(this));
|
|
6667
|
-
this.registerPlugin(new Label_12_POS(this));
|
|
6668
|
-
this.registerPlugin(new Label_13Through18_Slash(this));
|
|
6669
|
-
this.registerPlugin(new Label_15(this));
|
|
6670
|
-
this.registerPlugin(new Label_15_FST(this));
|
|
6671
|
-
this.registerPlugin(new Label_16_Honeywell(this));
|
|
6672
|
-
this.registerPlugin(new Label_16_N_Space(this));
|
|
6673
|
-
this.registerPlugin(new Label_16_POSA1(this));
|
|
6674
|
-
this.registerPlugin(new Label_16_TOD(this));
|
|
6675
|
-
this.registerPlugin(new Label_1L_3Line(this));
|
|
6676
|
-
this.registerPlugin(new Label_1L_070(this));
|
|
6677
|
-
this.registerPlugin(new Label_1L_660(this));
|
|
6678
|
-
this.registerPlugin(new Label_1L_Slash(this));
|
|
6679
|
-
this.registerPlugin(new Label_20_POS(this));
|
|
6680
|
-
this.registerPlugin(new Label_21_POS(this));
|
|
6681
|
-
this.registerPlugin(new Label_22_OFF(this));
|
|
6682
|
-
this.registerPlugin(new Label_22_POS(this));
|
|
6683
|
-
this.registerPlugin(new Label_24_Slash(this));
|
|
6684
|
-
this.registerPlugin(new Label_2P_FM3(this));
|
|
6685
|
-
this.registerPlugin(new Label_2P_FM4(this));
|
|
6686
|
-
this.registerPlugin(new Label_2P_FM5(this));
|
|
6687
|
-
this.registerPlugin(new Label_30_Slash_EA(this));
|
|
6688
|
-
this.registerPlugin(new Label_44_ETA(this));
|
|
6689
|
-
this.registerPlugin(new Label_44_IN(this));
|
|
6690
|
-
this.registerPlugin(new Label_44_OFF(this));
|
|
6691
|
-
this.registerPlugin(new Label_44_ON(this));
|
|
6692
|
-
this.registerPlugin(new Label_44_POS(this));
|
|
6693
|
-
this.registerPlugin(new Label_44_Slash(this));
|
|
6694
|
-
this.registerPlugin(new Label_4A(this));
|
|
6695
|
-
this.registerPlugin(new Label_4A_01(this));
|
|
6696
|
-
this.registerPlugin(new Label_4A_DIS(this));
|
|
6697
|
-
this.registerPlugin(new Label_4A_DOOR(this));
|
|
6698
|
-
this.registerPlugin(new Label_4A_Slash_01(this));
|
|
6699
|
-
this.registerPlugin(new Label_4N(this));
|
|
6700
|
-
this.registerPlugin(new Label_4T_AGFSR(this));
|
|
6701
|
-
this.registerPlugin(new Label_4T_ETA(this));
|
|
6702
|
-
this.registerPlugin(new Label_B6_Forwardslash(this));
|
|
6703
|
-
this.registerPlugin(new Label_H2_02E(this));
|
|
6704
|
-
this.registerPlugin(new Label_H1_ATIS(this));
|
|
6705
|
-
this.registerPlugin(new Label_H1_EZF(this));
|
|
6706
|
-
this.registerPlugin(new Label_H1_FLR(this));
|
|
6707
|
-
this.registerPlugin(new Label_H1_M_POS(this));
|
|
6708
|
-
this.registerPlugin(new Label_H1_OHMA(this));
|
|
6709
|
-
this.registerPlugin(new Label_H1_OFP(this));
|
|
6710
|
-
this.registerPlugin(new Label_H1_Paren(this));
|
|
6711
|
-
this.registerPlugin(new Label_H1_WRN(this));
|
|
6712
|
-
this.registerPlugin(new Label_H1_StarPOS(this));
|
|
6713
|
-
this.registerPlugin(new Label_HX(this));
|
|
6714
|
-
this.registerPlugin(new Label_58(this));
|
|
6715
|
-
this.registerPlugin(new Label_80(this));
|
|
6716
|
-
this.registerPlugin(new Label_83(this));
|
|
6717
|
-
this.registerPlugin(new Label_8E(this));
|
|
6718
|
-
this.registerPlugin(new Label_1M_Slash(this));
|
|
6719
|
-
this.registerPlugin(new Label_MA(this));
|
|
6720
|
-
this.registerPlugin(new Label_SQ(this));
|
|
6721
|
-
this.registerPlugin(new Label_QP(this));
|
|
6722
|
-
this.registerPlugin(new Label_QQ(this));
|
|
6723
|
-
this.registerPlugin(new Label_QR(this));
|
|
6724
|
-
this.registerPlugin(new Label_QS(this));
|
|
6644
|
+
for (const PluginClass of pluginClasses) {
|
|
6645
|
+
this.registerPlugin(new PluginClass(this));
|
|
6646
|
+
}
|
|
6725
6647
|
}
|
|
6726
6648
|
registerPlugin(plugin) {
|
|
6727
6649
|
this.plugins.push(plugin);
|
|
6650
|
+
const qualifiers = plugin.qualifiers();
|
|
6651
|
+
const entry = {
|
|
6652
|
+
plugin,
|
|
6653
|
+
preambles: qualifiers.preambles && qualifiers.preambles.length > 0 ? qualifiers.preambles : void 0
|
|
6654
|
+
};
|
|
6655
|
+
for (const label of qualifiers.labels) {
|
|
6656
|
+
if (label === "*") {
|
|
6657
|
+
if (!this.wildcardSet.has(plugin)) {
|
|
6658
|
+
this.wildcardEntries.push(entry);
|
|
6659
|
+
this.wildcardSet.add(plugin);
|
|
6660
|
+
const wildcardInsertIndex = this.wildcardEntries.length - 1;
|
|
6661
|
+
for (const bucket of this.candidatesByLabel.values()) {
|
|
6662
|
+
bucket.splice(wildcardInsertIndex, 0, entry);
|
|
6663
|
+
}
|
|
6664
|
+
}
|
|
6665
|
+
} else {
|
|
6666
|
+
let bucket = this.candidatesByLabel.get(label);
|
|
6667
|
+
if (!bucket) {
|
|
6668
|
+
bucket = this.wildcardEntries.slice();
|
|
6669
|
+
this.candidatesByLabel.set(label, bucket);
|
|
6670
|
+
}
|
|
6671
|
+
if (!this.wildcardSet.has(plugin)) {
|
|
6672
|
+
bucket.push(entry);
|
|
6673
|
+
}
|
|
6674
|
+
}
|
|
6675
|
+
}
|
|
6728
6676
|
return true;
|
|
6729
6677
|
}
|
|
6730
6678
|
decode(message, options = {}) {
|
|
6731
|
-
const
|
|
6732
|
-
|
|
6733
|
-
if (qualifiers.labels.includes(message.label) || qualifiers.labels.length === 1 && qualifiers.labels[0] === "*") {
|
|
6734
|
-
if (qualifiers.preambles && qualifiers.preambles.length > 0) {
|
|
6735
|
-
const matching = qualifiers.preambles.filter((preamble) => {
|
|
6736
|
-
return message.text.substring(0, preamble.length) === preamble;
|
|
6737
|
-
});
|
|
6738
|
-
return matching.length >= 1;
|
|
6739
|
-
} else {
|
|
6740
|
-
return true;
|
|
6741
|
-
}
|
|
6742
|
-
}
|
|
6743
|
-
return false;
|
|
6744
|
-
});
|
|
6679
|
+
const text = message.text;
|
|
6680
|
+
const candidates = this.candidatesByLabel.get(message.label) ?? this.wildcardEntries;
|
|
6745
6681
|
if (options.debug) {
|
|
6746
6682
|
console.log("Usable plugins");
|
|
6747
|
-
console.log(
|
|
6683
|
+
console.log(
|
|
6684
|
+
candidates.filter((e) => this.matchesPreambles(text, e.preambles)).map((e) => e.plugin)
|
|
6685
|
+
);
|
|
6748
6686
|
}
|
|
6749
6687
|
let result = {
|
|
6750
6688
|
decoded: false,
|
|
@@ -6756,7 +6694,7 @@ var MessageDecoder = class {
|
|
|
6756
6694
|
},
|
|
6757
6695
|
message,
|
|
6758
6696
|
remaining: {
|
|
6759
|
-
text
|
|
6697
|
+
text
|
|
6760
6698
|
},
|
|
6761
6699
|
raw: {},
|
|
6762
6700
|
formatted: {
|
|
@@ -6764,10 +6702,14 @@ var MessageDecoder = class {
|
|
|
6764
6702
|
items: []
|
|
6765
6703
|
}
|
|
6766
6704
|
};
|
|
6767
|
-
for (let i = 0; i <
|
|
6768
|
-
const
|
|
6769
|
-
|
|
6770
|
-
|
|
6705
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
6706
|
+
const entry = candidates[i];
|
|
6707
|
+
if (!this.matchesPreambles(text, entry.preambles)) {
|
|
6708
|
+
continue;
|
|
6709
|
+
}
|
|
6710
|
+
const pluginResult = entry.plugin.decode(message, options);
|
|
6711
|
+
if (pluginResult.decoded) {
|
|
6712
|
+
result = pluginResult;
|
|
6771
6713
|
break;
|
|
6772
6714
|
}
|
|
6773
6715
|
}
|
|
@@ -6777,6 +6719,17 @@ var MessageDecoder = class {
|
|
|
6777
6719
|
}
|
|
6778
6720
|
return result;
|
|
6779
6721
|
}
|
|
6722
|
+
matchesPreambles(text, preambles) {
|
|
6723
|
+
if (!preambles) {
|
|
6724
|
+
return true;
|
|
6725
|
+
}
|
|
6726
|
+
for (let i = 0; i < preambles.length; i++) {
|
|
6727
|
+
if (text.startsWith(preambles[i])) {
|
|
6728
|
+
return true;
|
|
6729
|
+
}
|
|
6730
|
+
}
|
|
6731
|
+
return false;
|
|
6732
|
+
}
|
|
6780
6733
|
};
|
|
6781
6734
|
export {
|
|
6782
6735
|
IcaoDecoder,
|