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