open_dis_rust/information_operations/
information_operations_action_pdu.rs1use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::{
11 common::{
12 dis_error::DISError,
13 entity_id::EntityId,
14 enums::{
15 IOActionIOActionPhase, IOActionIOActionType, IOActionIOSimulationSource,
16 IOActionIOWarfareType,
17 },
18 pdu::Pdu,
19 pdu_header::{PduHeader, PduType, ProtocolFamily},
20 },
21 warfare::data_types::standard_variable_specification::StandardVariableSpecification,
22};
23
24#[derive(Clone, Debug)]
25pub struct InformationOperationsActionPdu {
27 pub pdu_header: PduHeader,
28 pub originating_simulation_id: EntityId,
29 pub receiving_simulation_id: EntityId,
30 pub request_id: u32,
31 pub io_warfare_type: IOActionIOWarfareType,
32 pub io_simulation_source: IOActionIOSimulationSource,
33 pub io_action_type: IOActionIOActionType,
34 pub io_action_phase: IOActionIOActionPhase,
35 pub padding1: u32,
36 pub io_attacker_entity_id: EntityId,
37 pub io_primary_target_entity_id: EntityId,
38 pub padding2: u16,
39 pub io_records: StandardVariableSpecification,
40}
41
42impl Default for InformationOperationsActionPdu {
43 fn default() -> Self {
54 InformationOperationsActionPdu {
55 pdu_header: PduHeader::default(
56 PduType::InformationOperationsAction,
57 ProtocolFamily::InformationOperations,
58 32,
59 ),
60 originating_simulation_id: EntityId::default(1),
61 receiving_simulation_id: EntityId::default(2),
62 request_id: 0,
63 io_warfare_type: IOActionIOWarfareType::default(),
64 io_simulation_source: IOActionIOSimulationSource::default(),
65 io_action_type: IOActionIOActionType::default(),
66 io_action_phase: IOActionIOActionPhase::default(),
67 padding1: 0,
68 io_attacker_entity_id: EntityId::default(3),
69 io_primary_target_entity_id: EntityId::default(4),
70 padding2: 0,
71 io_records: StandardVariableSpecification::default(),
72 }
73 }
74}
75
76impl Pdu for InformationOperationsActionPdu {
77 fn serialize(&mut self, buf: &mut BytesMut) {
78 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
79 .expect("The length of the PDU should fit in a u16.");
80 self.pdu_header.serialize(buf);
81 self.originating_simulation_id.serialize(buf);
82 self.receiving_simulation_id.serialize(buf);
83 buf.put_u32(self.request_id);
84 buf.put_u8(self.io_warfare_type as u8);
85 buf.put_u8(self.io_simulation_source as u8);
86 buf.put_u8(self.io_action_type as u8);
87 buf.put_u8(self.io_action_phase as u8);
88 buf.put_u32(self.padding1);
89 self.io_attacker_entity_id.serialize(buf);
90 self.io_primary_target_entity_id.serialize(buf);
91 buf.put_u16(self.padding2);
92 self.io_records.serialize(buf);
93 }
94
95 fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
96 where
97 Self: Sized,
98 {
99 let pdu_header = PduHeader::deserialize(&mut buffer);
100 if pdu_header.pdu_type == PduType::InformationOperationsAction {
101 let originating_simulation_id = EntityId::deserialize(&mut buffer);
102 let receiving_simulation_id = EntityId::deserialize(&mut buffer);
103 let request_id = buffer.get_u32();
104 let io_warfare_type = IOActionIOWarfareType::deserialize(&mut buffer);
105 let io_simulation_source = IOActionIOSimulationSource::deserialize(&mut buffer);
106 let io_action_type = IOActionIOActionType::deserialize(&mut buffer);
107 let io_action_phase = IOActionIOActionPhase::deserialize(&mut buffer);
108 let padding1 = buffer.get_u32();
109 let io_attacker_entity_id = EntityId::deserialize(&mut buffer);
110 let io_primary_target_entity_id = EntityId::deserialize(&mut buffer);
111 let padding2 = buffer.get_u16();
112 let io_records = StandardVariableSpecification::deserialize(&mut buffer);
113 Ok(InformationOperationsActionPdu {
114 pdu_header,
115 originating_simulation_id,
116 receiving_simulation_id,
117 request_id,
118 io_warfare_type,
119 io_simulation_source,
120 io_action_type,
121 io_action_phase,
122 padding1,
123 io_attacker_entity_id,
124 io_primary_target_entity_id,
125 padding2,
126 io_records,
127 })
128 } else {
129 Err(DISError::invalid_header(
130 format!(
131 "Expected PDU type InformationOperationsAction, got {:?}",
132 pdu_header.pdu_type
133 ),
134 None,
135 ))
136 }
137 }
138
139 fn as_any(&self) -> &dyn Any {
140 self
141 }
142
143 fn deserialize_without_header(
144 mut buffer: BytesMut,
145 pdu_header: PduHeader,
146 ) -> Result<Self, DISError>
147 where
148 Self: Sized,
149 {
150 let originating_simulation_id = EntityId::deserialize(&mut buffer);
151 let receiving_simulation_id = EntityId::deserialize(&mut buffer);
152 let request_id = buffer.get_u32();
153 let io_warfare_type = IOActionIOWarfareType::deserialize(&mut buffer);
154 let io_simulation_source = IOActionIOSimulationSource::deserialize(&mut buffer);
155 let io_action_type = IOActionIOActionType::deserialize(&mut buffer);
156 let io_action_phase = IOActionIOActionPhase::deserialize(&mut buffer);
157 let padding1 = buffer.get_u32();
158 let io_attacker_entity_id = EntityId::deserialize(&mut buffer);
159 let io_primary_target_entity_id = EntityId::deserialize(&mut buffer);
160 let padding2 = buffer.get_u16();
161 let io_records = StandardVariableSpecification::deserialize(&mut buffer);
162 Ok(InformationOperationsActionPdu {
163 pdu_header,
164 originating_simulation_id,
165 receiving_simulation_id,
166 request_id,
167 io_warfare_type,
168 io_simulation_source,
169 io_action_type,
170 io_action_phase,
171 padding1,
172 io_attacker_entity_id,
173 io_primary_target_entity_id,
174 padding2,
175 io_records,
176 })
177 }
178}
179
180#[cfg(test)]
181mod tests {
182 use super::InformationOperationsActionPdu;
183 use crate::common::{
184 pdu::Pdu,
185 pdu_header::{PduHeader, PduType, ProtocolFamily},
186 };
187 use bytes::BytesMut;
188
189 #[test]
190 fn create_header() {
191 let information_operations_action_pdu = InformationOperationsActionPdu::default();
192 let pdu_header = PduHeader::default(
193 PduType::InformationOperationsAction,
194 ProtocolFamily::InformationOperations,
195 32,
196 );
197
198 assert_eq!(
199 pdu_header.protocol_version,
200 information_operations_action_pdu
201 .pdu_header
202 .protocol_version
203 );
204 assert_eq!(
205 pdu_header.exercise_id,
206 information_operations_action_pdu.pdu_header.exercise_id
207 );
208 assert_eq!(
209 pdu_header.pdu_type,
210 information_operations_action_pdu.pdu_header.pdu_type
211 );
212 assert_eq!(
213 pdu_header.protocol_family,
214 information_operations_action_pdu.pdu_header.protocol_family
215 );
216 assert_eq!(
217 pdu_header.length,
218 information_operations_action_pdu.pdu_header.length
219 );
220 assert_eq!(
221 pdu_header.status_record,
222 information_operations_action_pdu.pdu_header.status_record
223 );
224 }
225
226 #[test]
227 fn deserialize_header() {
228 let mut information_operations_action_pdu = InformationOperationsActionPdu::default();
229 let mut buffer = BytesMut::new();
230 information_operations_action_pdu.serialize(&mut buffer);
231
232 let new_information_operations_action_pdu =
233 InformationOperationsActionPdu::deserialize(buffer).unwrap();
234 assert_eq!(
235 new_information_operations_action_pdu.pdu_header,
236 information_operations_action_pdu.pdu_header
237 );
238 }
239}