open_dis_rust/distributed_emissions/
iff_pdu.rs1use 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)]
26pub 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 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 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 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 fn as_any(&self) -> &dyn Any {
146 self
147 }
148
149 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}