someip_wire/packet.rs
1//! Packet module
2//!
3//! This module contains the `Packet` type, which is a read/write wrapper around a Some/IP packet buffer.
4
5use crate::error::Error;
6use crate::field;
7use crate::types::{MessageId, RequestId};
8use byteorder::{ByteOrder, NetworkEndian};
9use core::fmt;
10
11#[allow(dead_code)]
12pub type Result<T> = core::result::Result<T, Error>;
13
14/// A read/write wrapper around a Some/IP packet buffer.
15#[allow(dead_code)]
16#[derive(Debug, PartialEq, Eq, Clone)]
17pub struct Packet<T: AsRef<[u8]>> {
18 buffer: T,
19}
20
21#[allow(dead_code)]
22impl<T: AsRef<[u8]>> Packet<T> {
23 /// Creates a new unchecked `Packet`.
24 ///
25 /// # Arguments
26 ///
27 /// * `buffer` - A buffer containing the packet data.
28 ///
29 /// # Returns
30 ///
31 /// * `Packet` - A new `Packet` instance.
32 pub const fn new_unchecked(buffer: T) -> Packet<T> {
33 Packet { buffer }
34 }
35
36 /// Creates a new checked `Packet`.
37 ///
38 /// # Arguments
39 ///
40 /// * `buffer` - A buffer containing the packet data.
41 ///
42 /// # Returns
43 ///
44 /// * `Result<Packet>` - A new `Packet` instance if the buffer is valid.
45 pub fn new_checked(buffer: T) -> Result<Packet<T>> {
46 let packet = Self::new_unchecked(buffer);
47 match packet.check_len() {
48 Ok(_) => Ok(packet),
49 Err(_) => Err(Error),
50 }
51 }
52
53 /// Checks the length of the packet.
54 ///
55 /// # Returns
56 ///
57 /// * `Result<()>` - Ok if the length is valid, otherwise an error.
58 pub fn check_len(&self) -> Result<()> {
59 let len = self.buffer.as_ref().len();
60 if len < field::header::HEADER_LENGTH {
61 Err(Error)
62 } else {
63 Ok(())
64 }
65 }
66
67 /// Returns the inner buffer.
68 ///
69 /// # Returns
70 ///
71 /// * `T` - The inner buffer.
72 pub fn into_inner(self) -> T {
73 self.buffer
74 }
75
76 /// Returns a reference to the inner buffer.
77 ///
78 /// # Returns
79 ///
80 /// * `&[u8]` - A reference to the buffer.
81 #[inline]
82 pub fn as_slice(&self) -> &[u8] {
83 self.buffer.as_ref()
84 }
85
86 /// Returns the Message ID
87 ///
88 /// # Returns
89 ///
90 /// * `MessageId` - The Message ID of the packet
91 pub fn message_id(&self) -> MessageId {
92 let raw_id = NetworkEndian::read_u32(&self.buffer.as_ref()[field::header::MESSAGE_ID]);
93 MessageId::from_u32(raw_id)
94 }
95
96 /// Returns the Payload Length
97 ///
98 /// # Returns
99 ///
100 /// * `usize` - The Payload Length of the packet
101 pub fn payload_length(&self) -> usize {
102 NetworkEndian::read_u32(&self.buffer.as_ref()[field::header::LENGTH]) as usize
103 }
104
105 /// Returns the Request ID
106 ///
107 /// # Returns
108 ///
109 /// * `u32` - The Request ID of the packet
110 pub fn request_id(&self) -> RequestId {
111 RequestId::from_u32(NetworkEndian::read_u32(
112 &self.buffer.as_ref()[field::header::REQUEST_ID],
113 ))
114 }
115
116 /// Returns the Protocol Version
117 ///
118 /// # Returns
119 ///
120 /// * `u8` - The Protocol Version of the packet
121 pub fn protocol_version(&self) -> u8 {
122 self.buffer.as_ref()[field::header::PROTOCOL_VERSION.start]
123 }
124
125 /// Returns the Interface Version
126 ///
127 /// # Returns
128 ///
129 /// * `u8` - The Interface Version of the packet
130 pub fn interface_version(&self) -> u8 {
131 self.buffer.as_ref()[field::header::INTERFACE_VERSION.start]
132 }
133
134 /// Returns the Message Type (raw u8)
135 ///
136 /// # Returns
137 ///
138 /// * `u8` - The raw message type byte from the packet
139 pub fn message_type(&self) -> u8 {
140 self.buffer.as_ref()[field::header::MESSAGE_TYPE.start]
141 }
142
143 /// Returns the Return Code (raw u8)
144 ///
145 /// # Returns
146 ///
147 /// * `u8` - The raw return code byte from the packet
148 pub fn return_code(&self) -> u8 {
149 self.buffer.as_ref()[field::header::RETURN_CODE.start]
150 }
151
152 /// Returns the range of the payload data
153 ///
154 /// # Returns
155 ///
156 /// * `Range<usize>` - The range of the payload data.
157 pub fn payload_data_range(&self) -> core::ops::Range<usize> {
158 let payload_len = self.payload_length().saturating_sub(8); // Subtract 8 header bytes from SOME/IP length field
159 field::header::RETURN_CODE.end..field::header::RETURN_CODE.end + payload_len as usize
160 }
161
162 /// Returns the length of the payload data.
163 ///
164 /// # Returns
165 ///
166 /// * `usize` - The length of the payload data.
167 pub fn payload_data_length(&self) -> usize {
168 self.payload_length().saturating_sub(8) as usize // Subtract 8 header bytes from SOME/IP length field
169 }
170}
171
172#[allow(dead_code)]
173impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
174 /// Sets the Message ID
175 ///
176 /// # Arguments
177 ///
178 /// * `message_id` - The new Message ID to set
179 pub fn set_message_id(&mut self, message_id: MessageId) {
180 let raw_id = message_id.to_u32();
181 NetworkEndian::write_u32(&mut self.buffer.as_mut()[field::header::MESSAGE_ID], raw_id);
182 }
183
184 /// Sets the Payload Length
185 ///
186 /// # Arguments
187 ///
188 /// * `length` - The new Payload Length to set
189 pub fn set_payload_length(&mut self, length: u32) {
190 NetworkEndian::write_u32(
191 &mut self.buffer.as_mut()[field::header::LENGTH],
192 length,
193 );
194 }
195
196 /// Sets the Request ID
197 ///
198 /// # Arguments
199 ///
200 /// * `request_id` - The new Request ID to set
201 pub fn set_request_id(&mut self, request_id: RequestId) {
202 let raw_id = request_id.to_u32();
203 NetworkEndian::write_u32(&mut self.buffer.as_mut()[field::header::REQUEST_ID], raw_id);
204 }
205
206 /// Sets the Protocol Version
207 ///
208 /// # Arguments
209 ///
210 /// * `version` - The new Protocol Version to set
211 pub fn set_protocol_version(&mut self, version: u8) {
212 self.buffer.as_mut()[field::header::PROTOCOL_VERSION.start] = version;
213 }
214
215 /// Sets the Interface Version
216 ///
217 /// # Arguments
218 ///
219 /// * `version` - The new Interface Version to set
220 pub fn set_interface_version(&mut self, version: u8) {
221 self.buffer.as_mut()[field::header::INTERFACE_VERSION.start] = version;
222 }
223
224 /// Sets the Message Type (raw u8)
225 ///
226 /// # Arguments
227 ///
228 /// * `message_type` - The new message type byte to set
229 pub fn set_message_type(&mut self, message_type: u8) {
230 self.buffer.as_mut()[field::header::MESSAGE_TYPE.start] = message_type;
231 }
232
233 /// Sets the Return Code (raw u8)
234 ///
235 /// # Arguments
236 ///
237 /// * `return_code` - The new return code byte to set
238 pub fn set_return_code(&mut self, return_code: u8) {
239 self.buffer.as_mut()[field::header::RETURN_CODE.start] = return_code;
240 }
241}
242
243#[allow(dead_code)]
244impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> {
245 /// Returns a reference to the payload data,
246 ///
247 /// # Returns
248 ///
249 /// * `&'a [u8]` - A reference to the payload data.
250 #[inline]
251 pub fn payload_data(&self) -> &'a [u8] {
252 let payload_range = self.payload_data_range();
253 &self.buffer.as_ref()[payload_range]
254 }
255
256 /// Returns a reference to the entire message.
257 ///
258 /// # Returns
259 ///
260 /// * `&'a [u8]` - A reference to the entire message.
261 #[inline]
262 pub fn entire_message(&self) -> &'a [u8] {
263 let data = self.buffer.as_ref();
264 let total_length = field::header::HEADER_LENGTH + self.payload_data_length();
265 &data[..total_length]
266 }
267}
268
269#[allow(dead_code)]
270impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> Packet<&'a mut T> {
271 /// Returns a mutable reference to the payload data,
272 ///
273 /// # Returns
274 ///
275 /// * `&'a mut [u8]` - A mutable reference to the payload data.
276 #[inline]
277 pub fn payload_data_mut(&mut self) -> &mut [u8] {
278 let payload_range = self.payload_data_range();
279 &mut self.buffer.as_mut()[payload_range]
280 }
281
282 /// Returns a mutable reference to the entire message.
283 ///
284 /// # Returns
285 ///
286 /// * `&'a mut [u8]` - A mutable reference to the entire message.
287 #[inline]
288 pub fn entire_message_mut(&mut self) -> &mut [u8] {
289 let payload_length = self.payload_data_length();
290 let data = self.buffer.as_mut();
291 let total_length = field::header::HEADER_LENGTH + payload_length;
292 &mut data[..total_length]
293 }
294}
295
296impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
297 /// Formats the packet as a string
298 ///
299 /// # Arguments
300 ///
301 /// * `f` - The formatter
302 ///
303 /// # Returns
304 ///
305 /// * `fmt::Result` - The result of the formatting
306 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
307 write!(
308 f,
309 "Some/IP Packet: message_id={}, length={}, request_id={}, protocol_version={}, interface_version={}, message_type=0x{:02X}, return_code=0x{:02X}",
310 self.message_id(),
311 self.payload_length(),
312 self.request_id(),
313 self.protocol_version(),
314 self.interface_version(),
315 self.message_type(),
316 self.return_code()
317 )?;
318
319 Ok(())
320 }
321}