asterix-parser 1.0.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 +21 -0
- package/README.md +36 -0
- package/build/src/main/app.d.ts +8 -0
- package/build/src/main/app.js +66 -0
- package/build/src/main/data/uap/cat021.d.ts +6 -0
- package/build/src/main/data/uap/cat021.js +216 -0
- package/build/src/main/util/common.d.ts +27 -0
- package/build/src/main/util/common.js +79 -0
- package/build/src/main/util/preprocess.d.ts +33 -0
- package/build/src/main/util/preprocess.js +82 -0
- package/build/src/main/util/process/cat021.d.ts +13 -0
- package/build/src/main/util/process/cat021.js +1785 -0
- package/build/src/main/util/varlen/cat021.d.ts +9 -0
- package/build/src/main/util/varlen/cat021.js +235 -0
- package/build/src/test/app.test.d.ts +1 -0
- package/build/src/test/app.test.js +14 -0
- package/jest.config.js +9 -0
- package/package.json +43 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,1785 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cat021Process = void 0;
|
|
4
|
+
const common_1 = require("../common");
|
|
5
|
+
const preprocess_1 = require("../preprocess");
|
|
6
|
+
/**
|
|
7
|
+
* CAT 021 파싱
|
|
8
|
+
* @param record 단일 Record 파싱 결과
|
|
9
|
+
* @param bitArr Asterix 바이트 데이터
|
|
10
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
11
|
+
* @param dataItem 데이터 아이템 이름
|
|
12
|
+
* @param diLength 데이터 아이템 길이
|
|
13
|
+
*/
|
|
14
|
+
const cat021Process = (record, bitArr, currentPos, dataItem, diLength) => {
|
|
15
|
+
switch (dataItem) {
|
|
16
|
+
case "di008": {
|
|
17
|
+
di008(record, bitArr, currentPos);
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
case "di010": {
|
|
21
|
+
di010(record, bitArr, currentPos);
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
case "di015": {
|
|
25
|
+
di015(record, bitArr, currentPos);
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
case "di016": {
|
|
29
|
+
di016(record, bitArr, currentPos);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
case "di020": {
|
|
33
|
+
di020(record, bitArr, currentPos);
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case "di040": {
|
|
37
|
+
di040(record, bitArr, currentPos);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case "di070": {
|
|
41
|
+
di070(record, bitArr, currentPos);
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
case "di071": {
|
|
45
|
+
di071(record, bitArr, currentPos);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case "di072": {
|
|
49
|
+
di072(record, bitArr, currentPos);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case "di073": {
|
|
53
|
+
di073(record, bitArr, currentPos);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case "di074": {
|
|
57
|
+
di074(record, bitArr, currentPos);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case "di075": {
|
|
61
|
+
di075(record, bitArr, currentPos);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case "di076": {
|
|
65
|
+
di076(record, bitArr, currentPos);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case "di077": {
|
|
69
|
+
di077(record, bitArr, currentPos);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case "di080": {
|
|
73
|
+
di080(record, bitArr, currentPos);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
case "di090": {
|
|
77
|
+
di090(record, bitArr, currentPos);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case "di110": {
|
|
81
|
+
di110(record, bitArr, currentPos);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case "di130": {
|
|
85
|
+
di130(record, bitArr, currentPos);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "di131": {
|
|
89
|
+
di131(record, bitArr, currentPos);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case "di132": {
|
|
93
|
+
di132(record, bitArr, currentPos);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
case "di140": {
|
|
97
|
+
di140(record, bitArr, currentPos);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case "di145": {
|
|
101
|
+
di145(record, bitArr, currentPos);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case "di146": {
|
|
105
|
+
di146(record, bitArr, currentPos);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case "di148": {
|
|
109
|
+
di148(record, bitArr, currentPos);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case "di150": {
|
|
113
|
+
di150(record, bitArr, currentPos);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case "di151": {
|
|
117
|
+
di151(record, bitArr, currentPos);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case "di152": {
|
|
121
|
+
di152(record, bitArr, currentPos);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
case "di155": {
|
|
125
|
+
di155(record, bitArr, currentPos);
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case "di157": {
|
|
129
|
+
di157(record, bitArr, currentPos);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case "di160": {
|
|
133
|
+
di160(record, bitArr, currentPos);
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case "di161": {
|
|
137
|
+
di161(record, bitArr, currentPos);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case "di165": {
|
|
141
|
+
di165(record, bitArr, currentPos);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case "di170": {
|
|
145
|
+
di170(record, bitArr, currentPos);
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case "di200": {
|
|
149
|
+
di200(record, bitArr, currentPos);
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "di210": {
|
|
153
|
+
di210(record, bitArr, currentPos);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
case "di220": {
|
|
157
|
+
di220(record, bitArr, currentPos);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case "di230": {
|
|
161
|
+
di230(record, bitArr, currentPos);
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case "di250": {
|
|
165
|
+
di250(record, bitArr, currentPos);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
case "di260": {
|
|
169
|
+
di260(record, bitArr, currentPos);
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
case "di271": {
|
|
173
|
+
di271(record, bitArr, currentPos);
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
case "di295": {
|
|
177
|
+
di295(record, bitArr, currentPos);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
case "di400": {
|
|
181
|
+
di400(record, bitArr, currentPos);
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
case "SP": {
|
|
185
|
+
sp(record, bitArr, currentPos, diLength);
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case "RE": {
|
|
189
|
+
re(record, bitArr, currentPos, diLength);
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
default:
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
exports.cat021Process = cat021Process;
|
|
197
|
+
/**
|
|
198
|
+
* Data Item I021/008, Aircraft Operational Status
|
|
199
|
+
* 비행 중 항공기에서 이용 가능한 서비스 확인
|
|
200
|
+
* @param record 단일 Record 파싱 결과
|
|
201
|
+
* @param bitArr Asterix 바이트 데이터
|
|
202
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
203
|
+
*/
|
|
204
|
+
const di008 = (record, bitArr, currentPos) => {
|
|
205
|
+
const octet1 = bitArr[currentPos];
|
|
206
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
207
|
+
record["021_008_RA"] = "TCAS II or ACAS RA not active (0)";
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
record["021_008_RA"] = "TCAS RA active (1)";
|
|
211
|
+
}
|
|
212
|
+
const tcOctet = (0, common_1.octetOfRange)(octet1, 6, 5, 1);
|
|
213
|
+
switch (tcOctet) {
|
|
214
|
+
case 0:
|
|
215
|
+
record["021_008_TC"] = "no capability for Trajectory Change Reports (0)";
|
|
216
|
+
break;
|
|
217
|
+
case 1:
|
|
218
|
+
record["021_008_TC"] = "support for TC+0 reports only (1)";
|
|
219
|
+
break;
|
|
220
|
+
case 2:
|
|
221
|
+
record["021_008_TC"] = "support for multiple TC reports (2)";
|
|
222
|
+
break;
|
|
223
|
+
case 3:
|
|
224
|
+
record["021_008_TC"] = "reserved (3)";
|
|
225
|
+
break;
|
|
226
|
+
default:
|
|
227
|
+
record["021_008_TC"] = "UNDEFINED";
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
if ((octet1 & (1 << 4)) === 0) {
|
|
231
|
+
record["021_008_TS"] = "no capability to support Target State Reports (0)";
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
record["021_008_TS"] = "capable of supporting target State Reports (1)";
|
|
235
|
+
}
|
|
236
|
+
if ((octet1 & (1 << 3)) === 0) {
|
|
237
|
+
record["021_008_ARV"] = "no capability to generate ARV-reports (0)";
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
record["021_008_ARV"] = "capable of generate ARV-reports (1)";
|
|
241
|
+
}
|
|
242
|
+
if ((octet1 & (1 << 2)) === 0) {
|
|
243
|
+
record["021_008_CDTI/A"] = "CDTI not operational (0)";
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
record["021_008_CDTI/A"] = "CDTI operational (1)";
|
|
247
|
+
}
|
|
248
|
+
if ((octet1 & (1 << 1)) === 0) {
|
|
249
|
+
record["021_008_Not TCAS"] = "TCAS operational (0)";
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
record["021_008_Not TCAS"] = "TCAS not operational (1)";
|
|
253
|
+
}
|
|
254
|
+
if ((octet1 & (1 << 0)) === 0) {
|
|
255
|
+
record["021_008_SA"] = "Antenna Diversity (0)";
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
record["021_008_SA"] = "Single Antenna only (1)";
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* Data Item I021/010, Data Source Identifier
|
|
263
|
+
* 데이터를 수신받은 시스템의 ID 값
|
|
264
|
+
* 고정 길이, 2 octet
|
|
265
|
+
* @param record 단일 Record 파싱 결과
|
|
266
|
+
* @param bitArr Asterix 바이트 데이터
|
|
267
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
268
|
+
*/
|
|
269
|
+
const di010 = (record, bitArr, currentPos) => {
|
|
270
|
+
const octet1 = bitArr[currentPos++];
|
|
271
|
+
const octet2 = bitArr[currentPos++];
|
|
272
|
+
record["021_010_SAC"] = octet1;
|
|
273
|
+
record["021_010_SIC"] = octet2;
|
|
274
|
+
};
|
|
275
|
+
/**
|
|
276
|
+
* Data Item I021/015, Service Identification
|
|
277
|
+
* 한 명 이상의 사용자에게 제공한 서비스의 ID 값
|
|
278
|
+
* 고정 길이, 1 octet
|
|
279
|
+
* @param record 단일 Record 파싱 결과
|
|
280
|
+
* @param bitArr Asterix 바이트 데이터
|
|
281
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
282
|
+
*/
|
|
283
|
+
const di015 = (record, bitArr, currentPos) => {
|
|
284
|
+
const octet = bitArr[currentPos];
|
|
285
|
+
record["021_015_Service Identification"] = octet;
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* Data Item I021/016, Service Management
|
|
289
|
+
* 지상국 (SIC 코드로 식별됨)에서 제공하는 서비스 식별
|
|
290
|
+
* 고정 길이, 1 octet
|
|
291
|
+
* LSB(스케일링 계수): 0.5 s
|
|
292
|
+
* @param record 단일 Record 파싱 결과
|
|
293
|
+
* @param bitArr Asterix 바이트 데이터
|
|
294
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
295
|
+
*/
|
|
296
|
+
const di016 = (record, bitArr, currentPos) => {
|
|
297
|
+
const octet = bitArr[currentPos];
|
|
298
|
+
const rpValue = octet * 0.5;
|
|
299
|
+
record["021_016_RP"] = (rpValue === 0) ? "Data driven mode" : rpValue;
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* Data Item I021/020, Emitter Category
|
|
303
|
+
* 송신(출발지) ADS-B 장치의 특성
|
|
304
|
+
* 고정 길이, 1 octet
|
|
305
|
+
* @param record 단일 Record 파싱 결과
|
|
306
|
+
* @param bitArr Asterix 바이트 데이터
|
|
307
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
308
|
+
*/
|
|
309
|
+
const di020 = (record, bitArr, currentPos) => {
|
|
310
|
+
const octet = bitArr[currentPos];
|
|
311
|
+
switch (octet) {
|
|
312
|
+
case 0:
|
|
313
|
+
record["021_020_ECAT"] = "No ADS-B Emitter Category Information (0)";
|
|
314
|
+
break;
|
|
315
|
+
case 1:
|
|
316
|
+
record["021_020_ECAT"] = "light aircraft <= 15500 lbs (1)";
|
|
317
|
+
break;
|
|
318
|
+
case 2:
|
|
319
|
+
record["021_020_ECAT"] = "15500 lbs < small aircraft < 75000 lbs (2)";
|
|
320
|
+
break;
|
|
321
|
+
case 3:
|
|
322
|
+
record["021_020_ECAT"] = "75000 lbs < medium a/c < 300000 lbs (3)";
|
|
323
|
+
break;
|
|
324
|
+
case 4:
|
|
325
|
+
record["021_020_ECAT"] = "High Vortex Large (4)";
|
|
326
|
+
break;
|
|
327
|
+
case 5:
|
|
328
|
+
record["021_020_ECAT"] = "300000 lbs <= heavy aircraft (5)";
|
|
329
|
+
break;
|
|
330
|
+
case 6:
|
|
331
|
+
record["021_020_ECAT"] = "highly manoeuvrable (5g acceleration capability) and high speed (> 400 knots cruise) (6)";
|
|
332
|
+
break;
|
|
333
|
+
case 7:
|
|
334
|
+
record["021_020_ECAT"] = "reserved (7)";
|
|
335
|
+
break;
|
|
336
|
+
case 8:
|
|
337
|
+
record["021_020_ECAT"] = "reserved (8)";
|
|
338
|
+
break;
|
|
339
|
+
case 9:
|
|
340
|
+
record["021_020_ECAT"] = "reserved (9)";
|
|
341
|
+
break;
|
|
342
|
+
case 10:
|
|
343
|
+
record["021_020_ECAT"] = "rotocraft (10)";
|
|
344
|
+
break;
|
|
345
|
+
case 11:
|
|
346
|
+
record["021_020_ECAT"] = "glider / sailplane (11)";
|
|
347
|
+
break;
|
|
348
|
+
case 12:
|
|
349
|
+
record["021_020_ECAT"] = "lighter-than-air (12)";
|
|
350
|
+
break;
|
|
351
|
+
case 13:
|
|
352
|
+
record["021_020_ECAT"] = "unmanned aerial vehicle (13)";
|
|
353
|
+
break;
|
|
354
|
+
case 14:
|
|
355
|
+
record["021_020_ECAT"] = "space / transatmospheric vehicle (14)";
|
|
356
|
+
break;
|
|
357
|
+
case 15:
|
|
358
|
+
record["021_020_ECAT"] = "ultralight / handglider / paraglider (15)";
|
|
359
|
+
break;
|
|
360
|
+
case 16:
|
|
361
|
+
record["021_020_ECAT"] = "parachutist / skydiver (16)";
|
|
362
|
+
break;
|
|
363
|
+
case 17:
|
|
364
|
+
record["021_020_ECAT"] = "reserved (17)";
|
|
365
|
+
break;
|
|
366
|
+
case 18:
|
|
367
|
+
record["021_020_ECAT"] = "reserved (18)";
|
|
368
|
+
break;
|
|
369
|
+
case 19:
|
|
370
|
+
record["021_020_ECAT"] = "reserved (19)";
|
|
371
|
+
break;
|
|
372
|
+
case 20:
|
|
373
|
+
record["021_020_ECAT"] = "surface emergency vehicle (20)";
|
|
374
|
+
break;
|
|
375
|
+
case 21:
|
|
376
|
+
record["021_020_ECAT"] = "surface service vehicle (21)";
|
|
377
|
+
break;
|
|
378
|
+
case 22:
|
|
379
|
+
record["021_020_ECAT"] = "fixed ground or tethered obstruction (22)";
|
|
380
|
+
break;
|
|
381
|
+
case 23:
|
|
382
|
+
record["021_020_ECAT"] = "cluster obstacle (23)";
|
|
383
|
+
break;
|
|
384
|
+
case 24:
|
|
385
|
+
record["021_020_ECAT"] = "line obstacle (24)";
|
|
386
|
+
break;
|
|
387
|
+
default:
|
|
388
|
+
record["021_020_ECAT"] = "UNDEFINED";
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
/**
|
|
393
|
+
* Data Item I021/040, Target Report Descriptor
|
|
394
|
+
* 시스템에 의해 전송되는 데이터의 유형 및 특성
|
|
395
|
+
* 가변 길이
|
|
396
|
+
* @param record 단일 Record 파싱 결과
|
|
397
|
+
* @param bitArr Asterix 바이트 데이터
|
|
398
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
399
|
+
*/
|
|
400
|
+
const di040 = (record, bitArr, currentPos) => {
|
|
401
|
+
const octet1 = bitArr[currentPos++];
|
|
402
|
+
const atpOctet = (0, common_1.octetOfRange)(octet1, 7, 5, 2);
|
|
403
|
+
switch (atpOctet) {
|
|
404
|
+
case 0:
|
|
405
|
+
record["021_040_ATP"] = "24-Bit ICAO address (0)";
|
|
406
|
+
break;
|
|
407
|
+
case 1:
|
|
408
|
+
record["021_040_ATP"] = "Duplicate address (1)";
|
|
409
|
+
break;
|
|
410
|
+
case 2:
|
|
411
|
+
record["021_040_ATP"] = "Surface vehicle address (2)";
|
|
412
|
+
break;
|
|
413
|
+
case 3:
|
|
414
|
+
record["021_040_ATP"] = "Anonymous address (3)";
|
|
415
|
+
break;
|
|
416
|
+
case 4:
|
|
417
|
+
record["021_040_ATP"] = "Reserved for future use (4)";
|
|
418
|
+
break;
|
|
419
|
+
case 5:
|
|
420
|
+
record["021_040_ATP"] = "Reserved for future use (5)";
|
|
421
|
+
break;
|
|
422
|
+
case 6:
|
|
423
|
+
record["021_040_ATP"] = "Reserved for future use (6)";
|
|
424
|
+
break;
|
|
425
|
+
case 7:
|
|
426
|
+
record["021_040_ATP"] = "Reserved for future use (7)";
|
|
427
|
+
break;
|
|
428
|
+
default:
|
|
429
|
+
record["021_040_ATP"] = "UNDEFINED";
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
const arcOctet = (0, common_1.octetOfRange)(octet1, 4, 3, 1);
|
|
433
|
+
switch (arcOctet) {
|
|
434
|
+
case 0:
|
|
435
|
+
record["021_040_ARC"] = "25 ft (0)";
|
|
436
|
+
break;
|
|
437
|
+
case 1:
|
|
438
|
+
record["021_040_ARC"] = "100 ft (1)";
|
|
439
|
+
break;
|
|
440
|
+
case 2:
|
|
441
|
+
record["021_040_ARC"] = "Unknown (2)";
|
|
442
|
+
break;
|
|
443
|
+
case 3:
|
|
444
|
+
record["021_040_ARC"] = "Invalid (3)";
|
|
445
|
+
break;
|
|
446
|
+
default:
|
|
447
|
+
record["021_040_ARC"] = "UNDEFINED";
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
if ((octet1 & (1 << 2)) === 0) {
|
|
451
|
+
record["021_040_RC"] = "Default (0)";
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
record["021_040_RC"] = "Range Check passed, CPR Validation pending (1)";
|
|
455
|
+
}
|
|
456
|
+
if ((octet1 & (1 << 1)) === 0) {
|
|
457
|
+
record["021_040_RAB"] = "Report from target transponder (0)";
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
record["021_040_RAB"] = "Report from field monitor (fixed transponder) (1)";
|
|
461
|
+
}
|
|
462
|
+
if ((octet1 & 1) == 0)
|
|
463
|
+
return;
|
|
464
|
+
const octet2 = bitArr[currentPos++];
|
|
465
|
+
if ((octet2 & (1 << 7)) === 0) {
|
|
466
|
+
record["021_040_DRC"] = "No differential correction (ADS-B) (0)";
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
record["021_040_DRC"] = "Differential correction (ADS-B) (1)";
|
|
470
|
+
}
|
|
471
|
+
if ((octet2 & (1 << 6)) === 0) {
|
|
472
|
+
record["021_040_GBS"] = "Ground Bit not set (0)";
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
record["021_040_GBS"] = "Ground Bit set (1)";
|
|
476
|
+
}
|
|
477
|
+
if ((octet2 & (1 << 5)) === 0) {
|
|
478
|
+
record["021_040_SIM"] = "Actual target report (0)";
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
record["021_040_SIM"] = "Simulated target report (1)";
|
|
482
|
+
}
|
|
483
|
+
if ((octet2 & (1 << 4)) === 0) {
|
|
484
|
+
record["021_040_TST"] = "Default (0)";
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
record["021_040_TST"] = "Test Target (1)";
|
|
488
|
+
}
|
|
489
|
+
if ((octet2 & (1 << 3)) === 0) {
|
|
490
|
+
record["021_040_SAA"] = "Equipment capable to provide Selected Altitude (0)";
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
record["021_040_SAA"] = "Equipment not capable to provide Selected Altitude (1)";
|
|
494
|
+
}
|
|
495
|
+
const clOctet = (0, common_1.octetOfRange)(octet2, 2, 1, 1);
|
|
496
|
+
switch (clOctet) {
|
|
497
|
+
case 0:
|
|
498
|
+
record["021_040_CL"] = "Report valid (0)";
|
|
499
|
+
break;
|
|
500
|
+
case 1:
|
|
501
|
+
record["021_040_CL"] = "Report suspect (1)";
|
|
502
|
+
break;
|
|
503
|
+
case 2:
|
|
504
|
+
record["021_040_CL"] = "No information (2)";
|
|
505
|
+
break;
|
|
506
|
+
case 3:
|
|
507
|
+
record["021_040_CL"] = "Reserved for future use (3)";
|
|
508
|
+
break;
|
|
509
|
+
default:
|
|
510
|
+
record["021_040_CL"] = "UNDEFINED";
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
if ((octet2 & 1) == 0)
|
|
514
|
+
return;
|
|
515
|
+
const octet3 = bitArr[currentPos++];
|
|
516
|
+
if ((octet3 & (1 << 6)) === 0) {
|
|
517
|
+
record["021_040_LLC"] = "default (0)";
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
record["021_040_LLC"] = "Target is suspect (see note) (1)";
|
|
521
|
+
}
|
|
522
|
+
if ((octet3 & (1 << 5)) === 0) {
|
|
523
|
+
record["021_040_IPC"] = "default (see note) (0)";
|
|
524
|
+
}
|
|
525
|
+
else {
|
|
526
|
+
record["021_040_IPC"] = "Independent Position Check failed (1)";
|
|
527
|
+
}
|
|
528
|
+
if ((octet3 & (1 << 4)) === 0) {
|
|
529
|
+
record["021_040_NOGO"] = "NOGO-bit not set (0)";
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
record["021_040_NOGO"] = "NOGO-bit set (1)";
|
|
533
|
+
}
|
|
534
|
+
if ((octet3 & (1 << 3)) === 0) {
|
|
535
|
+
record["021_040_CPR"] = "CPR Validation correct (0)";
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
record["021_040_CPR"] = "CPR Validation failed (1)";
|
|
539
|
+
}
|
|
540
|
+
if ((octet3 & (1 << 2)) === 0) {
|
|
541
|
+
record["021_040_LDPJ"] = "LDPJ not detected (0)";
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
record["021_040_LDPJ"] = "LDPJ detected (1)";
|
|
545
|
+
}
|
|
546
|
+
if ((octet3 & (1 << 1)) === 0) {
|
|
547
|
+
record["021_040_RCF"] = "default (0)";
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
record["021_040_RCF"] = "Range Check failed (1)";
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
/**
|
|
554
|
+
* Data Item I021/070, Mode 3/A Code in Octal Representation
|
|
555
|
+
* 8진수 표현으로 변환된 Mode-3/A 코드
|
|
556
|
+
* 고정 길이, 1 octet
|
|
557
|
+
* @param record 단일 Record 파싱 결과
|
|
558
|
+
* @param bitArr Asterix 바이트 데이터
|
|
559
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
560
|
+
*/
|
|
561
|
+
const di070 = (record, bitArr, currentPos) => {
|
|
562
|
+
const octet1 = bitArr[currentPos++];
|
|
563
|
+
const octet2 = bitArr[currentPos++];
|
|
564
|
+
const aStr = (0, common_1.octetOfRange)(octet1, 3, 1, 2).toString();
|
|
565
|
+
const bStr = (((0, common_1.octetOfRange)(octet1, 0, 0, 0) << 2) | (0, common_1.octetOfRange)(octet2, 7, 6, 1)).toString();
|
|
566
|
+
const cStr = (0, common_1.octetOfRange)(octet2, 5, 3, 2).toString();
|
|
567
|
+
const dStr = (0, common_1.octetOfRange)(octet2, 2, 0, 2).toString();
|
|
568
|
+
record["021_070_Mode-3/A"] = aStr + bStr + cStr + dStr;
|
|
569
|
+
};
|
|
570
|
+
/**
|
|
571
|
+
* Data Item I021/071, Time of Applicability for Position
|
|
572
|
+
* 보고된 위치 정보의 유효 시간 (지난 자정 이후 경과된 시간 형태, 협정 세계시(UTC)로 표시)
|
|
573
|
+
* 고정 길이, 3 octet
|
|
574
|
+
* LSB(스케일링 계수): 1/128 s
|
|
575
|
+
* @param record 단일 Record 파싱 결과
|
|
576
|
+
* @param bitArr Asterix 바이트 데이터
|
|
577
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
578
|
+
*/
|
|
579
|
+
const di071 = (record, bitArr, currentPos) => {
|
|
580
|
+
const octet1 = bitArr[currentPos++];
|
|
581
|
+
const octet2 = bitArr[currentPos++];
|
|
582
|
+
const octet3 = bitArr[currentPos++];
|
|
583
|
+
const tapOctet = octet1 << (8 * 2) | octet2 << (8) | octet3;
|
|
584
|
+
record["021_071_Time of Applicability of Position"] = tapOctet / 128;
|
|
585
|
+
};
|
|
586
|
+
/**
|
|
587
|
+
* Data Item I021/072, Time of Applicability for Velocity
|
|
588
|
+
* 보고된 속도 정보의 유효 시간 (측정 시점), (지난 자정 이후 경과된 시간 형태, 협정 세계시(UTC)로 표시)
|
|
589
|
+
* 고정 길이, 3 octet
|
|
590
|
+
* LSB(스케일링 계수): 1/128 s
|
|
591
|
+
* @param record 단일 Record 파싱 결과
|
|
592
|
+
* @param bitArr Asterix 바이트 데이터
|
|
593
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
594
|
+
*/
|
|
595
|
+
const di072 = (record, bitArr, currentPos) => {
|
|
596
|
+
const octet1 = bitArr[currentPos++];
|
|
597
|
+
const octet2 = bitArr[currentPos++];
|
|
598
|
+
const octet3 = bitArr[currentPos++];
|
|
599
|
+
const tavOctet = octet1 << (8 * 2) | octet2 << (8) | octet3;
|
|
600
|
+
record["021_072_Time of Applicability of Velocity"] = tavOctet / 128;
|
|
601
|
+
};
|
|
602
|
+
/**
|
|
603
|
+
* Data Item I021/073, Time of Message Reception for Position
|
|
604
|
+
* 지상국에서 최종 위치 스퀴터(Squitter)를 수신한 시간 (지난 자정 이후 경과된 시간 형태, 협정 세계시(UTC)로 표시
|
|
605
|
+
* 고정 길이, 3 octet
|
|
606
|
+
* LSB(스케일링 계수): 1/128 s
|
|
607
|
+
* @param record 단일 Record 파싱 결과
|
|
608
|
+
* @param bitArr Asterix 바이트 데이터
|
|
609
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
610
|
+
*/
|
|
611
|
+
const di073 = (record, bitArr, currentPos) => {
|
|
612
|
+
const octet1 = bitArr[currentPos++];
|
|
613
|
+
const octet2 = bitArr[currentPos++];
|
|
614
|
+
const octet3 = bitArr[currentPos++];
|
|
615
|
+
const tmrpOctet = octet1 << (8 * 2) | octet2 << (8) | octet3;
|
|
616
|
+
record["021_073_Time of Message Reception of Position"] = tmrpOctet / 128;
|
|
617
|
+
};
|
|
618
|
+
/**
|
|
619
|
+
* Data Item I021/074, Time of Message Reception of Position–High Precision
|
|
620
|
+
* 지상국이 최종 ADS-B 위치 정보를 수신한 시각 (UTC 시각의 초 단위 이하(분수)로 표현)
|
|
621
|
+
* 고정 길이, 4 octet
|
|
622
|
+
* LSB(스케일링 계수): 2^-30s
|
|
623
|
+
* @param record 단일 Record 파싱 결과
|
|
624
|
+
* @param bitArr Asterix 바이트 데이터
|
|
625
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
626
|
+
*/
|
|
627
|
+
const di074 = (record, bitArr, currentPos) => {
|
|
628
|
+
const octet1 = bitArr[currentPos++];
|
|
629
|
+
const fsiOctet = (0, common_1.octetOfRange)(octet1, 7, 6, 1);
|
|
630
|
+
switch (fsiOctet) {
|
|
631
|
+
case 0:
|
|
632
|
+
record["021_074_FSI"] = "TOMRp whole seconds = (I021/073) Whole seconds (0)";
|
|
633
|
+
break;
|
|
634
|
+
case 1:
|
|
635
|
+
record["021_074_FSI"] = "TOMRp whole seconds = (I021/073) Whole seconds + 1 (1)";
|
|
636
|
+
break;
|
|
637
|
+
case 2:
|
|
638
|
+
record["021_074_FSI"] = "TOMRp whole seconds = (I021/073) Whole seconds - 1 (2)";
|
|
639
|
+
break;
|
|
640
|
+
case 3:
|
|
641
|
+
record["021_074_FSI"] = "Reserved (3)";
|
|
642
|
+
break;
|
|
643
|
+
default:
|
|
644
|
+
record["021_074_FSI"] = "UNDEFINED";
|
|
645
|
+
break;
|
|
646
|
+
}
|
|
647
|
+
const tmrpFrontOctet = (0, common_1.octetOfRange)(octet1, 5, 0, 5);
|
|
648
|
+
const octet2 = bitArr[currentPos++];
|
|
649
|
+
const octet3 = bitArr[currentPos++];
|
|
650
|
+
const octet4 = bitArr[currentPos++];
|
|
651
|
+
const tmrpOctet = (tmrpFrontOctet << (8 * 3)) | (octet2 << (8 * 2)) | (octet3 << (8)) | octet4;
|
|
652
|
+
const tmrp = tmrpOctet / (1 << 30);
|
|
653
|
+
record["021_074_Time of Message Reception of Position - high precision"] = tmrp;
|
|
654
|
+
};
|
|
655
|
+
/**
|
|
656
|
+
* Data Item I021/075, Time of Message Reception for Velocity
|
|
657
|
+
* 지상국에서 최종 속도 스퀴터(Squitter)를 수신한 시간 (지난 자정 이후 경과된 시간 형태, 협정 세계시(UTC)로 표시)
|
|
658
|
+
* 고정 길이, 3 octet
|
|
659
|
+
* LSB(스케일링 계수): 1/128 s
|
|
660
|
+
* @param record 단일 Record 파싱 결과
|
|
661
|
+
* @param bitArr Asterix 바이트 데이터
|
|
662
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
663
|
+
*/
|
|
664
|
+
const di075 = (record, bitArr, currentPos) => {
|
|
665
|
+
const octet1 = bitArr[currentPos++];
|
|
666
|
+
const octet2 = bitArr[currentPos++];
|
|
667
|
+
const octet3 = bitArr[currentPos++];
|
|
668
|
+
const ttiOctet = octet1 << (8 * 2) | octet2 << (8) | octet3;
|
|
669
|
+
record["021_075_Time of Message Reception of Velocity"] = ttiOctet / 128;
|
|
670
|
+
};
|
|
671
|
+
/**
|
|
672
|
+
* Data Item I021/076, Time of Message Reception of Velocity–High Precision
|
|
673
|
+
* 지상국이 최종 ADS-B 속도 정보를 수신한 시각 (UTC 시각의 초 단위 이하(분수)로 표현
|
|
674
|
+
* 고정 길이, 4 octet
|
|
675
|
+
* LSB(스케일링 계수): 2^-30s
|
|
676
|
+
* @param record 단일 Record 파싱 결과
|
|
677
|
+
* @param bitArr Asterix 바이트 데이터
|
|
678
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
679
|
+
*/
|
|
680
|
+
const di076 = (record, bitArr, currentPos) => {
|
|
681
|
+
const octet1 = bitArr[currentPos++];
|
|
682
|
+
const fsiOctet = (0, common_1.octetOfRange)(octet1, 7, 6, 1);
|
|
683
|
+
switch (fsiOctet) {
|
|
684
|
+
case 3:
|
|
685
|
+
record["021_076_FSI"] = "Reserved (3)";
|
|
686
|
+
break;
|
|
687
|
+
case 2:
|
|
688
|
+
record["021_076_FSI"] = "TOMRv whole seconds = (I021/075) Whole seconds - 1 (2)";
|
|
689
|
+
break;
|
|
690
|
+
case 1:
|
|
691
|
+
record["021_076_FSI"] = "TOMRv whole seconds = (I021/075) Whole seconds + 1 (1)";
|
|
692
|
+
break;
|
|
693
|
+
case 0:
|
|
694
|
+
record["021_076_FSI"] = "TOMRv whole seconds = (I021/075) Whole seconds (0)";
|
|
695
|
+
break;
|
|
696
|
+
default:
|
|
697
|
+
record["021_076_FSI"] = "UNDEFINED";
|
|
698
|
+
break;
|
|
699
|
+
}
|
|
700
|
+
const tmrvFrontOctet = (0, common_1.octetOfRange)(octet1, 5, 0, 5);
|
|
701
|
+
const octet2 = bitArr[currentPos++];
|
|
702
|
+
const octet3 = bitArr[currentPos++];
|
|
703
|
+
const octet4 = bitArr[currentPos++];
|
|
704
|
+
const tmrvOctet = (tmrvFrontOctet << (8 * 3)) | (octet2 << (8 * 2)) | (octet3 << (8)) | octet4;
|
|
705
|
+
const tmrv = tmrvOctet / (1 << 30);
|
|
706
|
+
record["021_076_Time of Message Reception of Velocity - high precision"] = tmrv;
|
|
707
|
+
};
|
|
708
|
+
/**
|
|
709
|
+
* Data Item I021/077, Time of ASTERIX Report Transmission
|
|
710
|
+
* ASTERIX 카테고리 021 보고서 송신 시각 (지난 자정 이후 경과된 시간 형태, 협정 세계시(UTC)로 표시)
|
|
711
|
+
* 고정 길이, 3 octet
|
|
712
|
+
* LSB(스케일링 계수): 1/128 s
|
|
713
|
+
* @param record 단일 Record 파싱 결과
|
|
714
|
+
* @param bitArr Asterix 바이트 데이터
|
|
715
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
716
|
+
*/
|
|
717
|
+
const di077 = (record, bitArr, currentPos) => {
|
|
718
|
+
const octet1 = bitArr[currentPos++];
|
|
719
|
+
const octet2 = bitArr[currentPos++];
|
|
720
|
+
const octet3 = bitArr[currentPos++];
|
|
721
|
+
const ttiOctet = octet1 << (8 * 2) | octet2 << (8) | octet3;
|
|
722
|
+
record["021_077_Time of ASTERIX Report Transmission"] = ttiOctet / 128;
|
|
723
|
+
};
|
|
724
|
+
/**
|
|
725
|
+
* Data Item I021/080, Target Address
|
|
726
|
+
* 타겟의 주소
|
|
727
|
+
* 고정 길이, 3 octet
|
|
728
|
+
* @param record 단일 Record 파싱 결과
|
|
729
|
+
* @param bitArr Asterix 바이트 데이터
|
|
730
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
731
|
+
*/
|
|
732
|
+
const di080 = (record, bitArr, currentPos) => {
|
|
733
|
+
const octet1 = bitArr[currentPos++];
|
|
734
|
+
const octet2 = bitArr[currentPos++];
|
|
735
|
+
const octet3 = bitArr[currentPos++];
|
|
736
|
+
const taOctet = octet1 << (8 * 2) | octet2 << (8) | octet3;
|
|
737
|
+
record["021_080_Target Address"] = taOctet.toString(16).toUpperCase().padStart(6, '0');
|
|
738
|
+
};
|
|
739
|
+
/**
|
|
740
|
+
* Data Item I021/090, Quality Indicators
|
|
741
|
+
* MOPS 버전에 따라 항공기(a/c)가 송신하는 ADS-B 품질 지표
|
|
742
|
+
* 가변 길이
|
|
743
|
+
* @param record 단일 Record 파싱 결과
|
|
744
|
+
* @param bitArr Asterix 바이트 데이터
|
|
745
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
746
|
+
*/
|
|
747
|
+
const di090 = (record, bitArr, currentPos) => {
|
|
748
|
+
const octet1 = bitArr[currentPos++];
|
|
749
|
+
const nuacOctet = (0, common_1.octetOfRange)(octet1, 7, 5, 2);
|
|
750
|
+
record["021_090_NUCrorNACv"] = nuacOctet;
|
|
751
|
+
const nuicOctet = (0, common_1.octetOfRange)(octet1, 4, 1, 3);
|
|
752
|
+
record["021_090_NUCporNIC"] = nuicOctet;
|
|
753
|
+
// 마지막 비트가 0이면 종료
|
|
754
|
+
if ((octet1 & 1) == 0)
|
|
755
|
+
return;
|
|
756
|
+
const octet2 = bitArr[currentPos++];
|
|
757
|
+
const nicOctet = (octet2 & (1 << 7)) !== 0 ? 1 : 0;
|
|
758
|
+
record["021_090_NICbaro"] = nicOctet;
|
|
759
|
+
const silOctet = (0, common_1.octetOfRange)(octet2, 6, 5, 1);
|
|
760
|
+
record["021_090_SIL"] = silOctet;
|
|
761
|
+
const nacpOctet = (0, common_1.octetOfRange)(octet2, 4, 1, 3);
|
|
762
|
+
record["021_090_NACp"] = nacpOctet;
|
|
763
|
+
// 마지막 비트가 0이면 종료
|
|
764
|
+
if ((octet2 & 1) == 0)
|
|
765
|
+
return;
|
|
766
|
+
const octet3 = bitArr[currentPos++];
|
|
767
|
+
const silsOctet = (octet3 & (1 << 5)) !== 0 ? 1 : 0;
|
|
768
|
+
record["021_090_SILS"] = silsOctet;
|
|
769
|
+
const sdaOctet = (0, common_1.octetOfRange)(octet3, 4, 3, 1);
|
|
770
|
+
record["021_090_SDA"] = sdaOctet;
|
|
771
|
+
const gvaOctet = (0, common_1.octetOfRange)(octet3, 2, 1, 1);
|
|
772
|
+
record["021_090_GVA"] = gvaOctet;
|
|
773
|
+
if ((octet3 & 1) == 0)
|
|
774
|
+
return;
|
|
775
|
+
const octet4 = bitArr[currentPos++];
|
|
776
|
+
const picOctet = (0, common_1.octetOfRange)(octet4, 7, 4, 3);
|
|
777
|
+
record["021_090_PIC"] = picOctet;
|
|
778
|
+
};
|
|
779
|
+
/**
|
|
780
|
+
* Data Item I021/110, Trajectory Intent
|
|
781
|
+
* 항공기의 4D 예상(계획) 경로를 나타내는 보고서
|
|
782
|
+
* 가변 길이
|
|
783
|
+
* TID - 2의 보수 처리 필요
|
|
784
|
+
* @param record 단일 Record 파싱 결과
|
|
785
|
+
* @param bitArr Asterix 바이트 데이터
|
|
786
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
787
|
+
*/
|
|
788
|
+
const di110 = (record, bitArr, currentPos) => {
|
|
789
|
+
const octet1 = bitArr[currentPos++];
|
|
790
|
+
if ((octet1 & (1 << 7)) !== 0) {
|
|
791
|
+
// TIS O
|
|
792
|
+
di110TIS(record, bitArr, currentPos);
|
|
793
|
+
currentPos++;
|
|
794
|
+
}
|
|
795
|
+
if ((octet1 & (1 << 6)) !== 0) {
|
|
796
|
+
// TID O
|
|
797
|
+
di110TID(record, bitArr, currentPos);
|
|
798
|
+
currentPos++;
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
/**
|
|
802
|
+
* Data Item I021/110, Subfield 1
|
|
803
|
+
* Trajectory Intent Status
|
|
804
|
+
* @param record 단일 Record 파싱 결과
|
|
805
|
+
* @param bitArr Asterix 바이트 데이터
|
|
806
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
807
|
+
*/
|
|
808
|
+
const di110TIS = (record, bitArr, currentPos) => {
|
|
809
|
+
const octet1 = bitArr[currentPos++];
|
|
810
|
+
// NAV
|
|
811
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
812
|
+
record["021_110_NAV"] = "Trajectory Intent Data is available for this aircraft (0)";
|
|
813
|
+
}
|
|
814
|
+
else {
|
|
815
|
+
record["021_110_NAV"] = "Trajectory Intent Data is not available for this aircraft (1)";
|
|
816
|
+
}
|
|
817
|
+
// NVB
|
|
818
|
+
if ((octet1 & (1 << 6)) === 0) {
|
|
819
|
+
record["021_110_NVB"] = "Trajectory Intent Data is valid (0)";
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
record["021_110_NVB"] = "Trajectory Intent Data is not valid (1)";
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
/**
|
|
826
|
+
* Data Item I021/110, Subfield 2
|
|
827
|
+
* Trajectory Intent Data
|
|
828
|
+
* @param record 단일 Record 파싱 결과
|
|
829
|
+
* @param bitArr Asterix 바이트 데이터
|
|
830
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
831
|
+
*/
|
|
832
|
+
const di110TID = (record, bitArr, currentPos) => {
|
|
833
|
+
const octet1 = bitArr[currentPos++];
|
|
834
|
+
for (let index = 0; index < octet1; index++) {
|
|
835
|
+
const octet2 = bitArr[currentPos++];
|
|
836
|
+
if ((octet2 & (1 << 7)) === 0) {
|
|
837
|
+
record["021_110_NVB_" + (index + 1)] = "Trajectory Intent Data is valid (0)";
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
record["021_110_NVB_" + (index + 1)] = "Trajectory Intent Data is not valid (1)";
|
|
841
|
+
}
|
|
842
|
+
if ((octet2 & (1 << 6)) === 0) {
|
|
843
|
+
record["021_110_NC_" + (index + 1)] = "TCP compliance (0)";
|
|
844
|
+
}
|
|
845
|
+
else {
|
|
846
|
+
record["021_110_NC_" + (index + 1)] = "TCP non-compliance (1)";
|
|
847
|
+
}
|
|
848
|
+
record["021_110_TCP number_" + (index + 1)] = (0, common_1.octetOfRange)(octet2, 5, 0, 5);
|
|
849
|
+
const octet3 = bitArr[currentPos++];
|
|
850
|
+
const octet4 = bitArr[currentPos++];
|
|
851
|
+
const altOctet = octet3 << (8) | octet4;
|
|
852
|
+
const alt = (0, common_1.twosCompliment)(altOctet, 16) * 10;
|
|
853
|
+
record["021_110_Altitude_" + (index + 1)] = alt;
|
|
854
|
+
const octet5 = bitArr[currentPos++];
|
|
855
|
+
const octet6 = bitArr[currentPos++];
|
|
856
|
+
const octet7 = bitArr[currentPos++];
|
|
857
|
+
const latOctet = octet5 << (8 * 2) | octet6 << (8) | octet7;
|
|
858
|
+
const octet8 = bitArr[currentPos++];
|
|
859
|
+
const octet9 = bitArr[currentPos++];
|
|
860
|
+
const octet10 = bitArr[currentPos++];
|
|
861
|
+
const lonOctet = octet8 << (8 * 2) | octet9 << (8) | octet10;
|
|
862
|
+
const lat = (0, common_1.twosCompliment)(latOctet, 24) * 180.0 / (1 << 23);
|
|
863
|
+
const lon = (0, common_1.twosCompliment)(lonOctet, 24) * 180.0 / (1 << 23);
|
|
864
|
+
record["021_110_Latitude In WGS-84_" + (index + 1)] = lat;
|
|
865
|
+
record["021_110_Longitude In WGS-84_" + (index + 1)] = lon;
|
|
866
|
+
const octet11 = bitArr[currentPos++];
|
|
867
|
+
const ptOctet = (0, common_1.octetOfRange)(octet11, 7, 4, 3);
|
|
868
|
+
switch (ptOctet) {
|
|
869
|
+
case 0:
|
|
870
|
+
record["021_110_Point Type_" + (index + 1)] = "Unknown (0)";
|
|
871
|
+
break;
|
|
872
|
+
case 1:
|
|
873
|
+
record["021_110_Point Type_" + (index + 1)] = "Fly by waypoint (LT) (1)";
|
|
874
|
+
break;
|
|
875
|
+
case 2:
|
|
876
|
+
record["021_110_Point Type_" + (index + 1)] = "Fly over waypoint (LT) (2)";
|
|
877
|
+
break;
|
|
878
|
+
case 3:
|
|
879
|
+
record["021_110_Point Type_" + (index + 1)] = "Hold pattern (LT) (3)";
|
|
880
|
+
break;
|
|
881
|
+
case 4:
|
|
882
|
+
record["021_110_Point Type_" + (index + 1)] = "Procedure hold (LT) (4)";
|
|
883
|
+
break;
|
|
884
|
+
case 5:
|
|
885
|
+
record["021_110_Point Type_" + (index + 1)] = "Procedure turn (LT) (5)";
|
|
886
|
+
break;
|
|
887
|
+
case 6:
|
|
888
|
+
record["021_110_Point Type_" + (index + 1)] = "RF leg (LT) (6)";
|
|
889
|
+
break;
|
|
890
|
+
case 7:
|
|
891
|
+
record["021_110_Point Type_" + (index + 1)] = "Top of climb (VT) (7)";
|
|
892
|
+
break;
|
|
893
|
+
case 8:
|
|
894
|
+
record["021_110_Point Type_" + (index + 1)] = "Top of descent (VT) (8)";
|
|
895
|
+
break;
|
|
896
|
+
case 9:
|
|
897
|
+
record["021_110_Point Type_" + (index + 1)] = "Start of level (VT) (9)";
|
|
898
|
+
break;
|
|
899
|
+
case 10:
|
|
900
|
+
record["021_110_Point Type_" + (index + 1)] = "Cross-over altitude (VT) (10)";
|
|
901
|
+
break;
|
|
902
|
+
case 11:
|
|
903
|
+
record["021_110_Point Type_" + (index + 1)] = "Transition altitude (VT) (11)";
|
|
904
|
+
break;
|
|
905
|
+
default:
|
|
906
|
+
record["021_110_Point Type_" + (index + 1)] = "UNDEFINED";
|
|
907
|
+
break;
|
|
908
|
+
}
|
|
909
|
+
const tdOctet = (0, common_1.octetOfRange)(octet11, 3, 2, 1);
|
|
910
|
+
switch (tdOctet) {
|
|
911
|
+
case 0:
|
|
912
|
+
record["021_110_TD_" + (index + 1)] = "N/A (0)";
|
|
913
|
+
break;
|
|
914
|
+
case 1:
|
|
915
|
+
record["021_110_TD_" + (index + 1)] = "Turn right (1)";
|
|
916
|
+
break;
|
|
917
|
+
case 2:
|
|
918
|
+
record["021_110_TD_" + (index + 1)] = "Turn left (2)";
|
|
919
|
+
break;
|
|
920
|
+
case 3:
|
|
921
|
+
record["021_110_TD_" + (index + 1)] = "No turn (3)";
|
|
922
|
+
break;
|
|
923
|
+
default:
|
|
924
|
+
record["021_110_TD_" + (index + 1)] = "UNDEFINED";
|
|
925
|
+
break;
|
|
926
|
+
}
|
|
927
|
+
if ((octet11 & (1 << 1)) === 0) {
|
|
928
|
+
record["021_110_TRA_" + (index + 1)] = "TTR not available (0)";
|
|
929
|
+
}
|
|
930
|
+
else {
|
|
931
|
+
record["021_110_TRA_" + (index + 1)] = "TTR available (1)";
|
|
932
|
+
}
|
|
933
|
+
if ((octet11 & (1)) === 0) {
|
|
934
|
+
record["021_110_TOA_" + (index + 1)] = "TOV available (0)";
|
|
935
|
+
}
|
|
936
|
+
else {
|
|
937
|
+
record["021_110_TOA_" + (index + 1)] = "TOV not available (1)";
|
|
938
|
+
}
|
|
939
|
+
const octet12 = bitArr[currentPos++];
|
|
940
|
+
const octet13 = bitArr[currentPos++];
|
|
941
|
+
const octet14 = bitArr[currentPos++];
|
|
942
|
+
const tovOctet = octet12 << (8 * 2) | octet13 << (8) | octet14;
|
|
943
|
+
record["021_110_TOV_" + (index + 1)] = tovOctet;
|
|
944
|
+
const octet15 = bitArr[currentPos++];
|
|
945
|
+
const octet16 = bitArr[currentPos++];
|
|
946
|
+
const ttrOctet = octet15 << (8) | octet16;
|
|
947
|
+
record["021_110_TTR_" + (index + 1)] = ttrOctet * 0.01;
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
/**
|
|
951
|
+
* Data Item I021/130, Position in WGS-84 Co-ordinates
|
|
952
|
+
* WGS-84 좌표계 기준 위치
|
|
953
|
+
* 고정 길이, 6 octet
|
|
954
|
+
* 2의 보수 처리 필요
|
|
955
|
+
* @param record 단일 Record 파싱 결과
|
|
956
|
+
* @param bitArr Asterix 바이트 데이터
|
|
957
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
958
|
+
*/
|
|
959
|
+
const di130 = (record, bitArr, currentPos) => {
|
|
960
|
+
const octet1 = bitArr[currentPos++];
|
|
961
|
+
const octet2 = bitArr[currentPos++];
|
|
962
|
+
const octet3 = bitArr[currentPos++];
|
|
963
|
+
const latOctet = octet1 << (8 * 2) | octet2 << (8) | octet3;
|
|
964
|
+
const octet4 = bitArr[currentPos++];
|
|
965
|
+
const octet5 = bitArr[currentPos++];
|
|
966
|
+
const octet6 = bitArr[currentPos++];
|
|
967
|
+
const lonOctet = octet4 << (8 * 2) | octet5 << (8) | octet6;
|
|
968
|
+
const lat = (0, common_1.twosCompliment)(latOctet, 24) * 180.0 / (1 << 23);
|
|
969
|
+
const lon = (0, common_1.twosCompliment)(lonOctet, 24) * 180.0 / (1 << 23);
|
|
970
|
+
record["021_130_Latitude In WGS-84"] = lat;
|
|
971
|
+
record["021_130_Longitude In WGS-84"] = lon;
|
|
972
|
+
};
|
|
973
|
+
/**
|
|
974
|
+
* Data Item I021/131, High-Resolution Position in WGS-84 Co-ordinates
|
|
975
|
+
* WGS-84 좌표계 기준 위치
|
|
976
|
+
* 고정 길이, 8 octet
|
|
977
|
+
* 2의 보수 처리 필요
|
|
978
|
+
* @param record 단일 Record 파싱 결과
|
|
979
|
+
* @param bitArr Asterix 바이트 데이터
|
|
980
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
981
|
+
*/
|
|
982
|
+
const di131 = (record, bitArr, currentPos) => {
|
|
983
|
+
const octet1 = bitArr[currentPos++];
|
|
984
|
+
const octet2 = bitArr[currentPos++];
|
|
985
|
+
const octet3 = bitArr[currentPos++];
|
|
986
|
+
const octet4 = bitArr[currentPos++];
|
|
987
|
+
const latOctet = octet1 << (8 * 3) | octet2 << (8 * 2) | octet3 << (8) | octet4;
|
|
988
|
+
const octet5 = bitArr[currentPos++];
|
|
989
|
+
const octet6 = bitArr[currentPos++];
|
|
990
|
+
const octet7 = bitArr[currentPos++];
|
|
991
|
+
const octet8 = bitArr[currentPos++];
|
|
992
|
+
const lonOctet = octet5 << (8 * 3) | octet6 << (8 * 2) | octet7 << (8) | octet8;
|
|
993
|
+
const lat = (0, common_1.twosCompliment)(latOctet, 32) * 180.0 / (1 << 30);
|
|
994
|
+
const lon = (0, common_1.twosCompliment)(lonOctet, 32) * 180.0 / (1 << 30);
|
|
995
|
+
record["021_131_Latitude In WGS-84"] = lat;
|
|
996
|
+
record["021_131_Longitude In WGS-84"] = lon;
|
|
997
|
+
};
|
|
998
|
+
/**
|
|
999
|
+
* Data Item I021/132, Message Amplitude
|
|
1000
|
+
* 지상국에서 수신한 ADS-B 메시지의 진폭(dBm 단위)으로, 2의 보수 방식으로 인코딩됨
|
|
1001
|
+
* 고정 길이, 1 octet
|
|
1002
|
+
* LSB(스케일링 계수): 1 dBm
|
|
1003
|
+
* 2의 보수 처리 필요
|
|
1004
|
+
* @param record 단일 Record 파싱 결과
|
|
1005
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1006
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1007
|
+
*/
|
|
1008
|
+
const di132 = (record, bitArr, currentPos) => {
|
|
1009
|
+
const octet1 = bitArr[currentPos++];
|
|
1010
|
+
const mam = (0, common_1.twosCompliment)(octet1, 8);
|
|
1011
|
+
record["021_132_MAM"] = mam;
|
|
1012
|
+
};
|
|
1013
|
+
/**
|
|
1014
|
+
* Data Item I021/140, Geometric Height
|
|
1015
|
+
* WGS-84로 정의된 지구 타원체의 접평면으로부터의 최소 높이이며, 2의 보수 형식으로 표현됨
|
|
1016
|
+
* 고정 길이, 2 octet
|
|
1017
|
+
* LSB(스케일링 계수): 6.25 ft
|
|
1018
|
+
* 2의 보수 처리 필요
|
|
1019
|
+
* @param record 단일 Record 파싱 결과
|
|
1020
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1021
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1022
|
+
*/
|
|
1023
|
+
const di140 = (record, bitArr, currentPos) => {
|
|
1024
|
+
const octet1 = bitArr[currentPos++];
|
|
1025
|
+
const octet2 = bitArr[currentPos++];
|
|
1026
|
+
const geoAltOctet = octet1 << (8) | octet2;
|
|
1027
|
+
const geoAlt = (0, common_1.twosCompliment)(geoAltOctet, 16) * 6.25;
|
|
1028
|
+
record["021_140_Geometric Height (GH)"] = geoAlt;
|
|
1029
|
+
};
|
|
1030
|
+
/**
|
|
1031
|
+
* Data Item I021/145, Flight Level
|
|
1032
|
+
* QNH 보정을 거치지 않은 기압 측정치 기반의 비행 고도(Flight Level)이며, 2의 보수 형식으로 표현됨
|
|
1033
|
+
* 고정 길이, 2 octet
|
|
1034
|
+
* LSB(스케일링 계수): 1 / 4 FL
|
|
1035
|
+
* 2의 보수 처리 필요
|
|
1036
|
+
* @param record 단일 Record 파싱 결과
|
|
1037
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1038
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1039
|
+
*/
|
|
1040
|
+
const di145 = (record, bitArr, currentPos) => {
|
|
1041
|
+
const octet1 = bitArr[currentPos++];
|
|
1042
|
+
const octet2 = bitArr[currentPos++];
|
|
1043
|
+
const flOctet = octet1 << (8) | octet2;
|
|
1044
|
+
const fl = (0, common_1.twosCompliment)(flOctet, 16) * 0.25;
|
|
1045
|
+
record["021_145_Fligth Level"] = fl;
|
|
1046
|
+
};
|
|
1047
|
+
/**
|
|
1048
|
+
* Data Item I021/146, Selected Altitude
|
|
1049
|
+
* 항공 전자 장치(Avionics)에서 제공되는 선택 고도(Selected Altitude)로,
|
|
1050
|
+
* 조종사가 MCP/FCU에 입력한 관제 지시 고도(ATC Cleared Altitude) 또는 FMS(비행 관리 시스템) 선택 고도 중 하나에 해당함
|
|
1051
|
+
* 고정 길이, 2 octet
|
|
1052
|
+
* LSB(스케일링 계수): 25ft
|
|
1053
|
+
* 2의 보수 처리 필요
|
|
1054
|
+
* @param record 단일 Record 파싱 결과
|
|
1055
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1056
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1057
|
+
*/
|
|
1058
|
+
const di146 = (record, bitArr, currentPos) => {
|
|
1059
|
+
const octet1 = bitArr[currentPos++];
|
|
1060
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
1061
|
+
record["021_146_SAS"] = "No source information provided (0)";
|
|
1062
|
+
}
|
|
1063
|
+
else {
|
|
1064
|
+
record["021_146_SAS"] = "Source Information provided (1)";
|
|
1065
|
+
}
|
|
1066
|
+
const sourceOctet = (0, common_1.octetOfRange)(octet1, 6, 5, 1);
|
|
1067
|
+
switch (sourceOctet) {
|
|
1068
|
+
case 0:
|
|
1069
|
+
record["021_146_Source"] = "Unknown (0)";
|
|
1070
|
+
break;
|
|
1071
|
+
case 1:
|
|
1072
|
+
record["021_146_Source"] = "Aircraft Altitude (Holding Altitude) (1)";
|
|
1073
|
+
break;
|
|
1074
|
+
case 2:
|
|
1075
|
+
record["021_146_Source"] = "MCP/FCU Selected Altitude (2)";
|
|
1076
|
+
break;
|
|
1077
|
+
case 3:
|
|
1078
|
+
record["021_146_Source"] = "FMS Selected Altitude (3)";
|
|
1079
|
+
break;
|
|
1080
|
+
default:
|
|
1081
|
+
record["021_146_Source"] = "UNDEFINED";
|
|
1082
|
+
break;
|
|
1083
|
+
}
|
|
1084
|
+
const altFrontOctet = (0, common_1.octetOfRange)(octet1, 4, 0, 4);
|
|
1085
|
+
const octet2 = bitArr[currentPos++];
|
|
1086
|
+
const altOctet = altFrontOctet << (8) | octet2;
|
|
1087
|
+
const alt = (0, common_1.twosCompliment)(altOctet, 13) * 25;
|
|
1088
|
+
record["021_146_Altitude"] = alt;
|
|
1089
|
+
};
|
|
1090
|
+
/**
|
|
1091
|
+
* Data Item I021/148, Final State Selected Altitude
|
|
1092
|
+
* 고도 제어 패널(MCP/FCU)로부터 추출된, 항공 교통 관제(ATC) 승인 고도와 일치하는 수직 의도(Vertical Intent) 값
|
|
1093
|
+
* 고정 길이, 2 octet
|
|
1094
|
+
* LSB(스케일링 계수): 25ft
|
|
1095
|
+
* 2의 보수 처리 필요
|
|
1096
|
+
* @param record 단일 Record 파싱 결과
|
|
1097
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1098
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1099
|
+
*/
|
|
1100
|
+
const di148 = (record, bitArr, currentPos) => {
|
|
1101
|
+
const octet1 = bitArr[currentPos++];
|
|
1102
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
1103
|
+
record["021_148_MV"] = "Not active or unknown (0)";
|
|
1104
|
+
}
|
|
1105
|
+
else {
|
|
1106
|
+
record["021_148_MV"] = "Active (1)";
|
|
1107
|
+
}
|
|
1108
|
+
if ((octet1 & (1 << 6)) === 0) {
|
|
1109
|
+
record["021_148_AH"] = "Not active or unknown (0)";
|
|
1110
|
+
}
|
|
1111
|
+
else {
|
|
1112
|
+
record["021_148_AH"] = "Active (1)";
|
|
1113
|
+
}
|
|
1114
|
+
if ((octet1 & (1 << 5)) === 0) {
|
|
1115
|
+
record["021_148_AM"] = "Not active or unknown (0)";
|
|
1116
|
+
}
|
|
1117
|
+
else {
|
|
1118
|
+
record["021_148_AM"] = "Active (1)";
|
|
1119
|
+
}
|
|
1120
|
+
const altFrontOctet = (0, common_1.octetOfRange)(octet1, 4, 0, 4);
|
|
1121
|
+
const octet2 = bitArr[currentPos++];
|
|
1122
|
+
const altOctet = altFrontOctet << (8) | octet2;
|
|
1123
|
+
const alt = (0, common_1.twosCompliment)(altOctet, 13) * 25;
|
|
1124
|
+
record["021_148_Altitude"] = alt;
|
|
1125
|
+
};
|
|
1126
|
+
/**
|
|
1127
|
+
* Data Item I021/150, Air Speed
|
|
1128
|
+
* 산출 대기 속도 (공기 벡터의 구성 요소)
|
|
1129
|
+
* 고정 길이, 2 octet
|
|
1130
|
+
* LSB(스케일링 계수): 2^-14 NM/s / 0.001
|
|
1131
|
+
* @param record 단일 Record 파싱 결과
|
|
1132
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1133
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1134
|
+
*/
|
|
1135
|
+
const di150 = (record, bitArr, currentPos) => {
|
|
1136
|
+
const octet1 = bitArr[currentPos++];
|
|
1137
|
+
const asFrontOctet = (0, common_1.octetOfRange)(octet1, 6, 0, 6);
|
|
1138
|
+
const octet2 = bitArr[currentPos++];
|
|
1139
|
+
const asOctet = asFrontOctet << (8) | octet2;
|
|
1140
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
1141
|
+
record["021_150_IM"] = "Air Speed = IAS (1)";
|
|
1142
|
+
record["021_150_Air Speed"] = asOctet / (1 << 14);
|
|
1143
|
+
}
|
|
1144
|
+
else {
|
|
1145
|
+
record["021_150_IM"] = "Air Speed = Mach (0)";
|
|
1146
|
+
record["021_150_Air Speed"] = asOctet * 0.001;
|
|
1147
|
+
}
|
|
1148
|
+
};
|
|
1149
|
+
/**
|
|
1150
|
+
* Data Item I021/151 True Airspeed
|
|
1151
|
+
* 진대기 속도
|
|
1152
|
+
* 고정 길이, 2 octet
|
|
1153
|
+
* LSB(스케일링 계수): 1 knot
|
|
1154
|
+
* @param record 단일 Record 파싱 결과
|
|
1155
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1156
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1157
|
+
*/
|
|
1158
|
+
const di151 = (record, bitArr, currentPos) => {
|
|
1159
|
+
const octet1 = bitArr[currentPos++];
|
|
1160
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
1161
|
+
record["021_150_IM"] = "Value in defined range (0)";
|
|
1162
|
+
}
|
|
1163
|
+
else {
|
|
1164
|
+
record["021_150_IM"] = "Value exceeds defined range (1)";
|
|
1165
|
+
}
|
|
1166
|
+
const tasFrontOctet = (0, common_1.octetOfRange)(octet1, 6, 0, 6);
|
|
1167
|
+
const octet2 = bitArr[currentPos++];
|
|
1168
|
+
const tasOctet = tasFrontOctet << (8) | octet2;
|
|
1169
|
+
record["021_151_True Air Speed"] = tasOctet;
|
|
1170
|
+
};
|
|
1171
|
+
/**
|
|
1172
|
+
* Data Item I021/152, Magnetic Heading
|
|
1173
|
+
* 항공기의 기수(코 부분)가 가리키는 방향을 자북(지구 자기장의 북쪽)을 기준으로 측정된 각도
|
|
1174
|
+
* 고정 길이, 2 octet
|
|
1175
|
+
* LSB(스케일링 계수): 360 / 2^16
|
|
1176
|
+
* @param record 단일 Record 파싱 결과
|
|
1177
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1178
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1179
|
+
*/
|
|
1180
|
+
const di152 = (record, bitArr, currentPos) => {
|
|
1181
|
+
const octet1 = bitArr[currentPos++];
|
|
1182
|
+
const octet2 = bitArr[currentPos++];
|
|
1183
|
+
const mhOctet = octet1 << (8) | octet2;
|
|
1184
|
+
const mh = (mhOctet * 360.0) / (1 << 16);
|
|
1185
|
+
record["021_152_Magnetic Heading"] = mh;
|
|
1186
|
+
};
|
|
1187
|
+
/**
|
|
1188
|
+
* Data Item I021/155, Barometric Vertical Rate
|
|
1189
|
+
* 기압 수직 속도이며, 2의 보수 형식으로 표현됨
|
|
1190
|
+
* 고정 길이, 2 octet
|
|
1191
|
+
* LSB(스케일링 계수): 6.25 feet/minute
|
|
1192
|
+
* @param record 단일 Record 파싱 결과
|
|
1193
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1194
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1195
|
+
*/
|
|
1196
|
+
const di155 = (record, bitArr, currentPos) => {
|
|
1197
|
+
const octet1 = bitArr[currentPos++];
|
|
1198
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
1199
|
+
record["021_155_RE"] = "Value in defined range (0)";
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
record["021_155_RE"] = "Value exceeds defined range (1)";
|
|
1203
|
+
}
|
|
1204
|
+
const bvrFrontOctet = (0, common_1.octetOfRange)(octet1, 6, 0, 6);
|
|
1205
|
+
const octet2 = bitArr[currentPos++];
|
|
1206
|
+
const bvrOctet = bvrFrontOctet << (8) | octet2;
|
|
1207
|
+
const bvr = (0, common_1.twosCompliment)(bvrOctet, 15) * 6.25;
|
|
1208
|
+
record["021_155_Barometric Vertical Rate"] = bvr;
|
|
1209
|
+
};
|
|
1210
|
+
/**
|
|
1211
|
+
* Data Item I021/157, Geometric Vertical Rate
|
|
1212
|
+
* WGS-84를 기준으로 한 기하학적 수직 속도이며, 2의 보수 형식으로 표현됨
|
|
1213
|
+
* 고정 길이, 2 octet
|
|
1214
|
+
* LSB(스케일링 계수): 6.25 feet/minute
|
|
1215
|
+
* @param record 단일 Record 파싱 결과
|
|
1216
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1217
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1218
|
+
*/
|
|
1219
|
+
const di157 = (record, bitArr, currentPos) => {
|
|
1220
|
+
const octet1 = bitArr[currentPos++];
|
|
1221
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
1222
|
+
record["021_157_RE"] = "Value in defined range (0)";
|
|
1223
|
+
}
|
|
1224
|
+
else {
|
|
1225
|
+
record["021_157_RE"] = "Value exceeds defined range (1)";
|
|
1226
|
+
}
|
|
1227
|
+
const bvrFrontOctet = (0, common_1.octetOfRange)(octet1, 6, 0, 6);
|
|
1228
|
+
const octet2 = bitArr[currentPos++];
|
|
1229
|
+
const bvrOctet = bvrFrontOctet << (8) | octet2;
|
|
1230
|
+
const bvr = (0, common_1.twosCompliment)(bvrOctet, 15) * 6.25;
|
|
1231
|
+
record["021_157_Geometric Vertical Rate"] = bvr;
|
|
1232
|
+
};
|
|
1233
|
+
/**
|
|
1234
|
+
* Data Item I021/160, Airborne Ground Vector
|
|
1235
|
+
* 공중 지면 벡터(Airborne Ground Vector)의 구성 요소인 지표 속도(Ground Speed)와 지적(Track Angle)
|
|
1236
|
+
* 고정 길이, 4 octet
|
|
1237
|
+
* LSB(스케일링 계수): 2^-14 NM/s
|
|
1238
|
+
* @param record 단일 Record 파싱 결과
|
|
1239
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1240
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1241
|
+
*/
|
|
1242
|
+
const di160 = (record, bitArr, currentPos) => {
|
|
1243
|
+
const octet1 = bitArr[currentPos++];
|
|
1244
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
1245
|
+
record["021_160_RE"] = "Value in defined range (0)";
|
|
1246
|
+
}
|
|
1247
|
+
else {
|
|
1248
|
+
record["021_160_RE"] = "Value exceeds defined range (1)";
|
|
1249
|
+
}
|
|
1250
|
+
const gsFrontOctet = (0, common_1.octetOfRange)(octet1, 6, 0, 6);
|
|
1251
|
+
const octet2 = bitArr[currentPos++];
|
|
1252
|
+
const gsOctet = gsFrontOctet << (8) | octet2;
|
|
1253
|
+
const gs = gsOctet / (1 << 14);
|
|
1254
|
+
record["021_160_Ground Speed"] = gs;
|
|
1255
|
+
const octet3 = bitArr[currentPos++];
|
|
1256
|
+
const octet4 = bitArr[currentPos++];
|
|
1257
|
+
const taOctet = octet3 << (8) | octet4;
|
|
1258
|
+
const ta = (taOctet * 360) / (1 << 16);
|
|
1259
|
+
record["021_160_Track Angle"] = ta;
|
|
1260
|
+
};
|
|
1261
|
+
/**
|
|
1262
|
+
* Data Item I021/161, Track Number
|
|
1263
|
+
* 특정 트랙 파일 내에서 개별 트랙 기록을 구분하는 고유한 참조용 정수 값
|
|
1264
|
+
* 고정 길이, 2 octet
|
|
1265
|
+
* @param record 단일 Record 파싱 결과
|
|
1266
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1267
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1268
|
+
*/
|
|
1269
|
+
const di161 = (record, bitArr, currentPos) => {
|
|
1270
|
+
const octet1 = bitArr[currentPos++];
|
|
1271
|
+
const tnFrontOctet = (0, common_1.octetOfRange)(octet1, 3, 0, 3);
|
|
1272
|
+
const octet2 = bitArr[currentPos++];
|
|
1273
|
+
const tnOctet = tnFrontOctet << (8) | octet2;
|
|
1274
|
+
record["021_161_TRACK NUMBER"] = tnOctet;
|
|
1275
|
+
};
|
|
1276
|
+
/**
|
|
1277
|
+
* Data Item I021/165, Track Angle Rate
|
|
1278
|
+
* 2의 보수 형식으로 표현된 선회율(회전 속도)
|
|
1279
|
+
* 고정 길이, 4 octet
|
|
1280
|
+
* LSB(스케일링 계수): 1/32 °/s
|
|
1281
|
+
* 2의 보수 필요
|
|
1282
|
+
* @param record 단일 Record 파싱 결과
|
|
1283
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1284
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1285
|
+
*/
|
|
1286
|
+
const di165 = (record, bitArr, currentPos) => {
|
|
1287
|
+
const octet1 = bitArr[currentPos++];
|
|
1288
|
+
const tarFrontOctet = (0, common_1.octetOfRange)(octet1, 1, 0, 1);
|
|
1289
|
+
const octet2 = bitArr[currentPos++];
|
|
1290
|
+
const tarOctet = tarFrontOctet << (8) | octet2;
|
|
1291
|
+
const tar = tarOctet / 32;
|
|
1292
|
+
record["021_165_TAR"] = tar;
|
|
1293
|
+
};
|
|
1294
|
+
/**
|
|
1295
|
+
* Data Item I021/170, Target Identification
|
|
1296
|
+
* 타겟(항공기 또는 차량)이 보고한 8자 이내의 고유 식별 정
|
|
1297
|
+
* 고정 길이, 6 octet
|
|
1298
|
+
* @param record 단일 Record 파싱 결과
|
|
1299
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1300
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1301
|
+
*/
|
|
1302
|
+
const di170 = (record, bitArr, currentPos) => {
|
|
1303
|
+
const octet1 = bitArr[currentPos++];
|
|
1304
|
+
const octet2 = bitArr[currentPos++];
|
|
1305
|
+
const octet3 = bitArr[currentPos++];
|
|
1306
|
+
const char123Octet = (octet1 << (8 * 2)) | (octet2 << 8) | octet3;
|
|
1307
|
+
const char1Octet = (0, common_1.octetOfRange)(char123Octet, 23, 18, 5);
|
|
1308
|
+
const char2Octet = (0, common_1.octetOfRange)(char123Octet, 17, 12, 5);
|
|
1309
|
+
const char3Octet = (0, common_1.octetOfRange)(char123Octet, 11, 6, 5);
|
|
1310
|
+
const char4Octet = (0, common_1.octetOfRange)(char123Octet, 5, 0, 5);
|
|
1311
|
+
const octet4 = bitArr[currentPos++];
|
|
1312
|
+
const octet5 = bitArr[currentPos++];
|
|
1313
|
+
const octet6 = bitArr[currentPos++];
|
|
1314
|
+
const char456Octet = (octet4 << (8 * 2)) | (octet5 << 8) | octet6;
|
|
1315
|
+
const char5Octet = (0, common_1.octetOfRange)(char456Octet, 23, 18, 5);
|
|
1316
|
+
const char6Octet = (0, common_1.octetOfRange)(char456Octet, 17, 12, 5);
|
|
1317
|
+
const char7Octet = (0, common_1.octetOfRange)(char456Octet, 11, 6, 5);
|
|
1318
|
+
const char8Octet = (0, common_1.octetOfRange)(char456Octet, 5, 0, 5);
|
|
1319
|
+
const convertedChars = [
|
|
1320
|
+
char1Octet, char2Octet, char3Octet, char4Octet,
|
|
1321
|
+
char5Octet, char6Octet, char7Octet, char8Octet
|
|
1322
|
+
].map(code => (0, common_1.getChar)(code)) // 숫자를 문자로 변환
|
|
1323
|
+
.filter(char => char !== "") // 빈 문자열("") 제거
|
|
1324
|
+
.join(""); // 하나의 문자열로 합치기
|
|
1325
|
+
record["021_170_Target Identification"] = convertedChars;
|
|
1326
|
+
};
|
|
1327
|
+
/**
|
|
1328
|
+
* Data Item I021/200, Target Status
|
|
1329
|
+
* 타겟(추적 대상)의 상태
|
|
1330
|
+
* 고정 길이, 1 octet
|
|
1331
|
+
* @param record 단일 Record 파싱 결과
|
|
1332
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1333
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1334
|
+
*/
|
|
1335
|
+
const di200 = (record, bitArr, currentPos) => {
|
|
1336
|
+
const octet1 = bitArr[currentPos++];
|
|
1337
|
+
if ((octet1 & (1 << 7)) === 0) {
|
|
1338
|
+
record["021_200_ICF"] = "No intent change active (0)";
|
|
1339
|
+
}
|
|
1340
|
+
else {
|
|
1341
|
+
record["021_200_ICF"] = "Intent change flag raised (1)";
|
|
1342
|
+
}
|
|
1343
|
+
if ((octet1 & (1 << 6)) === 0) {
|
|
1344
|
+
record["021_200_LNAV"] = "LNAV Mode engaged (0)";
|
|
1345
|
+
}
|
|
1346
|
+
else {
|
|
1347
|
+
record["021_200_LNAV"] = "LNAV Mode not engaged (1)";
|
|
1348
|
+
}
|
|
1349
|
+
if ((octet1 & (1 << 5)) === 0) {
|
|
1350
|
+
record["021_200_ME"] = "No military emergency (0)";
|
|
1351
|
+
}
|
|
1352
|
+
else {
|
|
1353
|
+
record["021_200_ME"] = "Military emergency (1)";
|
|
1354
|
+
}
|
|
1355
|
+
const psOctet = (0, common_1.octetOfRange)(octet1, 4, 2, 2);
|
|
1356
|
+
switch (psOctet) {
|
|
1357
|
+
case 0:
|
|
1358
|
+
record["021_200_PS"] = "No emergency / not reported (0)";
|
|
1359
|
+
break;
|
|
1360
|
+
case 1:
|
|
1361
|
+
record["021_200_PS"] = "General emergency (1)";
|
|
1362
|
+
break;
|
|
1363
|
+
case 2:
|
|
1364
|
+
record["021_200_PS"] = "Lifeguard / medical emergency (2)";
|
|
1365
|
+
break;
|
|
1366
|
+
case 3:
|
|
1367
|
+
record["021_200_PS"] = "Minimum fuel (3)";
|
|
1368
|
+
break;
|
|
1369
|
+
case 4:
|
|
1370
|
+
record["021_200_PS"] = "No communications (4)";
|
|
1371
|
+
break;
|
|
1372
|
+
case 5:
|
|
1373
|
+
record["021_200_PS"] = "Unlawful interference (5)";
|
|
1374
|
+
break;
|
|
1375
|
+
case 6:
|
|
1376
|
+
record["021_200_PS"] = "'Downed' Aircraft (6)";
|
|
1377
|
+
break;
|
|
1378
|
+
default:
|
|
1379
|
+
record["021_200_PS"] = "UNDEFINED";
|
|
1380
|
+
break;
|
|
1381
|
+
}
|
|
1382
|
+
const ssOctet = (0, common_1.octetOfRange)(octet1, 1, 0, 1);
|
|
1383
|
+
switch (ssOctet) {
|
|
1384
|
+
case 0:
|
|
1385
|
+
record["021_200_SS"] = "No condition reported (0)";
|
|
1386
|
+
break;
|
|
1387
|
+
case 1:
|
|
1388
|
+
record["021_200_SS"] = "Permanent Alert (Emergency condition) (1)";
|
|
1389
|
+
break;
|
|
1390
|
+
case 2:
|
|
1391
|
+
record["021_200_SS"] = "Temporary Alert (change in Mode 3/A Code other than emergency) (2)";
|
|
1392
|
+
break;
|
|
1393
|
+
case 3:
|
|
1394
|
+
record["021_200_SS"] = "SPI set (3)";
|
|
1395
|
+
break;
|
|
1396
|
+
default:
|
|
1397
|
+
record["021_200_SS"] = "UNDEFINED";
|
|
1398
|
+
break;
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1401
|
+
/**
|
|
1402
|
+
* Data Item I021/210, MOPS Version
|
|
1403
|
+
* 항공기(a/c)가 ADS-B 데이터를 송신하기 위해 사용하는 MOPS(최소 운용 성능 표준) 버전 식별
|
|
1404
|
+
* 고정 길이, 1 octet
|
|
1405
|
+
* @param record 단일 Record 파싱 결과
|
|
1406
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1407
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1408
|
+
*/
|
|
1409
|
+
const di210 = (record, bitArr, currentPos) => {
|
|
1410
|
+
const octet1 = bitArr[currentPos++];
|
|
1411
|
+
if ((octet1 & (1 << 6)) === 0) {
|
|
1412
|
+
record["021_210_VNS"] = "The MOPS Version is supported by the GS (0)";
|
|
1413
|
+
}
|
|
1414
|
+
else {
|
|
1415
|
+
record["021_210_VNS"] = "The MOPS Version is not supported by the GS (1)";
|
|
1416
|
+
}
|
|
1417
|
+
const vnOctet = (0, common_1.octetOfRange)(octet1, 5, 3, 2);
|
|
1418
|
+
switch (vnOctet) {
|
|
1419
|
+
case 0:
|
|
1420
|
+
record["021_210_VN"] = "ED102/DO-260 [Ref. 7] (0)";
|
|
1421
|
+
break;
|
|
1422
|
+
case 1:
|
|
1423
|
+
record["021_210_VN"] = "DO-260A [Ref. 8] (1)";
|
|
1424
|
+
break;
|
|
1425
|
+
case 2:
|
|
1426
|
+
record["021_210_VN"] = "ED102A/DO-260B [Ref. 10] (2)";
|
|
1427
|
+
break;
|
|
1428
|
+
case 3:
|
|
1429
|
+
record["021_210_VN"] = "ED-102B/DO-260C [Ref. 11] (3)";
|
|
1430
|
+
break;
|
|
1431
|
+
default:
|
|
1432
|
+
record["021_210_VN"] = "UNDEFINED";
|
|
1433
|
+
break;
|
|
1434
|
+
}
|
|
1435
|
+
const lttOctet = (0, common_1.octetOfRange)(octet1, 2, 0, 2);
|
|
1436
|
+
switch (lttOctet) {
|
|
1437
|
+
case 0:
|
|
1438
|
+
record["021_210_LTT"] = "Other (0)";
|
|
1439
|
+
break;
|
|
1440
|
+
case 1:
|
|
1441
|
+
record["021_210_LTT"] = "UAT (1)";
|
|
1442
|
+
break;
|
|
1443
|
+
case 2:
|
|
1444
|
+
record["021_210_LTT"] = "1090 ES (2)";
|
|
1445
|
+
break;
|
|
1446
|
+
case 3:
|
|
1447
|
+
record["021_210_LTT"] = "VDL 4 (3)";
|
|
1448
|
+
break;
|
|
1449
|
+
case 4:
|
|
1450
|
+
record["021_210_LTT"] = "Not assigned (4)";
|
|
1451
|
+
break;
|
|
1452
|
+
case 5:
|
|
1453
|
+
record["021_210_LTT"] = "Not assigned (5)";
|
|
1454
|
+
break;
|
|
1455
|
+
case 6:
|
|
1456
|
+
record["021_210_LTT"] = "Not assigned (6)";
|
|
1457
|
+
break;
|
|
1458
|
+
case 7:
|
|
1459
|
+
record["021_210_LTT"] = "Not assigned (7)";
|
|
1460
|
+
break;
|
|
1461
|
+
default:
|
|
1462
|
+
record["021_210_LTT"] = "UNDEFINED";
|
|
1463
|
+
break;
|
|
1464
|
+
}
|
|
1465
|
+
};
|
|
1466
|
+
/**
|
|
1467
|
+
* Data Item I021/220, Met Information
|
|
1468
|
+
* 기상 정보
|
|
1469
|
+
* 가변 길이
|
|
1470
|
+
* @param record 단일 Record 파싱 결과
|
|
1471
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1472
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1473
|
+
*/
|
|
1474
|
+
const di220 = (record, bitArr, currentPos) => {
|
|
1475
|
+
const octet1 = bitArr[currentPos++];
|
|
1476
|
+
if ((octet1 & (1 << 7)) != 0) {
|
|
1477
|
+
// WS
|
|
1478
|
+
const octet1 = bitArr[currentPos++];
|
|
1479
|
+
const octet2 = bitArr[currentPos++];
|
|
1480
|
+
const wsOctet = (octet1 << 8) | octet2;
|
|
1481
|
+
record["021_220_Wind Speed"] = wsOctet;
|
|
1482
|
+
}
|
|
1483
|
+
if ((octet1 & (1 << 6)) != 0) {
|
|
1484
|
+
// WD
|
|
1485
|
+
const octet1 = bitArr[currentPos++];
|
|
1486
|
+
const octet2 = bitArr[currentPos++];
|
|
1487
|
+
const wdOctet = (octet1 << 8) | octet2;
|
|
1488
|
+
record["021_220_Wind Direction"] = wdOctet;
|
|
1489
|
+
}
|
|
1490
|
+
if ((octet1 & (1 << 5)) != 0) {
|
|
1491
|
+
// TMP
|
|
1492
|
+
const octet1 = bitArr[currentPos++];
|
|
1493
|
+
const octet2 = bitArr[currentPos++];
|
|
1494
|
+
const wdOctet = (octet1 << 8) | octet2;
|
|
1495
|
+
record["021_220_Temperature"] = wdOctet;
|
|
1496
|
+
}
|
|
1497
|
+
if ((octet1 & (1 << 4)) != 0) {
|
|
1498
|
+
// TRB
|
|
1499
|
+
const octet1 = bitArr[currentPos++];
|
|
1500
|
+
record["021_220_Turbulence"] = octet1;
|
|
1501
|
+
}
|
|
1502
|
+
};
|
|
1503
|
+
/**
|
|
1504
|
+
* Data Item I021/230, Roll Angle
|
|
1505
|
+
* 선회 중인 항공기의 롤 각도(Roll Angle, 경사각)를 2의 보수 형식으로 표현한 것
|
|
1506
|
+
* 고정 길이, 2 octet
|
|
1507
|
+
* LSB(스케일링 계수): 0.01 degree
|
|
1508
|
+
* 2의 보수 필요
|
|
1509
|
+
* @param record 단일 Record 파싱 결과
|
|
1510
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1511
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1512
|
+
*/
|
|
1513
|
+
const di230 = (record, bitArr, currentPos) => {
|
|
1514
|
+
const octet1 = bitArr[currentPos++];
|
|
1515
|
+
const octet2 = bitArr[currentPos++];
|
|
1516
|
+
const raOctet = (octet1 << 8) | octet2;
|
|
1517
|
+
const ra = (0, common_1.twosCompliment)(raOctet, 16) * 0.01;
|
|
1518
|
+
record["021_230_Roll Angle"] = ra;
|
|
1519
|
+
};
|
|
1520
|
+
/**
|
|
1521
|
+
* Data Item I021/250, Mode S MB Data
|
|
1522
|
+
* 항공기 트랜스폰더(송수신기)로부터 추출된 Mode S Comm B 데이터
|
|
1523
|
+
* 가변 길이
|
|
1524
|
+
* @param record 단일 Record 파싱 결과
|
|
1525
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1526
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1527
|
+
*/
|
|
1528
|
+
const di250 = (record, bitArr, currentPos) => {
|
|
1529
|
+
const octet1 = bitArr[currentPos++];
|
|
1530
|
+
for (let index = 0; index < octet1; index++) {
|
|
1531
|
+
const octet2 = bitArr[currentPos++];
|
|
1532
|
+
const octet3 = bitArr[currentPos++];
|
|
1533
|
+
const octet4 = bitArr[currentPos++];
|
|
1534
|
+
const octet5 = bitArr[currentPos++];
|
|
1535
|
+
const octet6 = bitArr[currentPos++];
|
|
1536
|
+
const octet7 = bitArr[currentPos++];
|
|
1537
|
+
const octet8 = bitArr[currentPos++];
|
|
1538
|
+
const mbOctet = (octet2 << (8 * 6)) | (octet3 << (8 * 5)) |
|
|
1539
|
+
(octet4 << (8 * 4)) | (octet5 << (8 * 3)) |
|
|
1540
|
+
(octet6 << (8 * 2)) | (octet7 << 8) | octet8;
|
|
1541
|
+
record["021_230_MB DATA_" + (index + 1)] = mbOctet;
|
|
1542
|
+
const octet9 = bitArr[currentPos++];
|
|
1543
|
+
const bds1Octet = (0, common_1.octetOfRange)(octet9, 7, 4, 3);
|
|
1544
|
+
const bds2Octet = (0, common_1.octetOfRange)(octet9, 3, 0, 3);
|
|
1545
|
+
record["021_230_BDS1_" + (index + 1)] = bds1Octet;
|
|
1546
|
+
record["021_230_BDS2_" + (index + 1)] = bds2Octet;
|
|
1547
|
+
}
|
|
1548
|
+
};
|
|
1549
|
+
/**
|
|
1550
|
+
* Data Item I021/260, ACAS Resolution Advisory Report
|
|
1551
|
+
* RA 메시지 및 위협 식별 데이터를 송신하는 트랜스폰더와 연결된 ACAS가 생성한, 현재 활성화된 회피 지시(RA) 정보(있는 경우)
|
|
1552
|
+
* 고정 길이, 7 octet
|
|
1553
|
+
* @param record 단일 Record 파싱 결과
|
|
1554
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1555
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1556
|
+
*/
|
|
1557
|
+
const di260 = (record, bitArr, currentPos) => {
|
|
1558
|
+
const octet1 = bitArr[currentPos++];
|
|
1559
|
+
const typOctet = (0, common_1.octetOfRange)(octet1, 7, 3, 4);
|
|
1560
|
+
record["021_260_TYP"] = typOctet;
|
|
1561
|
+
const stypOctet = (0, common_1.octetOfRange)(octet1, 2, 0, 2);
|
|
1562
|
+
record["021_260_STYP"] = stypOctet;
|
|
1563
|
+
const octet2 = bitArr[currentPos++];
|
|
1564
|
+
const octet3 = bitArr[currentPos++];
|
|
1565
|
+
const araOctet = (octet2 << 6) | (0, common_1.octetOfRange)(octet3, 7, 2, 5);
|
|
1566
|
+
record["021_260_ARA"] = araOctet;
|
|
1567
|
+
const octet4 = bitArr[currentPos++];
|
|
1568
|
+
const racOctet = (0, common_1.octetOfRange)(octet3, 1, 0, 1) | (0, common_1.octetOfRange)(octet4, 7, 6, 1);
|
|
1569
|
+
record["021_260_RAC"] = racOctet;
|
|
1570
|
+
record["021_260_RAT"] = ((octet4 & (1 << 5)) != 0) ? 1 : 0;
|
|
1571
|
+
record["021_260_MTE"] = ((octet4 & (1 << 4)) != 0) ? 1 : 0;
|
|
1572
|
+
record["021_260_TTI"] = (0, common_1.octetOfRange)(octet4, 3, 2, 1);
|
|
1573
|
+
const tidFrontValue = (0, common_1.octetOfRange)(octet4, 1, 0, 1);
|
|
1574
|
+
const octet5 = bitArr[currentPos++];
|
|
1575
|
+
const octet6 = bitArr[currentPos++];
|
|
1576
|
+
const octet7 = bitArr[currentPos++];
|
|
1577
|
+
record["021_260_TID"] = (tidFrontValue << (8 * 3)) | (octet5 << (8 * 2)) | (octet6 << 8) | (octet7);
|
|
1578
|
+
};
|
|
1579
|
+
/**
|
|
1580
|
+
* Data Item I021/271, Surface Capabilities and Characteristics\
|
|
1581
|
+
* 지상 활주 중(지상에 있는 동안) 항공기의 운용 가능 능력
|
|
1582
|
+
* 가변 길이
|
|
1583
|
+
* @param record 단일 Record 파싱 결과
|
|
1584
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1585
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1586
|
+
*/
|
|
1587
|
+
const di271 = (record, bitArr, currentPos) => {
|
|
1588
|
+
const octet1 = bitArr[currentPos++];
|
|
1589
|
+
if ((octet1 & (1 << 5)) === 0) {
|
|
1590
|
+
record["021_271_POA"] = "Position transmitted is not ADS-B position reference point (0)";
|
|
1591
|
+
}
|
|
1592
|
+
else {
|
|
1593
|
+
record["021_271_POA"] = "Position transmitted is ADS-B position reference point (1)";
|
|
1594
|
+
}
|
|
1595
|
+
if ((octet1 & (1 << 4)) === 0) {
|
|
1596
|
+
record["021_271_CDTI/S"] = "CDTI not operational (0)";
|
|
1597
|
+
}
|
|
1598
|
+
else {
|
|
1599
|
+
record["021_271_CDTI/S"] = "CDTI operational (1)";
|
|
1600
|
+
}
|
|
1601
|
+
if ((octet1 & (1 << 3)) === 0) {
|
|
1602
|
+
record["021_271_B2 low"] = ">= 70 Watts (0)";
|
|
1603
|
+
}
|
|
1604
|
+
else {
|
|
1605
|
+
record["021_271_B2 low"] = "< 70 Watts (1)";
|
|
1606
|
+
}
|
|
1607
|
+
if ((octet1 & (1 << 2)) === 0) {
|
|
1608
|
+
record["021_271_RAS"] = "Aircraft not receiving ATC-services (0)";
|
|
1609
|
+
}
|
|
1610
|
+
else {
|
|
1611
|
+
record["021_271_RAS"] = "Aircraft receiving ATC services (1)";
|
|
1612
|
+
}
|
|
1613
|
+
if ((octet1 & (1 << 1)) === 0) {
|
|
1614
|
+
record["021_271_IDENT"] = "IDENT switch not active (0)";
|
|
1615
|
+
}
|
|
1616
|
+
else {
|
|
1617
|
+
record["021_271_IDENT"] = "IDENT switch active (1)";
|
|
1618
|
+
}
|
|
1619
|
+
if ((octet1 & (1)) === 0)
|
|
1620
|
+
return;
|
|
1621
|
+
const octet2 = bitArr[currentPos++];
|
|
1622
|
+
const lwValue = (0, common_1.octetOfRange)(octet2, 7, 4, 3);
|
|
1623
|
+
record["021_271_LW"] = lwValue;
|
|
1624
|
+
};
|
|
1625
|
+
/**
|
|
1626
|
+
* Data Item I021/295, Data Ages
|
|
1627
|
+
* 제공된 데이터의 생성 경과 시간(데이터의 신선도)
|
|
1628
|
+
* 가변 길이
|
|
1629
|
+
* @param record 단일 Record 파싱 결과
|
|
1630
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1631
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1632
|
+
*/
|
|
1633
|
+
const di295 = (record, bitArr, currentPos) => {
|
|
1634
|
+
const { bits, headerLen } = (0, preprocess_1.parseIndicator)(bitArr, currentPos);
|
|
1635
|
+
currentPos += headerLen;
|
|
1636
|
+
if ((0, common_1.isBitSet)(bits, 1, currentPos)) {
|
|
1637
|
+
// AOS
|
|
1638
|
+
const octet1 = bitArr[currentPos++];
|
|
1639
|
+
record["021_295_AOS"] = octet1 * 0.1;
|
|
1640
|
+
}
|
|
1641
|
+
if ((0, common_1.isBitSet)(bits, 2, currentPos)) {
|
|
1642
|
+
// TRD
|
|
1643
|
+
const octet1 = bitArr[currentPos++];
|
|
1644
|
+
record["021_295_TRD"] = octet1 * 0.1;
|
|
1645
|
+
}
|
|
1646
|
+
if ((0, common_1.isBitSet)(bits, 3, currentPos)) {
|
|
1647
|
+
// M3A
|
|
1648
|
+
const octet1 = bitArr[currentPos++];
|
|
1649
|
+
record["021_295_M3A"] = octet1 * 0.1;
|
|
1650
|
+
}
|
|
1651
|
+
if ((0, common_1.isBitSet)(bits, 4, currentPos)) {
|
|
1652
|
+
// QI
|
|
1653
|
+
const octet1 = bitArr[currentPos++];
|
|
1654
|
+
record["021_295_QI"] = octet1 * 0.1;
|
|
1655
|
+
}
|
|
1656
|
+
if ((0, common_1.isBitSet)(bits, 5, currentPos)) {
|
|
1657
|
+
// TI
|
|
1658
|
+
const octet1 = bitArr[currentPos++];
|
|
1659
|
+
record["021_295_TI"] = octet1 * 0.1;
|
|
1660
|
+
}
|
|
1661
|
+
if ((0, common_1.isBitSet)(bits, 6, currentPos)) {
|
|
1662
|
+
// MAM
|
|
1663
|
+
const octet1 = bitArr[currentPos++];
|
|
1664
|
+
record["021_295_MAM"] = octet1 * 0.1;
|
|
1665
|
+
}
|
|
1666
|
+
if ((0, common_1.isBitSet)(bits, 7, currentPos)) {
|
|
1667
|
+
// GH
|
|
1668
|
+
const octet1 = bitArr[currentPos++];
|
|
1669
|
+
record["021_295_GH"] = octet1 * 0.1;
|
|
1670
|
+
}
|
|
1671
|
+
if ((0, common_1.isBitSet)(bits, 8, currentPos)) {
|
|
1672
|
+
// FL
|
|
1673
|
+
const octet1 = bitArr[currentPos++];
|
|
1674
|
+
record["021_295_FL"] = octet1 * 0.1;
|
|
1675
|
+
}
|
|
1676
|
+
if ((0, common_1.isBitSet)(bits, 9, currentPos)) {
|
|
1677
|
+
// ISA
|
|
1678
|
+
const octet1 = bitArr[currentPos++];
|
|
1679
|
+
record["021_295_ISA"] = octet1 * 0.1;
|
|
1680
|
+
}
|
|
1681
|
+
if ((0, common_1.isBitSet)(bits, 10, currentPos)) {
|
|
1682
|
+
// FSA
|
|
1683
|
+
const octet1 = bitArr[currentPos++];
|
|
1684
|
+
record["021_295_FSA"] = octet1 * 0.1;
|
|
1685
|
+
}
|
|
1686
|
+
if ((0, common_1.isBitSet)(bits, 11, currentPos)) {
|
|
1687
|
+
// AS
|
|
1688
|
+
const octet1 = bitArr[currentPos++];
|
|
1689
|
+
record["021_295_AS"] = octet1 * 0.1;
|
|
1690
|
+
}
|
|
1691
|
+
if ((0, common_1.isBitSet)(bits, 12, currentPos)) {
|
|
1692
|
+
// TAS
|
|
1693
|
+
const octet1 = bitArr[currentPos++];
|
|
1694
|
+
record["021_295_TAS"] = octet1 * 0.1;
|
|
1695
|
+
}
|
|
1696
|
+
if ((0, common_1.isBitSet)(bits, 13, currentPos)) {
|
|
1697
|
+
// MH
|
|
1698
|
+
const octet1 = bitArr[currentPos++];
|
|
1699
|
+
record["021_295_MH"] = octet1 * 0.1;
|
|
1700
|
+
}
|
|
1701
|
+
if ((0, common_1.isBitSet)(bits, 14, currentPos)) {
|
|
1702
|
+
// BVR
|
|
1703
|
+
const octet1 = bitArr[currentPos++];
|
|
1704
|
+
record["021_295_BVR"] = octet1 * 0.1;
|
|
1705
|
+
}
|
|
1706
|
+
if ((0, common_1.isBitSet)(bits, 15, currentPos)) {
|
|
1707
|
+
// GVR
|
|
1708
|
+
const octet1 = bitArr[currentPos++];
|
|
1709
|
+
record["021_295_GVR"] = octet1 * 0.1;
|
|
1710
|
+
}
|
|
1711
|
+
if ((0, common_1.isBitSet)(bits, 16, currentPos)) {
|
|
1712
|
+
// GV
|
|
1713
|
+
const octet1 = bitArr[currentPos++];
|
|
1714
|
+
record["021_295_GV"] = octet1 * 0.1;
|
|
1715
|
+
}
|
|
1716
|
+
if ((0, common_1.isBitSet)(bits, 17, currentPos)) {
|
|
1717
|
+
// TAR
|
|
1718
|
+
const octet1 = bitArr[currentPos++];
|
|
1719
|
+
record["021_295_TAR"] = octet1 * 0.1;
|
|
1720
|
+
}
|
|
1721
|
+
if ((0, common_1.isBitSet)(bits, 18, currentPos)) {
|
|
1722
|
+
// TI
|
|
1723
|
+
const octet1 = bitArr[currentPos++];
|
|
1724
|
+
record["021_295_TI"] = octet1 * 0.1;
|
|
1725
|
+
}
|
|
1726
|
+
if ((0, common_1.isBitSet)(bits, 19, currentPos)) {
|
|
1727
|
+
// TS
|
|
1728
|
+
const octet1 = bitArr[currentPos++];
|
|
1729
|
+
record["021_295_TS"] = octet1 * 0.1;
|
|
1730
|
+
}
|
|
1731
|
+
if ((0, common_1.isBitSet)(bits, 20, currentPos)) {
|
|
1732
|
+
// MET
|
|
1733
|
+
const octet1 = bitArr[currentPos++];
|
|
1734
|
+
record["021_295_MET"] = octet1 * 0.1;
|
|
1735
|
+
}
|
|
1736
|
+
if ((0, common_1.isBitSet)(bits, 21, currentPos)) {
|
|
1737
|
+
// ROA
|
|
1738
|
+
const octet1 = bitArr[currentPos++];
|
|
1739
|
+
record["021_295_ROA"] = octet1 * 0.1;
|
|
1740
|
+
}
|
|
1741
|
+
if ((0, common_1.isBitSet)(bits, 22, currentPos)) {
|
|
1742
|
+
// ARA
|
|
1743
|
+
const octet1 = bitArr[currentPos++];
|
|
1744
|
+
record["021_295_ARA"] = octet1 * 0.1;
|
|
1745
|
+
}
|
|
1746
|
+
if ((0, common_1.isBitSet)(bits, 23, currentPos)) {
|
|
1747
|
+
// SCC
|
|
1748
|
+
const octet1 = bitArr[currentPos++];
|
|
1749
|
+
record["021_295_SCC"] = octet1 * 0.1;
|
|
1750
|
+
}
|
|
1751
|
+
};
|
|
1752
|
+
/**
|
|
1753
|
+
* Data Item I021/400, Receiver ID
|
|
1754
|
+
* 분산 시스템 내 지상국 식별자(명칭)
|
|
1755
|
+
* 고정 길이, 1 octet
|
|
1756
|
+
* @param record 단일 Record 파싱 결과
|
|
1757
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1758
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1759
|
+
*/
|
|
1760
|
+
const di400 = (record, bitArr, currentPos) => {
|
|
1761
|
+
const octet1 = bitArr[currentPos++];
|
|
1762
|
+
record["021_400_RID"] = octet1;
|
|
1763
|
+
};
|
|
1764
|
+
/**
|
|
1765
|
+
* Data Item SP - 문서 상에 파싱 규칙 없음
|
|
1766
|
+
* 가변 길이
|
|
1767
|
+
* @param record 단일 Record 파싱 결과
|
|
1768
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1769
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1770
|
+
* @param diLength 메모리 재할당 방지
|
|
1771
|
+
*/
|
|
1772
|
+
const sp = (record, bitArr, currentPos, diLength) => {
|
|
1773
|
+
record["021_SP"] = (0, preprocess_1.getHexString)(bitArr, currentPos, diLength);
|
|
1774
|
+
};
|
|
1775
|
+
/**
|
|
1776
|
+
* Data Item RE - 문서 상에 파싱 규칙 없음
|
|
1777
|
+
* 가변 길이
|
|
1778
|
+
* @param record 단일 Record 파싱 결과
|
|
1779
|
+
* @param bitArr Asterix 바이트 데이터
|
|
1780
|
+
* @param currentPos 데이터 아이템 시작 인덱스
|
|
1781
|
+
* @param diLength 데이터 길이
|
|
1782
|
+
*/
|
|
1783
|
+
const re = (record, bitArr, currentPos, diLength) => {
|
|
1784
|
+
record["021_RE"] = (0, preprocess_1.getHexString)(bitArr, currentPos, diLength);
|
|
1785
|
+
};
|