open_dis_rust/simulation_management_with_reliability/
set_data_reliable_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 crate::common::{
8    dis_error::DISError,
9    entity_id::EntityId,
10    pdu::Pdu,
11    pdu_header::{PduHeader, PduType, ProtocolFamily},
12};
13use bytes::{Buf, BufMut, BytesMut};
14use std::any::Any;
15
16#[derive(Copy, Clone, Debug)]
17/// Implemented according to IEEE 1278.1-2012 ยง7.11.10
18pub struct SetDataReliablePdu {
19    pub pdu_header: PduHeader,
20    pub originating_entity_id: EntityId,
21    pub receiving_entity_id: EntityId,
22    pub required_reliability_service: u8,
23    pub pad1: u16,
24    pub pad2: u8,
25    pub request_id: u32,
26    pub number_of_fixed_datum_records: u32,
27    pub number_of_variable_datum_records: u32,
28    pub fixed_datum_records: u64,
29    pub variable_datum_records: u64,
30}
31
32impl Default for SetDataReliablePdu {
33    fn default() -> Self {
34        SetDataReliablePdu {
35            pdu_header: PduHeader::default(
36                PduType::SetDataReliable,
37                ProtocolFamily::SimulationManagementWithReliability,
38                56,
39            ),
40            originating_entity_id: EntityId::default(1),
41            receiving_entity_id: EntityId::default(2),
42            required_reliability_service: 0,
43            pad1: 0,
44            pad2: 0,
45            request_id: 0,
46            number_of_fixed_datum_records: 0,
47            number_of_variable_datum_records: 0,
48            fixed_datum_records: 0,
49            variable_datum_records: 0,
50        }
51    }
52}
53
54impl Pdu for SetDataReliablePdu {
55    fn serialize(&mut self, buf: &mut BytesMut) {
56        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
57            .expect("The length of the PDU should fit in a u16.");
58        self.pdu_header.serialize(buf);
59        self.originating_entity_id.serialize(buf);
60        self.receiving_entity_id.serialize(buf);
61        buf.put_u8(self.required_reliability_service);
62        buf.put_u16(self.pad1);
63        buf.put_u8(self.pad2);
64        buf.put_u32(self.request_id);
65        buf.put_u32(self.number_of_fixed_datum_records);
66        buf.put_u32(self.number_of_variable_datum_records);
67        buf.put_u64(self.fixed_datum_records);
68        buf.put_u64(self.variable_datum_records);
69    }
70
71    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
72    where
73        Self: Sized,
74    {
75        let pdu_header = PduHeader::deserialize(&mut buffer);
76        if pdu_header.pdu_type == PduType::SetDataReliable {
77            let originating_entity_id = EntityId::deserialize(&mut buffer);
78            let receiving_entity_id = EntityId::deserialize(&mut buffer);
79            let required_reliability_service = buffer.get_u8();
80            let pad1 = buffer.get_u16();
81            let pad2 = buffer.get_u8();
82            let request_id = buffer.get_u32();
83            let number_of_fixed_datum_records = buffer.get_u32();
84            let number_of_variable_datum_records = buffer.get_u32();
85            let mut fixed_datum_records: u64 = 0;
86            for _record in 0..number_of_fixed_datum_records as usize {
87                fixed_datum_records += buffer.get_u64();
88            }
89            let mut variable_datum_records: u64 = 0;
90            for _record in 0..number_of_variable_datum_records as usize {
91                variable_datum_records += buffer.get_u64();
92            }
93
94            Ok(SetDataReliablePdu {
95                pdu_header,
96                originating_entity_id,
97                receiving_entity_id,
98                required_reliability_service,
99                pad1,
100                pad2,
101                request_id,
102                number_of_fixed_datum_records,
103                number_of_variable_datum_records,
104                fixed_datum_records,
105                variable_datum_records,
106            })
107        } else {
108            Err(DISError::invalid_header(
109                format!(
110                    "Expected PDU type SetDataReliable, got {:?}",
111                    pdu_header.pdu_type
112                ),
113                None,
114            ))
115        }
116    }
117
118    fn as_any(&self) -> &dyn Any {
119        self
120    }
121
122    fn deserialize_without_header(
123        mut buffer: BytesMut,
124        pdu_header: PduHeader,
125    ) -> Result<Self, DISError>
126    where
127        Self: Sized,
128    {
129        let originating_entity_id = EntityId::deserialize(&mut buffer);
130        let receiving_entity_id = EntityId::deserialize(&mut buffer);
131        let required_reliability_service = buffer.get_u8();
132        let pad1 = buffer.get_u16();
133        let pad2 = buffer.get_u8();
134        let request_id = buffer.get_u32();
135        let number_of_fixed_datum_records = buffer.get_u32();
136        let number_of_variable_datum_records = buffer.get_u32();
137        let mut fixed_datum_records: u64 = 0;
138        for _record in 0..number_of_fixed_datum_records as usize {
139            fixed_datum_records += buffer.get_u64();
140        }
141        let mut variable_datum_records: u64 = 0;
142        for _record in 0..number_of_variable_datum_records as usize {
143            variable_datum_records += buffer.get_u64();
144        }
145
146        Ok(SetDataReliablePdu {
147            pdu_header,
148            originating_entity_id,
149            receiving_entity_id,
150            required_reliability_service,
151            pad1,
152            pad2,
153            request_id,
154            number_of_fixed_datum_records,
155            number_of_variable_datum_records,
156            fixed_datum_records,
157            variable_datum_records,
158        })
159    }
160}
161
162#[cfg(test)]
163mod tests {
164    use super::SetDataReliablePdu;
165    use crate::common::{
166        pdu::Pdu,
167        pdu_header::{PduHeader, PduType, ProtocolFamily},
168    };
169    use bytes::BytesMut;
170
171    #[test]
172    fn create_header() {
173        let set_data_reliable_pdu = SetDataReliablePdu::default();
174        let pdu_header = PduHeader::default(
175            PduType::SetDataReliable,
176            ProtocolFamily::SimulationManagementWithReliability,
177            448 / 8,
178        );
179
180        assert_eq!(
181            pdu_header.protocol_version,
182            set_data_reliable_pdu.pdu_header.protocol_version
183        );
184        assert_eq!(
185            pdu_header.exercise_id,
186            set_data_reliable_pdu.pdu_header.exercise_id
187        );
188        assert_eq!(
189            pdu_header.pdu_type,
190            set_data_reliable_pdu.pdu_header.pdu_type
191        );
192        assert_eq!(
193            pdu_header.protocol_family,
194            set_data_reliable_pdu.pdu_header.protocol_family
195        );
196        assert_eq!(pdu_header.length, set_data_reliable_pdu.pdu_header.length);
197        assert_eq!(
198            pdu_header.status_record,
199            set_data_reliable_pdu.pdu_header.status_record
200        );
201    }
202
203    #[test]
204    fn deserialize_header() {
205        let mut set_data_reliable_pdu = SetDataReliablePdu::default();
206        let mut buffer = BytesMut::new();
207        set_data_reliable_pdu.serialize(&mut buffer);
208
209        let new_set_data_reliable_pdu = SetDataReliablePdu::deserialize(buffer).unwrap();
210        assert_eq!(
211            new_set_data_reliable_pdu.pdu_header,
212            set_data_reliable_pdu.pdu_header
213        );
214    }
215}