1#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct NoPositionMessage {
5 data: Vec<u8>,
6}
7
8impl NoPositionMessage {
9 pub fn decode(data: Vec<u8>) -> Self {
10 Self { data }
11 }
12
13 pub fn surveillance_status(&self) -> u8 {
15 (self.data[4] >> 1) & 0x03
16 }
17
18 pub fn nic_supplement_b(&self) -> bool {
20 self.data[4] & 0x01 != 0
21 }
22
23 pub fn altitude(&self) -> u16 { todo!() }
25
26 pub fn utc_sync(&self) -> bool {
28 (self.data[6] >> 3) & 0x01 != 0
29 }
30
31 pub fn cpr_format(&self) -> u8 {
33 (self.data[6] >> 2) & 0x01
34 }
35}
36
37#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct AirbornePositionMessage {
41 data: Vec<u8>,
42}
43
44impl AirbornePositionMessage {
45 pub fn decode(data: Vec<u8>) -> Self {
46 Self { data }
47 }
48
49 pub fn altitude_mops01(&self) -> u16 { todo!() }
50 pub fn cpr_lat_mops01(&self) -> u32 { todo!() }
51 pub fn cpr_lon_mops01(&self) -> u32 { todo!() }
52
53 pub fn altitude_mops2(&self) -> u16 { todo!() }
54 pub fn cpr_lat_mops2(&self) -> u32 { todo!() }
55 pub fn cpr_lon_mops2(&self) -> u32 { todo!() }
56}
57
58#[derive(Debug, Clone, PartialEq, Eq)]
61pub struct SurfacePositionMessage {
62 data: Vec<u8>,
63}
64
65impl SurfacePositionMessage {
66 pub fn decode(data: Vec<u8>) -> Self {
67 Self { data }
68 }
69
70 pub fn ground_speed_mops01(&self) -> u16 { todo!() }
71 pub fn cpr_lat_mops01(&self) -> u32 { todo!() }
72 pub fn cpr_lon_mops01(&self) -> u32 { todo!() }
73
74 pub fn ground_speed_mops2(&self) -> u16 { todo!() }
75 pub fn cpr_lat_mops2(&self) -> u32 { todo!() }
76 pub fn cpr_lon_mops2(&self) -> u32 { todo!() }
77}
78
79#[derive(Clone, PartialEq, Eq)]
83pub struct AircraftIdentityMessage {
84 data: Vec<u8>,
85}
86
87impl std::fmt::Debug for AircraftIdentityMessage {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 f.debug_struct("AircraftIdentityMessage")
90 .field("emitter_category", &self.emitter_category())
91 .field("callsign", &self.callsign())
92 .finish()
93 }
94}
95
96impl AircraftIdentityMessage {
97 pub fn decode(data: Vec<u8>) -> Self {
98 Self { data }
99 }
100
101 pub fn emitter_category(&self) -> u8 {
102 self.data[4] & 0x07
103 }
104
105 pub fn callsign(&self) -> String {
106 const CHARSET: &[u8; 64] = b"#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######";
108
109 let d = &self.data;
110 let chars: [u8; 8] = [
111 (d[5] >> 2) & 0x3F,
112 ((d[5] & 0x03) << 4) | (d[6] >> 4),
113 ((d[6] & 0x0F) << 2) | (d[7] >> 6),
114 d[7] & 0x3F,
115 (d[8] >> 2) & 0x3F,
116 ((d[8] & 0x03) << 4) | (d[9] >> 4),
117 ((d[9] & 0x0F) << 2) | (d[10] >> 6),
118 d[10] & 0x3F,
119 ];
120
121 chars.iter()
122 .map(|&i| CHARSET[i as usize] as char)
123 .collect::<String>()
124 .trim_end_matches(['_', '#'])
125 .to_string()
126 }
127}
128
129#[derive(Debug, Clone, PartialEq, Eq)]
132pub struct AirborneVelocityGroundMessage {
133 data: Vec<u8>,
134}
135
136impl AirborneVelocityGroundMessage {
137 pub fn decode(data: Vec<u8>) -> Self {
138 Self { data }
139 }
140
141 pub fn velocity_ew_mops0(&self) -> i16 { todo!() }
142 pub fn velocity_ns_mops0(&self) -> i16 { todo!() }
143 pub fn vertical_rate_mops0(&self) -> i16 { todo!() }
144
145 pub fn velocity_ew_mops1(&self) -> i16 { todo!() }
146 pub fn velocity_ns_mops1(&self) -> i16 { todo!() }
147 pub fn vertical_rate_mops1(&self) -> i16 { todo!() }
148
149 pub fn velocity_ew_mops2(&self) -> i16 { todo!() }
150 pub fn velocity_ns_mops2(&self) -> i16 { todo!() }
151 pub fn vertical_rate_mops2(&self) -> i16 { todo!() }
152}
153
154#[derive(Debug, Clone, PartialEq, Eq)]
157pub struct AirborneVelocityAirspeedMessage {
158 data: Vec<u8>,
159}
160
161impl AirborneVelocityAirspeedMessage {
162 pub fn decode(data: Vec<u8>) -> Self {
163 Self { data }
164 }
165
166 pub fn airspeed_mops0(&self) -> u16 { todo!() }
167 pub fn heading_mops0(&self) -> u16 { todo!() }
168 pub fn vertical_rate_mops0(&self) -> i16 { todo!() }
169
170 pub fn airspeed_mops1(&self) -> u16 { todo!() }
171 pub fn heading_mops1(&self) -> u16 { todo!() }
172 pub fn vertical_rate_mops1(&self) -> i16 { todo!() }
173
174 pub fn airspeed_mops2(&self) -> u16 { todo!() }
175 pub fn heading_mops2(&self) -> u16 { todo!() }
176 pub fn vertical_rate_mops2(&self) -> i16 { todo!() }
177}
178
179#[derive(Clone, PartialEq, Eq)]
183pub struct TestModeAMessage {
184 data: Vec<u8>,
185}
186
187impl std::fmt::Debug for TestModeAMessage {
188 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189 f.debug_struct("TestModeAMessage")
190 .field("mode_a_code", &format_args!("{:04o}", self.mode_a_code()))
191 .finish()
192 }
193}
194
195impl TestModeAMessage {
196 pub fn decode(data: Vec<u8>) -> Self {
197 Self { data }
198 }
199
200 pub fn mode_a_code(&self) -> u16 { todo!() }
202}
203
204#[derive(Debug, Clone, PartialEq, Eq)]
207pub struct AircraftStatusEmergencyMessage {
208 data: Vec<u8>,
209}
210
211impl AircraftStatusEmergencyMessage {
212 pub fn decode(data: Vec<u8>) -> Self {
213 Self { data }
214 }
215
216 pub fn emergency_state_mops01(&self) -> u8 { todo!() }
217 pub fn emergency_state_mops2(&self) -> u8 { todo!() }
218}
219
220#[derive(Debug, Clone, PartialEq, Eq)]
224pub struct AircraftStatusTcasMessage {
225 data: Vec<u8>,
226}
227
228impl AircraftStatusTcasMessage {
229 pub fn decode(data: Vec<u8>) -> Self {
230 Self { data }
231 }
232
233 pub fn ara(&self) -> u16 { todo!() }
234 pub fn rac(&self) -> u8 { todo!() }
235}
236
237#[derive(Debug, Clone, PartialEq, Eq)]
240pub struct TargetStateStatusMessage {
241 data: Vec<u8>,
242}
243
244impl TargetStateStatusMessage {
245 pub fn decode(data: Vec<u8>) -> Self {
246 Self { data }
247 }
248
249 pub fn target_altitude_mops1(&self) -> u16 { todo!() }
250 pub fn vertical_mode_mops1(&self) -> u8 { todo!() }
251
252 pub fn target_altitude_mops2(&self) -> u16 { todo!() }
253 pub fn vertical_mode_mops2(&self) -> u8 { todo!() }
254}
255
256#[derive(Debug, Clone, PartialEq, Eq)]
259pub struct AircraftOperationalStatusAirborneMessage {
260 data: Vec<u8>,
261}
262
263impl AircraftOperationalStatusAirborneMessage {
264 pub fn decode(data: Vec<u8>) -> Self {
265 Self { data }
266 }
267
268 pub fn capability_codes_mops0(&self) -> u16 { todo!() }
269 pub fn operational_mode_codes_mops0(&self) -> u16 { todo!() }
270
271 pub fn capability_codes_mops1(&self) -> u16 { todo!() }
272 pub fn operational_mode_codes_mops1(&self) -> u16 { todo!() }
273
274 pub fn capability_codes_mops2(&self) -> u16 { todo!() }
275 pub fn operational_mode_codes_mops2(&self) -> u16 { todo!() }
276}
277
278#[derive(Debug, Clone, PartialEq, Eq)]
281pub struct AircraftOperationalStatusSurfaceMessage {
282 data: Vec<u8>,
283}
284
285impl AircraftOperationalStatusSurfaceMessage {
286 pub fn decode(data: Vec<u8>) -> Self {
287 Self { data }
288 }
289
290 pub fn capability_codes_mops1(&self) -> u16 { todo!() }
291 pub fn operational_mode_codes_mops1(&self) -> u16 { todo!() }
292
293 pub fn capability_codes_mops2(&self) -> u16 { todo!() }
294 pub fn operational_mode_codes_mops2(&self) -> u16 { todo!() }
295}
296
297#[derive(Debug, Clone, PartialEq, Eq)]
300pub enum AdsbMessage {
301 NoPosition(NoPositionMessage),
302 AirbornePosition(AirbornePositionMessage),
303 SurfacePosition(SurfacePositionMessage),
304 AircraftIdentity(AircraftIdentityMessage),
305 AirborneVelocityGround(AirborneVelocityGroundMessage),
306 AirborneVelocityAirspeed(AirborneVelocityAirspeedMessage),
307 TestModeA(TestModeAMessage),
308 AircraftStatusEmergency(AircraftStatusEmergencyMessage),
309 AircraftStatusTcas(AircraftStatusTcasMessage),
310 TargetStateStatus(TargetStateStatusMessage),
311 AircraftOperationalStatusAirborne(AircraftOperationalStatusAirborneMessage),
312 AircraftOperationalStatusSurface(AircraftOperationalStatusSurfaceMessage),
313}
314
315impl AdsbMessage {
316 pub fn decode(data: Vec<u8>) -> Self {
317 let tc = (data[4] >> 3) & 0x1F;
318 let sub_type = data[4] & 0x07;
319
320 match tc {
321 0 => AdsbMessage::NoPosition(NoPositionMessage::decode(data)),
322 1..=4 => AdsbMessage::AircraftIdentity(AircraftIdentityMessage::decode(data)),
323 5..=8 => AdsbMessage::SurfacePosition(SurfacePositionMessage::decode(data)),
324 9..=18 | 20..=22 => AdsbMessage::AirbornePosition(AirbornePositionMessage::decode(data)),
325 19 => match sub_type {
326 1..=2 => AdsbMessage::AirborneVelocityGround(AirborneVelocityGroundMessage::decode(data)),
327 3..=4 => AdsbMessage::AirborneVelocityAirspeed(AirborneVelocityAirspeedMessage::decode(data)),
328 _ => todo!("unknown velocity sub-type {sub_type}"),
329 },
330 23 => match sub_type {
331 7 => AdsbMessage::TestModeA(TestModeAMessage::decode(data)),
332 _ => todo!("unknown test sub-type {sub_type}"),
333 },
334 28 => match sub_type {
335 1 => AdsbMessage::AircraftStatusEmergency(AircraftStatusEmergencyMessage::decode(data)),
336 2 => AdsbMessage::AircraftStatusTcas(AircraftStatusTcasMessage::decode(data)),
337 _ => todo!("unknown aircraft status sub-type {sub_type}"),
338 },
339 29 => AdsbMessage::TargetStateStatus(TargetStateStatusMessage::decode(data)),
340 31 => match sub_type {
341 0 => AdsbMessage::AircraftOperationalStatusAirborne(AircraftOperationalStatusAirborneMessage::decode(data)),
342 1 => AdsbMessage::AircraftOperationalStatusSurface(AircraftOperationalStatusSurfaceMessage::decode(data)),
343 _ => todo!("unknown operational status sub-type {sub_type}"),
344 },
345 _ => todo!("unknown TC {tc}"),
346 }
347 }
348}