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