@squawk/mode-s 0.1.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/README.md +243 -0
- package/dist/acas.d.ts +14 -0
- package/dist/acas.d.ts.map +1 -0
- package/dist/acas.js +90 -0
- package/dist/altitude.d.ts +34 -0
- package/dist/altitude.d.ts.map +1 -0
- package/dist/altitude.js +99 -0
- package/dist/bits.d.ts +41 -0
- package/dist/bits.d.ts.map +1 -0
- package/dist/bits.js +55 -0
- package/dist/comm-b.d.ts +37 -0
- package/dist/comm-b.d.ts.map +1 -0
- package/dist/comm-b.js +245 -0
- package/dist/cpr.d.ts +71 -0
- package/dist/cpr.d.ts.map +1 -0
- package/dist/cpr.js +220 -0
- package/dist/emergency-status.d.ts +10 -0
- package/dist/emergency-status.d.ts.map +1 -0
- package/dist/emergency-status.js +21 -0
- package/dist/frame.d.ts +42 -0
- package/dist/frame.d.ts.map +1 -0
- package/dist/frame.js +68 -0
- package/dist/identification.d.ts +10 -0
- package/dist/identification.d.ts.map +1 -0
- package/dist/identification.js +64 -0
- package/dist/identity.d.ts +11 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +20 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/message.d.ts +40 -0
- package/dist/message.d.ts.map +1 -0
- package/dist/message.js +293 -0
- package/dist/mode-ac.d.ts +17 -0
- package/dist/mode-ac.d.ts.map +1 -0
- package/dist/mode-ac.js +86 -0
- package/dist/operational-status.d.ts +9 -0
- package/dist/operational-status.d.ts.map +1 -0
- package/dist/operational-status.js +23 -0
- package/dist/surface-movement.d.ts +9 -0
- package/dist/surface-movement.d.ts.map +1 -0
- package/dist/surface-movement.js +37 -0
- package/dist/target-state-status.d.ts +9 -0
- package/dist/target-state-status.d.ts.map +1 -0
- package/dist/target-state-status.js +34 -0
- package/dist/test-utils.d.ts +7 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +17 -0
- package/dist/types/acas.d.ts +82 -0
- package/dist/types/acas.d.ts.map +1 -0
- package/dist/types/acas.js +1 -0
- package/dist/types/comm-b.d.ts +69 -0
- package/dist/types/comm-b.d.ts.map +1 -0
- package/dist/types/comm-b.js +1 -0
- package/dist/types/cpr.d.ts +25 -0
- package/dist/types/cpr.d.ts.map +1 -0
- package/dist/types/cpr.js +1 -0
- package/dist/types/emergency-status.d.ts +6 -0
- package/dist/types/emergency-status.d.ts.map +1 -0
- package/dist/types/emergency-status.js +1 -0
- package/dist/types/frame.d.ts +32 -0
- package/dist/types/frame.d.ts.map +1 -0
- package/dist/types/frame.js +1 -0
- package/dist/types/identification.d.ts +9 -0
- package/dist/types/identification.d.ts.map +1 -0
- package/dist/types/identification.js +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/message.d.ts +235 -0
- package/dist/types/message.d.ts.map +1 -0
- package/dist/types/message.js +1 -0
- package/dist/types/mode-ac.d.ts +16 -0
- package/dist/types/mode-ac.d.ts.map +1 -0
- package/dist/types/mode-ac.js +1 -0
- package/dist/types/operational-status.d.ts +28 -0
- package/dist/types/operational-status.d.ts.map +1 -0
- package/dist/types/operational-status.js +1 -0
- package/dist/types/target-state-status.d.ts +34 -0
- package/dist/types/target-state-status.d.ts.map +1 -0
- package/dist/types/target-state-status.js +1 -0
- package/dist/types/velocity.d.ts +35 -0
- package/dist/types/velocity.d.ts.map +1 -0
- package/dist/types/velocity.js +1 -0
- package/dist/velocity.d.ts +9 -0
- package/dist/velocity.d.ts.map +1 -0
- package/dist/velocity.js +73 -0
- package/package.json +61 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import type { AcasResolutionAdvisoryReport } from './acas.js';
|
|
2
|
+
import type { CommBRegister } from './comm-b.js';
|
|
3
|
+
import type { EmergencyState } from './emergency-status.js';
|
|
4
|
+
import type { AircraftIdentification } from './identification.js';
|
|
5
|
+
import type { AircraftOperationalStatus } from './operational-status.js';
|
|
6
|
+
import type { TargetStateAndStatus } from './target-state-status.js';
|
|
7
|
+
import type { AirborneVelocity } from './velocity.js';
|
|
8
|
+
/**
|
|
9
|
+
* Where a DF17/18 extended squitter's address and data actually came from.
|
|
10
|
+
* DF17 is always `icaoDirect` - it carries no control field, and a DF17
|
|
11
|
+
* transponder is, by protocol definition, always ICAO-addressed and
|
|
12
|
+
* broadcasting its own state directly. For DF18, this is derived from the
|
|
13
|
+
* control field (CF):
|
|
14
|
+
* - `icaoDirect` (CF=0): ICAO-addressed, direct from the aircraft - same as DF17.
|
|
15
|
+
* - `anonymousDirect` (CF=1): a self-assigned or anonymous address (e.g. a
|
|
16
|
+
* ground vehicle's ADS-B-out unit with no Mode-S allocation), direct from
|
|
17
|
+
* the transmitting participant - `icaoHex` is not a registered ICAO address.
|
|
18
|
+
* - `icaoTisb` (CF=2): ICAO-addressed, but ground-station-derived (TIS-B,
|
|
19
|
+
* fine format) rather than heard directly from the aircraft's own transponder.
|
|
20
|
+
* - `anonymousTisb` (CF=5): a ground-assigned track-file address (TIS-B, fine
|
|
21
|
+
* format, non-ICAO) - `icaoHex` is not a registered ICAO address.
|
|
22
|
+
* - `adsr` (CF=6): ICAO-addressed, relayed from another data link (e.g. UAT)
|
|
23
|
+
* by a ground station (ADS-B Rebroadcast).
|
|
24
|
+
*/
|
|
25
|
+
export type MessageSource = 'icaoDirect' | 'anonymousDirect' | 'icaoTisb' | 'anonymousTisb' | 'adsr';
|
|
26
|
+
/** Fields common to every decoded DF17/18 extended squitter message. */
|
|
27
|
+
export interface ExtendedSquitterCommon {
|
|
28
|
+
/**
|
|
29
|
+
* 24-bit hex address from the message's AA field. A real, registered ICAO
|
|
30
|
+
* Mode-S address when `messageSource` is `icaoDirect`/`icaoTisb`/`adsr` -
|
|
31
|
+
* an anonymous or ground-assigned identifier, not a registered ICAO
|
|
32
|
+
* address, when `messageSource` is `anonymousDirect`/`anonymousTisb`.
|
|
33
|
+
*/
|
|
34
|
+
icaoHex: string;
|
|
35
|
+
/** Where this message's address and data actually came from - see {@link MessageSource}. */
|
|
36
|
+
messageSource: MessageSource;
|
|
37
|
+
}
|
|
38
|
+
/** A DF17/18 extended squitter airborne or surface position message. */
|
|
39
|
+
export interface ExtendedSquitterPosition extends ExtendedSquitterCommon {
|
|
40
|
+
/** Discriminant tag identifying this as a decoded airborne or surface position message. */
|
|
41
|
+
kind: 'extendedSquitterPosition';
|
|
42
|
+
/** Whether this is a surface (on-ground) or airborne position message. */
|
|
43
|
+
surface: boolean;
|
|
44
|
+
/** Whether the CPR fields use the even or odd format. */
|
|
45
|
+
cprFormat: 'even' | 'odd';
|
|
46
|
+
/** Raw 17-bit CPR-encoded latitude field, or undefined for a type-code-0 airborne position message (no position information available - altitude may still be valid). */
|
|
47
|
+
latCpr: number | undefined;
|
|
48
|
+
/** Raw 17-bit CPR-encoded longitude field, or undefined for a type-code-0 airborne position message (no position information available - altitude may still be valid). */
|
|
49
|
+
lonCpr: number | undefined;
|
|
50
|
+
/** Decoded altitude in feet. Always undefined for a surface position - surface messages carry ground movement/track in place of altitude. */
|
|
51
|
+
altitudeFt: number | undefined;
|
|
52
|
+
/** Ground speed in knots, decoded from the movement field. Always undefined for an airborne position - airborne messages carry altitude in the same bits instead. */
|
|
53
|
+
groundSpeedKt: number | undefined;
|
|
54
|
+
/** Track over ground in degrees true. Always undefined for an airborne position, and for a surface position whose track status bit is unset (no valid track available). */
|
|
55
|
+
trueTrackDeg: number | undefined;
|
|
56
|
+
}
|
|
57
|
+
/** A DF17/18 extended squitter airborne velocity message. */
|
|
58
|
+
export interface ExtendedSquitterVelocity extends ExtendedSquitterCommon {
|
|
59
|
+
/** Discriminant tag identifying this as a decoded airborne velocity message. */
|
|
60
|
+
kind: 'extendedSquitterVelocity';
|
|
61
|
+
/** The decoded velocity. */
|
|
62
|
+
velocity: AirborneVelocity;
|
|
63
|
+
}
|
|
64
|
+
/** A DF17/18 extended squitter aircraft identification message. */
|
|
65
|
+
export interface ExtendedSquitterIdentification extends ExtendedSquitterCommon {
|
|
66
|
+
/** Discriminant tag identifying this as a decoded aircraft identification message. */
|
|
67
|
+
kind: 'extendedSquitterIdentification';
|
|
68
|
+
/** The decoded callsign and category. */
|
|
69
|
+
identification: AircraftIdentification;
|
|
70
|
+
}
|
|
71
|
+
/** A DF17/18 extended squitter Target State and Status message (type code 29). */
|
|
72
|
+
export interface ExtendedSquitterTargetStateAndStatus extends ExtendedSquitterCommon {
|
|
73
|
+
/** Discriminant tag identifying this as a decoded Target State and Status message. */
|
|
74
|
+
kind: 'extendedSquitterTargetStateAndStatus';
|
|
75
|
+
/** The decoded target state and status. */
|
|
76
|
+
targetStateAndStatus: TargetStateAndStatus;
|
|
77
|
+
}
|
|
78
|
+
/** A DF17/18 extended squitter Aircraft Operational Status message (type code 31). */
|
|
79
|
+
export interface ExtendedSquitterOperationalStatus extends ExtendedSquitterCommon {
|
|
80
|
+
/** Discriminant tag identifying this as a decoded Aircraft Operational Status message. */
|
|
81
|
+
kind: 'extendedSquitterOperationalStatus';
|
|
82
|
+
/** The decoded operational status. */
|
|
83
|
+
operationalStatus: AircraftOperationalStatus;
|
|
84
|
+
}
|
|
85
|
+
/** A DF11 all-call reply - confirms an aircraft's ICAO address, carries no other data. */
|
|
86
|
+
export interface AllCallReply {
|
|
87
|
+
/** Discriminant tag identifying this as a decoded DF11 all-call reply. */
|
|
88
|
+
kind: 'allCallReply';
|
|
89
|
+
/** 24-bit ICAO hex address of the transmitting aircraft. */
|
|
90
|
+
icaoHex: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* A DF0 short air-air surveillance reply (ACAS/TCAS interrogation reply
|
|
94
|
+
* from an aircraft with no resolution advisory currently active - an
|
|
95
|
+
* aircraft replying while an RA is active sends the longer DF16 instead).
|
|
96
|
+
* Like {@link SurveillanceAltitudeReply}, this is a targeted response whose
|
|
97
|
+
* CRC is XORed with the responding aircraft's ICAO address rather than
|
|
98
|
+
* being a plain checksum - `candidateIcaoHex` needs cross-checking against
|
|
99
|
+
* known traffic before it can be trusted.
|
|
100
|
+
*/
|
|
101
|
+
export interface ShortAirAirSurveillanceReply {
|
|
102
|
+
/** Discriminant tag identifying this as a decoded DF0 short air-air surveillance reply. */
|
|
103
|
+
kind: 'shortAirAirSurveillanceReply';
|
|
104
|
+
/** Candidate 24-bit ICAO hex address, recovered from the CRC field - verify against known traffic before trusting it. */
|
|
105
|
+
candidateIcaoHex: string;
|
|
106
|
+
/** Whether the replying aircraft is on the ground, from the vertical status bit. */
|
|
107
|
+
surface: boolean;
|
|
108
|
+
/** Decoded altitude in feet, or undefined if the AC field is empty or invalid. */
|
|
109
|
+
altitudeFt: number | undefined;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A DF16 long air-air surveillance reply - an ACAS/TCAS interrogation reply
|
|
113
|
+
* from an aircraft with a Resolution Advisory currently active. Like
|
|
114
|
+
* {@link SurveillanceAltitudeReply}, this is a targeted response whose CRC
|
|
115
|
+
* is XORed with the responding aircraft's ICAO address rather than being a
|
|
116
|
+
* plain checksum - `candidateIcaoHex` needs cross-checking against known
|
|
117
|
+
* traffic before it can be trusted.
|
|
118
|
+
*/
|
|
119
|
+
export interface LongAirAirSurveillanceReply {
|
|
120
|
+
/** Discriminant tag identifying this as a decoded DF16 long air-air surveillance reply. */
|
|
121
|
+
kind: 'longAirAirSurveillanceReply';
|
|
122
|
+
/** Candidate 24-bit ICAO hex address, recovered from the CRC field - verify against known traffic before trusting it. */
|
|
123
|
+
candidateIcaoHex: string;
|
|
124
|
+
/** Whether the replying aircraft is on the ground, from the vertical status bit. */
|
|
125
|
+
surface: boolean;
|
|
126
|
+
/** Decoded altitude in feet, or undefined if the AC field is empty or invalid. */
|
|
127
|
+
altitudeFt: number | undefined;
|
|
128
|
+
/** The active Resolution Advisory report, or undefined if its Threat Type Indicator was the reserved value. Altitude and address above remain independently valid even when this is undefined. */
|
|
129
|
+
resolutionAdvisory: AcasResolutionAdvisoryReport | undefined;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* A DF4/20 Mode-S surveillance altitude reply. Unlike a squitter, this is
|
|
133
|
+
* a targeted response to an interrogation - its CRC is XORed with the
|
|
134
|
+
* responding aircraft's ICAO address rather than being a plain checksum,
|
|
135
|
+
* so `candidateIcaoHex` is only trustworthy once cross-checked against an
|
|
136
|
+
* address already known from squitter traffic (this package does not
|
|
137
|
+
* perform that cross-check itself; see {@link ModeSMessageEnvelope.crcRemainder}).
|
|
138
|
+
*/
|
|
139
|
+
export interface SurveillanceAltitudeReply {
|
|
140
|
+
/** Discriminant tag identifying this as a decoded DF4 surveillance altitude reply. */
|
|
141
|
+
kind: 'surveillanceAltitudeReply';
|
|
142
|
+
/** Candidate 24-bit ICAO hex address, recovered from the CRC field - verify against known traffic before trusting it. */
|
|
143
|
+
candidateIcaoHex: string;
|
|
144
|
+
/** Decoded altitude in feet, or undefined if the AC field is empty or invalid. */
|
|
145
|
+
altitudeFt: number | undefined;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* A DF20 Comm-B altitude reply - the same altitude payload as
|
|
149
|
+
* {@link SurveillanceAltitudeReply} (DF4), extended with a 56-bit MB field
|
|
150
|
+
* carrying an Enhanced Surveillance Comm-B register. Like
|
|
151
|
+
* {@link SurveillanceAltitudeReply}, this is a targeted response whose CRC
|
|
152
|
+
* is XORed with the responding aircraft's ICAO address rather than being a
|
|
153
|
+
* plain checksum - `candidateIcaoHex` needs cross-checking against known
|
|
154
|
+
* traffic before it can be trusted.
|
|
155
|
+
*/
|
|
156
|
+
export interface CommBAltitudeReply {
|
|
157
|
+
/** Discriminant tag identifying this as a decoded DF20 Comm-B altitude reply. */
|
|
158
|
+
kind: 'commBAltitudeReply';
|
|
159
|
+
/** Candidate 24-bit ICAO hex address, recovered from the CRC field - verify against known traffic before trusting it. */
|
|
160
|
+
candidateIcaoHex: string;
|
|
161
|
+
/** Decoded altitude in feet, or undefined if the AC field is empty or invalid. */
|
|
162
|
+
altitudeFt: number | undefined;
|
|
163
|
+
/** Every Enhanced Surveillance Comm-B register the MB field plausibly holds - see {@link inferCommBRegisters}. Empty if none matched. */
|
|
164
|
+
commBRegisters: CommBRegister[];
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* A DF5/21 Mode-S surveillance identity (squawk) reply. Like
|
|
168
|
+
* {@link SurveillanceAltitudeReply}, this is a targeted response whose CRC
|
|
169
|
+
* is XORed with the responding aircraft's ICAO address rather than being a
|
|
170
|
+
* plain checksum - `candidateIcaoHex` needs cross-checking against known
|
|
171
|
+
* traffic before it can be trusted.
|
|
172
|
+
*/
|
|
173
|
+
export interface SurveillanceIdentityReply {
|
|
174
|
+
/** Discriminant tag identifying this as a decoded DF5 surveillance identity reply. */
|
|
175
|
+
kind: 'surveillanceIdentityReply';
|
|
176
|
+
/** Candidate 24-bit ICAO hex address, recovered from the CRC field - verify against known traffic before trusting it. */
|
|
177
|
+
candidateIcaoHex: string;
|
|
178
|
+
/** The decoded 4-digit octal squawk code. */
|
|
179
|
+
squawk: string;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* A DF21 Comm-B identity reply - the same squawk payload as
|
|
183
|
+
* {@link SurveillanceIdentityReply} (DF5), extended with a 56-bit MB field
|
|
184
|
+
* carrying an Enhanced Surveillance Comm-B register. Like
|
|
185
|
+
* {@link SurveillanceAltitudeReply}, this is a targeted response whose CRC
|
|
186
|
+
* is XORed with the responding aircraft's ICAO address rather than being a
|
|
187
|
+
* plain checksum - `candidateIcaoHex` needs cross-checking against known
|
|
188
|
+
* traffic before it can be trusted.
|
|
189
|
+
*/
|
|
190
|
+
export interface CommBIdentityReply {
|
|
191
|
+
/** Discriminant tag identifying this as a decoded DF21 Comm-B identity reply. */
|
|
192
|
+
kind: 'commBIdentityReply';
|
|
193
|
+
/** Candidate 24-bit ICAO hex address, recovered from the CRC field - verify against known traffic before trusting it. */
|
|
194
|
+
candidateIcaoHex: string;
|
|
195
|
+
/** The decoded 4-digit octal squawk code. */
|
|
196
|
+
squawk: string;
|
|
197
|
+
/** Every Enhanced Surveillance Comm-B register the MB field plausibly holds - see {@link inferCommBRegisters}. Empty if none matched. */
|
|
198
|
+
commBRegisters: CommBRegister[];
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* A DF17/18 extended squitter aircraft status message (type code 28,
|
|
202
|
+
* subtype 1 - emergency/priority status). Subtype 2 (TCAS/ACAS resolution
|
|
203
|
+
* advisory broadcast) decodes to {@link ExtendedSquitterAcasRaBroadcast}
|
|
204
|
+
* instead.
|
|
205
|
+
*/
|
|
206
|
+
export interface ExtendedSquitterEmergencyStatus extends ExtendedSquitterCommon {
|
|
207
|
+
/** Discriminant tag identifying this as a decoded type-code-28 subtype-1 emergency/priority status message. */
|
|
208
|
+
kind: 'extendedSquitterEmergencyStatus';
|
|
209
|
+
/** The declared emergency/priority state. */
|
|
210
|
+
emergencyState: EmergencyState;
|
|
211
|
+
/** The squawk code broadcast alongside the emergency state - the same code the aircraft would transmit via a DF5/21 Mode-S reply, sent here natively over ADS-B. */
|
|
212
|
+
squawk: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* A DF17/18 extended squitter aircraft status message (type code 28,
|
|
216
|
+
* subtype 2 - ACAS/TCAS Resolution Advisory broadcast). Lets aircraft
|
|
217
|
+
* without interrogation capability see that a nearby aircraft has an active
|
|
218
|
+
* RA. Carries the same BDS 3,0 content as a DF16 reply's `resolutionAdvisory`.
|
|
219
|
+
*/
|
|
220
|
+
export interface ExtendedSquitterAcasRaBroadcast extends ExtendedSquitterCommon {
|
|
221
|
+
/** Discriminant tag identifying this as a decoded type-code-28 subtype-2 ACAS Resolution Advisory broadcast. */
|
|
222
|
+
kind: 'extendedSquitterAcasRaBroadcast';
|
|
223
|
+
/** The active Resolution Advisory report. */
|
|
224
|
+
resolutionAdvisory: AcasResolutionAdvisoryReport;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* A decoded Mode-S message. Discriminated by `kind`. DF24 (Comm-D) is
|
|
228
|
+
* recognized at the envelope level but not decoded by this package -
|
|
229
|
+
* {@link decodeModeSMessage} returns undefined for it, the same as a
|
|
230
|
+
* genuinely unsupported or invalid message. DF19 (military extended
|
|
231
|
+
* squitter) and DF22 (military use) are reserved formats with no publicly
|
|
232
|
+
* documented payload and are not decoded, for the same reason.
|
|
233
|
+
*/
|
|
234
|
+
export type DecodedModeSMessage = ExtendedSquitterPosition | ExtendedSquitterVelocity | ExtendedSquitterIdentification | ExtendedSquitterTargetStateAndStatus | ExtendedSquitterOperationalStatus | ExtendedSquitterEmergencyStatus | ExtendedSquitterAcasRaBroadcast | AllCallReply | ShortAirAirSurveillanceReply | LongAirAirSurveillanceReply | SurveillanceAltitudeReply | CommBAltitudeReply | SurveillanceIdentityReply | CommBIdentityReply;
|
|
235
|
+
//# sourceMappingURL=message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/types/message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,aAAa,GACvB,YAAY,GAAG,iBAAiB,GAAG,UAAU,GAAG,eAAe,GAAG,MAAM,CAAC;AAE3E,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,wEAAwE;AACxE,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACtE,2FAA2F;IAC3F,IAAI,EAAE,0BAA0B,CAAC;IACjC,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC;IAC1B,yKAAyK;IACzK,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,0KAA0K;IAC1K,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,6IAA6I;IAC7I,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,qKAAqK;IACrK,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,2KAA2K;IAC3K,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,6DAA6D;AAC7D,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACtE,gFAAgF;IAChF,IAAI,EAAE,0BAA0B,CAAC;IACjC,4BAA4B;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,mEAAmE;AACnE,MAAM,WAAW,8BAA+B,SAAQ,sBAAsB;IAC5E,sFAAsF;IACtF,IAAI,EAAE,gCAAgC,CAAC;IACvC,yCAAyC;IACzC,cAAc,EAAE,sBAAsB,CAAC;CACxC;AAED,kFAAkF;AAClF,MAAM,WAAW,oCAAqC,SAAQ,sBAAsB;IAClF,sFAAsF;IACtF,IAAI,EAAE,sCAAsC,CAAC;IAC7C,2CAA2C;IAC3C,oBAAoB,EAAE,oBAAoB,CAAC;CAC5C;AAED,sFAAsF;AACtF,MAAM,WAAW,iCAAkC,SAAQ,sBAAsB;IAC/E,0FAA0F;IAC1F,IAAI,EAAE,mCAAmC,CAAC;IAC1C,sCAAsC;IACtC,iBAAiB,EAAE,yBAAyB,CAAC;CAC9C;AAED,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,IAAI,EAAE,cAAc,CAAC;IACrB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,4BAA4B;IAC3C,2FAA2F;IAC3F,IAAI,EAAE,8BAA8B,CAAC;IACrC,yHAAyH;IACzH,gBAAgB,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,OAAO,EAAE,OAAO,CAAC;IACjB,kFAAkF;IAClF,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IAC1C,2FAA2F;IAC3F,IAAI,EAAE,6BAA6B,CAAC;IACpC,yHAAyH;IACzH,gBAAgB,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,OAAO,EAAE,OAAO,CAAC;IACjB,kFAAkF;IAClF,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,kMAAkM;IAClM,kBAAkB,EAAE,4BAA4B,GAAG,SAAS,CAAC;CAC9D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,sFAAsF;IACtF,IAAI,EAAE,2BAA2B,CAAC;IAClC,yHAAyH;IACzH,gBAAgB,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,IAAI,EAAE,oBAAoB,CAAC;IAC3B,yHAAyH;IACzH,gBAAgB,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,yIAAyI;IACzI,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACxC,sFAAsF;IACtF,IAAI,EAAE,2BAA2B,CAAC;IAClC,yHAAyH;IACzH,gBAAgB,EAAE,MAAM,CAAC;IACzB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,IAAI,EAAE,oBAAoB,CAAC;IAC3B,yHAAyH;IACzH,gBAAgB,EAAE,MAAM,CAAC;IACzB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,yIAAyI;IACzI,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,+BAAgC,SAAQ,sBAAsB;IAC7E,+GAA+G;IAC/G,IAAI,EAAE,iCAAiC,CAAC;IACxC,6CAA6C;IAC7C,cAAc,EAAE,cAAc,CAAC;IAC/B,oKAAoK;IACpK,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,+BAAgC,SAAQ,sBAAsB;IAC7E,gHAAgH;IAChH,IAAI,EAAE,iCAAiC,CAAC;IACxC,6CAA6C;IAC7C,kBAAkB,EAAE,4BAA4B,CAAC;CAClD;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAC3B,wBAAwB,GACxB,wBAAwB,GACxB,8BAA8B,GAC9B,oCAAoC,GACpC,iCAAiC,GACjC,+BAA+B,GAC/B,+BAA+B,GAC/B,YAAY,GACZ,4BAA4B,GAC5B,2BAA2B,GAC3B,yBAAyB,GACzB,kBAAkB,GAClB,yBAAyB,GACzB,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decoded Mode A/C reply. Mode A/C predates Mode-S and carries no ICAO
|
|
3
|
+
* address - there is nothing here that identifies which aircraft sent it,
|
|
4
|
+
* only the squawk code and (if the reply looks like a valid altitude
|
|
5
|
+
* report) an altitude.
|
|
6
|
+
*/
|
|
7
|
+
export interface ModeAcReply {
|
|
8
|
+
kind: 'modeAc';
|
|
9
|
+
/** 4-digit octal squawk code, e.g. "1200". */
|
|
10
|
+
squawk: string;
|
|
11
|
+
/** True if the Ident (SPI - Special Position Identification) pulse is set. */
|
|
12
|
+
identActive: boolean;
|
|
13
|
+
/** Altitude in feet, if the reply decodes as a valid Mode C altitude report. Undefined for a Mode A (identity-only) reply or an invalid code. */
|
|
14
|
+
altitudeFt: number | undefined;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=mode-ac.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode-ac.d.ts","sourceRoot":"","sources":["../../src/types/mode-ac.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,WAAW,EAAE,OAAO,CAAC;IACrB,iJAAiJ;IACjJ,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decoded ADS-B Aircraft Operational Status (BDS 6,5, type code 31) -
|
|
3
|
+
* capability/operational mode codes, ADS-B version, and navigation
|
|
4
|
+
* integrity/accuracy fields, per RTCA DO-260B section 2.2.3.2.7.2.
|
|
5
|
+
*/
|
|
6
|
+
export interface AircraftOperationalStatus {
|
|
7
|
+
/** Whether this report describes a surface (on-ground) aircraft, from the 3-bit subtype field (1 = surface; only 0 and 1 are defined, so anything else reports as `false`). */
|
|
8
|
+
surface: boolean;
|
|
9
|
+
/** The ADS-B version this message was encoded to (0, 1, or 2 in practice). Gates whether `nicBaro`/`silSupplementPerHour` are populated, and how `capabilityClassCode`/`operationalModeCode` should be interpreted. */
|
|
10
|
+
adsbVersion: number;
|
|
11
|
+
/** Raw 16-bit Capability Class Code field. Its sub-field breakdown depends on both `surface` and `adsbVersion`; not decoded further by this package - see RTCA DO-260B section 2.2.3.2.7.2.1 (or DO-260/DO-260A for earlier versions). */
|
|
12
|
+
capabilityClassCode: number;
|
|
13
|
+
/** Raw 16-bit Operational Mode Code field. Its sub-field breakdown depends on both `surface` and `adsbVersion`; not decoded further by this package - see RTCA DO-260B section 2.2.3.2.7.2.2 (or DO-260/DO-260A for earlier versions). */
|
|
14
|
+
operationalModeCode: number;
|
|
15
|
+
/** Navigation Integrity Category Supplement-A. */
|
|
16
|
+
nicSupplementA: boolean;
|
|
17
|
+
/** Navigation Accuracy Category for Position, 0-15 (higher is more accurate). */
|
|
18
|
+
navAccuracyCategoryPosition: number;
|
|
19
|
+
/** Source Integrity Level, 0-3 (higher is more reliable). */
|
|
20
|
+
sourceIntegrityLevel: number;
|
|
21
|
+
/** Whether the reported altitude source meets the Navigation Integrity Category barometric requirement. Only populated for an airborne report on ADS-B version 1 or 2 - undefined otherwise (version 0 has no defined meaning for this bit, and surface reports do not carry it). */
|
|
22
|
+
nicBaro: boolean | undefined;
|
|
23
|
+
/** Heading/track reference direction. */
|
|
24
|
+
headingReference: 'true' | 'magnetic';
|
|
25
|
+
/** Whether the Source Integrity Level is based on a per-hour probability (true) rather than a per-sample probability (false). Only populated on ADS-B version 2 - undefined otherwise. */
|
|
26
|
+
silSupplementPerHour: boolean | undefined;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=operational-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operational-status.d.ts","sourceRoot":"","sources":["../../src/types/operational-status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,+KAA+K;IAC/K,OAAO,EAAE,OAAO,CAAC;IACjB,uNAAuN;IACvN,WAAW,EAAE,MAAM,CAAC;IACpB,0OAA0O;IAC1O,mBAAmB,EAAE,MAAM,CAAC;IAC5B,0OAA0O;IAC1O,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,cAAc,EAAE,OAAO,CAAC;IACxB,iFAAiF;IACjF,2BAA2B,EAAE,MAAM,CAAC;IACpC,6DAA6D;IAC7D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qRAAqR;IACrR,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,GAAG,UAAU,CAAC;IACtC,0LAA0L;IAC1L,oBAAoB,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decoded ADS-B Target State and Status (BDS 6,2, type code 29) - the
|
|
3
|
+
* pilot's selected altitude/heading targets, altimeter setting, and
|
|
4
|
+
* active autopilot/nav modes, per RTCA DO-260B section 2.2.3.2.7.1.
|
|
5
|
+
*/
|
|
6
|
+
export interface TargetStateAndStatus {
|
|
7
|
+
/** Source of the selected altitude target - undefined when `selectedAltitudeFt` is unavailable. */
|
|
8
|
+
selectedAltitudeSource: 'mcpFcu' | 'fms' | undefined;
|
|
9
|
+
/** MCP/FCU or FMS selected altitude target, in feet. Undefined if not available. */
|
|
10
|
+
selectedAltitudeFt: number | undefined;
|
|
11
|
+
/** Barometric pressure (altimeter) setting, in millibars/hectopascals. Undefined if not available. */
|
|
12
|
+
baroPressureSettingMb: number | undefined;
|
|
13
|
+
/** Selected heading/track angle, in degrees. Undefined if not available. */
|
|
14
|
+
selectedHeadingDeg: number | undefined;
|
|
15
|
+
/** Navigation Accuracy Category for Position, 0-15 (higher is more accurate). */
|
|
16
|
+
navAccuracyCategoryPosition: number;
|
|
17
|
+
/** Whether the reported altitude source meets the Navigation Integrity Category barometric requirement. */
|
|
18
|
+
nicBaro: boolean;
|
|
19
|
+
/** Source Integrity Level, 0-3 (higher is more reliable). */
|
|
20
|
+
sourceIntegrityLevel: number;
|
|
21
|
+
/** Whether the autopilot is engaged. Undefined when mode status is not reported. */
|
|
22
|
+
autopilotEngaged: boolean | undefined;
|
|
23
|
+
/** Whether VNAV mode is active. Undefined when mode status is not reported. */
|
|
24
|
+
vnavModeActive: boolean | undefined;
|
|
25
|
+
/** Whether altitude-hold mode is active. Undefined when mode status is not reported. */
|
|
26
|
+
altitudeHoldModeActive: boolean | undefined;
|
|
27
|
+
/** Whether approach mode is active. Undefined when mode status is not reported. */
|
|
28
|
+
approachModeActive: boolean | undefined;
|
|
29
|
+
/** Whether LNAV mode is active. Undefined when mode status is not reported. */
|
|
30
|
+
lnavModeActive: boolean | undefined;
|
|
31
|
+
/** Whether ACAS/TCAS is operational (not inhibited or failed). Always reported, regardless of mode status. */
|
|
32
|
+
tcasOperational: boolean;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=target-state-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target-state-status.d.ts","sourceRoot":"","sources":["../../src/types/target-state-status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,mGAAmG;IACnG,sBAAsB,EAAE,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IACrD,oFAAoF;IACpF,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,sGAAsG;IACtG,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,4EAA4E;IAC5E,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,iFAAiF;IACjF,2BAA2B,EAAE,MAAM,CAAC;IACpC,2GAA2G;IAC3G,OAAO,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,+EAA+E;IAC/E,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,wFAAwF;IACxF,sBAAsB,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5C,mFAAmF;IACnF,kBAAkB,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,+EAA+E;IAC/E,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,8GAA8G;IAC9G,eAAe,EAAE,OAAO,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Fields common to both airborne velocity subtypes (ADS-B BDS 0,9). */
|
|
2
|
+
export interface AirborneVelocityCommon {
|
|
3
|
+
/** Vertical rate in feet per minute, positive for climbing. Undefined if not available. */
|
|
4
|
+
verticalRateFtPerMin: number | undefined;
|
|
5
|
+
/** Source of the vertical rate measurement. */
|
|
6
|
+
verticalRateSource: 'gnss' | 'barometric';
|
|
7
|
+
/** Geometric altitude minus barometric altitude, in feet. Undefined if not available. */
|
|
8
|
+
geoMinusBaroAltitudeFt: number | undefined;
|
|
9
|
+
}
|
|
10
|
+
/** Airborne velocity decoded from a ground-speed subtype (1 or 2) message. */
|
|
11
|
+
export interface GroundSpeedVelocity extends AirborneVelocityCommon {
|
|
12
|
+
subtype: 'groundSpeed';
|
|
13
|
+
/** Ground speed in knots. Undefined if not available. */
|
|
14
|
+
groundSpeedKt: number | undefined;
|
|
15
|
+
/** Track over ground in degrees true. Undefined if not available. */
|
|
16
|
+
trueTrackDeg: number | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** Airborne velocity decoded from an airspeed subtype (3 or 4) message. */
|
|
19
|
+
export interface AirSpeedVelocity extends AirborneVelocityCommon {
|
|
20
|
+
subtype: 'airSpeed';
|
|
21
|
+
/** Indicated airspeed in knots. Undefined if not available or the message reports true airspeed instead. */
|
|
22
|
+
indicatedAirspeedKt: number | undefined;
|
|
23
|
+
/** True airspeed in knots. Undefined if not available or the message reports indicated airspeed instead. */
|
|
24
|
+
trueAirspeedKt: number | undefined;
|
|
25
|
+
/** Magnetic heading in degrees. Undefined if not available. */
|
|
26
|
+
magneticHeadingDeg: number | undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Decoded ADS-B airborne velocity (BDS 0,9, type code 19). Ground-speed
|
|
30
|
+
* subtypes report true track; airspeed subtypes report magnetic heading -
|
|
31
|
+
* airspeed messages are transmitted when the aircraft lacks a good
|
|
32
|
+
* GPS-derived track and falls back to its compass heading instead.
|
|
33
|
+
*/
|
|
34
|
+
export type AirborneVelocity = GroundSpeedVelocity | AirSpeedVelocity;
|
|
35
|
+
//# sourceMappingURL=velocity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"velocity.d.ts","sourceRoot":"","sources":["../../src/types/velocity.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACrC,2FAA2F;IAC3F,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,+CAA+C;IAC/C,kBAAkB,EAAE,MAAM,GAAG,YAAY,CAAC;IAC1C,yFAAyF;IACzF,sBAAsB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C;AAED,8EAA8E;AAC9E,MAAM,WAAW,mBAAoB,SAAQ,sBAAsB;IACjE,OAAO,EAAE,aAAa,CAAC;IACvB,yDAAyD;IACzD,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,qEAAqE;IACrE,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,2EAA2E;AAC3E,MAAM,WAAW,gBAAiB,SAAQ,sBAAsB;IAC9D,OAAO,EAAE,UAAU,CAAC;IACpB,4GAA4G;IAC5G,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,4GAA4G;IAC5G,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,+DAA+D;IAC/D,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AirborneVelocity } from './types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Decodes an ADS-B airborne velocity message (BDS 0,9, type code 19).
|
|
4
|
+
*
|
|
5
|
+
* @param me - The 7-byte ME field of a DF17/18 message whose type code is 19.
|
|
6
|
+
* @returns The decoded velocity, or undefined if the subtype field is not one of the four defined values (1-4).
|
|
7
|
+
*/
|
|
8
|
+
export declare function decodeAirborneVelocity(me: Uint8Array): AirborneVelocity | undefined;
|
|
9
|
+
//# sourceMappingURL=velocity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"velocity.d.ts","sourceRoot":"","sources":["../src/velocity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,kBAAkB,CAAC;AAgF1B;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAWnF"}
|
package/dist/velocity.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { extractBits } from './bits.js';
|
|
2
|
+
/**
|
|
3
|
+
* Decodes the vertical-rate and geometric/barometric altitude-difference
|
|
4
|
+
* fields shared by both airborne velocity subtypes.
|
|
5
|
+
*/
|
|
6
|
+
function decodeCommonTrailer(me) {
|
|
7
|
+
const verticalRateSource = extractBits(me, 35, 1) === 1 ? 'barometric' : 'gnss';
|
|
8
|
+
const verticalRateSign = extractBits(me, 36, 1);
|
|
9
|
+
const verticalRateMagnitude = extractBits(me, 37, 9);
|
|
10
|
+
const verticalRateFtPerMin = verticalRateMagnitude === 0
|
|
11
|
+
? undefined
|
|
12
|
+
: (verticalRateSign === 1 ? -1 : 1) * (verticalRateMagnitude - 1) * 64;
|
|
13
|
+
const diffSign = extractBits(me, 48, 1);
|
|
14
|
+
const diffMagnitude = extractBits(me, 49, 7);
|
|
15
|
+
const geoMinusBaroAltitudeFt = diffMagnitude === 0 || diffMagnitude === 127
|
|
16
|
+
? undefined
|
|
17
|
+
: (diffSign === 1 ? -1 : 1) * (diffMagnitude - 1) * 25;
|
|
18
|
+
return { verticalRateFtPerMin, verticalRateSource, geoMinusBaroAltitudeFt };
|
|
19
|
+
}
|
|
20
|
+
function decodeGroundSpeed(me, subtype, common) {
|
|
21
|
+
const eastWestSign = extractBits(me, 13, 1);
|
|
22
|
+
const eastWestMagnitude = extractBits(me, 14, 10);
|
|
23
|
+
const northSouthSign = extractBits(me, 24, 1);
|
|
24
|
+
const northSouthMagnitude = extractBits(me, 25, 10);
|
|
25
|
+
if (eastWestMagnitude === 0 || northSouthMagnitude === 0) {
|
|
26
|
+
return { subtype: 'groundSpeed', groundSpeedKt: undefined, trueTrackDeg: undefined, ...common };
|
|
27
|
+
}
|
|
28
|
+
const scale = subtype === 2 ? 4 : 1;
|
|
29
|
+
const eastWest = (eastWestMagnitude - 1) * scale;
|
|
30
|
+
const northSouth = (northSouthMagnitude - 1) * scale;
|
|
31
|
+
const velocityEast = eastWestSign === 1 ? -eastWest : eastWest;
|
|
32
|
+
const velocityNorth = northSouthSign === 1 ? -northSouth : northSouth;
|
|
33
|
+
const groundSpeedKt = Math.sqrt(velocityEast * velocityEast + velocityNorth * velocityNorth);
|
|
34
|
+
let trueTrackDeg = (Math.atan2(velocityEast, velocityNorth) * 180) / Math.PI;
|
|
35
|
+
if (trueTrackDeg < 0) {
|
|
36
|
+
trueTrackDeg += 360;
|
|
37
|
+
}
|
|
38
|
+
return { subtype: 'groundSpeed', groundSpeedKt, trueTrackDeg, ...common };
|
|
39
|
+
}
|
|
40
|
+
function decodeAirSpeed(me, subtype, common) {
|
|
41
|
+
const headingStatus = extractBits(me, 13, 1);
|
|
42
|
+
const headingRaw = extractBits(me, 14, 10);
|
|
43
|
+
const airspeedType = extractBits(me, 24, 1);
|
|
44
|
+
const airspeedMagnitude = extractBits(me, 25, 10);
|
|
45
|
+
const magneticHeadingDeg = headingStatus === 0 ? undefined : (headingRaw / 1024) * 360;
|
|
46
|
+
const scale = subtype === 4 ? 4 : 1;
|
|
47
|
+
const airspeedKt = airspeedMagnitude === 0 ? undefined : (airspeedMagnitude - 1) * scale;
|
|
48
|
+
const isTrueAirspeed = airspeedType === 1;
|
|
49
|
+
return {
|
|
50
|
+
subtype: 'airSpeed',
|
|
51
|
+
indicatedAirspeedKt: isTrueAirspeed ? undefined : airspeedKt,
|
|
52
|
+
trueAirspeedKt: isTrueAirspeed ? airspeedKt : undefined,
|
|
53
|
+
magneticHeadingDeg,
|
|
54
|
+
...common,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Decodes an ADS-B airborne velocity message (BDS 0,9, type code 19).
|
|
59
|
+
*
|
|
60
|
+
* @param me - The 7-byte ME field of a DF17/18 message whose type code is 19.
|
|
61
|
+
* @returns The decoded velocity, or undefined if the subtype field is not one of the four defined values (1-4).
|
|
62
|
+
*/
|
|
63
|
+
export function decodeAirborneVelocity(me) {
|
|
64
|
+
const subtype = extractBits(me, 5, 3);
|
|
65
|
+
const common = decodeCommonTrailer(me);
|
|
66
|
+
if (subtype === 1 || subtype === 2) {
|
|
67
|
+
return decodeGroundSpeed(me, subtype, common);
|
|
68
|
+
}
|
|
69
|
+
if (subtype === 3 || subtype === 4) {
|
|
70
|
+
return decodeAirSpeed(me, subtype, common);
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@squawk/mode-s",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Decode raw Mode-S/ADS-B messages: DF/CRC parsing, CPR position, velocity, identification, and altitude",
|
|
6
|
+
"author": "Neil Cochran",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/neilcochran/squawk",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/neilcochran/squawk.git",
|
|
12
|
+
"directory": "packages/libs/mode-s"
|
|
13
|
+
},
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=22"
|
|
16
|
+
},
|
|
17
|
+
"typedocMain": "src/index.ts",
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./browser": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"!dist/**/*.spec.*"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc",
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"test:coverage": "vitest run --coverage",
|
|
38
|
+
"lint": "tsc --noEmit && eslint src",
|
|
39
|
+
"lint:pack": "publint && attw --pack . --profile esm-only",
|
|
40
|
+
"api:check": "api-extractor run --verbose",
|
|
41
|
+
"api:report": "api-extractor run --local --verbose"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@squawk/types": "^0.8.6"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^25.9.3"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"aviation",
|
|
51
|
+
"typescript",
|
|
52
|
+
"mode-s",
|
|
53
|
+
"adsb",
|
|
54
|
+
"ads-b",
|
|
55
|
+
"transponder",
|
|
56
|
+
"decoder"
|
|
57
|
+
],
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"access": "public"
|
|
60
|
+
}
|
|
61
|
+
}
|