open_dis_rust/radio_communications/
transmitter_pdu.rs

1//     open-dis-rust - Rust implementation of the IEEE-1278.1 Distributed Interactive Simulation
2//     Copyright (C) 2023 Cameron Howell
3//
4//     Licensed under the BSD-2-Clause License
5
6use crate::common::{
7    dis_error::DISError,
8    entity_id::EntityId,
9    pdu::Pdu,
10    pdu_header::{PduHeader, PduType, ProtocolFamily},
11    vector3_double::Vector3Double,
12    vector3_float::Vector3Float,
13};
14use bytes::{Buf, BufMut, BytesMut};
15use std::any::Any;
16
17use super::data_types::{modulation_type::ModulationType, radio_entity_type::RadioEntityType};
18
19#[derive(Clone, Debug)]
20/// Implemented according to IEEE 1278.1-2012 ยง7.7.2
21pub struct TransmitterPdu {
22    pub pdu_header: PduHeader,
23    pub entity_id: EntityId,
24    pub radio_id: u16,
25    pub radio_entity_type: RadioEntityType,
26    pub transmit_state: u8,
27    pub input_source: u8,
28    pub padding1: u16,
29    pub antenna_location: Vector3Double,
30    pub relative_antenna_location: Vector3Float,
31    pub antenna_pattern_type: u16,
32    pub antenna_pattern_count: u16,
33    pub frequency: u64,
34    pub transmit_frequency_bandwidth: f32,
35    pub power: f32,
36    pub modulation_type: ModulationType,
37    pub crypto_system: u16,
38    pub crypto_key_id: u16,
39    pub modulation_parameter_count: u8,
40    pub padding2: u16,
41    pub padding3: u8,
42    pub modulation_parameter_list: Vec<Vector3Float>,
43    pub antenna_pattern_list: Vec<Vector3Float>,
44}
45
46impl Default for TransmitterPdu {
47    /// Creates a default Transmitter PDU with arbitrary originating and receiving
48    /// entity IDs
49    ///
50    /// # Examples
51    ///
52    /// Initializing a Transmitter PDU:
53    /// ```
54    /// use open_dis_rust::radio_communications::transmitter_pdu::TransmitterPdu;
55    /// let transmitter_pdu = TransmitterPdu::default();
56    /// ```
57    ///
58    fn default() -> Self {
59        TransmitterPdu {
60            pdu_header: PduHeader::default(
61                PduType::Transmitter,
62                ProtocolFamily::RadioCommunications,
63                112,
64            ),
65            entity_id: EntityId::default(1),
66            radio_id: 0,
67            radio_entity_type: RadioEntityType::default(),
68            transmit_state: 0,
69            input_source: 0,
70            padding1: 0,
71            antenna_location: Vector3Double::default(),
72            relative_antenna_location: Vector3Float::default(),
73            antenna_pattern_type: 0,
74            antenna_pattern_count: 0,
75            frequency: 0,
76            transmit_frequency_bandwidth: 0.0,
77            power: 0.0,
78            modulation_type: ModulationType::default(),
79            crypto_system: 0,
80            crypto_key_id: 0,
81            modulation_parameter_count: 0,
82            padding2: 0,
83            padding3: 0,
84            modulation_parameter_list: vec![Vector3Float::default()],
85            antenna_pattern_list: vec![Vector3Float::default()],
86        }
87    }
88}
89
90impl Pdu for TransmitterPdu {
91    fn serialize(&mut self, buf: &mut BytesMut) {
92        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
93            .expect("The length of the PDU should fit in a u16.");
94        self.pdu_header.serialize(buf);
95        self.entity_id.serialize(buf);
96        buf.put_u16(self.radio_id);
97        self.radio_entity_type.serialize(buf);
98        buf.put_u8(self.transmit_state);
99        buf.put_u8(self.input_source);
100        buf.put_u16(self.padding1);
101        self.antenna_location.serialize(buf);
102        self.relative_antenna_location.serialize(buf);
103        buf.put_u16(self.antenna_pattern_type);
104        buf.put_u16(self.antenna_pattern_count);
105        buf.put_u64(self.frequency);
106        buf.put_f32(self.transmit_frequency_bandwidth);
107        buf.put_f32(self.power);
108        self.modulation_type.serialize(buf);
109        buf.put_u16(self.crypto_system);
110        buf.put_u16(self.crypto_key_id);
111        buf.put_u8(self.modulation_parameter_count);
112        buf.put_u16(self.padding2);
113        buf.put_u8(self.padding3);
114        for i in 0..self.modulation_parameter_list.len() {
115            self.modulation_parameter_list[i].serialize(buf);
116        }
117        for i in 0..self.antenna_pattern_list.len() {
118            self.antenna_pattern_list[i].serialize(buf);
119        }
120    }
121
122    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
123    where
124        Self: Sized,
125    {
126        let pdu_header = PduHeader::deserialize(&mut buffer);
127        if pdu_header.pdu_type == PduType::Transmitter {
128            let entity_id = EntityId::deserialize(&mut buffer);
129            let radio_id = buffer.get_u16();
130            let radio_entity_type = RadioEntityType::deserialize(&mut buffer);
131            let transmit_state = buffer.get_u8();
132            let input_source = buffer.get_u8();
133            let padding1 = buffer.get_u16();
134            let antenna_location = Vector3Double::deserialize(&mut buffer);
135            let relative_antenna_location = Vector3Float::deserialize(&mut buffer);
136            let antenna_pattern_type = buffer.get_u16();
137            let antenna_pattern_count = buffer.get_u16();
138            let frequency = buffer.get_u64();
139            let transmit_frequency_bandwidth = buffer.get_f32();
140            let power = buffer.get_f32();
141            let modulation_type = ModulationType::deserialize(&mut buffer);
142            let crypto_system = buffer.get_u16();
143            let crypto_key_id = buffer.get_u16();
144            let modulation_parameter_count = buffer.get_u8();
145            let padding2 = buffer.get_u16();
146            let padding3 = buffer.get_u8();
147            let mut modulation_parameter_list: Vec<Vector3Float> = vec![];
148            for _i in 0..modulation_parameter_count {
149                modulation_parameter_list.push(Vector3Float::deserialize(&mut buffer));
150            }
151            let mut antenna_pattern_list: Vec<Vector3Float> = vec![];
152            for _i in 0..antenna_pattern_count {
153                antenna_pattern_list.push(Vector3Float::deserialize(&mut buffer));
154            }
155            Ok(TransmitterPdu {
156                pdu_header,
157                entity_id,
158                radio_id,
159                radio_entity_type,
160                transmit_state,
161                input_source,
162                padding1,
163                antenna_location,
164                relative_antenna_location,
165                antenna_pattern_type,
166                antenna_pattern_count,
167                frequency,
168                transmit_frequency_bandwidth,
169                power,
170                modulation_type,
171                crypto_system,
172                crypto_key_id,
173                modulation_parameter_count,
174                padding2,
175                padding3,
176                modulation_parameter_list,
177                antenna_pattern_list,
178            })
179        } else {
180            Err(DISError::invalid_header(
181                format!(
182                    "Expected PDU type Transmitter, got {:?}",
183                    pdu_header.pdu_type
184                ),
185                None,
186            ))
187        }
188    }
189
190    fn as_any(&self) -> &dyn Any {
191        self
192    }
193
194    fn deserialize_without_header(
195        mut buffer: BytesMut,
196        pdu_header: PduHeader,
197    ) -> Result<Self, DISError>
198    where
199        Self: Sized,
200    {
201        let entity_id = EntityId::deserialize(&mut buffer);
202        let radio_id = buffer.get_u16();
203        let radio_entity_type = RadioEntityType::deserialize(&mut buffer);
204        let transmit_state = buffer.get_u8();
205        let input_source = buffer.get_u8();
206        let padding1 = buffer.get_u16();
207        let antenna_location = Vector3Double::deserialize(&mut buffer);
208        let relative_antenna_location = Vector3Float::deserialize(&mut buffer);
209        let antenna_pattern_type = buffer.get_u16();
210        let antenna_pattern_count = buffer.get_u16();
211        let frequency = buffer.get_u64();
212        let transmit_frequency_bandwidth = buffer.get_f32();
213        let power = buffer.get_f32();
214        let modulation_type = ModulationType::deserialize(&mut buffer);
215        let crypto_system = buffer.get_u16();
216        let crypto_key_id = buffer.get_u16();
217        let modulation_parameter_count = buffer.get_u8();
218        let padding2 = buffer.get_u16();
219        let padding3 = buffer.get_u8();
220        let mut modulation_parameter_list: Vec<Vector3Float> = vec![];
221        for _i in 0..modulation_parameter_count {
222            modulation_parameter_list.push(Vector3Float::deserialize(&mut buffer));
223        }
224        let mut antenna_pattern_list: Vec<Vector3Float> = vec![];
225        for _i in 0..antenna_pattern_count {
226            antenna_pattern_list.push(Vector3Float::deserialize(&mut buffer));
227        }
228        Ok(TransmitterPdu {
229            pdu_header,
230            entity_id,
231            radio_id,
232            radio_entity_type,
233            transmit_state,
234            input_source,
235            padding1,
236            antenna_location,
237            relative_antenna_location,
238            antenna_pattern_type,
239            antenna_pattern_count,
240            frequency,
241            transmit_frequency_bandwidth,
242            power,
243            modulation_type,
244            crypto_system,
245            crypto_key_id,
246            modulation_parameter_count,
247            padding2,
248            padding3,
249            modulation_parameter_list,
250            antenna_pattern_list,
251        })
252    }
253}
254
255#[cfg(test)]
256mod tests {
257    use super::TransmitterPdu;
258    use crate::common::{
259        pdu::Pdu,
260        pdu_header::{PduHeader, PduType, ProtocolFamily},
261    };
262    use bytes::BytesMut;
263
264    #[test]
265    fn create_header() {
266        let transmitter_pdu = TransmitterPdu::default();
267        let pdu_header = PduHeader::default(
268            PduType::Transmitter,
269            ProtocolFamily::RadioCommunications,
270            896 / 8,
271        );
272
273        assert_eq!(
274            pdu_header.protocol_version,
275            transmitter_pdu.pdu_header.protocol_version
276        );
277        assert_eq!(
278            pdu_header.exercise_id,
279            transmitter_pdu.pdu_header.exercise_id
280        );
281        assert_eq!(pdu_header.pdu_type, transmitter_pdu.pdu_header.pdu_type);
282        assert_eq!(
283            pdu_header.protocol_family,
284            transmitter_pdu.pdu_header.protocol_family
285        );
286        assert_eq!(pdu_header.length, transmitter_pdu.pdu_header.length);
287        assert_eq!(
288            pdu_header.status_record,
289            transmitter_pdu.pdu_header.status_record
290        );
291    }
292
293    #[test]
294    fn deserialize_header() {
295        let mut transmitter_pdu = TransmitterPdu::default();
296        let mut buffer = BytesMut::new();
297        transmitter_pdu.serialize(&mut buffer);
298
299        let new_transmitter_pdu = TransmitterPdu::deserialize(buffer).unwrap();
300        assert_eq!(new_transmitter_pdu.pdu_header, transmitter_pdu.pdu_header);
301    }
302}