open_dis_rust/simulation_management_with_reliability/
comment_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.13
18pub struct CommentReliablePdu {
19    pub pdu_header: PduHeader,
20    pub originating_entity_id: EntityId,
21    pub receiving_entity_id: EntityId,
22    pub number_of_fixed_datum_records: u32,
23    pub number_of_variable_datum_records: u32,
24    pub fixed_datum_records: u64,
25    pub variable_datum_records: u64,
26}
27
28impl Default for CommentReliablePdu {
29    fn default() -> Self {
30        CommentReliablePdu {
31            pdu_header: PduHeader::default(
32                PduType::CommentReliable,
33                ProtocolFamily::SimulationManagementWithReliability,
34                56,
35            ),
36            originating_entity_id: EntityId::default(1),
37            receiving_entity_id: EntityId::default(2),
38            number_of_fixed_datum_records: 0,
39            number_of_variable_datum_records: 0,
40            fixed_datum_records: 0,
41            variable_datum_records: 0,
42        }
43    }
44}
45
46impl Pdu for CommentReliablePdu {
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_u32(self.number_of_fixed_datum_records);
54        buf.put_u32(self.number_of_variable_datum_records);
55        buf.put_u64(self.fixed_datum_records);
56        buf.put_u64(self.variable_datum_records);
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::CommentReliable {
65            let originating_entity_id = EntityId::deserialize(&mut buffer);
66            let receiving_entity_id = EntityId::deserialize(&mut buffer);
67            let number_of_fixed_datum_records = buffer.get_u32();
68            let number_of_variable_datum_records = buffer.get_u32();
69            let mut fixed_datum_records: u64 = 0;
70            for _record in 0..number_of_fixed_datum_records as usize {
71                fixed_datum_records += buffer.get_u64();
72            }
73            let mut variable_datum_records: u64 = 0;
74            for _record in 0..number_of_variable_datum_records as usize {
75                variable_datum_records += buffer.get_u64();
76            }
77
78            Ok(CommentReliablePdu {
79                pdu_header,
80                originating_entity_id,
81                receiving_entity_id,
82                number_of_fixed_datum_records,
83                number_of_variable_datum_records,
84                fixed_datum_records,
85                variable_datum_records,
86            })
87        } else {
88            Err(DISError::invalid_header(
89                format!(
90                    "Expected PDU type CommentReliable, got {:?}",
91                    pdu_header.pdu_type
92                ),
93                None,
94            ))
95        }
96    }
97
98    fn as_any(&self) -> &dyn Any {
99        self
100    }
101
102    fn deserialize_without_header(
103        mut buffer: BytesMut,
104        pdu_header: PduHeader,
105    ) -> Result<Self, DISError>
106    where
107        Self: Sized,
108    {
109        let originating_entity_id = EntityId::deserialize(&mut buffer);
110        let receiving_entity_id = EntityId::deserialize(&mut buffer);
111        let number_of_fixed_datum_records = buffer.get_u32();
112        let number_of_variable_datum_records = buffer.get_u32();
113        let mut fixed_datum_records: u64 = 0;
114        for _record in 0..number_of_fixed_datum_records as usize {
115            fixed_datum_records += buffer.get_u64();
116        }
117        let mut variable_datum_records: u64 = 0;
118        for _record in 0..number_of_variable_datum_records as usize {
119            variable_datum_records += buffer.get_u64();
120        }
121
122        Ok(CommentReliablePdu {
123            pdu_header,
124            originating_entity_id,
125            receiving_entity_id,
126            number_of_fixed_datum_records,
127            number_of_variable_datum_records,
128            fixed_datum_records,
129            variable_datum_records,
130        })
131    }
132}
133
134#[cfg(test)]
135mod tests {
136    use super::CommentReliablePdu;
137    use crate::common::pdu_header::{PduHeader, PduType, ProtocolFamily};
138
139    #[test]
140    fn create_header() {
141        let comment_reliable_pdu = CommentReliablePdu::default();
142        let pdu_header = PduHeader::default(
143            PduType::CommentReliable,
144            ProtocolFamily::SimulationManagementWithReliability,
145            448 / 8,
146        );
147
148        assert_eq!(
149            pdu_header.protocol_version,
150            comment_reliable_pdu.pdu_header.protocol_version
151        );
152        assert_eq!(
153            pdu_header.exercise_id,
154            comment_reliable_pdu.pdu_header.exercise_id
155        );
156        assert_eq!(
157            pdu_header.pdu_type,
158            comment_reliable_pdu.pdu_header.pdu_type
159        );
160        assert_eq!(
161            pdu_header.protocol_family,
162            comment_reliable_pdu.pdu_header.protocol_family
163        );
164        assert_eq!(pdu_header.length, comment_reliable_pdu.pdu_header.length);
165        assert_eq!(
166            pdu_header.status_record,
167            comment_reliable_pdu.pdu_header.status_record
168        );
169    }
170}