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