open_dis_rust/simulation_management_with_reliability/
create_entity_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.2
18pub struct CreateEntityReliablePdu {
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}
27
28impl Default for CreateEntityReliablePdu {
29    fn default() -> Self {
30        CreateEntityReliablePdu {
31            pdu_header: PduHeader::default(
32                PduType::CreateEntityReliable,
33                ProtocolFamily::SimulationManagementWithReliability,
34                56,
35            ),
36            originating_entity_id: EntityId::default(1),
37            receiving_entity_id: EntityId::default(2),
38            required_reliability_service: 0,
39            pad1: 0,
40            pad2: 0,
41            request_id: 0,
42        }
43    }
44}
45
46impl Pdu for CreateEntityReliablePdu {
47    fn serialize(&mut self, buf: &mut BytesMut) {
48        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
49            .expect("The length of the PDU should fit in a u16.");
50        self.pdu_header.serialize(buf);
51        self.originating_entity_id.serialize(buf);
52        self.receiving_entity_id.serialize(buf);
53        buf.put_u8(self.required_reliability_service);
54        buf.put_u16(self.pad1);
55        buf.put_u8(self.pad2);
56        buf.put_u32(self.request_id);
57    }
58
59    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
60    where
61        Self: Sized,
62    {
63        let pdu_header = PduHeader::deserialize(&mut buffer);
64        if pdu_header.pdu_type == PduType::CreateEntityReliable {
65            let originating_entity_id = EntityId::deserialize(&mut buffer);
66            let receiving_entity_id = EntityId::deserialize(&mut buffer);
67            let required_reliability_service = buffer.get_u8();
68            let pad1 = buffer.get_u16();
69            let pad2 = buffer.get_u8();
70            let request_id = buffer.get_u32();
71
72            Ok(CreateEntityReliablePdu {
73                pdu_header,
74                originating_entity_id,
75                receiving_entity_id,
76                required_reliability_service,
77                pad1,
78                pad2,
79                request_id,
80            })
81        } else {
82            Err(DISError::invalid_header(
83                format!(
84                    "Expected PDU type CreateEntityReliable, got {:?}",
85                    pdu_header.pdu_type
86                ),
87                None,
88            ))
89        }
90    }
91
92    fn as_any(&self) -> &dyn Any {
93        self
94    }
95
96    fn deserialize_without_header(
97        mut buffer: BytesMut,
98        pdu_header: PduHeader,
99    ) -> Result<Self, DISError>
100    where
101        Self: Sized,
102    {
103        let originating_entity_id = EntityId::deserialize(&mut buffer);
104        let receiving_entity_id = EntityId::deserialize(&mut buffer);
105        let required_reliability_service = buffer.get_u8();
106        let pad1 = buffer.get_u16();
107        let pad2 = buffer.get_u8();
108        let request_id = buffer.get_u32();
109
110        Ok(CreateEntityReliablePdu {
111            pdu_header,
112            originating_entity_id,
113            receiving_entity_id,
114            required_reliability_service,
115            pad1,
116            pad2,
117            request_id,
118        })
119    }
120}
121
122#[cfg(test)]
123mod tests {
124    use super::CreateEntityReliablePdu;
125    use crate::common::pdu_header::{PduHeader, PduType, ProtocolFamily};
126
127    #[test]
128    fn create_header() {
129        let create_entity_reliable_pdu = CreateEntityReliablePdu::default();
130        let pdu_header = PduHeader::default(
131            PduType::CreateEntityReliable,
132            ProtocolFamily::SimulationManagementWithReliability,
133            448 / 8,
134        );
135
136        assert_eq!(
137            pdu_header.protocol_version,
138            create_entity_reliable_pdu.pdu_header.protocol_version
139        );
140        assert_eq!(
141            pdu_header.exercise_id,
142            create_entity_reliable_pdu.pdu_header.exercise_id
143        );
144        assert_eq!(
145            pdu_header.pdu_type,
146            create_entity_reliable_pdu.pdu_header.pdu_type
147        );
148        assert_eq!(
149            pdu_header.protocol_family,
150            create_entity_reliable_pdu.pdu_header.protocol_family
151        );
152        assert_eq!(
153            pdu_header.length,
154            create_entity_reliable_pdu.pdu_header.length
155        );
156        assert_eq!(
157            pdu_header.status_record,
158            create_entity_reliable_pdu.pdu_header.status_record
159        );
160    }
161}