1use crate::error::Error;
6use crate::field;
7use byteorder::{ByteOrder, NetworkEndian};
8use core::fmt;
9
10#[allow(dead_code)]
12pub type Result<T> = core::result::Result<T, Error>;
13
14#[allow(dead_code)]
24#[derive(Debug, PartialEq, Eq, Clone)]
25pub struct Packet<T: AsRef<[u8]>> {
26 buffer: T,
27}
28
29#[allow(dead_code)]
30impl<T: AsRef<[u8]>> Packet<T> {
31 pub const fn new_unchecked(buffer: T) -> Packet<T> {
41 Packet { buffer }
42 }
43
44 pub fn new_checked(buffer: T) -> Result<Packet<T>> {
54 let packet = Self::new_unchecked(buffer);
55 packet.check_len()?;
56 Ok(packet)
57 }
58
59 pub fn check_len(&self) -> Result<()> {
65 let len = self.buffer.as_ref().len();
66 if len < field::entries::MIN_HEADER_LEN {
67 return Err(Error::BufferTooShort);
68 }
69
70 let entries_len = self.entries_length();
72
73 let min_with_entries = field::entries::OPTIONS_LENGTH(entries_len).end;
75 if len < min_with_entries {
76 return Err(Error::BufferTooShort);
77 }
78
79 let options_len = self.options_length();
80
81 let required_len = field::entries::OPTIONS_ARRAY(entries_len, options_len).end;
83 if len < required_len {
84 return Err(Error::BufferTooShort);
85 }
86
87 Ok(())
88 }
89
90 pub fn into_inner(self) -> T {
96 self.buffer
97 }
98
99 #[inline]
105 pub fn as_slice(&self) -> &[u8] {
106 self.buffer.as_ref()
107 }
108
109 pub fn flags(&self) -> u8 {
115 self.buffer.as_ref()[field::header::FLAGS.start]
116 }
117
118 pub fn reserved(&self) -> u32 {
124 let bytes = &self.buffer.as_ref()[field::header::RESERVED];
125 ((bytes[0] as u32) << 16) | ((bytes[1] as u32) << 8) | (bytes[2] as u32)
127 }
128
129 pub fn entries_length(&self) -> usize {
135 NetworkEndian::read_u32(&self.buffer.as_ref()[field::entries::LENGTH]) as usize
136 }
137
138 pub fn entries_array(&self) -> &[u8] {
144 let len = self.entries_length();
145 let range = field::entries::ENTRIES_ARRAY(len);
146 &self.buffer.as_ref()[range]
147 }
148
149 pub fn options_length(&self) -> usize {
155 let entries_len = self.entries_length();
156 NetworkEndian::read_u32(&self.buffer.as_ref()[field::entries::OPTIONS_LENGTH(entries_len)]) as usize
157 }
158
159 pub fn options_array(&self) -> &[u8] {
165 let entries_len = self.entries_length();
166 let options_len = self.options_length();
167 &self.buffer.as_ref()[field::entries::OPTIONS_ARRAY(entries_len, options_len)]
168 }
169
170 pub fn total_length(&self) -> usize {
176 let entries_len = self.entries_length();
177 let options_len = self.options_length();
178 field::entries::OPTIONS_ARRAY(entries_len, options_len).end
179 }
180}
181
182#[allow(dead_code)]
183impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
184 pub fn set_flags(&mut self, flags: u8) {
190 self.buffer.as_mut()[field::header::FLAGS.start] = flags;
191 }
192
193 pub fn set_reserved(&mut self, reserved: u32) {
199 let bytes = &mut self.buffer.as_mut()[field::header::RESERVED];
200 bytes[0] = ((reserved >> 16) & 0xFF) as u8;
201 bytes[1] = ((reserved >> 8) & 0xFF) as u8;
202 bytes[2] = (reserved & 0xFF) as u8;
203 }
204
205 pub fn set_entries_length(&mut self, length: u32) {
211 NetworkEndian::write_u32(&mut self.buffer.as_mut()[field::entries::LENGTH], length);
212 }
213
214 pub fn entries_array_mut(&mut self) -> &mut [u8] {
220 let len = self.entries_length();
221 let range = field::entries::ENTRIES_ARRAY(len);
222 &mut self.buffer.as_mut()[range]
223 }
224
225 pub fn set_options_length(&mut self, length: u32) {
231 let entries_len = self.entries_length();
232 NetworkEndian::write_u32(&mut self.buffer.as_mut()[field::entries::OPTIONS_LENGTH(entries_len)], length);
233 }
234
235 pub fn options_array_mut(&mut self) -> &mut [u8] {
241 let entries_len = self.entries_length();
242 let options_len = self.options_length();
243 &mut self.buffer.as_mut()[field::entries::OPTIONS_ARRAY(entries_len, options_len)]
244 }
245}
246
247impl<T: AsRef<[u8]>> fmt::Display for Packet<T> {
248 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
249 write!(
250 f,
251 "SOME/IP-SD Packet: flags=0x{:02X}, entries_len={}, options_len={}",
252 self.flags(),
253 self.entries_length(),
254 self.options_length()
255 )
256 }
257}
258
259#[cfg(test)]
260mod tests {
261 use super::*;
262
263 #[test]
264 fn test_packet_new_unchecked() {
265 let buffer = [0u8; 12];
266 let packet = Packet::new_unchecked(&buffer[..]);
267 assert_eq!(packet.as_slice().len(), 12);
268 }
269
270 #[test]
271 fn test_packet_too_short() {
272 let buffer = [0u8; 8]; let result = Packet::new_checked(&buffer[..]);
274 assert_eq!(result, Err(Error::BufferTooShort));
275 }
276
277 #[test]
278 fn test_packet_flags() {
279 let mut buffer = [0u8; 12];
280 let mut packet = Packet::new_unchecked(&mut buffer[..]);
281 packet.set_flags(0x80);
282 assert_eq!(packet.flags(), 0x80);
283 }
284
285 #[test]
286 fn test_packet_reserved() {
287 let mut buffer = [0u8; 12];
288 let mut packet = Packet::new_unchecked(&mut buffer[..]);
289 packet.set_reserved(0x123456);
290 assert_eq!(packet.reserved(), 0x123456);
291 }
292
293 #[test]
294 fn test_packet_entries_length() {
295 let mut buffer = [0u8; 20];
296 let mut packet = Packet::new_unchecked(&mut buffer[..]);
297 packet.set_entries_length(8);
298 assert_eq!(packet.entries_length(), 8);
299 }
300
301 #[test]
302 fn test_packet_with_entries_and_options() {
303 let mut buffer = [0u8; 12 + 16 + 8];
306 let mut packet = Packet::new_unchecked(&mut buffer[..]);
307
308 packet.set_flags(0x80);
309 packet.set_reserved(0);
310 packet.set_entries_length(16);
311
312 {
314 let entries = packet.entries_array_mut();
315 for (i, byte) in entries.iter_mut().enumerate() {
316 *byte = i as u8;
317 }
318 }
319
320 packet.set_options_length(8);
321
322 {
324 let options = packet.options_array_mut();
325 for (i, byte) in options.iter_mut().enumerate() {
326 *byte = (i + 100) as u8;
327 }
328 }
329
330 assert_eq!(packet.flags(), 0x80);
331 assert_eq!(packet.entries_length(), 16);
332 assert_eq!(packet.options_length(), 8);
333 assert_eq!(packet.entries_array()[0], 0);
334 assert_eq!(packet.options_array()[0], 100);
335 }
336}