open_dis_rust/entity_management/
aggregate_state_pdu.rs1use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::common::{
11 dis_error::DISError,
12 entity_id::EntityId,
13 entity_type::EntityType,
14 euler_angles::EulerAngles,
15 pdu::Pdu,
16 pdu_header::{PduHeader, PduType, ProtocolFamily},
17 vector3_double::Vector3Double,
18 vector3_float::Vector3Float,
19};
20
21use super::data_types::{aggregate_id::AggregateId, aggregate_marking::AggregateMarking};
22
23#[derive(Clone, Debug)]
24pub struct AggregateStatePdu {
26 pub pdu_header: PduHeader,
27 pub aggregate_id: EntityId,
28 pub force_id: u8,
29 pub aggregate_state: u8,
30 pub aggregate_type: EntityType,
31 pub formation: u32,
32 pub aggregate_marking: AggregateMarking,
33 pub dimensions: Vector3Float,
34 pub orientation: EulerAngles,
35 pub center_of_mass: Vector3Double,
36 pub velocity: Vector3Float,
37 pub number_of_dis_aggregates: u16,
38 pub number_of_dis_entities: u16,
39 pub number_of_silent_aggregate_types: u16,
40 pub number_of_silent_entity_types: u16,
41 pub aggregate_id_list: Vec<AggregateId>,
42 pub entity_id_list: Vec<EntityId>,
43 pub pad2: u8,
44 pub silent_aggregate_system_list: Vec<EntityType>,
45 pub silent_entity_system_list: Vec<EntityType>,
46 pub number_of_variable_datum_records: u32,
47 pub variable_datum_list: Vec<u64>,
48}
49
50impl Default for AggregateStatePdu {
51 fn default() -> Self {
62 AggregateStatePdu {
63 pdu_header: PduHeader::default(
64 PduType::AggregateState,
65 ProtocolFamily::EntityManagement,
66 56,
67 ),
68 aggregate_id: EntityId::default(1),
69 force_id: 0,
70 aggregate_state: 0,
71 aggregate_type: EntityType::default(),
72 formation: 0,
73 aggregate_marking: AggregateMarking::default(),
74 dimensions: Vector3Float::default(),
75 orientation: EulerAngles::default(),
76 center_of_mass: Vector3Double::default(),
77 velocity: Vector3Float::default(),
78 number_of_dis_aggregates: 0,
79 number_of_dis_entities: 0,
80 number_of_silent_aggregate_types: 0,
81 number_of_silent_entity_types: 0,
82 aggregate_id_list: vec![],
83 entity_id_list: vec![],
84 pad2: 0,
85 silent_aggregate_system_list: vec![],
86 silent_entity_system_list: vec![],
87 number_of_variable_datum_records: 0,
88 variable_datum_list: vec![],
89 }
90 }
91}
92
93impl Pdu for AggregateStatePdu {
94 fn serialize(&mut self, buf: &mut BytesMut) {
95 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
96 .expect("The length of the PDU should fit in a u16.");
97 self.pdu_header.serialize(buf);
98 self.aggregate_id.serialize(buf);
99 buf.put_u8(self.force_id);
100 buf.put_u8(self.aggregate_state);
101 self.aggregate_type.serialize(buf);
102 buf.put_u32(self.formation);
103 self.aggregate_marking.serialize(buf);
104 self.dimensions.serialize(buf);
105 self.orientation.serialize(buf);
106 self.center_of_mass.serialize(buf);
107 self.velocity.serialize(buf);
108 buf.put_u16(self.number_of_dis_aggregates);
109 buf.put_u16(self.number_of_dis_entities);
110 buf.put_u16(self.number_of_silent_aggregate_types);
111 buf.put_u16(self.number_of_silent_entity_types);
112 for i in 0..self.aggregate_id_list.len() {
113 self.aggregate_id_list[i].serialize(buf);
114 }
115 for i in 0..self.entity_id_list.len() {
116 self.entity_id_list[i].serialize(buf);
117 }
118 buf.put_u8(self.pad2);
119 for i in 0..self.silent_aggregate_system_list.len() {
120 self.silent_aggregate_system_list[i].serialize(buf);
121 }
122 for i in 0..self.silent_entity_system_list.len() {
123 self.silent_entity_system_list[i].serialize(buf);
124 }
125 buf.put_u32(self.number_of_variable_datum_records);
126 for i in 0..self.variable_datum_list.len() {
127 buf.put_u64(self.variable_datum_list[i]);
128 }
129 }
130
131 fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
132 where
133 Self: Sized,
134 {
135 let pdu_header = PduHeader::deserialize(&mut buffer);
136 if pdu_header.pdu_type == PduType::AggregateState {
137 let aggregate_id = EntityId::deserialize(&mut buffer);
138 let force_id = buffer.get_u8();
139 let aggregate_state = buffer.get_u8();
140 let aggregate_type = EntityType::deserialize(&mut buffer);
141 let formation = buffer.get_u32();
142 let aggregate_marking = AggregateMarking::deserialize(&mut buffer);
143 let dimensions = Vector3Float::deserialize(&mut buffer);
144 let orientation = EulerAngles::deserialize(&mut buffer);
145 let center_of_mass = Vector3Double::deserialize(&mut buffer);
146 let velocity = Vector3Float::deserialize(&mut buffer);
147 let number_of_dis_aggregates = buffer.get_u16();
148 let number_of_dis_entities = buffer.get_u16();
149 let number_of_silent_aggregate_types = buffer.get_u16();
150 let number_of_silent_entity_types = buffer.get_u16();
151 let mut aggregate_id_list: Vec<AggregateId> = vec![];
152 for _i in 0..number_of_dis_aggregates {
153 aggregate_id_list.push(AggregateId::deserialize(&mut buffer));
154 }
155 let mut entity_id_list: Vec<EntityId> = vec![];
156 for _i in 0..number_of_dis_entities {
157 entity_id_list.push(EntityId::deserialize(&mut buffer));
158 }
159 let pad2 = buffer.get_u8();
160 let mut silent_aggregate_system_list: Vec<EntityType> = vec![];
161 for _i in 0..number_of_silent_aggregate_types {
162 silent_aggregate_system_list.push(EntityType::deserialize(&mut buffer));
163 }
164 let mut silent_entity_system_list: Vec<EntityType> = vec![];
165 for _i in 0..number_of_silent_entity_types {
166 silent_entity_system_list.push(EntityType::deserialize(&mut buffer));
167 }
168 let number_of_variable_datum_records = buffer.get_u32();
169 let mut variable_datum_list: Vec<u64> = vec![];
170 for _i in 0..number_of_variable_datum_records {
171 variable_datum_list.push(buffer.get_u64());
172 }
173 Ok(AggregateStatePdu {
174 pdu_header,
175 aggregate_id,
176 force_id,
177 aggregate_state,
178 aggregate_type,
179 formation,
180 aggregate_marking,
181 dimensions,
182 orientation,
183 center_of_mass,
184 velocity,
185 number_of_dis_aggregates,
186 number_of_dis_entities,
187 number_of_silent_aggregate_types,
188 number_of_silent_entity_types,
189 aggregate_id_list,
190 entity_id_list,
191 pad2,
192 silent_aggregate_system_list,
193 silent_entity_system_list,
194 number_of_variable_datum_records,
195 variable_datum_list,
196 })
197 } else {
198 Err(DISError::invalid_header(
199 format!(
200 "Expected PDU type AggregateState, got {:?}",
201 pdu_header.pdu_type
202 ),
203 None,
204 ))
205 }
206 }
207
208 fn as_any(&self) -> &dyn Any {
209 self
210 }
211
212 fn deserialize_without_header(
213 mut buffer: BytesMut,
214 pdu_header: PduHeader,
215 ) -> Result<Self, DISError>
216 where
217 Self: Sized,
218 {
219 let aggregate_id = EntityId::deserialize(&mut buffer);
220 let force_id = buffer.get_u8();
221 let aggregate_state = buffer.get_u8();
222 let aggregate_type = EntityType::deserialize(&mut buffer);
223 let formation = buffer.get_u32();
224 let aggregate_marking = AggregateMarking::deserialize(&mut buffer);
225 let dimensions = Vector3Float::deserialize(&mut buffer);
226 let orientation = EulerAngles::deserialize(&mut buffer);
227 let center_of_mass = Vector3Double::deserialize(&mut buffer);
228 let velocity = Vector3Float::deserialize(&mut buffer);
229 let number_of_dis_aggregates = buffer.get_u16();
230 let number_of_dis_entities = buffer.get_u16();
231 let number_of_silent_aggregate_types = buffer.get_u16();
232 let number_of_silent_entity_types = buffer.get_u16();
233 let mut aggregate_id_list: Vec<AggregateId> = vec![];
234 for _i in 0..number_of_dis_aggregates {
235 aggregate_id_list.push(AggregateId::deserialize(&mut buffer));
236 }
237 let mut entity_id_list: Vec<EntityId> = vec![];
238 for _i in 0..number_of_dis_entities {
239 entity_id_list.push(EntityId::deserialize(&mut buffer));
240 }
241 let pad2 = buffer.get_u8();
242 let mut silent_aggregate_system_list: Vec<EntityType> = vec![];
243 for _i in 0..number_of_silent_aggregate_types {
244 silent_aggregate_system_list.push(EntityType::deserialize(&mut buffer));
245 }
246 let mut silent_entity_system_list: Vec<EntityType> = vec![];
247 for _i in 0..number_of_silent_entity_types {
248 silent_entity_system_list.push(EntityType::deserialize(&mut buffer));
249 }
250 let number_of_variable_datum_records = buffer.get_u32();
251 let mut variable_datum_list: Vec<u64> = vec![];
252 for _i in 0..number_of_variable_datum_records {
253 variable_datum_list.push(buffer.get_u64());
254 }
255 Ok(AggregateStatePdu {
256 pdu_header,
257 aggregate_id,
258 force_id,
259 aggregate_state,
260 aggregate_type,
261 formation,
262 aggregate_marking,
263 dimensions,
264 orientation,
265 center_of_mass,
266 velocity,
267 number_of_dis_aggregates,
268 number_of_dis_entities,
269 number_of_silent_aggregate_types,
270 number_of_silent_entity_types,
271 aggregate_id_list,
272 entity_id_list,
273 pad2,
274 silent_aggregate_system_list,
275 silent_entity_system_list,
276 number_of_variable_datum_records,
277 variable_datum_list,
278 })
279 }
280}
281
282#[cfg(test)]
283mod tests {
284 use super::AggregateStatePdu;
285 use crate::common::{
286 pdu::Pdu,
287 pdu_header::{PduHeader, PduType, ProtocolFamily},
288 };
289 use bytes::BytesMut;
290
291 #[test]
292 fn create_header() {
293 let aggregate_state_pdu = AggregateStatePdu::default();
294 let pdu_header = PduHeader::default(
295 PduType::AggregateState,
296 ProtocolFamily::EntityManagement,
297 448 / 8,
298 );
299
300 assert_eq!(
301 pdu_header.protocol_version,
302 aggregate_state_pdu.pdu_header.protocol_version
303 );
304 assert_eq!(
305 pdu_header.exercise_id,
306 aggregate_state_pdu.pdu_header.exercise_id
307 );
308 assert_eq!(pdu_header.pdu_type, aggregate_state_pdu.pdu_header.pdu_type);
309 assert_eq!(
310 pdu_header.protocol_family,
311 aggregate_state_pdu.pdu_header.protocol_family
312 );
313 assert_eq!(pdu_header.length, aggregate_state_pdu.pdu_header.length);
314 assert_eq!(
315 pdu_header.status_record,
316 aggregate_state_pdu.pdu_header.status_record
317 );
318 }
319
320 #[test]
321 fn deserialize_header() {
322 let mut aggregate_state_pdu = AggregateStatePdu::default();
323 let mut buffer = BytesMut::new();
324 aggregate_state_pdu.serialize(&mut buffer);
325
326 let new_aggregate_state_pdu = AggregateStatePdu::deserialize(buffer).unwrap();
327 assert_eq!(
328 new_aggregate_state_pdu.pdu_header,
329 aggregate_state_pdu.pdu_header
330 );
331 }
332}