open_dis_rust/radio_communications/
receiver_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.4
17pub struct ReceiverPdu {
18    pub pdu_header: PduHeader,
19    pub entity_id: EntityId,
20    pub radio_id: u16,
21    pub receiver_state: u16,
22    pub padding1: u16,
23    pub received_power: f32,
24    pub transmitter_entity_id: EntityId,
25    pub transmitter_radio_id: u16,
26}
27
28impl Default for ReceiverPdu {
29    /// Creates a default Receiver PDU with arbitrary originating and receiving
30    /// entity IDs
31    ///
32    /// # Examples
33    ///
34    /// Initializing a Receiver PDU:
35    /// ```
36    /// use open_dis_rust::radio_communications::receiver_pdu::ReceiverPdu;
37    /// let receiver_pdu = ReceiverPdu::default();
38    /// ```
39    ///
40    fn default() -> Self {
41        ReceiverPdu {
42            pdu_header: PduHeader::default(
43                PduType::Receiver,
44                ProtocolFamily::RadioCommunications,
45                56,
46            ),
47            entity_id: EntityId::default(1),
48            radio_id: 0,
49            receiver_state: 0,
50            padding1: 0,
51            received_power: 0.0,
52            transmitter_entity_id: EntityId::default(2),
53            transmitter_radio_id: 0,
54        }
55    }
56}
57
58impl Pdu for ReceiverPdu {
59    fn serialize(&mut self, buf: &mut BytesMut) {
60        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
61            .expect("The length of the PDU should fit in a u16.");
62        self.pdu_header.serialize(buf);
63        self.entity_id.serialize(buf);
64        buf.put_u16(self.radio_id);
65        buf.put_u16(self.receiver_state);
66        buf.put_u16(self.padding1);
67        buf.put_f32(self.received_power);
68        self.transmitter_entity_id.serialize(buf);
69        buf.put_u16(self.transmitter_radio_id);
70    }
71
72    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
73    where
74        Self: Sized,
75    {
76        let pdu_header = PduHeader::deserialize(&mut buffer);
77        if pdu_header.pdu_type == PduType::Receiver {
78            let entity_id = EntityId::deserialize(&mut buffer);
79            let radio_id = buffer.get_u16();
80            let receiver_state = buffer.get_u16();
81            let padding1 = buffer.get_u16();
82            let received_power = buffer.get_f32();
83            let transmitter_entity_id = EntityId::deserialize(&mut buffer);
84            let transmitter_radio_id = buffer.get_u16();
85            Ok(ReceiverPdu {
86                pdu_header,
87                entity_id,
88                radio_id,
89                receiver_state,
90                padding1,
91                received_power,
92                transmitter_entity_id,
93                transmitter_radio_id,
94            })
95        } else {
96            Err(DISError::invalid_header(
97                format!("Expected PDU type Receiver, got {:?}", pdu_header.pdu_type),
98                None,
99            ))
100        }
101    }
102
103    fn as_any(&self) -> &dyn Any {
104        self
105    }
106
107    fn deserialize_without_header(
108        mut buffer: BytesMut,
109        pdu_header: PduHeader,
110    ) -> Result<Self, DISError>
111    where
112        Self: Sized,
113    {
114        let entity_id = EntityId::deserialize(&mut buffer);
115        let radio_id = buffer.get_u16();
116        let receiver_state = buffer.get_u16();
117        let padding1 = buffer.get_u16();
118        let received_power = buffer.get_f32();
119        let transmitter_entity_id = EntityId::deserialize(&mut buffer);
120        let transmitter_radio_id = buffer.get_u16();
121        Ok(ReceiverPdu {
122            pdu_header,
123            entity_id,
124            radio_id,
125            receiver_state,
126            padding1,
127            received_power,
128            transmitter_entity_id,
129            transmitter_radio_id,
130        })
131    }
132}
133
134#[cfg(test)]
135mod tests {
136    use super::ReceiverPdu;
137    use crate::common::{
138        pdu::Pdu,
139        pdu_header::{PduHeader, PduType, ProtocolFamily},
140    };
141    use bytes::BytesMut;
142
143    #[test]
144    fn create_header() {
145        let receiver_pdu = ReceiverPdu::default();
146        let pdu_header = PduHeader::default(
147            PduType::Receiver,
148            ProtocolFamily::RadioCommunications,
149            448 / 8,
150        );
151
152        assert_eq!(
153            pdu_header.protocol_version,
154            receiver_pdu.pdu_header.protocol_version
155        );
156        assert_eq!(pdu_header.exercise_id, receiver_pdu.pdu_header.exercise_id);
157        assert_eq!(pdu_header.pdu_type, receiver_pdu.pdu_header.pdu_type);
158        assert_eq!(
159            pdu_header.protocol_family,
160            receiver_pdu.pdu_header.protocol_family
161        );
162        assert_eq!(pdu_header.length, receiver_pdu.pdu_header.length);
163        assert_eq!(
164            pdu_header.status_record,
165            receiver_pdu.pdu_header.status_record
166        );
167    }
168
169    #[test]
170    fn deserialize_header() {
171        let mut receiver_pdu = ReceiverPdu::default();
172        let mut buffer = BytesMut::new();
173        receiver_pdu.serialize(&mut buffer);
174
175        let new_receiver_pdu = ReceiverPdu::deserialize(buffer).unwrap();
176        assert_eq!(new_receiver_pdu.pdu_header, receiver_pdu.pdu_header);
177    }
178}