someip_wire/
payload.rs

1use crate::{error::*, field, packet::*, types::*};
2use core::fmt;
3
4/// A high-level representation of a Some/IP message.
5#[allow(dead_code)]
6#[derive(Debug, PartialEq, Eq, Clone, Copy)]
7pub struct Repr<'a> {
8    /// Message ID (32 bits)
9    pub message_id: MessageId,
10    /// Payload length (32 bits)
11    pub length: u32,
12    /// Request ID (32 bits)
13    pub request_id: RequestId,
14    /// Protocol version (8 bits)
15    pub protocol_version: u8,
16    /// Interface version (8 bits)
17    pub interface_version: u8,
18    /// Message type (8 bits)
19    pub message_type: MessageType,
20    /// Return code (8 bits)
21    pub return_code: crate::types::ReturnCode,
22    /// Payload data (variable length)
23    pub data: &'a [u8],
24}
25
26#[allow(dead_code)]
27impl<'a> Repr<'a> {
28    pub fn parse<T>(packet: &'a Packet<T>) -> core::result::Result<Repr<'a>, Error>
29    where
30        T: AsRef<[u8]>,
31    {
32        let buffer = packet.as_slice();
33
34        if buffer.len() < field::header::LENGTH {
35            return Err(Error);
36        }
37
38        let message_id = MessageId::from_u32(u32::from_be_bytes(
39            buffer[field::header::MESSAGE_ID].try_into().unwrap(),
40        ));
41        let length = u32::from_be_bytes(buffer[field::header::PAYLOAD_LENGTH].try_into().unwrap());
42        let request_id = RequestId::from_u32(u32::from_be_bytes(
43            buffer[field::header::REQUEST_ID].try_into().unwrap(),
44        ));
45        let protocol_version = buffer[field::header::PROTOCOL_VERSION.start];
46        let interface_version = buffer[field::header::INTERFACE_VERSION.start];
47        let message_type_byte = buffer[field::header::MESSAGE_TYPE.start];
48        let message_type = MessageType::from_u8(message_type_byte).ok_or(Error)?;
49        let return_code_byte = buffer[field::header::RETURN_CODE.start];
50        let return_code = crate::types::ReturnCode::from_u8(return_code_byte).ok_or(Error)?;
51
52        let payload_start = field::header::RETURN_CODE.end;
53        let payload_end = payload_start + (length as usize);
54        if buffer.len() < payload_end {
55            return Err(Error);
56        }
57        let data = &buffer[payload_start..payload_end];
58
59        Ok(Repr {
60            message_id,
61            length,
62            request_id,
63            protocol_version,
64            interface_version,
65            message_type,
66            return_code,
67            data,
68        })
69    }
70
71    /// Emits the high-level representation of the Some/IP packet into the provided packet/buffer.
72    ///
73    /// # Arguments
74    ///
75    /// * `packet` - A mutable reference to the packet where the high-level representation will be written.
76    pub fn emit<T>(&self, packet: &mut Packet<&mut T>)
77    where
78        T: AsRef<[u8]> + AsMut<[u8]> + ?Sized,
79    {
80        packet.set_message_id(self.message_id);
81        packet.set_payload_length(self.length);
82        packet.set_request_id(self.request_id);
83        packet.set_protocol_version(self.protocol_version);
84        packet.set_interface_version(self.interface_version);
85        packet.set_message_type(self.message_type.as_u8());
86        packet.set_return_code(self.return_code.as_u8());
87
88        // Copy payload data
89        let payload_mut = packet.payload_data_mut();
90        payload_mut[..self.data.len()].copy_from_slice(self.data);
91    }
92}
93
94impl<'a> fmt::Display for Repr<'a> {
95    /// Formats the high-level representation as a string.
96    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97        write!(
98            f,
99            "SOME/IP Payload: message_id={}, length={}, request_id={}, protocol_version={}, interface_version={}, message_type={}, return_code={}, data_len={}",
100            self.message_id,
101            self.length,
102            self.request_id,
103            self.protocol_version,
104            self.interface_version,
105            self.message_type,
106            self.return_code,
107            self.data.len()
108        )
109    }
110}