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