open_dis_rust/radio_communications/
intercom_signal_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};
12use bytes::{Buf, BufMut, BytesMut};
13use std::any::Any;
14
15#[derive(Clone, Debug)]
16/// Implemented according to IEEE 1278.1-2012 ยง7.7.5
17pub struct IntercomSignalPdu {
18    pub pdu_header: PduHeader,
19    pub entity_id: EntityId,
20    pub radio_id: u16,
21    pub communications_device_id: u16,
22    pub encoding_scheme: u16,
23    pub tdl_type: u16,
24    pub sample_rate: u32,
25    pub data_length: u16,
26    pub samples: u16,
27    pub data: Vec<u8>,
28}
29
30impl Default for IntercomSignalPdu {
31    /// Creates a default Intercom Signal PDU with arbitrary originating and receiving
32    /// entity IDs
33    ///
34    /// # Examples
35    ///
36    /// Initializing an Intercom Signal PDU:
37    /// ```
38    /// use open_dis_rust::radio_communications::intercom_signal_pdu::IntercomSignalPdu;
39    /// let intercom_signal_pdu = IntercomSignalPdu::default();
40    /// ```
41    ///
42    fn default() -> Self {
43        IntercomSignalPdu {
44            pdu_header: PduHeader::default(
45                PduType::IntercomSignal,
46                ProtocolFamily::RadioCommunications,
47                56,
48            ),
49            entity_id: EntityId::default(1),
50            radio_id: 0,
51            communications_device_id: 0,
52            encoding_scheme: 0,
53            tdl_type: 0,
54            sample_rate: 0,
55            data_length: 0,
56            samples: 0,
57            data: vec![],
58        }
59    }
60}
61
62impl Pdu for IntercomSignalPdu {
63    fn serialize(&mut self, buf: &mut BytesMut) {
64        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
65            .expect("The length of the PDU should fit in a u16.");
66        self.pdu_header.serialize(buf);
67        self.entity_id.serialize(buf);
68        buf.put_u16(self.radio_id);
69        buf.put_u16(self.communications_device_id);
70        buf.put_u16(self.encoding_scheme);
71        buf.put_u16(self.tdl_type);
72        buf.put_u32(self.sample_rate);
73        buf.put_u16(self.data_length);
74        buf.put_u16(self.samples);
75        for i in 0..self.data.len() {
76            buf.put_u8(self.data[i]);
77        }
78    }
79
80    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
81    where
82        Self: Sized,
83    {
84        let pdu_header = PduHeader::deserialize(&mut buffer);
85        if pdu_header.pdu_type == PduType::IntercomSignal {
86            let entity_id = EntityId::deserialize(&mut buffer);
87            let radio_id = buffer.get_u16();
88            let communications_device_id = buffer.get_u16();
89            let encoding_scheme = buffer.get_u16();
90            let tdl_type = buffer.get_u16();
91            let sample_rate = buffer.get_u32();
92            let data_length = buffer.get_u16();
93            let samples = buffer.get_u16();
94            let mut data: Vec<u8> = vec![];
95            for _i in 0..data_length {
96                data.push(buffer.get_u8());
97            }
98            Ok(IntercomSignalPdu {
99                pdu_header,
100                entity_id,
101                radio_id,
102                communications_device_id,
103                encoding_scheme,
104                tdl_type,
105                sample_rate,
106                data_length,
107                samples,
108                data,
109            })
110        } else {
111            Err(DISError::invalid_header(
112                format!(
113                    "Expected PDU type IntercomSignal, 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 entity_id = EntityId::deserialize(&mut buffer);
133        let radio_id = buffer.get_u16();
134        let communications_device_id = buffer.get_u16();
135        let encoding_scheme = buffer.get_u16();
136        let tdl_type = buffer.get_u16();
137        let sample_rate = buffer.get_u32();
138        let data_length = buffer.get_u16();
139        let samples = buffer.get_u16();
140        let mut data: Vec<u8> = vec![];
141        for _i in 0..data_length {
142            data.push(buffer.get_u8());
143        }
144        Ok(IntercomSignalPdu {
145            pdu_header,
146            entity_id,
147            radio_id,
148            communications_device_id,
149            encoding_scheme,
150            tdl_type,
151            sample_rate,
152            data_length,
153            samples,
154            data,
155        })
156    }
157}
158
159#[cfg(test)]
160mod tests {
161    use super::IntercomSignalPdu;
162    use crate::common::{
163        pdu::Pdu,
164        pdu_header::{PduHeader, PduType, ProtocolFamily},
165    };
166    use bytes::BytesMut;
167
168    #[test]
169    fn create_header() {
170        let intercom_signal_pdu = IntercomSignalPdu::default();
171        let pdu_header = PduHeader::default(
172            PduType::IntercomSignal,
173            ProtocolFamily::RadioCommunications,
174            448 / 8,
175        );
176
177        assert_eq!(
178            pdu_header.protocol_version,
179            intercom_signal_pdu.pdu_header.protocol_version
180        );
181        assert_eq!(
182            pdu_header.exercise_id,
183            intercom_signal_pdu.pdu_header.exercise_id
184        );
185        assert_eq!(pdu_header.pdu_type, intercom_signal_pdu.pdu_header.pdu_type);
186        assert_eq!(
187            pdu_header.protocol_family,
188            intercom_signal_pdu.pdu_header.protocol_family
189        );
190        assert_eq!(pdu_header.length, intercom_signal_pdu.pdu_header.length);
191        assert_eq!(
192            pdu_header.status_record,
193            intercom_signal_pdu.pdu_header.status_record
194        );
195    }
196
197    #[test]
198    fn deserialize_header() {
199        let mut intercom_signal_pdu = IntercomSignalPdu::default();
200        let mut buffer = BytesMut::new();
201        intercom_signal_pdu.serialize(&mut buffer);
202
203        let new_intercom_signal_pdu = IntercomSignalPdu::deserialize(buffer).unwrap();
204        assert_eq!(
205            new_intercom_signal_pdu.pdu_header,
206            intercom_signal_pdu.pdu_header
207        );
208    }
209}