1use crate::common::iff::builder::{
2 ChangeOptionsRecordBuilder, DapSourceBuilder, EnhancedMode1CodeBuilder,
3 FundamentalOperationalDataBuilder, IffBuilder, IffDataRecordBuilder,
4 IffDataSpecificationBuilder, IffFundamentalParameterDataBuilder, IffLayer2Builder,
5 IffLayer3Builder, IffLayer4Builder, IffLayer5Builder, InformationLayersBuilder,
6 LayerHeaderBuilder, Mode5InterrogatorBasicDataBuilder, Mode5InterrogatorStatusBuilder,
7 Mode5MessageFormatsBuilder, Mode5TransponderBasicDataBuilder, Mode5TransponderStatusBuilder,
8 Mode5TransponderSupplementalDataBuilder, ModeSAltitudeBuilder,
9 ModeSInterrogatorBasicDataBuilder, ModeSInterrogatorStatusBuilder, ModeSLevelsPresentBuilder,
10 ModeSTransponderBasicDataBuilder, ModeSTransponderStatusBuilder, SystemIdBuilder,
11 SystemSpecificDataBuilder, SystemStatusBuilder,
12};
13use crate::common::model::{
14 length_padded_to_num, BeamData, EntityId, EventId, PduBody, SimulationAddress, VectorF32,
15};
16use crate::common::{BodyInfo, Interaction};
17use crate::constants::{
18 BIT_0_IN_BYTE, BIT_1_IN_BYTE, BIT_2_IN_BYTE, BIT_3_IN_BYTE, BIT_4_IN_BYTE, BIT_5_IN_BYTE,
19 BIT_6_IN_BYTE, BIT_7_IN_BYTE, FOUR_OCTETS, SIX_OCTETS,
20};
21use crate::enumerations::{
22 AircraftIdentificationType, AircraftPresentDomain, AntennaSelection, CapabilityReport,
23 DataCategory, IffApplicableModes, IffSystemMode, IffSystemName, IffSystemType,
24 Level2SquitterStatus, Mode5IffMission, Mode5LevelSelection, Mode5LocationErrors,
25 Mode5MessageFormatsStatus, Mode5PlatformType, Mode5Reply, Mode5SAltitudeResolution,
26 ModeSSquitterRecordSource, ModeSSquitterType, ModeSTransmitState, NavigationSource, PduType,
27 VariableRecordType,
28};
29#[cfg(feature = "serde")]
30use serde::{Deserialize, Serialize};
31
32pub const IFF_PDU_LAYER_1_DATA_LENGTH_OCTETS: u16 = 48;
33pub const BASE_IFF_DATA_RECORD_LENGTH_OCTETS: u16 = 6;
34
35#[derive(Clone, Debug, Default, PartialEq)]
41#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
42pub struct Iff {
43 pub emitting_entity_id: EntityId,
44 pub event_id: EventId,
45 pub relative_antenna_location: VectorF32,
46 pub system_id: SystemId,
47 pub system_designator: u8, pub system_specific_data: u8, pub fundamental_operational_data: FundamentalOperationalData, pub layer_2: Option<IffLayer2>, pub layer_3: Option<IffLayer3>, pub layer_4: Option<IffLayer4>, pub layer_5: Option<IffLayer5>, }
56
57impl Iff {
58 #[must_use]
59 pub fn builder() -> IffBuilder {
60 IffBuilder::new()
61 }
62
63 #[must_use]
64 pub fn into_builder(self) -> IffBuilder {
65 IffBuilder::new_from_body(self)
66 }
67
68 #[must_use]
69 pub fn into_pdu_body(self) -> PduBody {
70 PduBody::IFF(self)
71 }
72}
73
74impl BodyInfo for Iff {
75 fn body_length(&self) -> u16 {
76 IFF_PDU_LAYER_1_DATA_LENGTH_OCTETS
77 + if let Some(layer_2) = &self.layer_2 {
78 layer_2.data_length()
79 } else {
80 0
81 }
82 + if let Some(layer_3) = &self.layer_3 {
83 layer_3.data_length()
84 } else {
85 0
86 }
87 + if let Some(layer_4) = &self.layer_4 {
88 layer_4.data_length()
89 } else {
90 0
91 }
92 + if let Some(layer_5) = &self.layer_5 {
93 layer_5.data_length()
94 } else {
95 0
96 }
97 }
98
99 fn body_type(&self) -> PduType {
100 PduType::IFF
101 }
102}
103
104impl Interaction for Iff {
105 fn originator(&self) -> Option<&EntityId> {
106 Some(&self.emitting_entity_id)
107 }
108
109 fn receiver(&self) -> Option<&EntityId> {
110 None
111 }
112}
113
114#[derive(Clone, Debug, PartialEq)]
119#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
120pub struct IffLayer2 {
121 pub layer_header: LayerHeader,
122 pub beam_data: BeamData,
123 pub operational_parameter_1: u8,
124 pub operational_parameter_2: u8,
125 pub iff_fundamental_parameters: Vec<IffFundamentalParameterData>,
126}
127
128impl Default for IffLayer2 {
129 fn default() -> Self {
130 Self {
131 layer_header: LayerHeader {
132 layer_number: 2,
133 ..Default::default()
134 },
135 beam_data: BeamData::default(),
136 operational_parameter_1: 0,
137 operational_parameter_2: 0,
138 iff_fundamental_parameters: vec![IffFundamentalParameterData::default()],
139 }
140 }
141}
142
143impl IffLayer2 {
144 #[must_use]
145 pub fn builder() -> IffLayer2Builder {
146 IffLayer2Builder::new()
147 }
148
149 #[must_use]
150 pub fn data_length(&self) -> u16 {
151 const LAYER_2_BASE_DATA_LENGTH_OCTETS: u16 = 28;
152 const IFF_FUNDAMENTAL_PARAMETER_DATA_LENGTH_OCTETS: u16 = 24;
153 LAYER_2_BASE_DATA_LENGTH_OCTETS
154 + (self.iff_fundamental_parameters.len() as u16
155 * IFF_FUNDAMENTAL_PARAMETER_DATA_LENGTH_OCTETS)
156 }
157
158 #[must_use]
159 pub fn finalize_layer_header_length(mut self) -> Self {
160 self.layer_header.length = self.data_length();
161 self
162 }
163}
164
165#[derive(Clone, Debug, PartialEq)]
169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
170pub struct IffLayer3 {
171 pub layer_header: LayerHeader,
172 pub reporting_simulation: SimulationAddress,
173 pub mode_5_basic_data: Mode5BasicData,
174 pub data_records: IffDataSpecification, }
176
177impl Default for IffLayer3 {
178 fn default() -> Self {
179 Self {
180 layer_header: LayerHeader {
181 layer_number: 3,
182 ..Default::default()
183 },
184 reporting_simulation: SimulationAddress::default(),
185 mode_5_basic_data: Mode5BasicData::default(),
186 data_records: IffDataSpecification::default(),
187 }
188 }
189}
190
191impl IffLayer3 {
192 #[must_use]
193 pub fn builder() -> IffLayer3Builder {
194 IffLayer3Builder::new()
195 }
196
197 #[must_use]
198 pub fn data_length(&self) -> u16 {
199 const LAYER_3_BASE_DATA_LENGTH_OCTETS: u16 = 26;
200 LAYER_3_BASE_DATA_LENGTH_OCTETS + self.data_records.data_length()
201 }
202
203 #[must_use]
204 pub fn finalize_layer_header_length(mut self) -> Self {
205 self.layer_header.length = self.data_length();
206 self
207 }
208}
209
210#[derive(Clone, Debug, PartialEq)]
213#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
214#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
215pub enum Mode5BasicData {
216 Interrogator(Mode5InterrogatorBasicData), Transponder(Mode5TransponderBasicData), }
219
220impl Default for Mode5BasicData {
221 fn default() -> Self {
222 Self::Interrogator(Mode5InterrogatorBasicData::default())
223 }
224}
225
226impl Mode5BasicData {
227 #[must_use]
228 pub fn new_interrogator(basic_data: Mode5InterrogatorBasicData) -> Self {
229 Self::Interrogator(basic_data)
230 }
231
232 #[must_use]
233 pub fn new_transponder(basic_data: Mode5TransponderBasicData) -> Self {
234 Self::Transponder(basic_data)
235 }
236}
237
238#[derive(Clone, Debug, PartialEq)]
240#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
241pub struct IffLayer4 {
242 pub layer_header: LayerHeader,
243 pub reporting_simulation: SimulationAddress,
244 pub mode_s_basic_data: ModeSBasicData,
245 pub data_records: IffDataSpecification, }
247
248impl Default for IffLayer4 {
249 fn default() -> Self {
250 Self {
251 layer_header: LayerHeader {
252 layer_number: 4,
253 ..Default::default()
254 },
255 reporting_simulation: SimulationAddress::default(),
256 mode_s_basic_data: ModeSBasicData::default(),
257 data_records: IffDataSpecification::default(),
258 }
259 }
260}
261
262impl IffLayer4 {
263 #[must_use]
264 pub fn builder() -> IffLayer4Builder {
265 IffLayer4Builder::new()
266 }
267
268 #[must_use]
269 pub fn data_length(&self) -> u16 {
270 const LAYER_4_BASE_DATA_LENGTH_OCTETS: u16 = 34;
271 LAYER_4_BASE_DATA_LENGTH_OCTETS + self.data_records.data_length()
272 }
273
274 #[must_use]
275 pub fn finalize_layer_header_length(mut self) -> Self {
276 self.layer_header.length = self.data_length();
277 self
278 }
279}
280
281#[derive(Clone, Debug, PartialEq)]
284#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
285#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
286pub enum ModeSBasicData {
287 Interrogator(ModeSInterrogatorBasicData), Transponder(ModeSTransponderBasicData), }
290
291impl Default for ModeSBasicData {
292 fn default() -> Self {
293 Self::Interrogator(ModeSInterrogatorBasicData::default())
294 }
295}
296
297impl ModeSBasicData {
298 #[must_use]
299 pub fn new_interrogator(basic_data: ModeSInterrogatorBasicData) -> Self {
300 Self::Interrogator(basic_data)
301 }
302
303 #[must_use]
304 pub fn new_transponder(basic_data: ModeSTransponderBasicData) -> Self {
305 Self::Transponder(basic_data)
306 }
307}
308
309#[derive(Clone, Debug, PartialEq)]
311#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
312pub struct IffLayer5 {
313 pub layer_header: LayerHeader,
314 pub reporting_simulation: SimulationAddress,
315 pub applicable_layers: InformationLayers,
316 pub data_category: DataCategory,
317 pub data_records: IffDataSpecification,
318}
319
320impl Default for IffLayer5 {
321 fn default() -> Self {
322 Self {
323 layer_header: LayerHeader {
324 layer_number: 5,
325 ..Default::default()
326 },
327 reporting_simulation: SimulationAddress::default(),
328 applicable_layers: InformationLayers::default(),
329 data_category: DataCategory::default(),
330 data_records: IffDataSpecification::default(),
331 }
332 }
333}
334
335impl IffLayer5 {
336 #[must_use]
337 pub fn builder() -> IffLayer5Builder {
338 IffLayer5Builder::new()
339 }
340
341 #[must_use]
342 pub fn data_length(&self) -> u16 {
343 const LAYER_5_BASE_DATA_LENGTH_OCTETS: u16 = 14;
344 LAYER_5_BASE_DATA_LENGTH_OCTETS + self.data_records.data_length()
345 }
346
347 #[must_use]
348 pub fn finalize_layer_header_length(mut self) -> Self {
349 self.layer_header.length = self.data_length();
350 self
351 }
352}
353
354#[allow(clippy::struct_excessive_bools)]
356#[derive(Copy, Clone, Default, Debug, PartialEq)]
357#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
358pub struct ChangeOptionsRecord {
359 pub change_indicator: bool,
360 pub system_specific_field_1: bool,
361 pub system_specific_field_2: bool,
362 pub heartbeat_indicator: bool,
363 pub transponder_interrogator_indicator: bool,
364 pub simulation_mode: bool,
365 pub interactive_capable: bool,
366 pub test_mode: bool,
367}
368
369impl ChangeOptionsRecord {
370 #[must_use]
371 pub fn builder() -> ChangeOptionsRecordBuilder {
372 ChangeOptionsRecordBuilder::new()
373 }
374}
375
376impl From<u8> for ChangeOptionsRecord {
377 fn from(record: u8) -> Self {
378 let builder = ChangeOptionsRecord::builder();
379 let builder = if ((record & BIT_0_IN_BYTE) >> 7) != 0 {
380 builder.set_change_indicator()
381 } else {
382 builder
383 };
384
385 let builder = if ((record & BIT_1_IN_BYTE) >> 6) != 0 {
386 builder.set_system_specific_field_1()
387 } else {
388 builder
389 };
390
391 let builder = if ((record & BIT_2_IN_BYTE) >> 5) != 0 {
392 builder.set_system_specific_field_2()
393 } else {
394 builder
395 };
396
397 let builder = if ((record & BIT_3_IN_BYTE) >> 4) != 0 {
398 builder.set_heartbeat_indicator()
399 } else {
400 builder
401 };
402
403 let builder = if ((record & BIT_4_IN_BYTE) >> 3) != 0 {
404 builder.set_transponder_interrogator_indicator()
405 } else {
406 builder
407 };
408
409 let builder = if ((record & BIT_5_IN_BYTE) >> 2) != 0 {
410 builder.set_simulation_mode()
411 } else {
412 builder
413 };
414
415 let builder = if ((record & BIT_6_IN_BYTE) >> 1) != 0 {
416 builder.set_interactive_capable()
417 } else {
418 builder
419 };
420
421 let builder = if (record & BIT_7_IN_BYTE) != 0 {
422 builder.set_test_mode()
423 } else {
424 builder
425 };
426
427 builder.build()
428 }
429}
430
431impl From<&ChangeOptionsRecord> for u8 {
432 fn from(value: &ChangeOptionsRecord) -> Self {
433 let mut byte = 0u8;
434 if value.change_indicator {
435 byte += BIT_0_IN_BYTE;
436 }
437 if value.system_specific_field_1 {
438 byte += BIT_1_IN_BYTE;
439 }
440 if value.system_specific_field_2 {
441 byte += BIT_2_IN_BYTE;
442 }
443 if value.heartbeat_indicator {
444 byte += BIT_3_IN_BYTE;
445 }
446 if value.transponder_interrogator_indicator {
447 byte += BIT_4_IN_BYTE;
448 }
449 if value.simulation_mode {
450 byte += BIT_5_IN_BYTE;
451 }
452 if value.interactive_capable {
453 byte += BIT_6_IN_BYTE;
454 }
455 if value.test_mode {
456 byte += BIT_7_IN_BYTE;
457 }
458 byte
459 }
460}
461
462#[derive(Clone, Default, Debug, PartialEq)]
464#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
465pub struct FundamentalOperationalData {
466 pub system_status: SystemStatus,
467 pub data_field_1: u8,
468 pub information_layers: InformationLayers,
469 pub data_field_2: u8,
470 pub parameter_1: u16,
471 pub parameter_2: u16,
472 pub parameter_3: u16,
473 pub parameter_4: u16,
474 pub parameter_5: u16,
475 pub parameter_6: u16,
476}
477
478impl FundamentalOperationalData {
479 #[must_use]
480 pub fn builder() -> FundamentalOperationalDataBuilder {
481 FundamentalOperationalDataBuilder::new()
482 }
483}
484
485#[derive(Copy, Clone, Default, Debug, PartialEq)]
488#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
489pub enum ParameterCapable {
490 #[default]
491 Capable,
492 NotCapable,
493}
494
495#[derive(Copy, Clone, Default, Debug, PartialEq)]
498#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
499pub enum OperationalStatus {
500 #[default]
501 Operational,
502 SystemFailed,
503}
504
505#[derive(Copy, Clone, Default, Debug, PartialEq)]
508#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
509pub enum LayersPresenceApplicability {
510 #[default]
511 NotPresentApplicable, PresentApplicable, }
514
515#[derive(Clone, Default, Debug, PartialEq)]
517#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
518pub struct IffDataRecord {
519 pub record_type: VariableRecordType, pub record_specific_fields: Vec<u8>,
521}
522
523impl IffDataRecord {
524 #[must_use]
525 pub fn new() -> Self {
526 Self::default()
527 }
528
529 #[must_use]
530 pub fn builder() -> IffDataRecordBuilder {
531 IffDataRecordBuilder::new()
532 }
533
534 #[must_use]
535 pub fn data_length(&self) -> u16 {
536 length_padded_to_num(SIX_OCTETS + self.record_specific_fields.len(), FOUR_OCTETS)
537 .record_length as u16
538 }
539}
540
541#[derive(Clone, Default, Debug, PartialEq)]
543#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
544pub struct IffDataSpecification {
545 pub iff_data_records: Vec<IffDataRecord>,
546}
547
548impl IffDataSpecification {
549 #[must_use]
550 pub fn new() -> Self {
551 Self {
552 iff_data_records: vec![],
553 }
554 }
555
556 #[must_use]
557 pub fn builder() -> IffDataSpecificationBuilder {
558 IffDataSpecificationBuilder::new()
559 }
560
561 #[must_use]
562 pub fn data_length(&self) -> u16 {
563 const NUMBER_OF_DATA_RECORDS_OCTETS: u16 = 2;
564 let iff_data_records_data_length: u16 = self
565 .iff_data_records
566 .iter()
567 .map(IffDataRecord::data_length)
568 .sum();
569 NUMBER_OF_DATA_RECORDS_OCTETS + iff_data_records_data_length
570 }
571}
572
573#[derive(Copy, Clone, Default, Debug, PartialEq)]
575#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
576pub struct InformationLayers {
577 pub layer_1: LayersPresenceApplicability,
578 pub layer_2: LayersPresenceApplicability,
579 pub layer_3: LayersPresenceApplicability,
580 pub layer_4: LayersPresenceApplicability,
581 pub layer_5: LayersPresenceApplicability,
582 pub layer_6: LayersPresenceApplicability,
583 pub layer_7: LayersPresenceApplicability,
584}
585
586impl InformationLayers {
587 #[must_use]
588 pub fn builder() -> InformationLayersBuilder {
589 InformationLayersBuilder::new()
590 }
591}
592
593impl From<u8> for InformationLayers {
594 fn from(record: u8) -> Self {
595 let builder = InformationLayers::builder()
596 .with_layer_1(LayersPresenceApplicability::from(
597 (record & BIT_1_IN_BYTE) >> 6,
598 ))
599 .with_layer_2(LayersPresenceApplicability::from(
600 (record & BIT_2_IN_BYTE) >> 5,
601 ))
602 .with_layer_3(LayersPresenceApplicability::from(
603 (record & BIT_3_IN_BYTE) >> 4,
604 ))
605 .with_layer_4(LayersPresenceApplicability::from(
606 (record & BIT_4_IN_BYTE) >> 3,
607 ))
608 .with_layer_5(LayersPresenceApplicability::from(
609 (record & BIT_5_IN_BYTE) >> 2,
610 ))
611 .with_layer_6(LayersPresenceApplicability::from(
612 (record & BIT_6_IN_BYTE) >> 1,
613 ))
614 .with_layer_7(LayersPresenceApplicability::from(record & BIT_7_IN_BYTE));
615
616 builder.build()
617 }
618}
619
620impl From<&InformationLayers> for u8 {
621 fn from(value: &InformationLayers) -> Self {
622 let layer_1 = u8::from(&value.layer_1) << 6;
623 let layer_2 = u8::from(&value.layer_2) << 5;
624 let layer_3 = u8::from(&value.layer_3) << 4;
625 let layer_4 = u8::from(&value.layer_4) << 3;
626 let layer_5 = u8::from(&value.layer_5) << 2;
627 let layer_6 = u8::from(&value.layer_6) << 1;
628 let layer_7 = u8::from(&value.layer_7);
629
630 layer_1 | layer_2 | layer_3 | layer_4 | layer_5 | layer_6 | layer_7
631 }
632}
633
634#[derive(Clone, Default, Debug, PartialEq)]
636#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
637pub struct IffFundamentalParameterData {
638 pub erp: f32,
639 pub frequency: f32,
640 pub pgrf: f32,
641 pub pulse_width: f32,
642 pub burst_length: f32,
643 pub applicable_modes: IffApplicableModes,
644 pub system_specific_data: SystemSpecificData,
645}
646
647impl IffFundamentalParameterData {
648 #[must_use]
649 pub fn builder() -> IffFundamentalParameterDataBuilder {
650 IffFundamentalParameterDataBuilder::new()
651 }
652}
653
654#[derive(Clone, Default, Debug, PartialEq)]
656#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
657pub struct LayerHeader {
658 pub layer_number: u8,
659 pub layer_specific_information: u8,
660 pub length: u16,
661}
662
663impl LayerHeader {
664 #[must_use]
665 pub fn new() -> Self {
666 LayerHeader::default()
667 }
668
669 #[must_use]
670 pub fn builder() -> LayerHeaderBuilder {
671 LayerHeaderBuilder::new()
672 }
673}
674
675#[derive(Copy, Clone, Default, Debug, PartialEq)]
677#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
678pub struct SystemSpecificData {
679 pub part_1: u8,
680 pub part_2: u8,
681 pub part_3: u8,
682}
683
684impl SystemSpecificData {
685 #[must_use]
686 pub fn new() -> Self {
687 SystemSpecificData::default()
688 }
689
690 #[must_use]
691 pub fn builder() -> SystemSpecificDataBuilder {
692 SystemSpecificDataBuilder::new()
693 }
694}
695
696#[derive(Copy, Clone, Default, Debug, PartialEq)]
698#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
699pub struct SystemId {
700 pub system_type: IffSystemType,
701 pub system_name: IffSystemName,
702 pub system_mode: IffSystemMode,
703 pub change_options: ChangeOptionsRecord,
704}
705
706impl SystemId {
707 #[must_use]
708 pub fn new() -> Self {
709 SystemId::default()
710 }
711
712 #[must_use]
713 pub fn builder() -> SystemIdBuilder {
714 SystemIdBuilder::new()
715 }
716}
717
718#[derive(Clone, Default, Debug, PartialEq)]
721#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
722pub struct DapSource {
723 pub indicated_air_speed: DapValue,
724 pub mach_number: DapValue,
725 pub ground_speed: DapValue,
726 pub magnetic_heading: DapValue,
727 pub track_angle_rate: DapValue,
728 pub true_track_angle: DapValue,
729 pub true_airspeed: DapValue,
730 pub vertical_rate: DapValue,
731}
732
733impl DapSource {
734 #[must_use]
735 pub fn new() -> Self {
736 DapSource::default()
737 }
738
739 #[must_use]
740 pub fn builder() -> DapSourceBuilder {
741 DapSourceBuilder::new()
742 }
743}
744
745impl From<u8> for DapSource {
746 fn from(record: u8) -> Self {
747 let indicated_air_speed = DapValue::from((record & BIT_0_IN_BYTE) >> 7);
748 let mach_number = DapValue::from((record & BIT_1_IN_BYTE) >> 6);
749 let ground_speed = DapValue::from((record & BIT_2_IN_BYTE) >> 5);
750 let magnetic_heading = DapValue::from((record & BIT_3_IN_BYTE) >> 4);
751 let track_angle_rate = DapValue::from((record & BIT_4_IN_BYTE) >> 3);
752 let true_track_angle = DapValue::from((record & BIT_5_IN_BYTE) >> 2);
753 let true_airspeed = DapValue::from((record & BIT_6_IN_BYTE) >> 1);
754 let vertical_rate = DapValue::from(record & BIT_7_IN_BYTE);
755
756 DapSource::builder()
757 .with_indicated_air_speed(indicated_air_speed)
758 .with_mach_number(mach_number)
759 .with_ground_speed(ground_speed)
760 .with_magnetic_heading(magnetic_heading)
761 .with_track_angle_rate(track_angle_rate)
762 .with_true_track_angle(true_track_angle)
763 .with_true_airspeed(true_airspeed)
764 .with_vertical_rate(vertical_rate)
765 .build()
766 }
767}
768
769impl From<&DapSource> for u8 {
770 fn from(value: &DapSource) -> Self {
771 let indicated_air_speed = u8::from(&value.indicated_air_speed) << 7;
772 let mach_number = u8::from(&value.mach_number) << 6;
773 let ground_speed = u8::from(&value.ground_speed) << 5;
774 let magnetic_heading = u8::from(&value.magnetic_heading) << 4;
775 let track_angle_rate = u8::from(&value.track_angle_rate) << 3;
776 let true_track_angle = u8::from(&value.true_track_angle) << 2;
777 let true_airspeed = u8::from(&value.true_airspeed) << 1;
778 let vertical_rate = u8::from(&value.vertical_rate);
779
780 indicated_air_speed
781 | mach_number
782 | ground_speed
783 | magnetic_heading
784 | track_angle_rate
785 | true_track_angle
786 | true_airspeed
787 | vertical_rate
788 }
789}
790
791#[derive(Clone, Default, Debug, PartialEq)]
793#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
794pub enum DapValue {
795 #[default]
796 ComputeLocally, DataRecordAvailable, }
799
800#[derive(Clone, Default, Debug, PartialEq)]
802#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
803pub struct EnhancedMode1Code {
804 pub code_element_1_d: u16,
805 pub code_element_2_c: u16,
806 pub code_element_3_b: u16,
807 pub code_element_4_a: u16,
808 pub on_off_status: OnOffStatus,
809 pub damage_status: DamageStatus,
810 pub malfunction_status: MalfunctionStatus,
811}
812
813impl EnhancedMode1Code {
814 #[must_use]
815 pub fn new() -> Self {
816 EnhancedMode1Code::default()
817 }
818
819 #[must_use]
820 pub fn builder() -> EnhancedMode1CodeBuilder {
821 EnhancedMode1CodeBuilder::new()
822 }
823}
824
825impl From<u16> for EnhancedMode1Code {
826 fn from(record: u16) -> Self {
827 const BITS_0_2: u16 = 0xE000;
828 const BITS_3_5: u16 = 0x1C00;
829 const BITS_6_8: u16 = 0x0380;
830 const BITS_9_11: u16 = 0x0070;
831 const BITS_13: u16 = 0x0004;
832 const BITS_14: u16 = 0x0002;
833 const BITS_15: u16 = 0x0001;
834
835 let code_element_1_d = (record & BITS_0_2) >> 13;
836 let code_element_2_c = (record & BITS_3_5) >> 10;
837 let code_element_3_b = (record & BITS_6_8) >> 7;
838 let code_element_4_a = (record & BITS_9_11) >> 4;
839 let on_off_status = OnOffStatus::from(((record & BITS_13) >> 2) as u8);
840 let damage_status = DamageStatus::from(((record & BITS_14) >> 1) as u8);
841 let malfunction_status = MalfunctionStatus::from((record & BITS_15) as u8);
842
843 EnhancedMode1Code::builder()
844 .with_code_element_1_d(code_element_1_d)
845 .with_code_element_2_c(code_element_2_c)
846 .with_code_element_3_b(code_element_3_b)
847 .with_code_element_4_a(code_element_4_a)
848 .with_on_off_status(on_off_status)
849 .with_damage_status(damage_status)
850 .with_malfunction_status(malfunction_status)
851 .build()
852 }
853}
854
855impl From<&EnhancedMode1Code> for u16 {
856 fn from(value: &EnhancedMode1Code) -> Self {
857 let code_element_1: u16 = value.code_element_1_d << 13;
858 let code_element_2: u16 = value.code_element_2_c << 10;
859 let code_element_3: u16 = value.code_element_3_b << 7;
860 let code_element_4: u16 = value.code_element_4_a << 4;
861 let on_off_status: u16 = u16::from(u8::from(&value.on_off_status)) << 2;
862 let damage_status: u16 = u16::from(u8::from(&value.damage_status)) << 1;
863 let malfunction_status: u16 = u16::from(u8::from(&value.malfunction_status));
864
865 code_element_1
866 | code_element_2
867 | code_element_3
868 | code_element_4
869 | on_off_status
870 | damage_status
871 | malfunction_status
872 }
873}
874
875#[derive(Clone, Default, Debug, PartialEq)]
877#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
878pub struct Mode5InterrogatorBasicData {
879 pub status: Mode5InterrogatorStatus, pub mode_5_message_formats_present: Mode5MessageFormats, pub interrogated_entity_id: EntityId,
882}
883
884impl Mode5InterrogatorBasicData {
885 #[must_use]
886 pub fn new() -> Self {
887 Mode5InterrogatorBasicData::default()
888 }
889
890 #[must_use]
891 pub fn builder() -> Mode5InterrogatorBasicDataBuilder {
892 Mode5InterrogatorBasicDataBuilder::new()
893 }
894}
895
896#[derive(Clone, Default, Debug, PartialEq)]
898#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
899pub struct Mode5InterrogatorStatus {
900 pub iff_mission: Mode5IffMission,
901 pub mode_5_message_formats_status: Mode5MessageFormatsStatus,
902 pub on_off_status: OnOffStatus,
903 pub damage_status: DamageStatus,
904 pub malfunction_status: MalfunctionStatus,
905}
906
907impl Mode5InterrogatorStatus {
908 #[must_use]
909 pub fn new() -> Self {
910 Mode5InterrogatorStatus::default()
911 }
912
913 #[must_use]
914 pub fn builder() -> Mode5InterrogatorStatusBuilder {
915 Mode5InterrogatorStatusBuilder::new()
916 }
917}
918
919impl From<u8> for Mode5InterrogatorStatus {
920 fn from(record: u8) -> Self {
921 const BITS_0_2: u8 = 0xE0;
922 let iff_mission = Mode5IffMission::from((record & BITS_0_2) >> 5);
923 let mode_5_message_formats_status =
924 Mode5MessageFormatsStatus::from((record & BIT_3_IN_BYTE) >> 4);
925 let on_off_status = OnOffStatus::from((record & BIT_5_IN_BYTE) >> 2);
926 let damage_status = DamageStatus::from((record & BIT_6_IN_BYTE) >> 1);
927 let malfunction_status = MalfunctionStatus::from(record & BIT_7_IN_BYTE);
928
929 Mode5InterrogatorStatus::builder()
930 .with_iff_mission(iff_mission)
931 .with_mode_5_message_formats_status(mode_5_message_formats_status)
932 .with_on_off_status(on_off_status)
933 .with_damage_status(damage_status)
934 .with_malfunction_status(malfunction_status)
935 .build()
936 }
937}
938
939impl From<&Mode5InterrogatorStatus> for u8 {
940 fn from(value: &Mode5InterrogatorStatus) -> Self {
941 let iff_mission: u8 = u8::from(value.iff_mission) << 5;
942 let message_formats_status: u8 = u8::from(value.mode_5_message_formats_status) << 4;
943 let on_off_status: u8 = u8::from(&value.on_off_status) << 2;
944 let damage_status: u8 = u8::from(&value.damage_status) << 1;
945 let malfunction_status: u8 = u8::from(&value.malfunction_status);
946
947 iff_mission | message_formats_status | on_off_status | damage_status | malfunction_status
948 }
949}
950
951#[derive(Clone, Default, Debug, PartialEq)]
953#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
954pub struct Mode5MessageFormats {
955 pub message_format_0: IffPresence, pub message_format_1: IffPresence,
957 pub message_format_2: IffPresence,
958 pub message_format_3: IffPresence,
959 pub message_format_4: IffPresence,
960 pub message_format_5: IffPresence,
961 pub message_format_6: IffPresence,
962 pub message_format_7: IffPresence,
963 pub message_format_8: IffPresence,
964 pub message_format_9: IffPresence,
965 pub message_format_10: IffPresence,
966 pub message_format_11: IffPresence,
967 pub message_format_12: IffPresence,
968 pub message_format_13: IffPresence,
969 pub message_format_14: IffPresence,
970 pub message_format_15: IffPresence,
971 pub message_format_16: IffPresence,
972 pub message_format_17: IffPresence,
973 pub message_format_18: IffPresence,
974 pub message_format_19: IffPresence,
975 pub message_format_20: IffPresence,
976 pub message_format_21: IffPresence,
977 pub message_format_22: IffPresence,
978 pub message_format_23: IffPresence,
979 pub message_format_24: IffPresence,
980 pub message_format_25: IffPresence,
981 pub message_format_26: IffPresence,
982 pub message_format_27: IffPresence,
983 pub message_format_28: IffPresence,
984 pub message_format_29: IffPresence,
985 pub message_format_30: IffPresence,
986 pub message_format_31: IffPresence,
987}
988
989impl Mode5MessageFormats {
990 #[must_use]
991 pub fn new() -> Self {
992 Mode5MessageFormats::default()
993 }
994
995 #[must_use]
996 pub fn builder() -> Mode5MessageFormatsBuilder {
997 Mode5MessageFormatsBuilder::new()
998 }
999}
1000
1001impl From<u32> for Mode5MessageFormats {
1002 #[allow(clippy::cast_possible_truncation)]
1003 #[allow(clippy::similar_names)]
1004 fn from(record: u32) -> Self {
1005 let format_0 = IffPresence::from(((record >> 31) as u8) & BIT_7_IN_BYTE);
1006 let format_1 = IffPresence::from(((record >> 30) as u8) & BIT_7_IN_BYTE);
1007 let format_2 = IffPresence::from(((record >> 29) as u8) & BIT_7_IN_BYTE);
1008 let format_3 = IffPresence::from(((record >> 28) as u8) & BIT_7_IN_BYTE);
1009 let format_4 = IffPresence::from(((record >> 27) as u8) & BIT_7_IN_BYTE);
1010 let format_5 = IffPresence::from(((record >> 26) as u8) & BIT_7_IN_BYTE);
1011 let format_6 = IffPresence::from(((record >> 25) as u8) & BIT_7_IN_BYTE);
1012 let format_7 = IffPresence::from(((record >> 24) as u8) & BIT_7_IN_BYTE);
1013 let format_8 = IffPresence::from(((record >> 23) as u8) & BIT_7_IN_BYTE);
1014 let format_9 = IffPresence::from(((record >> 22) as u8) & BIT_7_IN_BYTE);
1015 let format_10 = IffPresence::from(((record >> 21) as u8) & BIT_7_IN_BYTE);
1016 let format_11 = IffPresence::from(((record >> 20) as u8) & BIT_7_IN_BYTE);
1017 let format_12 = IffPresence::from(((record >> 19) as u8) & BIT_7_IN_BYTE);
1018 let format_13 = IffPresence::from(((record >> 18) as u8) & BIT_7_IN_BYTE);
1019 let format_14 = IffPresence::from(((record >> 17) as u8) & BIT_7_IN_BYTE);
1020 let format_15 = IffPresence::from(((record >> 16) as u8) & BIT_7_IN_BYTE);
1021 let format_16 = IffPresence::from(((record >> 15) as u8) & BIT_7_IN_BYTE);
1022 let format_17 = IffPresence::from(((record >> 14) as u8) & BIT_7_IN_BYTE);
1023 let format_18 = IffPresence::from(((record >> 13) as u8) & BIT_7_IN_BYTE);
1024 let format_19 = IffPresence::from(((record >> 12) as u8) & BIT_7_IN_BYTE);
1025 let format_20 = IffPresence::from(((record >> 11) as u8) & BIT_7_IN_BYTE);
1026 let format_21 = IffPresence::from(((record >> 10) as u8) & BIT_7_IN_BYTE);
1027 let format_22 = IffPresence::from(((record >> 9) as u8) & BIT_7_IN_BYTE);
1028 let format_23 = IffPresence::from(((record >> 8) as u8) & BIT_7_IN_BYTE);
1029 let format_24 = IffPresence::from(((record >> 7) as u8) & BIT_7_IN_BYTE);
1030 let format_25 = IffPresence::from(((record >> 6) as u8) & BIT_7_IN_BYTE);
1031 let format_26 = IffPresence::from(((record >> 5) as u8) & BIT_7_IN_BYTE);
1032 let format_27 = IffPresence::from(((record >> 4) as u8) & BIT_7_IN_BYTE);
1033 let format_28 = IffPresence::from(((record >> 3) as u8) & BIT_7_IN_BYTE);
1034 let format_29 = IffPresence::from(((record >> 2) as u8) & BIT_7_IN_BYTE);
1035 let format_30 = IffPresence::from(((record >> 1) as u8) & BIT_7_IN_BYTE);
1036 let format_31 = IffPresence::from((record as u8) & BIT_7_IN_BYTE);
1037
1038 Mode5MessageFormats::builder()
1039 .with_message_format_0(format_0)
1040 .with_message_format_1(format_1)
1041 .with_message_format_2(format_2)
1042 .with_message_format_3(format_3)
1043 .with_message_format_4(format_4)
1044 .with_message_format_5(format_5)
1045 .with_message_format_6(format_6)
1046 .with_message_format_7(format_7)
1047 .with_message_format_8(format_8)
1048 .with_message_format_9(format_9)
1049 .with_message_format_10(format_10)
1050 .with_message_format_11(format_11)
1051 .with_message_format_12(format_12)
1052 .with_message_format_13(format_13)
1053 .with_message_format_14(format_14)
1054 .with_message_format_15(format_15)
1055 .with_message_format_16(format_16)
1056 .with_message_format_17(format_17)
1057 .with_message_format_18(format_18)
1058 .with_message_format_19(format_19)
1059 .with_message_format_20(format_20)
1060 .with_message_format_21(format_21)
1061 .with_message_format_22(format_22)
1062 .with_message_format_23(format_23)
1063 .with_message_format_24(format_24)
1064 .with_message_format_25(format_25)
1065 .with_message_format_26(format_26)
1066 .with_message_format_27(format_27)
1067 .with_message_format_28(format_28)
1068 .with_message_format_29(format_29)
1069 .with_message_format_30(format_30)
1070 .with_message_format_31(format_31)
1071 .build()
1072 }
1073}
1074
1075impl From<&Mode5MessageFormats> for u32 {
1076 #[allow(clippy::similar_names)]
1077 fn from(value: &Mode5MessageFormats) -> Self {
1078 let mf_0 = u32::from(&value.message_format_0) << 31;
1079 let mf_1 = u32::from(&value.message_format_1) << 30;
1080 let mf_2 = u32::from(&value.message_format_2) << 29;
1081 let mf_3 = u32::from(&value.message_format_3) << 28;
1082 let mf_4 = u32::from(&value.message_format_4) << 27;
1083 let mf_5 = u32::from(&value.message_format_5) << 26;
1084 let mf_6 = u32::from(&value.message_format_6) << 25;
1085 let mf_7 = u32::from(&value.message_format_7) << 24;
1086 let mf_8 = u32::from(&value.message_format_8) << 23;
1087 let mf_9 = u32::from(&value.message_format_9) << 22;
1088 let mf_10 = u32::from(&value.message_format_10) << 21;
1089 let mf_11 = u32::from(&value.message_format_11) << 20;
1090 let mf_12 = u32::from(&value.message_format_12) << 19;
1091 let mf_13 = u32::from(&value.message_format_13) << 18;
1092 let mf_14 = u32::from(&value.message_format_14) << 17;
1093 let mf_15 = u32::from(&value.message_format_15) << 16;
1094 let mf_16 = u32::from(&value.message_format_16) << 15;
1095 let mf_17 = u32::from(&value.message_format_17) << 14;
1096 let mf_18 = u32::from(&value.message_format_18) << 13;
1097 let mf_19 = u32::from(&value.message_format_19) << 12;
1098 let mf_20 = u32::from(&value.message_format_20) << 11;
1099 let mf_21 = u32::from(&value.message_format_21) << 10;
1100 let mf_22 = u32::from(&value.message_format_22) << 9;
1101 let mf_23 = u32::from(&value.message_format_23) << 8;
1102 let mf_24 = u32::from(&value.message_format_24) << 7;
1103 let mf_25 = u32::from(&value.message_format_25) << 6;
1104 let mf_26 = u32::from(&value.message_format_26) << 5;
1105 let mf_27 = u32::from(&value.message_format_27) << 4;
1106 let mf_28 = u32::from(&value.message_format_28) << 3;
1107 let mf_29 = u32::from(&value.message_format_29) << 2;
1108 let mf_30 = u32::from(&value.message_format_30) << 1;
1109 let mf_31 = u32::from(&value.message_format_31);
1110
1111 mf_0 | mf_1
1112 | mf_2
1113 | mf_3
1114 | mf_4
1115 | mf_5
1116 | mf_6
1117 | mf_7
1118 | mf_8
1119 | mf_9
1120 | mf_10
1121 | mf_11
1122 | mf_12
1123 | mf_13
1124 | mf_14
1125 | mf_15
1126 | mf_16
1127 | mf_17
1128 | mf_18
1129 | mf_19
1130 | mf_20
1131 | mf_21
1132 | mf_22
1133 | mf_23
1134 | mf_24
1135 | mf_25
1136 | mf_26
1137 | mf_27
1138 | mf_28
1139 | mf_29
1140 | mf_30
1141 | mf_31
1142 }
1143}
1144
1145#[derive(Clone, Default, Debug, PartialEq)]
1147#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1148pub struct Mode5TransponderBasicData {
1149 pub status: Mode5TransponderStatus,
1150 pub pin: u16,
1151 pub mode_5_message_formats_present: Mode5MessageFormats, pub enhanced_mode_1: EnhancedMode1Code, pub national_origin: u16, pub supplemental_data: Mode5TransponderSupplementalData, pub navigation_source: NavigationSource, pub figure_of_merit: u8, }
1158
1159impl Mode5TransponderBasicData {
1160 #[must_use]
1161 pub fn new() -> Self {
1162 Mode5TransponderBasicData::default()
1163 }
1164
1165 #[must_use]
1166 pub fn builder() -> Mode5TransponderBasicDataBuilder {
1167 Mode5TransponderBasicDataBuilder::new()
1168 }
1169}
1170
1171#[derive(Copy, Clone, Default, Debug, PartialEq)]
1173#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1174pub enum OnOffStatus {
1175 #[default]
1176 Off, On, }
1179
1180#[derive(Clone, Default, Debug, PartialEq)]
1182#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1183pub enum DamageStatus {
1184 #[default]
1185 NoDamage, Damaged, }
1188
1189#[derive(Clone, Default, Debug, PartialEq)]
1191#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1192pub enum MalfunctionStatus {
1193 #[default]
1194 NoMalfunction, Malfunction, }
1197
1198#[derive(Clone, Default, Debug, PartialEq)]
1200#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1201pub enum EnabledStatus {
1202 #[default]
1203 NotEnabled, Enabled, }
1206
1207#[derive(Clone, Default, Debug, PartialEq)]
1210#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1211pub enum LatLonAltSource {
1212 #[default]
1213 ComputeLocally, TransponderLocationDataRecordPresent, }
1216
1217#[derive(Clone, Default, Debug, PartialEq)]
1219#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1220pub struct Mode5TransponderSupplementalData {
1221 pub squitter_on_off_status: SquitterStatus,
1222 pub level_2_squitter_status: Level2SquitterStatus,
1223 pub iff_mission: Mode5IffMission,
1224}
1225
1226impl Mode5TransponderSupplementalData {
1227 #[must_use]
1228 pub fn new() -> Self {
1229 Mode5TransponderSupplementalData::default()
1230 }
1231
1232 #[must_use]
1233 pub fn builder() -> Mode5TransponderSupplementalDataBuilder {
1234 Mode5TransponderSupplementalDataBuilder::new()
1235 }
1236}
1237
1238impl From<u8> for Mode5TransponderSupplementalData {
1239 fn from(record: u8) -> Self {
1240 const BITS_2_4: u8 = 0x38;
1241 let squitter_status = SquitterStatus::from((record & BIT_0_IN_BYTE) >> 7);
1242 let level_2_squitter_status = Level2SquitterStatus::from((record & BIT_1_IN_BYTE) >> 6);
1243 let iff_mission = Mode5IffMission::from((record & BITS_2_4) >> 3);
1244
1245 Mode5TransponderSupplementalData::builder()
1246 .with_squitter_on_off_status(squitter_status)
1247 .with_level_2_squitter_status(level_2_squitter_status)
1248 .with_iff_mission(iff_mission)
1249 .build()
1250 }
1251}
1252
1253impl From<&Mode5TransponderSupplementalData> for u8 {
1254 fn from(value: &Mode5TransponderSupplementalData) -> Self {
1255 let squitter_status: u8 = u8::from(&value.squitter_on_off_status) << 7;
1256 let level_2_squitter_status: u8 = u8::from(value.level_2_squitter_status) << 6;
1257 let iff_mission: u8 = u8::from(value.iff_mission) << 3;
1258
1259 squitter_status | level_2_squitter_status | iff_mission
1260 }
1261}
1262
1263#[derive(Clone, Default, Debug, PartialEq)]
1265#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1266pub struct Mode5TransponderStatus {
1267 pub mode_5_reply: Mode5Reply,
1268 pub line_test: EnabledStatus,
1269 pub antenna_selection: AntennaSelection,
1270 pub crypto_control: IffPresence,
1271 pub lat_lon_alt_source: LatLonAltSource,
1272 pub location_errors: Mode5LocationErrors,
1273 pub platform_type: Mode5PlatformType,
1274 pub mode_5_level_selection: Mode5LevelSelection,
1275 pub on_off_status: OnOffStatus,
1276 pub damage_status: DamageStatus,
1277 pub malfunction_status: MalfunctionStatus,
1278}
1279
1280impl Mode5TransponderStatus {
1281 #[must_use]
1282 pub fn new() -> Self {
1283 Mode5TransponderStatus::default()
1284 }
1285
1286 #[must_use]
1287 pub fn builder() -> Mode5TransponderStatusBuilder {
1288 Mode5TransponderStatusBuilder::new()
1289 }
1290}
1291
1292impl From<u16> for Mode5TransponderStatus {
1293 fn from(record: u16) -> Self {
1294 const BITS_0_3: u16 = 0xF000;
1295 const BIT_4: u16 = 0x0800;
1296 const BITS_5_6: u16 = 0x0600;
1297 const BIT_7: u16 = 0x0100;
1298 const BIT_8: u16 = 0x0080;
1299 const BIT_9: u16 = 0x0040;
1300 const BIT_10: u16 = 0x0020;
1301 const BIT_11: u16 = 0x0010;
1302 const BIT_13: u16 = 0x0004;
1303 const BIT_14: u16 = 0x0002;
1304 const BIT_15: u16 = 0x0001;
1305 let mode_5_reply = Mode5Reply::from(((record & BITS_0_3) >> 12) as u8);
1306 let line_test = EnabledStatus::from(((record & BIT_4) >> 11) as u8);
1307 let antenna_selection = AntennaSelection::from(((record & BITS_5_6) >> 9) as u8);
1308 let crypto_control = IffPresence::from(((record & BIT_7) >> 8) as u8);
1309 let lat_lon_alt_source = LatLonAltSource::from(((record & BIT_8) >> 7) as u8);
1310 let location_errors = Mode5LocationErrors::from(((record & BIT_9) >> 6) as u8);
1311 let platform_type = Mode5PlatformType::from(((record & BIT_10) >> 5) as u8);
1312 let mode_5_level_selection = Mode5LevelSelection::from(((record & BIT_11) >> 4) as u8);
1313 let on_off_status = OnOffStatus::from(((record & BIT_13) >> 2) as u8);
1314 let damage_status = DamageStatus::from(((record & BIT_14) >> 1) as u8);
1315 let malfunction_status = MalfunctionStatus::from((record & BIT_15) as u8);
1316
1317 Mode5TransponderStatus::builder()
1318 .with_mode_5_reply(mode_5_reply)
1319 .with_line_test(line_test)
1320 .with_antenna_selection(antenna_selection)
1321 .with_crypto_control(crypto_control)
1322 .with_lat_lon_alt_source(lat_lon_alt_source)
1323 .with_location_errors(location_errors)
1324 .with_platform_type(platform_type)
1325 .with_mode_5_level_selection(mode_5_level_selection)
1326 .with_on_off_status(on_off_status)
1327 .with_damage_status(damage_status)
1328 .with_malfunction_status(malfunction_status)
1329 .build()
1330 }
1331}
1332
1333impl From<&Mode5TransponderStatus> for u16 {
1334 fn from(value: &Mode5TransponderStatus) -> Self {
1335 let mode_5_reply: u8 = u8::from(value.mode_5_reply) << 4;
1336 let line_test: u8 = u8::from(&value.line_test) << 3;
1337 let antenna_selection: u8 = u8::from(value.antenna_selection) << 1;
1338 let crypto_control: u8 = u32::from(&value.crypto_control) as u8;
1339
1340 let byte_1 = mode_5_reply | line_test | antenna_selection | crypto_control;
1341
1342 let lat_lon_alt_source: u8 = u8::from(&value.lat_lon_alt_source) << 7;
1343 let location_errors: u8 = u8::from(value.location_errors) << 6;
1344 let platform_type: u8 = u8::from(value.platform_type) << 5;
1345 let mode_5_level_selection: u8 = u8::from(value.mode_5_level_selection) << 4;
1346 let on_off_status: u8 = u8::from(&value.on_off_status) << 2;
1347 let damage_status: u8 = u8::from(&value.damage_status) << 1;
1348 let malfunction_status: u8 = (&value.malfunction_status).into();
1349
1350 let byte_2 = lat_lon_alt_source
1351 | location_errors
1352 | platform_type
1353 | mode_5_level_selection
1354 | on_off_status
1355 | damage_status
1356 | malfunction_status;
1357
1358 (u16::from(byte_1) << 8) | u16::from(byte_2)
1359 }
1360}
1361
1362#[derive(Clone, Default, Debug, PartialEq)]
1364#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1365pub struct ModeSAltitude {
1366 pub altitude: u16,
1367 pub resolution: Mode5SAltitudeResolution,
1368}
1369
1370impl ModeSAltitude {
1371 #[must_use]
1372 pub fn new() -> Self {
1373 ModeSAltitude::default()
1374 }
1375
1376 #[must_use]
1377 pub fn builder() -> ModeSAltitudeBuilder {
1378 ModeSAltitudeBuilder::new()
1379 }
1380}
1381
1382impl From<u16> for ModeSAltitude {
1383 fn from(record: u16) -> Self {
1384 const BITS_0_10: u16 = 0xFFE0;
1385 const BIT_11: u16 = 0x0010;
1386 let altitude = (record & BITS_0_10) >> 5;
1387 let resolution = Mode5SAltitudeResolution::from(((record & BIT_11) as u8) >> 4);
1388
1389 ModeSAltitude::builder()
1390 .with_altitude(altitude)
1391 .with_resolution(resolution)
1392 .build()
1393 }
1394}
1395
1396impl From<&ModeSAltitude> for u16 {
1397 fn from(value: &ModeSAltitude) -> Self {
1398 let resolution: u8 = value.resolution.into();
1399 let resolution: u16 = u16::from(resolution);
1400
1401 (value.altitude << 5) | (resolution << 4)
1402 }
1403}
1404
1405#[derive(Clone, Default, Debug, PartialEq)]
1407#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1408pub struct ModeSInterrogatorBasicData {
1409 pub mode_s_interrogator_status: ModeSInterrogatorStatus,
1410 pub mode_s_levels_present: ModeSLevelsPresent,
1411}
1412
1413impl ModeSInterrogatorBasicData {
1414 #[must_use]
1415 pub fn new() -> Self {
1416 ModeSInterrogatorBasicData::default()
1417 }
1418
1419 #[must_use]
1420 pub fn builder() -> ModeSInterrogatorBasicDataBuilder {
1421 ModeSInterrogatorBasicDataBuilder::new()
1422 }
1423}
1424
1425#[derive(Clone, Default, Debug, PartialEq)]
1427#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1428pub struct ModeSInterrogatorStatus {
1429 pub on_off_status: OnOffStatus,
1430 pub transmit_state: ModeSTransmitState,
1431 pub damage_status: DamageStatus,
1432 pub malfunction_status: MalfunctionStatus,
1433}
1434
1435impl ModeSInterrogatorStatus {
1436 #[must_use]
1437 pub fn new() -> Self {
1438 ModeSInterrogatorStatus::default()
1439 }
1440
1441 #[must_use]
1442 pub fn builder() -> ModeSInterrogatorStatusBuilder {
1443 ModeSInterrogatorStatusBuilder::new()
1444 }
1445}
1446
1447impl From<u8> for ModeSInterrogatorStatus {
1448 fn from(record: u8) -> Self {
1449 const BITS_1_3: u8 = 0x70;
1450 let on_off_status = OnOffStatus::from((record & BIT_0_IN_BYTE) >> 7);
1451 let transmit_state = ModeSTransmitState::from((record & BITS_1_3) >> 4);
1452 let damage_status = DamageStatus::from((record & BIT_4_IN_BYTE) >> 3);
1453 let malfunction_status = MalfunctionStatus::from((record & BIT_5_IN_BYTE) >> 2);
1454
1455 ModeSInterrogatorStatus::builder()
1456 .with_on_off_status(on_off_status)
1457 .with_transmit_state(transmit_state)
1458 .with_damage_status(damage_status)
1459 .with_malfunction_status(malfunction_status)
1460 .build()
1461 }
1462}
1463
1464impl From<&ModeSInterrogatorStatus> for u8 {
1465 fn from(value: &ModeSInterrogatorStatus) -> Self {
1466 let on_off_status: u8 = u8::from(&value.on_off_status) << 7;
1467 let transmit_state: u8 = u8::from(value.transmit_state) << 4;
1468 let damage_status: u8 = u8::from(&value.damage_status) << 3;
1469 let malfunction_status: u8 = u8::from(&value.malfunction_status) << 2;
1470
1471 on_off_status | transmit_state | damage_status | malfunction_status
1472 }
1473}
1474
1475#[derive(Clone, Default, Debug, PartialEq)]
1477#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1478pub struct ModeSLevelsPresent {
1479 pub level_1: IffPresence,
1480 pub level_2_els: IffPresence,
1481 pub level_2_ehs: IffPresence,
1482 pub level_3: IffPresence,
1483 pub level_4: IffPresence,
1484}
1485
1486impl ModeSLevelsPresent {
1487 #[must_use]
1488 pub fn new() -> Self {
1489 ModeSLevelsPresent::default()
1490 }
1491
1492 #[must_use]
1493 pub fn builder() -> ModeSLevelsPresentBuilder {
1494 ModeSLevelsPresentBuilder::new()
1495 }
1496}
1497
1498impl From<u8> for ModeSLevelsPresent {
1499 #[allow(clippy::similar_names)]
1500 fn from(record: u8) -> Self {
1501 let level_1 = IffPresence::from((record & BIT_1_IN_BYTE) >> 6);
1502 let level_2_els = IffPresence::from((record & BIT_2_IN_BYTE) >> 5);
1503 let level_2_ehs = IffPresence::from((record & BIT_3_IN_BYTE) >> 4);
1504 let level_3 = IffPresence::from((record & BIT_4_IN_BYTE) >> 3);
1505 let level_4 = IffPresence::from((record & BIT_5_IN_BYTE) >> 2);
1506
1507 ModeSLevelsPresent::builder()
1508 .with_level_1(level_1)
1509 .with_level_2_ehs(level_2_ehs)
1510 .with_level_2_els(level_2_els)
1511 .with_level_3(level_3)
1512 .with_level_4(level_4)
1513 .build()
1514 }
1515}
1516
1517impl From<&ModeSLevelsPresent> for u8 {
1518 #[allow(clippy::similar_names)]
1519 fn from(value: &ModeSLevelsPresent) -> Self {
1520 let level_1: u8 = u8::from(&value.level_1) << 6;
1521 let level_2_els: u8 = u8::from(&value.level_2_els) << 5;
1522 let level_2_ehs: u8 = u8::from(&value.level_2_ehs) << 4;
1523 let level_3: u8 = u8::from(&value.level_3) << 3;
1524 let level_4: u8 = u8::from(&value.level_4) << 2;
1525
1526 level_1 | level_2_els | level_2_ehs | level_3 | level_4
1527 }
1528}
1529
1530#[derive(Clone, Default, Debug, PartialEq)]
1532#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1533pub enum IffPresence {
1534 #[default]
1535 NotPresent, Present, }
1538
1539#[derive(Clone, Default, Debug, PartialEq)]
1541#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1542pub struct ModeSTransponderBasicData {
1543 pub status: ModeSTransponderStatus,
1544 pub levels_present: ModeSLevelsPresent,
1545 pub aircraft_present_domain: AircraftPresentDomain,
1546 pub aircraft_identification: String, pub aircraft_address: u32,
1548 pub aircraft_identification_type: AircraftIdentificationType,
1549 pub dap_source: DapSource, pub altitude: ModeSAltitude, pub capability_report: CapabilityReport,
1552}
1553
1554impl ModeSTransponderBasicData {
1555 #[must_use]
1556 pub fn new() -> Self {
1557 ModeSTransponderBasicData::default()
1558 }
1559
1560 #[must_use]
1561 pub fn builder() -> ModeSTransponderBasicDataBuilder {
1562 ModeSTransponderBasicDataBuilder::new()
1563 }
1564}
1565
1566#[derive(Clone, Default, Debug, PartialEq)]
1568#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1569pub struct ModeSTransponderStatus {
1570 pub squitter_status: SquitterStatus,
1571 pub squitter_type: ModeSSquitterType,
1572 pub squitter_record_source: ModeSSquitterRecordSource,
1573 pub airborne_position_report_indicator: IffPresence,
1574 pub airborne_velocity_report_indicator: IffPresence,
1575 pub surface_position_report_indicator: IffPresence,
1576 pub identification_report_indicator: IffPresence,
1577 pub event_driven_report_indicator: IffPresence,
1578 pub on_off_status: OnOffStatus,
1579 pub damage_status: DamageStatus,
1580 pub malfunction_status: MalfunctionStatus,
1581}
1582
1583impl ModeSTransponderStatus {
1584 #[must_use]
1585 pub fn new() -> Self {
1586 ModeSTransponderStatus::default()
1587 }
1588
1589 #[must_use]
1590 pub fn builder() -> ModeSTransponderStatusBuilder {
1591 ModeSTransponderStatusBuilder::new()
1592 }
1593}
1594
1595impl From<u16> for ModeSTransponderStatus {
1596 fn from(record: u16) -> Self {
1597 const BIT_0: u16 = 0x8000;
1598 const BITS_1_3: u16 = 0x7000;
1599 const BIT_4: u16 = 0x800;
1600 const BIT_5: u16 = 0x400;
1601 const BIT_6: u16 = 0x200;
1602 const BIT_7: u16 = 0x100;
1603 const BIT_8: u16 = 0x80;
1604 const BIT_9: u16 = 0x40;
1605 const BIT_13: u16 = 0x04;
1606 const BIT_14: u16 = 0x02;
1607 const BIT_15: u16 = 0x01;
1608
1609 let squitter_status = SquitterStatus::from(((record & BIT_0) >> 15) as u8);
1610 let squitter_type = ModeSSquitterType::from(((record & BITS_1_3) >> 12) as u8);
1611 let squitter_record_source =
1612 ModeSSquitterRecordSource::from(((record & BIT_4) >> 11) as u8);
1613 let airborne_pos_ri = IffPresence::from(((record & BIT_5) >> 10) as u8);
1614 let airborne_vel_ri = IffPresence::from(((record & BIT_6) >> 9) as u8);
1615 let surface_pos_ri = IffPresence::from(((record & BIT_7) >> 8) as u8);
1616 let ident_ri = IffPresence::from(((record & BIT_8) >> 7) as u8);
1617 let event_driven_ri = IffPresence::from(((record & BIT_9) >> 6) as u8);
1618 let on_off_status = OnOffStatus::from(((record & BIT_13) >> 2) as u8);
1619 let damage_status = DamageStatus::from(((record & BIT_14) >> 1) as u8);
1620 let malfunction_status = MalfunctionStatus::from((record & BIT_15) as u8);
1621
1622 ModeSTransponderStatus::builder()
1623 .with_squitter_status(squitter_status)
1624 .with_squitter_type(squitter_type)
1625 .with_squitter_record_source(squitter_record_source)
1626 .with_airborne_position_report_indicator(airborne_pos_ri)
1627 .with_airborne_velocity_report_indicator(airborne_vel_ri)
1628 .with_surface_position_report_indicator(surface_pos_ri)
1629 .with_identification_report_indicator(ident_ri)
1630 .with_event_driven_report_indicator(event_driven_ri)
1631 .with_on_off_status(on_off_status)
1632 .with_damage_status(damage_status)
1633 .with_malfunction_status(malfunction_status)
1634 .build()
1635 }
1636}
1637
1638impl From<&ModeSTransponderStatus> for u16 {
1639 fn from(value: &ModeSTransponderStatus) -> Self {
1640 let squitter_status: u8 = u8::from(&value.squitter_status) << 7;
1641 let squitter_type: u8 = u8::from(value.squitter_type) << 4;
1642 let squitter_record_source: u8 = u8::from(value.squitter_record_source) << 3;
1643 let airborne_pos_ri: u8 = u8::from(&value.airborne_position_report_indicator) << 2;
1644 let airborne_vel_ri: u8 = u8::from(&value.airborne_velocity_report_indicator) << 1;
1645 let surface_pos_ri: u8 = u8::from(&value.surface_position_report_indicator);
1646 let byte_1 = u16::from(
1647 squitter_status
1648 | squitter_type
1649 | squitter_record_source
1650 | airborne_pos_ri
1651 | airborne_vel_ri
1652 | surface_pos_ri,
1653 );
1654
1655 let ident_ri: u8 = u8::from(&value.identification_report_indicator) << 7;
1656 let event_driven_ri: u8 = u8::from(&value.event_driven_report_indicator) << 6;
1657 let on_off_status: u8 = u8::from(&value.on_off_status) << 2;
1658 let damage_status: u8 = u8::from(&value.damage_status) << 1;
1659 let malfunction_status: u8 = u8::from(&value.malfunction_status);
1660 let byte_2 = u16::from(
1661 ident_ri | event_driven_ri | on_off_status | damage_status | malfunction_status,
1662 );
1663
1664 (byte_1 << 8) | byte_2
1665 }
1666}
1667
1668#[derive(Clone, Default, Debug, PartialEq)]
1670#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1671pub enum SquitterStatus {
1672 #[default]
1673 Off, On, }
1676
1677#[derive(Copy, Clone, Default, Debug, PartialEq)]
1679#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1680pub struct SystemStatus {
1681 pub system_on_off_status: OnOffStatus,
1682 pub parameter_1_capable: ParameterCapable,
1683 pub parameter_2_capable: ParameterCapable,
1684 pub parameter_3_capable: ParameterCapable,
1685 pub parameter_4_capable: ParameterCapable,
1686 pub parameter_5_capable: ParameterCapable,
1687 pub parameter_6_capable: ParameterCapable,
1688 pub operational_status: OperationalStatus,
1689}
1690
1691impl SystemStatus {
1692 #[must_use]
1693 pub fn new() -> Self {
1694 SystemStatus::default()
1695 }
1696
1697 #[must_use]
1698 pub fn builder() -> SystemStatusBuilder {
1699 SystemStatusBuilder::new()
1700 }
1701}
1702
1703impl From<u8> for SystemStatus {
1704 fn from(record: u8) -> Self {
1705 let system_on_off_status = OnOffStatus::from((record & BIT_0_IN_BYTE) >> 7);
1706 let parameter_1_capable = ParameterCapable::from((record & BIT_1_IN_BYTE) >> 6);
1707 let parameter_2_capable = ParameterCapable::from((record & BIT_2_IN_BYTE) >> 5);
1708 let parameter_3_capable = ParameterCapable::from((record & BIT_3_IN_BYTE) >> 4);
1709 let parameter_4_capable = ParameterCapable::from((record & BIT_4_IN_BYTE) >> 3);
1710 let parameter_5_capable = ParameterCapable::from((record & BIT_5_IN_BYTE) >> 2);
1711 let parameter_6_capable = ParameterCapable::from((record & BIT_6_IN_BYTE) >> 1);
1712 let operational_status = OperationalStatus::from(record & BIT_7_IN_BYTE);
1713
1714 SystemStatus::builder()
1715 .with_system_on_off_status(system_on_off_status)
1716 .with_parameter_1_capable(parameter_1_capable)
1717 .with_parameter_2_capable(parameter_2_capable)
1718 .with_parameter_3_capable(parameter_3_capable)
1719 .with_parameter_4_capable(parameter_4_capable)
1720 .with_parameter_5_capable(parameter_5_capable)
1721 .with_parameter_6_capable(parameter_6_capable)
1722 .with_operational_status(operational_status)
1723 .build()
1724 }
1725}
1726
1727impl From<&SystemStatus> for u8 {
1728 fn from(value: &SystemStatus) -> Self {
1729 let system_on_off_status = u8::from(&value.system_on_off_status) << 7;
1730 let parameter_1 = u8::from(&value.parameter_1_capable) << 6;
1731 let parameter_2 = u8::from(&value.parameter_2_capable) << 5;
1732 let parameter_3 = u8::from(&value.parameter_3_capable) << 4;
1733 let parameter_4 = u8::from(&value.parameter_4_capable) << 3;
1734 let parameter_5 = u8::from(&value.parameter_5_capable) << 2;
1735 let parameter_6 = u8::from(&value.parameter_6_capable) << 1;
1736 let operational_status = u8::from(&value.operational_status);
1737
1738 system_on_off_status
1739 | parameter_1
1740 | parameter_2
1741 | parameter_3
1742 | parameter_4
1743 | parameter_5
1744 | parameter_6
1745 | operational_status
1746 }
1747}