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