1use crate::*;
2
3#[deprecated(
5 since = "0.5.0",
6 note = "Use SomeipHeader instead (renamed, 'i' is lower case now)."
7)]
8pub type SomeIpHeader = SomeipHeader;
9
10#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct SomeipHeader {
13 pub message_id: u32,
14 pub length: u32,
15 pub request_id: u32,
16 pub interface_version: u8,
17 pub message_type: MessageType,
19 pub return_code: u8, pub tp_header: Option<TpHeader>,
25}
26
27impl SomeipHeader {
28 pub fn new_sd_header(length: u32, session_id: u16, tp_header: Option<TpHeader>) -> Self {
30 Self {
31 message_id: SOMEIP_SD_MESSAGE_ID, length,
33 request_id: session_id as u32, interface_version: 0x01, message_type: MessageType::Notification, return_code: 0x00, tp_header,
38 }
39 }
40
41 #[inline]
43 pub fn service_id(&self) -> u16 {
44 ((self.message_id & 0xffff_0000) >> 16) as u16
45 }
46
47 #[inline]
49 pub fn set_service_id(&mut self, service_id: u16) {
50 self.message_id = (self.message_id & 0x0000_ffff) | (u32::from(service_id) << 16);
51 }
52
53 #[inline]
55 pub fn set_event_id(&mut self, event_id: u16) {
56 self.message_id = (self.message_id & 0xffff_0000) | u32::from(0x8000 | event_id);
57 }
58
59 #[inline]
61 pub fn set_method_id(&mut self, method_id: u16) {
62 debug_assert!(method_id <= 0x7FFF);
63 self.message_id = (self.message_id & 0xffff_0000) | u32::from(0x7fff & method_id);
64 }
65
66 #[inline]
68 pub fn set_method_or_event_id(&mut self, method_id: u16) {
69 self.message_id = (self.message_id & 0xffff_0000) | u32::from(method_id);
70 }
71
72 #[inline]
74 pub fn is_someip_sd(&self) -> bool {
75 SOMEIP_SD_MESSAGE_ID == self.message_id
76 }
77
78 #[inline]
80 pub fn is_event(&self) -> bool {
81 0 != self.message_id & 0x8000
82 }
83
84 #[inline]
86 pub fn event_or_method_id(&self) -> u16 {
87 (self.message_id & 0x0000_ffff) as u16
88 }
89
90 #[inline]
92 pub fn event_id(&self) -> Option<u16> {
93 if self.is_event() {
94 Some(self.event_or_method_id() & 0x7fff)
95 } else {
96 None
97 }
98 }
99
100 #[inline]
102 pub fn method_id(&self) -> Option<u16> {
103 if !self.is_event() {
104 Some(self.event_or_method_id() & 0x7fff)
105 } else {
106 None
107 }
108 }
109
110 pub fn write_raw<T: std::io::Write>(&self, writer: &mut T) -> Result<(), std::io::Error> {
112 writer.write_all(&self.base_to_bytes())?;
113 if let Some(ref tp) = self.tp_header {
114 tp.write(writer)?;
115 }
116 Ok(())
117 }
118
119 #[inline]
121 pub fn base_to_bytes(&self) -> [u8; SOMEIP_HEADER_LENGTH] {
122 let message_id_be = self.message_id.to_be_bytes();
123 let length_be = self.length.to_be_bytes();
124 let request_id_be = self.request_id.to_be_bytes();
125 [
126 message_id_be[0],
127 message_id_be[1],
128 message_id_be[2],
129 message_id_be[3],
130 length_be[0],
131 length_be[1],
132 length_be[2],
133 length_be[3],
134 request_id_be[0],
135 request_id_be[1],
136 request_id_be[2],
137 request_id_be[3],
138 SOMEIP_PROTOCOL_VERSION,
139 self.interface_version,
140 match self.tp_header {
141 Some(_) => (self.message_type.clone() as u8) | SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG,
142 None => self.message_type.clone() as u8,
143 },
144 self.return_code,
145 ]
146 }
147
148 pub fn read<T: std::io::Read>(
150 reader: &mut T,
151 ) -> Result<SomeipHeader, err::SomeipHeaderReadError> {
152 use err::{SomeipHeaderError::*, SomeipHeaderReadError::*};
153
154 let mut header_bytes: [u8; SOMEIP_HEADER_LENGTH] = [0; SOMEIP_HEADER_LENGTH];
156 reader.read_exact(&mut header_bytes).map_err(Io)?;
157
158 let length = u32::from_be_bytes([
160 header_bytes[4],
161 header_bytes[5],
162 header_bytes[6],
163 header_bytes[7],
164 ]);
165 if length < SOMEIP_LEN_OFFSET_TO_PAYLOAD {
166 return Err(Content(LengthFieldTooSmall(length)));
167 }
168
169 let protocol_version = header_bytes[12];
171 if SOMEIP_PROTOCOL_VERSION != protocol_version {
172 return Err(Content(UnsupportedProtocolVersion(protocol_version)));
173 }
174
175 let message_type_raw = header_bytes[14];
177 let message_type = {
178 use MessageType::*;
179 match message_type_raw & !(SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG) {
181 0x0 => Request,
182 0x1 => RequestNoReturn,
183 0x2 => Notification,
184 0x80 => Response,
185 0x81 => Error,
186 _ => return Err(Content(UnknownMessageType(message_type_raw))),
187 }
188 };
189
190 Ok(SomeipHeader {
191 message_id: u32::from_be_bytes([
192 header_bytes[0],
193 header_bytes[1],
194 header_bytes[2],
195 header_bytes[3],
196 ]),
197 length,
198 request_id: u32::from_be_bytes([
199 header_bytes[8],
200 header_bytes[9],
201 header_bytes[10],
202 header_bytes[11],
203 ]),
204 interface_version: header_bytes[13],
205 message_type,
206 return_code: header_bytes[15],
207 tp_header: if 0 != message_type_raw & SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG {
209 Some(TpHeader::read(reader).map_err(Io)?)
210 } else {
211 None
212 },
213 })
214 }
215}
216
217impl Default for SomeipHeader {
218 fn default() -> SomeipHeader {
219 SomeipHeader {
220 message_id: 0,
221 length: SOMEIP_LEN_OFFSET_TO_PAYLOAD,
222 request_id: 0,
223 interface_version: 0,
224 message_type: MessageType::Request,
225 return_code: 0,
226 tp_header: None,
227 }
228 }
229}
230
231#[cfg(test)]
232mod tests {
233 use super::proptest_generators::*;
234 use super::*;
235 use proptest::prelude::*;
236 use std::io::{Cursor, Write};
237 use MessageType::*;
238
239 const MESSAGE_TYPE_VALUES: &[MessageType; 5] =
240 &[Request, RequestNoReturn, Notification, Response, Error];
241
242 const MESSAGE_TYPE_VALUES_RAW: &[u8; 10] = &[
243 Request as u8,
244 RequestNoReturn as u8,
245 Notification as u8,
246 Response as u8,
247 Error as u8,
248 Request as u8 | SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG,
249 RequestNoReturn as u8 | SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG,
250 Notification as u8 | SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG,
251 Response as u8 | SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG,
252 Error as u8 | SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG,
253 ];
254
255 #[test]
256 fn default() {
257 let header: SomeipHeader = Default::default();
258 assert_eq!(0, header.message_id);
259 assert_eq!(SOMEIP_LEN_OFFSET_TO_PAYLOAD, header.length);
260 assert_eq!(0, header.request_id);
261 assert_eq!(0, header.interface_version);
262 assert_eq!(MessageType::Request, header.message_type);
263 assert_eq!(None, header.tp_header);
264 assert_eq!(0, header.return_code);
265 }
266
267 proptest! {
268 #[test]
269 fn write_read(ref input_base in someip_header_any()) {
270 for message_type in MESSAGE_TYPE_VALUES {
271 let input = {
272 let mut value = input_base.clone();
273 value.message_type = message_type.clone();
274 value
275 };
276 let mut buffer = Vec::new();
277 input.write_raw(&mut buffer).unwrap();
278
279 let mut cursor = Cursor::new(&buffer);
281 let result = SomeipHeader::read(&mut cursor).unwrap();
282 assert_eq!(input, result);
283
284 {
286 let buffer_len = buffer.len();
287 assert!(SomeipHeader::read(&mut Cursor::new(&buffer[..buffer_len-1])).unwrap_err().io_error().is_some());
288 }
289 }
290 }
291 }
292
293 proptest! {
294 #[test]
295 fn from_slice(length in SOMEIP_LEN_OFFSET_TO_PAYLOAD..1234,
296 ref input_base in someip_header_any(),
297 add in 0usize..15) {
298 for message_type in MESSAGE_TYPE_VALUES {
299 let length = if input_base.tp_header.is_some() {
301 length + TP_HEADER_LENGTH as u32
302 } else {
303 length
304 };
305
306 let input = {
307 let mut value = input_base.clone();
308 value.length = length;
309 value.message_type = message_type.clone();
310 value
311 };
312
313 let mut buffer = Vec::new();
314 input.write_raw(&mut buffer).unwrap();
315
316 let expected_length =
318 length as usize
319 + (SOMEIP_HEADER_LENGTH - SOMEIP_LEN_OFFSET_TO_PAYLOAD as usize);
320 buffer.resize(expected_length + add, 0);
321
322 let slice = SomeipMsgSlice::from_slice(&buffer[..]).unwrap();
324 assert_eq!(input.message_id, slice.message_id());
325 assert_eq!(input.length, slice.length());
326 assert_eq!(input.request_id, slice.request_id());
327 assert_eq!(SOMEIP_PROTOCOL_VERSION, slice.protocol_version());
328 assert_eq!(input.interface_version, slice.interface_version());
329 assert_eq!(input.message_type, slice.message_type());
330 assert_eq!(input.tp_header, slice.tp_header());
331 assert_eq!(input.tp_header.is_some(), slice.is_tp());
332 assert_eq!(input.return_code, slice.return_code());
333 assert_eq!(&buffer[(
334 if input.tp_header.is_some() {
335 SOMEIP_HEADER_LENGTH + TP_HEADER_LENGTH
336 } else {
337 SOMEIP_HEADER_LENGTH
338 }
339 )..expected_length], slice.payload());
340
341 assert_eq!(&buffer[..expected_length], slice.slice());
343
344 assert_eq!(input, slice.to_header());
346
347 use err::{*, SomeipSliceError::*};
349 assert_eq!(
350 SomeipMsgSlice::from_slice(&buffer[..expected_length-1]),
351 Err(Len(LenError {
352 required_len: expected_length,
353 len: expected_length - 1,
354 len_source: if expected_length <= SOMEIP_HEADER_LENGTH {
355 LenSource::Slice
356 } else {
357 LenSource::SomeipHeaderLength
358 },
359 layer: if expected_length <= SOMEIP_HEADER_LENGTH {
360 Layer::SomeipHeader
361 } else {
362 Layer::SomeipPayload
363 },
364 }))
365 );
366 }
367 }
368 }
369
370 proptest! {
371 #[test]
372 fn unknown_message_type(length in SOMEIP_LEN_OFFSET_TO_PAYLOAD..1234,
373 ref input_base in someip_header_any(),
374 message_type in any::<u8>().prop_filter("message type must be unknown",
375 |v| !MESSAGE_TYPE_VALUES_RAW.iter().any(|&x| (v == &x ||
376 (SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG | v) == x)))
377 )
378 {
379 let length = if 0 != (SOMEIP_HEADER_MESSAGE_TYPE_TP_FLAG & message_type) {
381 length + 4
382 } else {
383 length
384 };
385
386 let input = {
387 let mut value = input_base.clone();
388 value.length = length;
389 value
390 };
391
392 let mut buffer = Vec::new();
394 input.write_raw(&mut buffer).unwrap();
395
396 let expected_length = length as usize + (SOMEIP_HEADER_LENGTH - SOMEIP_LEN_OFFSET_TO_PAYLOAD as usize);
398 buffer.resize(expected_length, 0);
399
400 buffer[14] = message_type;
402
403 use err::{SomeipSliceError::*, SomeipHeaderError::*};
405 assert_eq!(
406 SomeipHeader::read(&mut Cursor::new(&buffer)).unwrap_err().content_error(),
407 Some(UnknownMessageType(message_type))
408 );
409 assert_eq!(
410 SomeipMsgSlice::from_slice(&buffer),
411 Err(Content(UnknownMessageType(message_type)))
412 );
413 }
414 }
415
416 #[test]
417 fn read_unsupported_protocol_version() {
418 let mut buffer = Vec::new();
419 SomeipHeader::default().write_raw(&mut buffer).unwrap();
420 buffer[4 * 3] = 0;
422 let mut cursor = Cursor::new(&buffer);
423 let result = SomeipHeader::read(&mut cursor);
424 use err::{SomeipHeaderError::*, SomeipSliceError::*};
425 assert_eq!(
426 result.unwrap_err().content_error(),
427 Some(UnsupportedProtocolVersion(0))
428 );
429 assert_eq!(
430 SomeipMsgSlice::from_slice(&buffer[..]),
431 Err(Content(UnsupportedProtocolVersion(0)))
432 );
433 }
434
435 #[test]
436 fn read_too_small_length_field() {
437 {
439 let mut buffer = Vec::new();
440 SomeipHeader::default().write_raw(&mut buffer).unwrap();
441 {
443 buffer[4] = 0;
444 buffer[5] = 0;
445 buffer[6] = 0;
446 buffer[7] = 0;
447 }
448 let mut cursor = Cursor::new(&buffer);
449 let result = SomeipHeader::read(&mut cursor);
450 use err::{SomeipHeaderError::*, SomeipSliceError::*};
451 assert_eq!(
452 result.unwrap_err().content_error(),
453 Some(LengthFieldTooSmall(0))
454 );
455 assert_eq!(
457 SomeipMsgSlice::from_slice(&buffer[..]),
458 Err(Content(LengthFieldTooSmall(0)))
459 );
460 }
461 {
463 let mut buffer = Vec::new();
464 SomeipHeader::default().write_raw(&mut buffer).unwrap();
465 const TOO_SMALL: u32 = SOMEIP_LEN_OFFSET_TO_PAYLOAD - 1;
467 {
468 let length_be = TOO_SMALL.to_be_bytes();
469 buffer[4] = length_be[0];
470 buffer[5] = length_be[1];
471 buffer[6] = length_be[2];
472 buffer[7] = length_be[3];
473 }
474 let mut cursor = Cursor::new(&buffer);
475 let result = SomeipHeader::read(&mut cursor);
476 use err::{SomeipHeaderError::*, SomeipSliceError::*};
477 assert_eq!(
478 result.unwrap_err().content_error(),
479 Some(LengthFieldTooSmall(TOO_SMALL))
480 );
481 assert_eq!(
482 SomeipMsgSlice::from_slice(&buffer[..]),
483 Err(Content(LengthFieldTooSmall(TOO_SMALL)))
484 );
485 }
486 }
487
488 proptest! {
489 #[test]
490 fn service_id(packet in someip_header_with_payload_any(),
491 service_id in 0x0u16..std::u16::MAX)
492 {
493 let mut header = packet.0.clone();
494 header.set_service_id(service_id);
495 assert_eq!(service_id, header.service_id());
496
497 let mut buffer = Vec::new();
499 header.write_raw(&mut buffer).unwrap();
500 buffer.write(&packet.1[..]).unwrap();
501 let slice = SomeipMsgSlice::from_slice(&buffer[..]).unwrap();
502
503 assert_eq!(service_id, slice.service_id());
504 }
505 }
506
507 proptest! {
508 #[test]
509 fn set_get_method_id(packet in someip_header_with_payload_any(),
510 method_id in 0u16..0x7fff)
511 {
512 let mut header = packet.0.clone();
513 header.set_method_id(method_id);
514
515 assert_eq!(method_id, header.event_or_method_id());
516 assert_eq!(Some(method_id), header.method_id());
517 assert_eq!(false, header.is_event());
518 assert_eq!(None, header.event_id());
519
520 let mut buffer = Vec::new();
522 header.write_raw(&mut buffer).unwrap();
523 buffer.write(&packet.1[..]).unwrap();
524 let slice = SomeipMsgSlice::from_slice(&buffer[..]).unwrap();
525
526 assert_eq!(false, slice.is_event());
527 assert_eq!(Some(method_id), slice.method_id());
528 assert_eq!(method_id, slice.event_or_method_id());
529 assert_eq!(None, slice.event_id());
530 }
531 }
532
533 proptest! {
534 #[test]
535 fn set_get_event_id(packet in someip_header_with_payload_any(),
536 event_id in 0u16..0x7fff)
537 {
538 let mut header = packet.0.clone();
539 header.set_event_id(event_id);
540
541 let id_with_bit = event_id | 0x8000;
542
543 assert_eq!(id_with_bit, header.event_or_method_id());
544 assert_eq!(Some(event_id), header.event_id());
545 assert_eq!(true, header.is_event());
546 assert_eq!(None, header.method_id());
547
548 let mut buffer = Vec::new();
550 header.write_raw(&mut buffer).unwrap();
551 buffer.write(&packet.1[..]).unwrap();
552 let slice = SomeipMsgSlice::from_slice(&buffer[..]).unwrap();
553
554 assert_eq!(true, slice.is_event());
555 assert_eq!(id_with_bit, slice.event_or_method_id());
556 assert_eq!(Some(event_id), slice.event_id());
557 assert_eq!(None, slice.method_id());
558 }
559 }
560
561 proptest! {
562 #[test]
563 fn set_method_or_event_id(packet in someip_header_with_payload_any(),
564 id in 0x0u16..std::u16::MAX)
565 {
566 let mut header = packet.0.clone();
567 header.set_method_or_event_id(id);
568
569 assert_eq!(id, header.event_or_method_id());
570 assert_eq!(id >= 0x8000, header.is_event());
571
572 let mut buffer = Vec::new();
574 header.write_raw(&mut buffer).unwrap();
575 buffer.write(&packet.1[..]).unwrap();
576 let slice = SomeipMsgSlice::from_slice(&buffer[..]).unwrap();
577
578 assert_eq!(id >= 0x8000, slice.is_event());
579 assert_eq!(id, slice.event_or_method_id());
580 }
581 }
582
583 proptest! {
584 #[test]
585 fn is_someip_sd(packet in someip_header_with_payload_any())
586 {
587 const SD_MESSAGE_ID: u32 = 0xFFFF8100;
588
589 let mut header = packet.0.clone();
590 header.message_id = SD_MESSAGE_ID;
591
592 assert_eq!(true, header.is_someip_sd());
593 assert_eq!(packet.0.message_id == SD_MESSAGE_ID, packet.0.is_someip_sd());
594
595 {
598 let mut buffer = Vec::new();
599 header.write_raw(&mut buffer).unwrap();
600 buffer.write(&packet.1[..]).unwrap();
601 let slice = SomeipMsgSlice::from_slice(&buffer[..]).unwrap();
602
603 assert_eq!(true, slice.is_someip_sd());
604 }
605 {
607 let mut buffer = Vec::new();
608 packet.0.write_raw(&mut buffer).unwrap();
609 buffer.write(&packet.1[..]).unwrap();
610 let slice = SomeipMsgSlice::from_slice(&buffer[..]).unwrap();
611
612 assert_eq!(packet.0.message_id == SD_MESSAGE_ID, slice.is_someip_sd());
613 }
614 }
615 }
616}