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