open_dis_rust/logistics/
service_request_pdu.rs

1//     open-dis-rust - Rust implementation of the IEEE 1278.1-2012 Distributed Interactive
2//                     Simulation (DIS) application protocol
3//     Copyright (C) 2023 Cameron Howell
4//
5//     Licensed under the BSD 2-Clause License
6
7use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::common::{
11    dis_error::DISError,
12    entity_id::EntityId,
13    pdu::Pdu,
14    pdu_header::{PduHeader, PduType, ProtocolFamily},
15};
16
17use super::data_types::supply_quantity::SupplyQuantity;
18
19#[derive(Clone, Debug)]
20/// Implemented according to IEEE 1278.1-2012 ยง7.4.2
21pub struct ServiceRequestPdu {
22    pub pdu_header: PduHeader,
23    pub receiving_entity_id: EntityId,
24    pub servicing_entity_id: EntityId,
25    pub service_type_requested: u8,
26    pub number_of_supply_types: u8,
27    pub padding1: i16,
28    pub supplies: Vec<SupplyQuantity>,
29}
30
31impl Default for ServiceRequestPdu {
32    /// Creates a default Service Request PDU with arbitrary receiving and supplying entity IDs
33    ///
34    /// # Examples
35    ///
36    /// Initializing a Service Request PDU:
37    /// ```
38    /// use open_dis_rust::logistics::service_request_pdu::ServiceRequestPdu;
39    /// let service_request_pdu = ServiceRequestPdu::default();
40    /// ```
41    ///
42    fn default() -> Self {
43        ServiceRequestPdu {
44            pdu_header: PduHeader::default(PduType::ServiceRequest, ProtocolFamily::Logistics, 56),
45            receiving_entity_id: EntityId::default(1),
46            servicing_entity_id: EntityId::default(2),
47            service_type_requested: 0,
48            number_of_supply_types: 0,
49            padding1: 0,
50            supplies: vec![],
51        }
52    }
53}
54
55impl Pdu for ServiceRequestPdu {
56    fn serialize(&mut self, buf: &mut BytesMut) {
57        self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
58            .expect("The length of the PDU should fit in a u16.");
59        self.pdu_header.serialize(buf);
60        self.receiving_entity_id.serialize(buf);
61        self.servicing_entity_id.serialize(buf);
62        buf.put_u8(self.service_type_requested);
63        buf.put_u8(self.number_of_supply_types);
64        buf.put_i16(self.padding1);
65        for i in 0..self.supplies.len() {
66            self.supplies[i].serialize(buf);
67        }
68    }
69
70    fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
71    where
72        Self: Sized,
73    {
74        let pdu_header = PduHeader::deserialize(&mut buffer);
75        if pdu_header.pdu_type == PduType::ServiceRequest {
76            let receiving_entity_id = EntityId::deserialize(&mut buffer);
77            let servicing_entity_id = EntityId::deserialize(&mut buffer);
78            let service_type_requested = buffer.get_u8();
79            let number_of_supply_types = buffer.get_u8();
80            let padding1 = buffer.get_i16();
81            let mut supplies: Vec<SupplyQuantity> = vec![];
82            for _i in 0..number_of_supply_types {
83                supplies.push(SupplyQuantity::deserialize(&mut buffer));
84            }
85
86            Ok(ServiceRequestPdu {
87                pdu_header,
88                receiving_entity_id,
89                servicing_entity_id,
90                service_type_requested,
91                number_of_supply_types,
92                padding1,
93                supplies,
94            })
95        } else {
96            Err(DISError::invalid_header(
97                format!(
98                    "Expected PDU type ServiceRequest, got {:?}",
99                    pdu_header.pdu_type
100                ),
101                None,
102            ))
103        }
104    }
105
106    fn as_any(&self) -> &dyn Any {
107        self
108    }
109
110    fn deserialize_without_header(
111        mut buffer: BytesMut,
112        pdu_header: PduHeader,
113    ) -> Result<Self, DISError>
114    where
115        Self: Sized,
116    {
117        let receiving_entity_id = EntityId::deserialize(&mut buffer);
118        let servicing_entity_id = EntityId::deserialize(&mut buffer);
119        let service_type_requested = buffer.get_u8();
120        let number_of_supply_types = buffer.get_u8();
121        let padding1 = buffer.get_i16();
122        let mut supplies: Vec<SupplyQuantity> = vec![];
123        for _i in 0..number_of_supply_types {
124            supplies.push(SupplyQuantity::deserialize(&mut buffer));
125        }
126
127        Ok(ServiceRequestPdu {
128            pdu_header,
129            receiving_entity_id,
130            servicing_entity_id,
131            service_type_requested,
132            number_of_supply_types,
133            padding1,
134            supplies,
135        })
136    }
137}
138
139#[cfg(test)]
140mod tests {
141    use super::ServiceRequestPdu;
142    use crate::common::{
143        pdu::Pdu,
144        pdu_header::{PduHeader, PduType, ProtocolFamily},
145    };
146    use bytes::BytesMut;
147
148    #[test]
149    fn create_header() {
150        let service_request_pdu = ServiceRequestPdu::default();
151        let pdu_header =
152            PduHeader::default(PduType::ServiceRequest, ProtocolFamily::Logistics, 448 / 8);
153
154        assert_eq!(
155            pdu_header.protocol_version,
156            service_request_pdu.pdu_header.protocol_version
157        );
158        assert_eq!(
159            pdu_header.exercise_id,
160            service_request_pdu.pdu_header.exercise_id
161        );
162        assert_eq!(pdu_header.pdu_type, service_request_pdu.pdu_header.pdu_type);
163        assert_eq!(
164            pdu_header.protocol_family,
165            service_request_pdu.pdu_header.protocol_family
166        );
167        assert_eq!(pdu_header.length, service_request_pdu.pdu_header.length);
168        assert_eq!(
169            pdu_header.status_record,
170            service_request_pdu.pdu_header.status_record
171        );
172    }
173
174    #[test]
175    fn deserialize_header() {
176        let mut service_request_pdu = ServiceRequestPdu::default();
177        let mut buffer = BytesMut::new();
178        service_request_pdu.serialize(&mut buffer);
179
180        let new_service_request_pdu = ServiceRequestPdu::deserialize(buffer).unwrap();
181        assert_eq!(
182            new_service_request_pdu.pdu_header,
183            service_request_pdu.pdu_header
184        );
185    }
186}