@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.
Files changed (89) hide show
  1. package/README.md +243 -0
  2. package/dist/acas.d.ts +14 -0
  3. package/dist/acas.d.ts.map +1 -0
  4. package/dist/acas.js +90 -0
  5. package/dist/altitude.d.ts +34 -0
  6. package/dist/altitude.d.ts.map +1 -0
  7. package/dist/altitude.js +99 -0
  8. package/dist/bits.d.ts +41 -0
  9. package/dist/bits.d.ts.map +1 -0
  10. package/dist/bits.js +55 -0
  11. package/dist/comm-b.d.ts +37 -0
  12. package/dist/comm-b.d.ts.map +1 -0
  13. package/dist/comm-b.js +245 -0
  14. package/dist/cpr.d.ts +71 -0
  15. package/dist/cpr.d.ts.map +1 -0
  16. package/dist/cpr.js +220 -0
  17. package/dist/emergency-status.d.ts +10 -0
  18. package/dist/emergency-status.d.ts.map +1 -0
  19. package/dist/emergency-status.js +21 -0
  20. package/dist/frame.d.ts +42 -0
  21. package/dist/frame.d.ts.map +1 -0
  22. package/dist/frame.js +68 -0
  23. package/dist/identification.d.ts +10 -0
  24. package/dist/identification.d.ts.map +1 -0
  25. package/dist/identification.js +64 -0
  26. package/dist/identity.d.ts +11 -0
  27. package/dist/identity.d.ts.map +1 -0
  28. package/dist/identity.js +20 -0
  29. package/dist/index.d.ts +32 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +21 -0
  32. package/dist/message.d.ts +40 -0
  33. package/dist/message.d.ts.map +1 -0
  34. package/dist/message.js +293 -0
  35. package/dist/mode-ac.d.ts +17 -0
  36. package/dist/mode-ac.d.ts.map +1 -0
  37. package/dist/mode-ac.js +86 -0
  38. package/dist/operational-status.d.ts +9 -0
  39. package/dist/operational-status.d.ts.map +1 -0
  40. package/dist/operational-status.js +23 -0
  41. package/dist/surface-movement.d.ts +9 -0
  42. package/dist/surface-movement.d.ts.map +1 -0
  43. package/dist/surface-movement.js +37 -0
  44. package/dist/target-state-status.d.ts +9 -0
  45. package/dist/target-state-status.d.ts.map +1 -0
  46. package/dist/target-state-status.js +34 -0
  47. package/dist/test-utils.d.ts +7 -0
  48. package/dist/test-utils.d.ts.map +1 -0
  49. package/dist/test-utils.js +17 -0
  50. package/dist/types/acas.d.ts +82 -0
  51. package/dist/types/acas.d.ts.map +1 -0
  52. package/dist/types/acas.js +1 -0
  53. package/dist/types/comm-b.d.ts +69 -0
  54. package/dist/types/comm-b.d.ts.map +1 -0
  55. package/dist/types/comm-b.js +1 -0
  56. package/dist/types/cpr.d.ts +25 -0
  57. package/dist/types/cpr.d.ts.map +1 -0
  58. package/dist/types/cpr.js +1 -0
  59. package/dist/types/emergency-status.d.ts +6 -0
  60. package/dist/types/emergency-status.d.ts.map +1 -0
  61. package/dist/types/emergency-status.js +1 -0
  62. package/dist/types/frame.d.ts +32 -0
  63. package/dist/types/frame.d.ts.map +1 -0
  64. package/dist/types/frame.js +1 -0
  65. package/dist/types/identification.d.ts +9 -0
  66. package/dist/types/identification.d.ts.map +1 -0
  67. package/dist/types/identification.js +1 -0
  68. package/dist/types/index.d.ts +12 -0
  69. package/dist/types/index.d.ts.map +1 -0
  70. package/dist/types/index.js +11 -0
  71. package/dist/types/message.d.ts +235 -0
  72. package/dist/types/message.d.ts.map +1 -0
  73. package/dist/types/message.js +1 -0
  74. package/dist/types/mode-ac.d.ts +16 -0
  75. package/dist/types/mode-ac.d.ts.map +1 -0
  76. package/dist/types/mode-ac.js +1 -0
  77. package/dist/types/operational-status.d.ts +28 -0
  78. package/dist/types/operational-status.d.ts.map +1 -0
  79. package/dist/types/operational-status.js +1 -0
  80. package/dist/types/target-state-status.d.ts +34 -0
  81. package/dist/types/target-state-status.d.ts.map +1 -0
  82. package/dist/types/target-state-status.js +1 -0
  83. package/dist/types/velocity.d.ts +35 -0
  84. package/dist/types/velocity.d.ts.map +1 -0
  85. package/dist/types/velocity.js +1 -0
  86. package/dist/velocity.d.ts +9 -0
  87. package/dist/velocity.d.ts.map +1 -0
  88. package/dist/velocity.js +73 -0
  89. 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":"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"}
@@ -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"}
@@ -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
+ }