open_dis_rust/distributed_emissions/
iff_pdu.rs

1//     open-dis-rust - Rust implementation of the IEEE 1278.1-2012 Distributed Interactive
2//                     Simulation (DIS) application protocol
3//     Copyright (C) 2023 Cameron Howell
4//
5//     Licensed under the BSD 2-Clause License
6
7use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::common::{
11    dis_error::DISError,
12    entity_id::EntityId,
13    event_id::EventId,
14    pdu::Pdu,
15    pdu_header::{PduHeader, PduType, ProtocolFamily},
16    vector3_float::Vector3Float,
17};
18
19use super::data_types::{
20    beam_data::BeamData, fundamental_operational_data::FundamentalOperationalData,
21    iff_fundamental_parameter_data::IFFFundamentalParameterData, layer_header::LayerHeader,
22    secondary_operational_data::SecondaryOperationalData, system_id::SystemId,
23};
24
25#[derive(Clone, Debug)]
26/// Implemented according to IEEE 1278.1-2012 ยง7.6.5
27pub struct IFFPdu {
28    pub pdu_header: PduHeader,
29    pub emitting_entity_id: EntityId,
30    pub event_id: EventId,
31    pub relative_antenna_location: Vector3Float,
32    pub number_of_iff_parameters: u32,
33    pub system_id: SystemId,
34    pub system_designator: u8,
35    pub system_specific_data: u8,
36    pub fundamental_operational_data: FundamentalOperationalData,
37    pub layer_header: LayerHeader,
38    pub beam_data: BeamData,
39    pub secondary_operational_data: SecondaryOperationalData,
40    pub iff_parameters: Vec<IFFFundamentalParameterData>,
41}
42
43impl Default for IFFPdu {
44    /// Creates a default-initialized IFF PDU
45    ///
46    /// # Examples
47    ///
48    /// Initializing an IFF PDU:
49    /// ```
50    /// use open_dis_rust::distributed_emissions::iff_pdu::IFFPdu;
51    /// let mut iff_pdu = IFFPdu::default();
52    /// ```
53    ///
54    fn default() -> Self {
55        IFFPdu {
56            pdu_header: PduHeader::default(
57                PduType::IFF,
58                ProtocolFamily::DistributedEmissionRegeneration,
59                56,
60            ),
61            emitting_entity_id: EntityId::default(1),
62            event_id: EventId::default(1),
63            relative_antenna_location: Vector3Float::default(),
64            number_of_iff_parameters: 0,
65            system_id: SystemId::default(),
66            system_designator: 0,
67            system_specific_data: 0,
68            fundamental_operational_data: FundamentalOperationalData::default(),
69            layer_header: LayerHeader::default(),
70            beam_data: BeamData::default(),
71            secondary_operational_data: SecondaryOperationalData::default(),
72            iff_parameters: vec![],
73        }
74    }
75}
76
77impl Pdu for IFFPdu {
78    /// Serialize contents of `IFFPdu` into `BytesMut` buffer
79    fn serialize(&mut self, buf: &mut BytesMut) {
80        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
81            .expect("The length of the PDU should fit in a u16.");
82        self.pdu_header.serialize(buf);
83        self.emitting_entity_id.serialize(buf);
84        self.event_id.serialize(buf);
85        self.relative_antenna_location.serialize(buf);
86        buf.put_u32(self.number_of_iff_parameters);
87        self.system_id.serialize(buf);
88        buf.put_u8(self.system_designator);
89        buf.put_u8(self.system_specific_data);
90        self.fundamental_operational_data.serialize(buf);
91        self.layer_header.serialize(buf);
92        self.beam_data.serialize(buf);
93        self.secondary_operational_data.serialize(buf);
94        for i in 0..self.iff_parameters.len() {
95            self.iff_parameters[i].serialize(buf);
96        }
97    }
98
99    /// Deserialize bytes from `BytesMut` buffer and interpret as `IFFPdu`
100    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
101    where
102        Self: Sized,
103    {
104        let pdu_header = PduHeader::deserialize(&mut buffer);
105        if pdu_header.pdu_type == PduType::IFF {
106            let emitting_entity_id = EntityId::deserialize(&mut buffer);
107            let event_id = EventId::deserialize(&mut buffer);
108            let relative_antenna_location = Vector3Float::deserialize(&mut buffer);
109            let number_of_iff_parameters = buffer.get_u32();
110            let system_id = SystemId::deserialize(&mut buffer);
111            let system_designator = buffer.get_u8();
112            let system_specific_data = buffer.get_u8();
113            let fundamental_operational_data = FundamentalOperationalData::deserialize(&mut buffer);
114            let layer_header = LayerHeader::deserialize(&mut buffer);
115            let beam_data = BeamData::deserialize(&mut buffer);
116            let secondary_operational_data = SecondaryOperationalData::deserialize(&mut buffer);
117            let mut iff_parameters: Vec<IFFFundamentalParameterData> = vec![];
118            for _i in 0..number_of_iff_parameters {
119                iff_parameters.push(IFFFundamentalParameterData::deserialize(&mut buffer));
120            }
121            Ok(IFFPdu {
122                pdu_header,
123                emitting_entity_id,
124                event_id,
125                relative_antenna_location,
126                number_of_iff_parameters,
127                system_id,
128                system_designator,
129                system_specific_data,
130                fundamental_operational_data,
131                layer_header,
132                beam_data,
133                secondary_operational_data,
134                iff_parameters,
135            })
136        } else {
137            Err(DISError::invalid_header(
138                format!("Expected PDU type IFF, got {:?}", pdu_header.pdu_type),
139                None,
140            ))
141        }
142    }
143
144    /// Treat `IFFPdu` as Any type
145    fn as_any(&self) -> &dyn Any {
146        self
147    }
148
149    /// Deserialize bytes from `BytesMut` buffer, but assume PDU header exists already
150    fn deserialize_without_header(
151        mut buffer: BytesMut,
152        pdu_header: PduHeader,
153    ) -> Result<Self, DISError>
154    where
155        Self: Sized,
156    {
157        let emitting_entity_id = EntityId::deserialize(&mut buffer);
158        let event_id = EventId::deserialize(&mut buffer);
159        let relative_antenna_location = Vector3Float::deserialize(&mut buffer);
160        let number_of_iff_parameters = buffer.get_u32();
161        let system_id = SystemId::deserialize(&mut buffer);
162        let system_designator = buffer.get_u8();
163        let system_specific_data = buffer.get_u8();
164        let fundamental_operational_data = FundamentalOperationalData::deserialize(&mut buffer);
165        let layer_header = LayerHeader::deserialize(&mut buffer);
166        let beam_data = BeamData::deserialize(&mut buffer);
167        let secondary_operational_data = SecondaryOperationalData::deserialize(&mut buffer);
168        let mut iff_parameters: Vec<IFFFundamentalParameterData> = vec![];
169        for _i in 0..number_of_iff_parameters {
170            iff_parameters.push(IFFFundamentalParameterData::deserialize(&mut buffer));
171        }
172        Ok(IFFPdu {
173            pdu_header,
174            emitting_entity_id,
175            event_id,
176            relative_antenna_location,
177            number_of_iff_parameters,
178            system_id,
179            system_designator,
180            system_specific_data,
181            fundamental_operational_data,
182            layer_header,
183            beam_data,
184            secondary_operational_data,
185            iff_parameters,
186        })
187    }
188}
189
190#[cfg(test)]
191mod tests {
192    use super::IFFPdu;
193    use crate::common::{
194        pdu::Pdu,
195        pdu_header::{PduHeader, PduType, ProtocolFamily},
196    };
197    use bytes::BytesMut;
198
199    #[test]
200    fn create_header() {
201        let iff_pdu = IFFPdu::default();
202        let pdu_header = PduHeader::default(
203            PduType::IFF,
204            ProtocolFamily::DistributedEmissionRegeneration,
205            448 / 8,
206        );
207
208        assert_eq!(
209            pdu_header.protocol_version,
210            iff_pdu.pdu_header.protocol_version
211        );
212        assert_eq!(pdu_header.exercise_id, iff_pdu.pdu_header.exercise_id);
213        assert_eq!(pdu_header.pdu_type, iff_pdu.pdu_header.pdu_type);
214        assert_eq!(
215            pdu_header.protocol_family,
216            iff_pdu.pdu_header.protocol_family
217        );
218        assert_eq!(pdu_header.length, iff_pdu.pdu_header.length);
219        assert_eq!(pdu_header.status_record, iff_pdu.pdu_header.status_record);
220    }
221
222    #[test]
223    fn cast_to_any() {
224        let iff_pdu = IFFPdu::default();
225        let any_pdu = iff_pdu.as_any();
226
227        assert!(any_pdu.is::<IFFPdu>());
228    }
229
230    #[test]
231    fn deserialize_header() {
232        let mut iff_pdu = IFFPdu::default();
233        let mut buffer = BytesMut::new();
234        iff_pdu.serialize(&mut buffer);
235
236        let new_iff_pdu = IFFPdu::deserialize(buffer).unwrap();
237        assert_eq!(new_iff_pdu.pdu_header, iff_pdu.pdu_header);
238    }
239}