open_dis_rust/entity_management/
aggregate_state_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    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)]
24/// Implemented according to IEEE 1278.1-2012 ยง7.8.2
25pub 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    /// Creates a default Aggregate State PDU with arbitrary aggregate ID
52    ///
53    /// # Examples
54    ///
55    /// Initializing an Aggregate State PDU:
56    /// ```
57    /// use open_dis_rust::entity_management::aggregate_state_pdu::AggregateStatePdu;
58    /// let aggregate_state_pdu = AggregateStatePdu::default();
59    /// ```
60    ///
61    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}