open_dis_rust/distributed_emissions/
supplemental_emission_pdu.rs1use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::common::{
11 dis_error::DISError,
12 entity_id::EntityId,
13 pdu::Pdu,
14 pdu_header::{PduHeader, PduType, ProtocolFamily},
15};
16
17use super::data_types::{
18 propulsion_system_data::PropulsionSystemData,
19 vectoring_nozzle_system_data::VectoringNozzleSystemData,
20};
21
22#[derive(Clone, Debug)]
23pub struct SupplementalEmissionPdu {
25 pub pdu_header: PduHeader,
26 pub originating_entity_id: EntityId,
27 pub infrared_signature_representation_index: u16,
28 pub acoustic_signature_representation_index: u16,
29 pub radar_cross_section_signature_representation_index: u16,
30 pub number_of_propulsion_systems: u16,
31 pub number_of_vectoring_nozzle_systems: u16,
32 pub propulsion_system_data: Vec<PropulsionSystemData>,
33 pub vectoring_nozzle_system_data: Vec<VectoringNozzleSystemData>,
34}
35
36impl Default for SupplementalEmissionPdu {
37 fn default() -> Self {
48 SupplementalEmissionPdu {
49 pdu_header: PduHeader::default(
50 PduType::SupplementalEmission,
51 ProtocolFamily::DistributedEmissionRegeneration,
52 56,
53 ),
54 originating_entity_id: EntityId::default(1),
55 infrared_signature_representation_index: 0,
56 acoustic_signature_representation_index: 0,
57 radar_cross_section_signature_representation_index: 0,
58 number_of_propulsion_systems: 0,
59 number_of_vectoring_nozzle_systems: 0,
60 propulsion_system_data: vec![],
61 vectoring_nozzle_system_data: vec![],
62 }
63 }
64}
65
66impl Pdu for SupplementalEmissionPdu {
67 fn serialize(&mut self, buf: &mut BytesMut) {
69 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
70 .expect("The length of the PDU should fit in a u16.");
71 self.pdu_header.serialize(buf);
72 self.originating_entity_id.serialize(buf);
73 buf.put_u16(self.infrared_signature_representation_index);
74 buf.put_u16(self.acoustic_signature_representation_index);
75 buf.put_u16(self.radar_cross_section_signature_representation_index);
76 buf.put_u16(self.number_of_propulsion_systems);
77 buf.put_u16(self.number_of_vectoring_nozzle_systems);
78 for i in 0..self.propulsion_system_data.len() {
79 self.propulsion_system_data[i].serialize(buf);
80 }
81 for i in 0..self.vectoring_nozzle_system_data.len() {
82 self.vectoring_nozzle_system_data[i].serialize(buf);
83 }
84 }
85
86 fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
88 where
89 Self: Sized,
90 {
91 let pdu_header = PduHeader::deserialize(&mut buffer);
92 if pdu_header.pdu_type == PduType::SupplementalEmission {
93 let originating_entity_id = EntityId::deserialize(&mut buffer);
94 let infrared_signature_representation_index = buffer.get_u16();
95 let acoustic_signature_representation_index = buffer.get_u16();
96 let radar_cross_section_signature_representation_index = buffer.get_u16();
97 let number_of_propulsion_systems = buffer.get_u16();
98 let number_of_vectoring_nozzle_systems = buffer.get_u16();
99 let mut propulsion_system_data: Vec<PropulsionSystemData> = vec![];
100 for _i in 0..number_of_propulsion_systems {
101 propulsion_system_data.push(PropulsionSystemData::deserialize(&mut buffer));
102 }
103 let mut vectoring_nozzle_system_data: Vec<VectoringNozzleSystemData> = vec![];
104 for _i in 0..number_of_vectoring_nozzle_systems {
105 vectoring_nozzle_system_data
106 .push(VectoringNozzleSystemData::deserialize(&mut buffer));
107 }
108 Ok(SupplementalEmissionPdu {
109 pdu_header,
110 originating_entity_id,
111 infrared_signature_representation_index,
112 acoustic_signature_representation_index,
113 radar_cross_section_signature_representation_index,
114 number_of_propulsion_systems,
115 number_of_vectoring_nozzle_systems,
116 propulsion_system_data,
117 vectoring_nozzle_system_data,
118 })
119 } else {
120 Err(DISError::invalid_header(
121 format!(
122 "Expected PDU type SupplementalEmission, got {:?}",
123 pdu_header.pdu_type
124 ),
125 None,
126 ))
127 }
128 }
129
130 fn as_any(&self) -> &dyn Any {
132 self
133 }
134
135 fn deserialize_without_header(
137 mut buffer: BytesMut,
138 pdu_header: PduHeader,
139 ) -> Result<Self, DISError>
140 where
141 Self: Sized,
142 {
143 let originating_entity_id = EntityId::deserialize(&mut buffer);
144 let infrared_signature_representation_index = buffer.get_u16();
145 let acoustic_signature_representation_index = buffer.get_u16();
146 let radar_cross_section_signature_representation_index = buffer.get_u16();
147 let number_of_propulsion_systems = buffer.get_u16();
148 let number_of_vectoring_nozzle_systems = buffer.get_u16();
149 let mut propulsion_system_data: Vec<PropulsionSystemData> = vec![];
150 for _i in 0..number_of_propulsion_systems {
151 propulsion_system_data.push(PropulsionSystemData::deserialize(&mut buffer));
152 }
153 let mut vectoring_nozzle_system_data: Vec<VectoringNozzleSystemData> = vec![];
154 for _i in 0..number_of_vectoring_nozzle_systems {
155 vectoring_nozzle_system_data.push(VectoringNozzleSystemData::deserialize(&mut buffer));
156 }
157 Ok(SupplementalEmissionPdu {
158 pdu_header,
159 originating_entity_id,
160 infrared_signature_representation_index,
161 acoustic_signature_representation_index,
162 radar_cross_section_signature_representation_index,
163 number_of_propulsion_systems,
164 number_of_vectoring_nozzle_systems,
165 propulsion_system_data,
166 vectoring_nozzle_system_data,
167 })
168 }
169}
170
171#[cfg(test)]
172mod tests {
173 use super::SupplementalEmissionPdu;
174 use crate::common::{
175 pdu::Pdu,
176 pdu_header::{PduHeader, PduType, ProtocolFamily},
177 };
178 use bytes::BytesMut;
179
180 #[test]
181 fn create_header() {
182 let supplemental_emission_pdu = SupplementalEmissionPdu::default();
183 let pdu_header = PduHeader::default(
184 PduType::SupplementalEmission,
185 ProtocolFamily::DistributedEmissionRegeneration,
186 448 / 8,
187 );
188
189 assert_eq!(
190 pdu_header.protocol_version,
191 supplemental_emission_pdu.pdu_header.protocol_version
192 );
193 assert_eq!(
194 pdu_header.exercise_id,
195 supplemental_emission_pdu.pdu_header.exercise_id
196 );
197 assert_eq!(
198 pdu_header.pdu_type,
199 supplemental_emission_pdu.pdu_header.pdu_type
200 );
201 assert_eq!(
202 pdu_header.protocol_family,
203 supplemental_emission_pdu.pdu_header.protocol_family
204 );
205 assert_eq!(
206 pdu_header.length,
207 supplemental_emission_pdu.pdu_header.length
208 );
209 assert_eq!(
210 pdu_header.status_record,
211 supplemental_emission_pdu.pdu_header.status_record
212 );
213 }
214
215 #[test]
216 fn cast_to_any() {
217 let supplemental_emission_pdu = SupplementalEmissionPdu::default();
218 let any_pdu = supplemental_emission_pdu.as_any();
219
220 assert!(any_pdu.is::<SupplementalEmissionPdu>());
221 }
222
223 #[test]
224 fn deserialize_header() {
225 let mut supplemental_emission_pdu = SupplementalEmissionPdu::default();
226 let mut buffer = BytesMut::new();
227 supplemental_emission_pdu.serialize(&mut buffer);
228
229 let new_supplemental_emission_pdu = SupplementalEmissionPdu::deserialize(buffer).unwrap();
230 assert_eq!(
231 new_supplemental_emission_pdu.pdu_header,
232 supplemental_emission_pdu.pdu_header
233 );
234 }
235}