Skip to main content

simple_someip/protocol/
message.rs

1use crate::{
2    protocol::{Error, Header, MessageType, ReturnCode, byte_order::Take},
3    traits::{PayloadWireFormat, WireFormat},
4};
5
6#[derive(Clone, Debug, Eq, PartialEq)]
7pub struct Message<PayloadDefinition> {
8    header: Header,
9    payload: PayloadDefinition,
10}
11
12impl<PayloadDefinition: PayloadWireFormat> Message<PayloadDefinition> {
13    pub const fn new(header: Header, payload: PayloadDefinition) -> Self {
14        Self { header, payload }
15    }
16
17    #[must_use]
18    pub fn new_sd(
19        request_id: u32,
20        sd_header: &<PayloadDefinition as PayloadWireFormat>::SdHeader,
21    ) -> Self {
22        let sd_header_size = sd_header.required_size();
23        Self::new(
24            Header::new_sd(request_id, sd_header_size),
25            PayloadDefinition::new_sd_payload(sd_header),
26        )
27    }
28
29    pub fn header(&self) -> &Header {
30        &self.header
31    }
32
33    pub const fn is_sd(&self) -> bool {
34        self.header.is_sd()
35    }
36
37    pub fn set_request_id(&mut self, request_id: u32) {
38        self.header.set_request_id(request_id);
39    }
40
41    pub fn get_sd_header(&self) -> Option<&<PayloadDefinition as PayloadWireFormat>::SdHeader> {
42        assert!(self.header().message_id.is_sd());
43        assert!(!self.header().message_type.is_tp());
44        self.payload.as_sd_header()
45    }
46
47    pub fn payload(&self) -> &PayloadDefinition {
48        &self.payload
49    }
50
51    pub fn payload_mut(&mut self) -> &mut PayloadDefinition {
52        &mut self.payload
53    }
54}
55
56impl<PayloadDefinition: PayloadWireFormat> WireFormat for Message<PayloadDefinition> {
57    fn decode<R: embedded_io::Read>(reader: &mut R) -> Result<Self, Error> {
58        let header = Header::decode(reader)?;
59        if header.message_id.is_sd() {
60            assert!(header.payload_size() >= 12, "SD message too short");
61            assert!(
62                header.protocol_version == 0x01,
63                "SD protocol version mismatch"
64            );
65            assert!(
66                header.interface_version == 0x01,
67                "SD interface version mismatch"
68            );
69            assert!(
70                header.message_type.message_type() == MessageType::Notification,
71                "SD message type mismatch"
72            );
73            assert!(
74                header.return_code == ReturnCode::Ok,
75                "SD return code mismatch"
76            );
77        }
78        let mut payload_reader = Take::new(reader, header.payload_size());
79        let payload =
80            PayloadDefinition::decode_with_message_id(header.message_id, &mut payload_reader)?;
81        Ok(Self::new(header, payload))
82    }
83
84    fn required_size(&self) -> usize {
85        self.header.required_size() + self.payload.required_size()
86    }
87
88    fn encode<W: embedded_io::Write>(&self, writer: &mut W) -> Result<usize, Error> {
89        Ok(self.header.encode(writer)? + self.payload.encode(writer)?)
90    }
91}