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