veecle_os_data_support_someip/
header.rs

1//! SOME/IP header de-/serialization.
2
3use crate::parse::{ByteReader, Parse, ParseError};
4use crate::serialize::{ByteWriter, Serialize, SerializeError};
5
6/// Creates a new type wrapping a primitive. The new type implements conversion from and to the primitive as well as
7/// [`Parse`].
8macro_rules! create_new_type {
9    (
10        $(#[$($attributes:tt)*])*
11        pub struct $name:ident($inner:ty);
12    ) => {
13        $(#[$($attributes)*])*
14        #[derive(Debug, Clone, Copy, PartialEq, Eq)]
15        pub struct $name($inner);
16
17        impl From<$name> for $inner {
18            fn from(value: $name) -> $inner {
19                value.0
20            }
21        }
22
23        impl From<$inner> for $name {
24            fn from(value: $inner) -> Self {
25                Self(value)
26            }
27        }
28
29        impl<'a> Parse<'a> for $name {
30            fn parse_partial(reader: &mut ByteReader<'a>) -> Result<Self, ParseError> {
31                Parse::parse_partial(reader).map($name)
32            }
33        }
34
35        impl<'a> Serialize for $name {
36            fn required_length(&self) -> usize {
37                self.0.required_length()
38            }
39
40            fn serialize_partial(&self, byte_writer: &mut ByteWriter) -> Result<(), SerializeError> {
41                self.0.serialize_partial(byte_writer)
42            }
43        }
44    };
45}
46
47create_new_type! {
48    /// SOME/IP service ID.
49    pub struct ServiceId(u16);
50}
51
52create_new_type! {
53    /// SOME/IP method ID.
54    pub struct MethodId(u16);
55}
56
57/// SOME/IP message ID.
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Parse, Serialize)]
59pub struct MessageId {
60    service_id: ServiceId,
61    method_id: MethodId,
62}
63
64impl MessageId {
65    /// Creates a new message ID.
66    pub fn new(service_id: ServiceId, method_id: MethodId) -> Self {
67        Self {
68            service_id,
69            method_id,
70        }
71    }
72
73    /// Returns the [`ServiceId`].
74    pub fn service_id(&self) -> ServiceId {
75        self.service_id
76    }
77
78    /// Sets the [`ServiceId`].
79    pub fn set_service_id(&mut self, service_id: ServiceId) {
80        self.service_id = service_id
81    }
82
83    /// Returns the [`MethodId`].
84    pub fn method_id(&self) -> MethodId {
85        self.method_id
86    }
87
88    /// Sets the [`MethodId`].
89    pub fn set_method_id(&mut self, method_id: MethodId) {
90        self.method_id = method_id
91    }
92}
93
94create_new_type! {
95    /// SOME/IP length header field.
96    pub struct Length(u32);
97}
98
99impl Length {
100    // Header fields included in the length.
101    const REMAINING_HEADER_SIZE: u32 = 8;
102
103    /// Calculates the length of the payload, not including any of the header.
104    ///
105    /// This does not take E2E protection into account.
106    pub fn from_payload_length(length: u32) -> Self {
107        Self(length + Self::REMAINING_HEADER_SIZE)
108    }
109
110    /// Calculates the length of the payload, not including any of the header.
111    ///
112    /// This does not take E2E protection into account.
113    pub fn payload_length(&self) -> u32 {
114        self.0.saturating_sub(Self::REMAINING_HEADER_SIZE)
115    }
116}
117
118create_new_type! {
119    /// SOME/IP client ID prefix.
120    pub struct Prefix(u8);
121}
122
123create_new_type! {
124    /// SOME/IP client ID inner ID.
125    pub struct ClientIdInner(u8);
126}
127
128/// SOME/IP client ID.
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Parse, Serialize)]
130pub struct ClientId {
131    prefix: Prefix,
132    id: ClientIdInner,
133}
134
135impl ClientId {
136    /// Creates a new client ID.
137    pub fn new(prefix: Prefix, id: ClientIdInner) -> Self {
138        Self { prefix, id }
139    }
140
141    /// Returns the prefix.
142    pub fn prefix(&self) -> Prefix {
143        self.prefix
144    }
145
146    /// Sets the prefix.
147    pub fn set_prefix(&mut self, prefix: Prefix) {
148        self.prefix = prefix
149    }
150
151    /// Returns the ID.
152    pub fn id(&self) -> ClientIdInner {
153        self.id
154    }
155
156    /// Sets the ID.
157    pub fn set_id(&mut self, id: ClientIdInner) {
158        self.id = id
159    }
160}
161
162create_new_type! {
163    /// SOME/IP session ID.
164    pub struct SessionId(u16);
165}
166
167impl SessionId {
168    /// Returns the next session ID.
169    pub fn next(&self) -> Self {
170        // Session handling is not active.
171        if self.0 == 0 {
172            return *self;
173        }
174
175        // The session ID needs to be in the range 0x1 - 0xFFFF.
176        let next_id = self.0.checked_add(1).unwrap_or(1);
177
178        Self(next_id)
179    }
180}
181
182/// SOME/IP request ID.
183#[derive(Debug, Clone, Copy, PartialEq, Eq, Parse, Serialize)]
184pub struct RequestId {
185    client_id: ClientId,
186    session_id: SessionId,
187}
188
189impl RequestId {
190    /// Creates a new message ID.
191    pub fn new(client_id: ClientId, session_id: SessionId) -> Self {
192        Self {
193            client_id,
194            session_id,
195        }
196    }
197
198    /// Returns the [`ClientId`].
199    pub fn client_id(&self) -> ClientId {
200        self.client_id
201    }
202
203    /// Sets the [`ClientId`].
204    pub fn set_client_id(&mut self, client_id: ClientId) {
205        self.client_id = client_id
206    }
207
208    /// Returns the [`SessionId`].
209    pub fn session_id(&self) -> SessionId {
210        self.session_id
211    }
212
213    /// Sets the [`SessionId`].
214    pub fn set_session_id(&mut self, session_id: SessionId) {
215        self.session_id = session_id
216    }
217}
218
219create_new_type! {
220    /// SOME/IP protocol version.
221    pub struct ProtocolVersion(u8);
222}
223
224create_new_type! {
225    /// SOME/IP interface version.
226    pub struct InterfaceVersion(u8);
227}
228
229/// SOME/IP message type version.
230#[derive(Debug, Clone, Copy, PartialEq, Eq)]
231pub enum MessageType {
232    /// A request expecting a response (even void).
233    Request,
234    /// A fire&forget request
235    RequestNoReturn,
236    /// A request of a notification/event callback expecting no response.
237    Notification,
238    /// The response message.
239    Response,
240    /// The response containing an error.
241    Error,
242    /// A TP request expecting a response (even void).
243    TpRequest,
244    /// A TP fire&forget request.
245    TpRequestNoReturn,
246    /// A TP request of a notification/event call-back expecting no response.
247    TpNotification,
248    /// The TP response message.
249    TpResponse,
250    /// The TP response containing an error.
251    TpError,
252}
253
254impl<'a> Parse<'a> for MessageType {
255    fn parse_partial(reader: &mut ByteReader<'a>) -> Result<Self, ParseError> {
256        let byte = reader.read_byte()?;
257
258        let message_type = match byte {
259            0x00 => Self::Request,
260            0x01 => Self::RequestNoReturn,
261            0x02 => Self::Notification,
262            0x80 => Self::Response,
263            0x81 => Self::Error,
264            0x20 => Self::TpRequest,
265            0x21 => Self::TpRequestNoReturn,
266            0x22 => Self::TpNotification,
267            0xA0 => Self::TpResponse,
268            0xA1 => Self::TpError,
269            _ => {
270                return Err(ParseError::MalformedMessage {
271                    failed_at: core::any::type_name::<Self>(),
272                });
273            }
274        };
275
276        Ok(message_type)
277    }
278}
279
280impl Serialize for MessageType {
281    fn required_length(&self) -> usize {
282        1
283    }
284
285    fn serialize_partial(&self, byte_writer: &mut ByteWriter) -> Result<(), SerializeError> {
286        match self {
287            MessageType::Request => byte_writer.write_byte(0x00),
288            MessageType::RequestNoReturn => byte_writer.write_byte(0x01),
289            MessageType::Notification => byte_writer.write_byte(0x02),
290            MessageType::Response => byte_writer.write_byte(0x80),
291            MessageType::Error => byte_writer.write_byte(0x81),
292            MessageType::TpRequest => byte_writer.write_byte(0x20),
293            MessageType::TpRequestNoReturn => byte_writer.write_byte(0x21),
294            MessageType::TpNotification => byte_writer.write_byte(0x22),
295            MessageType::TpResponse => byte_writer.write_byte(0xA0),
296            MessageType::TpError => byte_writer.write_byte(0xA1),
297        }
298    }
299}
300
301/// SOME/IP return code.
302#[derive(Debug, Clone, Copy, PartialEq, Eq)]
303pub enum ReturnCode {
304    /// No error occurred.
305    Ok,
306    /// An unspecified error occurred.
307    NotOk,
308    /// The requested Service ID is unknown.
309    UnknownService,
310    /// The requested Method ID is unknown. Service ID is known.
311    UnknownMethod,
312    /// Service ID and Method ID are known. Application not running.
313    NotReady,
314    /// System running the service is not reachable (internal error code only).
315    NotReachable,
316    /// A timeout occurred (internal error code only).
317    Timeout,
318    /// Version of SOME/IP protocol not supported.
319    WrongProtocolVersion,
320    /// Interface version mismatch.
321    WrongInterfaceVersion,
322    /// Deserialization error, so that payload cannot be de-serialized.
323    MalformedMessage,
324    /// An unexpected message type was received (e.g. REQUEST_NO_RETURN for a method defined as REQUEST).
325    WrongMessageType,
326    /// Repeated E2E calculation error.
327    E2ERepeated,
328    /// Wrong E2E sequence error.
329    E2EWrongSequence,
330    /// Not further specified E2E error.
331    E2E,
332    /// E2E not available.
333    E2ENotAvailable,
334    /// No new data for E2E calculation present.
335    E2ENoNewData,
336    /// Reserved for generic SOME/IP errors.
337    Reserved0(u8),
338    /// Reserved for specific errors of services and methods.
339    Reserved1(u8),
340}
341
342impl<'a> Parse<'a> for ReturnCode {
343    fn parse_partial(reader: &mut ByteReader<'a>) -> Result<Self, ParseError> {
344        let byte = reader.read_byte()?;
345
346        let return_code = match byte {
347            0x00 => Self::Ok,
348            0x01 => Self::NotOk,
349            0x02 => Self::UnknownService,
350            0x03 => Self::UnknownMethod,
351            0x04 => Self::NotReady,
352            0x05 => Self::NotReachable,
353            0x06 => Self::Timeout,
354            0x07 => Self::WrongProtocolVersion,
355            0x08 => Self::WrongInterfaceVersion,
356            0x09 => Self::MalformedMessage,
357            0x0A => Self::WrongMessageType,
358            0x0B => Self::E2ERepeated,
359            0x0C => Self::E2EWrongSequence,
360            0x0D => Self::E2E,
361            0x0E => Self::E2ENotAvailable,
362            0x0F => Self::E2ENoNewData,
363            0x10..=0x1F => Self::Reserved0(byte),
364            0x20..=0x5E => Self::Reserved1(byte),
365            _ => {
366                return Err(ParseError::MalformedMessage {
367                    failed_at: core::any::type_name::<Self>(),
368                });
369            }
370        };
371
372        Ok(return_code)
373    }
374}
375
376impl Serialize for ReturnCode {
377    fn required_length(&self) -> usize {
378        1
379    }
380
381    fn serialize_partial(&self, byte_writer: &mut ByteWriter) -> Result<(), SerializeError> {
382        match self {
383            ReturnCode::Ok => byte_writer.write_byte(0x00),
384            ReturnCode::NotOk => byte_writer.write_byte(0x01),
385            ReturnCode::UnknownService => byte_writer.write_byte(0x02),
386            ReturnCode::UnknownMethod => byte_writer.write_byte(0x03),
387            ReturnCode::NotReady => byte_writer.write_byte(0x04),
388            ReturnCode::NotReachable => byte_writer.write_byte(0x05),
389            ReturnCode::Timeout => byte_writer.write_byte(0x06),
390            ReturnCode::WrongProtocolVersion => byte_writer.write_byte(0x07),
391            ReturnCode::WrongInterfaceVersion => byte_writer.write_byte(0x08),
392            ReturnCode::MalformedMessage => byte_writer.write_byte(0x09),
393            ReturnCode::WrongMessageType => byte_writer.write_byte(0x0A),
394            ReturnCode::E2ERepeated => byte_writer.write_byte(0x0B),
395            ReturnCode::E2EWrongSequence => byte_writer.write_byte(0x0C),
396            ReturnCode::E2E => byte_writer.write_byte(0x0D),
397            ReturnCode::E2ENotAvailable => byte_writer.write_byte(0x0E),
398            ReturnCode::E2ENoNewData => byte_writer.write_byte(0x0F),
399            ReturnCode::Reserved0(byte) => byte_writer.write_byte(*byte),
400            ReturnCode::Reserved1(byte) => byte_writer.write_byte(*byte),
401        }
402    }
403}
404
405/// SOME/IP packet payload.
406#[derive(Debug, PartialEq)]
407pub struct Payload<'a>(&'a [u8]);
408
409impl<'a> From<&'a [u8]> for Payload<'a> {
410    fn from(bytes: &'a [u8]) -> Self {
411        Payload::new(bytes)
412    }
413}
414
415impl AsRef<[u8]> for Payload<'_> {
416    fn as_ref(&self) -> &[u8] {
417        self.0
418    }
419}
420
421impl<'a> Payload<'a> {
422    /// Creates a new [`Payload`] from the given bytes.
423    pub fn new(bytes: &'a [u8]) -> Self {
424        Self(bytes)
425    }
426
427    /// Returns the internal payload slice.
428    pub fn into_inner(self) -> &'a [u8] {
429        self.0
430    }
431}
432
433/// SOME/IP header.
434#[derive(Debug, Clone, PartialEq, Eq, Parse, Serialize)]
435pub struct Header {
436    message_id: MessageId,
437    length: Length,
438    request_id: RequestId,
439    protocol_version: ProtocolVersion,
440    interface_version: InterfaceVersion,
441    message_type: MessageType,
442    return_code: ReturnCode,
443}
444
445impl Header {
446    /// Creates a new [`Header`].
447    pub fn new(
448        message_id: MessageId,
449        length: Length,
450        request_id: RequestId,
451        protocol_version: ProtocolVersion,
452        interface_version: InterfaceVersion,
453        message_type: MessageType,
454        return_code: ReturnCode,
455    ) -> Self {
456        Self {
457            message_id,
458            length,
459            request_id,
460            protocol_version,
461            interface_version,
462            message_type,
463            return_code,
464        }
465    }
466
467    /// Returns the [`MessageId`].
468    pub fn message_id(&self) -> MessageId {
469        self.message_id
470    }
471
472    /// Returns the [`Length`].
473    pub fn length(&self) -> Length {
474        self.length
475    }
476
477    /// Returns the [`RequestId`].
478    pub fn request_id(&self) -> RequestId {
479        self.request_id
480    }
481
482    /// Returns the [`ProtocolVersion`].
483    pub fn protocol_version(&self) -> ProtocolVersion {
484        self.protocol_version
485    }
486
487    /// Returns the [`InterfaceVersion`].
488    pub fn interface_version(&self) -> InterfaceVersion {
489        self.interface_version
490    }
491
492    /// Returns the [`MessageType`].
493    pub fn message_type(&self) -> MessageType {
494        self.message_type
495    }
496
497    /// Returns the [`ReturnCode`].
498    pub fn return_code(&self) -> ReturnCode {
499        self.return_code
500    }
501
502    /// Returns the [`MessageId`].
503    pub fn set_message_id(&mut self, message_id: MessageId) {
504        self.message_id = message_id;
505    }
506
507    /// Sets the [`Length`].
508    pub fn set_length(&mut self, length: Length) {
509        self.length = length;
510    }
511
512    /// Sets the [`RequestId`].
513    pub fn set_request_id(&mut self, request_id: RequestId) {
514        self.request_id = request_id;
515    }
516
517    /// Sets the [`ProtocolVersion`].
518    pub fn set_protocol_version(&mut self, protocol_version: ProtocolVersion) {
519        self.protocol_version = protocol_version;
520    }
521
522    /// Sets the [`InterfaceVersion`].
523    pub fn set_interface_version(&mut self, interface_version: InterfaceVersion) {
524        self.interface_version = interface_version;
525    }
526
527    /// Sets the [`MessageType`].
528    pub fn set_message_type(&mut self, message_type: MessageType) {
529        self.message_type = message_type;
530    }
531
532    /// Sets the [`ReturnCode`].
533    pub fn set_return_code(&mut self, return_code: ReturnCode) {
534        self.return_code = return_code;
535    }
536
537    /// Splits the bytes into header and payload and returns the header as a [`Header`].
538    pub fn parse_with_payload(bytes: &[u8]) -> Result<(Header, Payload<'_>), ParseError> {
539        let mut reader = ByteReader::new(bytes);
540
541        let header = Header::parse_partial(&mut reader)?;
542        let payload = Payload(reader.remaining_slice());
543
544        Ok((header, payload))
545    }
546
547    /// Serializes the header and the payload into one packet.
548    pub fn serialize_with_payload<'a>(
549        &mut self,
550        payload: Payload,
551        buffer: &'a mut [u8],
552    ) -> Result<&'a [u8], SerializeError> {
553        let mut byte_writer = ByteWriter::new(buffer);
554
555        self.length = Length::from_payload_length(payload.as_ref().len() as u32);
556
557        let written = byte_writer.write_counted(|byte_writer| {
558            self.serialize_partial(byte_writer)?;
559            byte_writer.write_slice(payload.as_ref())
560        })?;
561
562        Ok(&buffer[..written])
563    }
564
565    /// Serializes the header and the payload into one packet.
566    pub fn serialize_with_serializable<'a>(
567        &mut self,
568        payload: &impl Serialize,
569        buffer: &'a mut [u8],
570    ) -> Result<&'a [u8], SerializeError> {
571        let mut byte_writer = ByteWriter::new(buffer);
572
573        self.length = Length::from_payload_length(payload.required_length() as u32);
574
575        let written = byte_writer.write_counted(|byte_writer| {
576            self.serialize_partial(byte_writer)?;
577            payload.serialize_partial(byte_writer)
578        })?;
579
580        Ok(&buffer[..written])
581    }
582}
583
584#[cfg(test)]
585#[cfg_attr(coverage_nightly, coverage(off))]
586mod tests {
587
588    use pretty_assertions::assert_eq;
589
590    use super::{
591        ClientId, Header, InterfaceVersion, Length, MessageId, MessageType, MethodId, Payload,
592        ProtocolVersion, RequestId, ReturnCode, ServiceId, SessionId,
593    };
594    use crate::header::{ClientIdInner, Prefix};
595    use crate::parse::{Parse, ParseError, ParseExt};
596    use crate::serialize::{Serialize, SerializeError};
597
598    const SOMEIP_PACKET_BYTES: &[u8] = &[
599        0x12, 0x34, // Service ID
600        0x56, 0x78, // Method ID
601        0x00, 0x00, 0x00, 0x12, // Length (18 bytes)
602        0x9A, 0xBC, // Client ID
603        0xDE, 0xF0, // Session ID
604        0x01, // Protocol Version
605        0x02, // Interface Version
606        0x01, // Message Type
607        0x00, // Return Code
608        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, // Payload
609    ];
610
611    #[test]
612    fn conversion() {
613        const EXPECTED_DATA: &[u8] = &[
614            0, 1, // Service ID
615            0, 2, // Method ID
616            0, 0, 0, 3, // Length
617            4, 5, // CLient ID
618            0, 6, // Session ID
619            7, // Protocol Version
620            8, // Interface Version
621            0, // Message Type
622            0, // Return Code
623        ];
624
625        let header = Header {
626            message_id: MessageId::new(ServiceId(1), MethodId(2)),
627            length: Length(3),
628            request_id: RequestId::new(ClientId::new(4.into(), 5.into()), SessionId(6)),
629            protocol_version: ProtocolVersion(7),
630            interface_version: InterfaceVersion(8),
631            message_type: MessageType::Request,
632            return_code: ReturnCode::Ok,
633        };
634
635        test_round_trip!(Header, header, EXPECTED_DATA);
636    }
637
638    #[test]
639    fn parse_with_payload_cut_off() {
640        for cut_off in 0..16 {
641            assert_eq!(
642                Header::parse_with_payload(&SOMEIP_PACKET_BYTES[..cut_off]),
643                Err(crate::parse::ParseError::PayloadTooShort)
644            );
645        }
646    }
647
648    #[test]
649    fn payload_from() {
650        let payload_data = [10, 20, 30];
651
652        let payload = Payload::new(payload_data.as_slice());
653        assert_eq!(payload.as_ref(), payload_data);
654
655        let payload = Payload::from(payload_data.as_slice());
656        assert_eq!(payload.as_ref(), payload_data);
657    }
658
659    #[test]
660    fn payload_into_inner() {
661        let payload_data = [10, 20, 30];
662
663        let payload = Payload::new(payload_data.as_slice());
664        assert_eq!(payload.into_inner(), payload_data);
665    }
666
667    #[test]
668    fn payload_length() {
669        let (header, payload) = Header::parse_with_payload(SOMEIP_PACKET_BYTES).unwrap();
670
671        assert_eq!(payload.as_ref(), &SOMEIP_PACKET_BYTES[16..]);
672        assert_eq!(
673            header.length.payload_length() as usize,
674            payload.as_ref().len()
675        );
676    }
677
678    #[test]
679    fn set_header_length_field() {
680        let mut header = Header {
681            message_id: MessageId::new(ServiceId(0), MethodId(0)),
682            length: Length(0),
683            request_id: RequestId::new(ClientId::new(0.into(), 0.into()), SessionId(0)),
684            protocol_version: ProtocolVersion(0),
685            interface_version: InterfaceVersion(0),
686            message_type: MessageType::Request,
687            return_code: ReturnCode::Ok,
688        };
689        let payload = [1, 2, 3, 4, 5];
690
691        let mut buffer = [0u8; 128];
692        let serialized = header
693            .serialize_with_payload(Payload(&payload), &mut buffer)
694            .unwrap();
695
696        let (parsed_header, parsed_payload) = Header::parse_with_payload(serialized).unwrap();
697
698        assert_eq!(
699            parsed_header.length.payload_length() as usize,
700            payload.len()
701        );
702        assert_eq!(parsed_payload.as_ref(), &payload);
703    }
704
705    #[test]
706    fn serialize_with_payload_buffer_too_small() {
707        let mut header = Header {
708            message_id: MessageId::new(ServiceId(0), MethodId(0)),
709            length: Length(0),
710            request_id: RequestId::new(ClientId::new(0.into(), 0.into()), SessionId(0)),
711            protocol_version: ProtocolVersion(0),
712            interface_version: InterfaceVersion(0),
713            message_type: MessageType::Request,
714            return_code: ReturnCode::Ok,
715        };
716        let payload = [1, 2, 3, 4, 5];
717
718        let mut buffer = [0u8; 128];
719
720        for buffer_length in 0..header.required_length() + payload.len() {
721            assert_eq!(
722                header.serialize_with_payload(Payload(&payload), &mut buffer[..buffer_length]),
723                Err(SerializeError::BufferTooSmall)
724            );
725        }
726    }
727
728    #[test]
729    fn getters_setters() {
730        let mut header = Header {
731            message_id: MessageId::new(ServiceId(0), MethodId(0)),
732            length: Length(0),
733            request_id: RequestId::new(ClientId::new(0.into(), 0.into()), SessionId(0)),
734            protocol_version: ProtocolVersion(0),
735            interface_version: InterfaceVersion(0),
736            message_type: MessageType::Request,
737            return_code: ReturnCode::Ok,
738        };
739
740        let mut message_id = MessageId::new(ServiceId(0), MethodId(0));
741
742        let service_id = ServiceId(8);
743        let method_id = MethodId(9);
744        message_id.set_service_id(service_id);
745        message_id.set_method_id(method_id);
746
747        let mut client_id = ClientId::new(Prefix(0), ClientIdInner(0));
748
749        let prefix = Prefix(8);
750        let client_id_inner = ClientIdInner(9);
751        client_id.set_prefix(prefix);
752        client_id.set_id(client_id_inner);
753
754        let length = Length(20);
755
756        let mut request_id =
757            RequestId::new(ClientId::new(Prefix(0), ClientIdInner(0)), SessionId(0));
758
759        let session_id = SessionId(10);
760        request_id.set_client_id(client_id);
761        request_id.set_session_id(session_id);
762
763        let protocol_version = ProtocolVersion(8);
764        let interface_version = InterfaceVersion(9);
765        let message_type = MessageType::Response;
766        let return_code = ReturnCode::NotOk;
767
768        header.set_message_id(message_id);
769        header.set_length(length);
770        header.set_request_id(request_id);
771        header.set_protocol_version(protocol_version);
772        header.set_interface_version(interface_version);
773        header.set_message_type(message_type);
774        header.set_return_code(return_code);
775
776        assert_eq!(header.message_id().service_id(), service_id);
777        assert_eq!(header.message_id().method_id(), method_id);
778
779        assert_eq!(header.length(), length);
780
781        assert_eq!(header.request_id().client_id().prefix(), prefix);
782        assert_eq!(header.request_id().client_id().id(), client_id_inner);
783        assert_eq!(header.request_id().session_id(), session_id);
784
785        assert_eq!(header.protocol_version(), protocol_version);
786        assert_eq!(header.interface_version(), interface_version);
787        assert_eq!(header.message_type(), message_type);
788        assert_eq!(header.return_code(), return_code);
789    }
790
791    #[test]
792    fn message_id_from_u32() {
793        const BYTES: [u8; 4] = [0x1, 0x2, 0x3, 0x4];
794
795        let parsed_message_id = MessageId::parse(&BYTES).unwrap();
796        let created_message_id = MessageId::new(
797            ServiceId::from(u16::from_be_bytes(BYTES[..2].try_into().unwrap())),
798            MethodId::from(u16::from_be_bytes(BYTES[2..].try_into().unwrap())),
799        );
800
801        assert_eq!(
802            parsed_message_id.service_id(),
803            created_message_id.service_id()
804        );
805        assert_eq!(
806            parsed_message_id.method_id(),
807            created_message_id.method_id()
808        );
809    }
810
811    #[test]
812    fn session_id_next() {
813        assert_eq!(SessionId(0).next(), SessionId(0));
814        assert_eq!(SessionId(1).next(), SessionId(2));
815        assert_eq!(SessionId(0xFFFF).next(), SessionId(1));
816    }
817
818    #[test]
819    fn message_types() {
820        const EXPECTED_DATA: &[u8] = &[0, 1, 2, 128, 129, 32, 33, 34, 160, 161];
821
822        #[derive(Debug, Clone, Copy, PartialEq, Eq, Parse, Serialize)]
823        struct Test(
824            MessageType,
825            MessageType,
826            MessageType,
827            MessageType,
828            MessageType,
829            MessageType,
830            MessageType,
831            MessageType,
832            MessageType,
833            MessageType,
834        );
835
836        let message_types = Test(
837            MessageType::Request,
838            MessageType::RequestNoReturn,
839            MessageType::Notification,
840            MessageType::Response,
841            MessageType::Error,
842            MessageType::TpRequest,
843            MessageType::TpRequestNoReturn,
844            MessageType::TpNotification,
845            MessageType::TpResponse,
846            MessageType::TpError,
847        );
848
849        test_round_trip!(Test, message_types, EXPECTED_DATA);
850    }
851
852    #[test]
853    fn invalid_message_type() {
854        const USED_VALUES: &[u8] = &[0x00, 0x01, 0x02, 0x80, 0x81, 0x20, 0x21, 0x22, 0xA0, 0xA1];
855
856        for byte in 0x00..0xFF {
857            if !USED_VALUES.contains(&byte) {
858                assert!(matches!(
859                    MessageType::parse(&[byte]),
860                    Err(ParseError::MalformedMessage { .. })
861                ));
862            }
863        }
864    }
865
866    #[test]
867    fn return_codes() {
868        const EXPECTED_DATA: &[u8] =
869            &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32];
870
871        #[derive(Debug, Clone, Copy, PartialEq, Eq, Parse, Serialize)]
872        struct Test(
873            ReturnCode,
874            ReturnCode,
875            ReturnCode,
876            ReturnCode,
877            ReturnCode,
878            ReturnCode,
879            ReturnCode,
880            ReturnCode,
881            ReturnCode,
882            ReturnCode,
883            ReturnCode,
884            ReturnCode,
885            ReturnCode,
886            ReturnCode,
887            ReturnCode,
888            ReturnCode,
889            ReturnCode,
890            ReturnCode,
891        );
892
893        let return_codes = Test(
894            ReturnCode::Ok,
895            ReturnCode::NotOk,
896            ReturnCode::UnknownService,
897            ReturnCode::UnknownMethod,
898            ReturnCode::NotReady,
899            ReturnCode::NotReachable,
900            ReturnCode::Timeout,
901            ReturnCode::WrongProtocolVersion,
902            ReturnCode::WrongInterfaceVersion,
903            ReturnCode::MalformedMessage,
904            ReturnCode::WrongMessageType,
905            ReturnCode::E2ERepeated,
906            ReturnCode::E2EWrongSequence,
907            ReturnCode::E2E,
908            ReturnCode::E2ENotAvailable,
909            ReturnCode::E2ENoNewData,
910            ReturnCode::Reserved0(0x10),
911            ReturnCode::Reserved1(0x20),
912        );
913
914        test_round_trip!(Test, return_codes, EXPECTED_DATA);
915    }
916
917    #[test]
918    fn invalid_return_code() {
919        for byte in 0x5F..0xFF {
920            assert!(matches!(
921                ReturnCode::parse(&[byte]),
922                Err(ParseError::MalformedMessage { .. })
923            ));
924        }
925    }
926
927    #[test]
928    fn serialize_with_serializable() {
929        #[derive(Debug, Parse, Serialize, Eq, PartialEq)]
930        pub struct SerializablePayload {
931            pub data: u32,
932            pub boolean: bool,
933        }
934
935        let mut header = Header {
936            message_id: MessageId::new(ServiceId(0), MethodId(0)),
937            length: Length(0),
938            request_id: RequestId::new(ClientId::new(0.into(), 0.into()), SessionId(0)),
939            protocol_version: ProtocolVersion(0),
940            interface_version: InterfaceVersion(0),
941            message_type: MessageType::Request,
942            return_code: ReturnCode::Ok,
943        };
944        let payload = SerializablePayload {
945            data: 1,
946            boolean: true,
947        };
948
949        let mut buffer = [0u8; 128];
950        let serialized = header
951            .serialize_with_serializable(&payload, &mut buffer)
952            .unwrap();
953
954        let (parsed_header, parsed_payload) = Header::parse_with_payload(serialized).unwrap();
955
956        assert_eq!(
957            parsed_header.length.payload_length() as usize,
958            payload.required_length()
959        );
960
961        let parsed_payload = SerializablePayload::parse(parsed_payload.into_inner()).unwrap();
962        assert_eq!(&parsed_payload, &payload);
963    }
964
965    #[test]
966    fn serialize_with_serializable_buffer_too_small() {
967        #[derive(Debug, Parse, Serialize, Eq, PartialEq)]
968        pub struct SerializablePayload {
969            pub data: u32,
970            pub boolean: bool,
971        }
972
973        let mut header = Header {
974            message_id: MessageId::new(ServiceId(0), MethodId(0)),
975            length: Length(0),
976            request_id: RequestId::new(ClientId::new(0.into(), 0.into()), SessionId(0)),
977            protocol_version: ProtocolVersion(0),
978            interface_version: InterfaceVersion(0),
979            message_type: MessageType::Request,
980            return_code: ReturnCode::Ok,
981        };
982        let payload = SerializablePayload {
983            data: 1,
984            boolean: true,
985        };
986
987        let mut buffer_header_fail = [0u8; 0];
988        assert_eq!(
989            header.serialize_with_serializable(&payload, &mut buffer_header_fail),
990            Err(SerializeError::BufferTooSmall)
991        );
992
993        let mut buffer_payload_fail = [0u8; 17];
994        assert_eq!(
995            header.serialize_with_serializable(&payload, &mut buffer_payload_fail),
996            Err(SerializeError::BufferTooSmall)
997        );
998    }
999}