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