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
428/// SOME/IP header.
429#[derive(Debug, Clone, PartialEq, Eq, Parse, Serialize)]
430pub struct Header {
431    message_id: MessageId,
432    length: Length,
433    request_id: RequestId,
434    protocol_version: ProtocolVersion,
435    interface_version: InterfaceVersion,
436    message_type: MessageType,
437    return_code: ReturnCode,
438}
439
440impl Header {
441    /// Creates a new [`Header`].
442    pub fn new(
443        message_id: MessageId,
444        length: Length,
445        request_id: RequestId,
446        protocol_version: ProtocolVersion,
447        interface_version: InterfaceVersion,
448        message_type: MessageType,
449        return_code: ReturnCode,
450    ) -> Self {
451        Self {
452            message_id,
453            length,
454            request_id,
455            protocol_version,
456            interface_version,
457            message_type,
458            return_code,
459        }
460    }
461
462    /// Returns the [`MessageId`].
463    pub fn message_id(&self) -> MessageId {
464        self.message_id
465    }
466
467    /// Returns the [`Length`].
468    pub fn length(&self) -> Length {
469        self.length
470    }
471
472    /// Returns the [`RequestId`].
473    pub fn request_id(&self) -> RequestId {
474        self.request_id
475    }
476
477    /// Returns the [`ProtocolVersion`].
478    pub fn protocol_version(&self) -> ProtocolVersion {
479        self.protocol_version
480    }
481
482    /// Returns the [`InterfaceVersion`].
483    pub fn interface_version(&self) -> InterfaceVersion {
484        self.interface_version
485    }
486
487    /// Returns the [`MessageType`].
488    pub fn message_type(&self) -> MessageType {
489        self.message_type
490    }
491
492    /// Returns the [`ReturnCode`].
493    pub fn return_code(&self) -> ReturnCode {
494        self.return_code
495    }
496
497    /// Returns the [`MessageId`].
498    pub fn set_message_id(&mut self, message_id: MessageId) {
499        self.message_id = message_id;
500    }
501
502    /// Sets the [`Length`].
503    pub fn set_length(&mut self, length: Length) {
504        self.length = length;
505    }
506
507    /// Sets the [`RequestId`].
508    pub fn set_request_id(&mut self, request_id: RequestId) {
509        self.request_id = request_id;
510    }
511
512    /// Sets the [`ProtocolVersion`].
513    pub fn set_protocol_version(&mut self, protocol_version: ProtocolVersion) {
514        self.protocol_version = protocol_version;
515    }
516
517    /// Sets the [`InterfaceVersion`].
518    pub fn set_interface_version(&mut self, interface_version: InterfaceVersion) {
519        self.interface_version = interface_version;
520    }
521
522    /// Sets the [`MessageType`].
523    pub fn set_message_type(&mut self, message_type: MessageType) {
524        self.message_type = message_type;
525    }
526
527    /// Sets the [`ReturnCode`].
528    pub fn set_return_code(&mut self, return_code: ReturnCode) {
529        self.return_code = return_code;
530    }
531
532    /// Splits the bytes into header and payload and returns the header as a [`Header`].
533    pub fn parse_with_payload(bytes: &[u8]) -> Result<(Header, Payload<'_>), ParseError> {
534        let mut reader = ByteReader::new(bytes);
535
536        let header = Header::parse_partial(&mut reader)?;
537        let payload = Payload(reader.remaining_slice());
538
539        Ok((header, payload))
540    }
541
542    /// Serializes the header and the payload into one packet.
543    pub fn serialize_with_payload<'a>(
544        &mut self,
545        payload: Payload,
546        buffer: &'a mut [u8],
547    ) -> Result<&'a [u8], SerializeError> {
548        let mut byte_writer = ByteWriter::new(buffer);
549
550        self.length = Length::from_payload_length(payload.as_ref().len() as u32);
551
552        let written = byte_writer.write_counted(|byte_writer| {
553            self.serialize_partial(byte_writer)?;
554            byte_writer.write_slice(payload.as_ref())
555        })?;
556
557        Ok(&buffer[..written])
558    }
559}
560
561#[cfg(test)]
562#[cfg_attr(coverage_nightly, coverage(off))]
563mod tests {
564
565    use pretty_assertions::assert_eq;
566
567    use super::{
568        ClientId, Header, InterfaceVersion, Length, MessageId, MessageType, MethodId, Payload,
569        ProtocolVersion, RequestId, ReturnCode, ServiceId, SessionId,
570    };
571    use crate::header::{ClientIdInner, Prefix};
572    use crate::parse::{Parse, ParseError, ParseExt};
573    use crate::serialize::{Serialize, SerializeError};
574
575    const SOMEIP_PACKET_BYTES: &[u8] = &[
576        0x12, 0x34, // Service ID
577        0x56, 0x78, // Method ID
578        0x00, 0x00, 0x00, 0x12, // Length (18 bytes)
579        0x9A, 0xBC, // Client ID
580        0xDE, 0xF0, // Session ID
581        0x01, // Protocol Version
582        0x02, // Interface Version
583        0x01, // Message Type
584        0x00, // Return Code
585        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, // Payload
586    ];
587
588    #[test]
589    fn conversion() {
590        const EXPECTED_DATA: &[u8] = &[
591            0, 1, // Service ID
592            0, 2, // Method ID
593            0, 0, 0, 3, // Length
594            4, 5, // CLient ID
595            0, 6, // Session ID
596            7, // Protocol Version
597            8, // Interface Version
598            0, // Message Type
599            0, // Return Code
600        ];
601
602        let header = Header {
603            message_id: MessageId::new(ServiceId(1), MethodId(2)),
604            length: Length(3),
605            request_id: RequestId::new(ClientId::new(4.into(), 5.into()), SessionId(6)),
606            protocol_version: ProtocolVersion(7),
607            interface_version: InterfaceVersion(8),
608            message_type: MessageType::Request,
609            return_code: ReturnCode::Ok,
610        };
611
612        test_round_trip!(Header, header, EXPECTED_DATA);
613    }
614
615    #[test]
616    fn parse_with_payload_cut_off() {
617        for cut_off in 0..16 {
618            assert_eq!(
619                Header::parse_with_payload(&SOMEIP_PACKET_BYTES[..cut_off]),
620                Err(crate::parse::ParseError::PayloadTooShort)
621            );
622        }
623    }
624
625    #[test]
626    fn payload_from() {
627        let payload_data = [10, 20, 30];
628
629        let payload = Payload::new(payload_data.as_slice());
630        assert_eq!(payload.as_ref(), payload_data);
631
632        let payload = Payload::from(payload_data.as_slice());
633        assert_eq!(payload.as_ref(), payload_data);
634    }
635
636    #[test]
637    fn payload_length() {
638        let (header, payload) = Header::parse_with_payload(SOMEIP_PACKET_BYTES).unwrap();
639
640        assert_eq!(payload.as_ref(), &SOMEIP_PACKET_BYTES[16..]);
641        assert_eq!(
642            header.length.payload_length() as usize,
643            payload.as_ref().len()
644        );
645    }
646
647    #[test]
648    fn set_header_length_field() {
649        let mut header = Header {
650            message_id: MessageId::new(ServiceId(0), MethodId(0)),
651            length: Length(0),
652            request_id: RequestId::new(ClientId::new(0.into(), 0.into()), SessionId(0)),
653            protocol_version: ProtocolVersion(0),
654            interface_version: InterfaceVersion(0),
655            message_type: MessageType::Request,
656            return_code: ReturnCode::Ok,
657        };
658        let payload = [1, 2, 3, 4, 5];
659
660        let mut buffer = [0u8; 128];
661        let serialized = header
662            .serialize_with_payload(Payload(&payload), &mut buffer)
663            .unwrap();
664
665        let (parsed_header, parsed_payload) = Header::parse_with_payload(serialized).unwrap();
666
667        assert_eq!(
668            parsed_header.length.payload_length() as usize,
669            payload.len()
670        );
671        assert_eq!(parsed_payload.as_ref(), &payload);
672    }
673
674    #[test]
675    fn serialize_with_payload_buffer_too_small() {
676        let mut header = Header {
677            message_id: MessageId::new(ServiceId(0), MethodId(0)),
678            length: Length(0),
679            request_id: RequestId::new(ClientId::new(0.into(), 0.into()), SessionId(0)),
680            protocol_version: ProtocolVersion(0),
681            interface_version: InterfaceVersion(0),
682            message_type: MessageType::Request,
683            return_code: ReturnCode::Ok,
684        };
685        let payload = [1, 2, 3, 4, 5];
686
687        let mut buffer = [0u8; 128];
688
689        for buffer_length in 0..header.required_length() + payload.len() {
690            assert_eq!(
691                header.serialize_with_payload(Payload(&payload), &mut buffer[..buffer_length]),
692                Err(SerializeError::BufferTooSmall)
693            );
694        }
695    }
696
697    #[test]
698    fn getters_setters() {
699        let mut header = Header {
700            message_id: MessageId::new(ServiceId(0), MethodId(0)),
701            length: Length(0),
702            request_id: RequestId::new(ClientId::new(0.into(), 0.into()), SessionId(0)),
703            protocol_version: ProtocolVersion(0),
704            interface_version: InterfaceVersion(0),
705            message_type: MessageType::Request,
706            return_code: ReturnCode::Ok,
707        };
708
709        let mut message_id = MessageId::new(ServiceId(0), MethodId(0));
710
711        let service_id = ServiceId(8);
712        let method_id = MethodId(9);
713        message_id.set_service_id(service_id);
714        message_id.set_method_id(method_id);
715
716        let mut client_id = ClientId::new(Prefix(0), ClientIdInner(0));
717
718        let prefix = Prefix(8);
719        let client_id_inner = ClientIdInner(9);
720        client_id.set_prefix(prefix);
721        client_id.set_id(client_id_inner);
722
723        let length = Length(20);
724
725        let mut request_id =
726            RequestId::new(ClientId::new(Prefix(0), ClientIdInner(0)), SessionId(0));
727
728        let session_id = SessionId(10);
729        request_id.set_client_id(client_id);
730        request_id.set_session_id(session_id);
731
732        let protocol_version = ProtocolVersion(8);
733        let interface_version = InterfaceVersion(9);
734        let message_type = MessageType::Response;
735        let return_code = ReturnCode::NotOk;
736
737        header.set_message_id(message_id);
738        header.set_length(length);
739        header.set_request_id(request_id);
740        header.set_protocol_version(protocol_version);
741        header.set_interface_version(interface_version);
742        header.set_message_type(message_type);
743        header.set_return_code(return_code);
744
745        assert_eq!(header.message_id().service_id(), service_id);
746        assert_eq!(header.message_id().method_id(), method_id);
747
748        assert_eq!(header.length(), length);
749
750        assert_eq!(header.request_id().client_id().prefix(), prefix);
751        assert_eq!(header.request_id().client_id().id(), client_id_inner);
752        assert_eq!(header.request_id().session_id(), session_id);
753
754        assert_eq!(header.protocol_version(), protocol_version);
755        assert_eq!(header.interface_version(), interface_version);
756        assert_eq!(header.message_type(), message_type);
757        assert_eq!(header.return_code(), return_code);
758    }
759
760    #[test]
761    fn message_id_from_u32() {
762        const BYTES: [u8; 4] = [0x1, 0x2, 0x3, 0x4];
763
764        let parsed_message_id = MessageId::parse(&BYTES).unwrap();
765        let created_message_id = MessageId::new(
766            ServiceId::from(u16::from_be_bytes(BYTES[..2].try_into().unwrap())),
767            MethodId::from(u16::from_be_bytes(BYTES[2..].try_into().unwrap())),
768        );
769
770        assert_eq!(
771            parsed_message_id.service_id(),
772            created_message_id.service_id()
773        );
774        assert_eq!(
775            parsed_message_id.method_id(),
776            created_message_id.method_id()
777        );
778    }
779
780    #[test]
781    fn session_id_next() {
782        assert_eq!(SessionId(0).next(), SessionId(0));
783        assert_eq!(SessionId(1).next(), SessionId(2));
784        assert_eq!(SessionId(0xFFFF).next(), SessionId(1));
785    }
786
787    #[test]
788    fn message_types() {
789        const EXPECTED_DATA: &[u8] = &[0, 1, 2, 128, 129, 32, 33, 34, 160, 161];
790
791        #[derive(Debug, Clone, Copy, PartialEq, Eq, Parse, Serialize)]
792        struct Test(
793            MessageType,
794            MessageType,
795            MessageType,
796            MessageType,
797            MessageType,
798            MessageType,
799            MessageType,
800            MessageType,
801            MessageType,
802            MessageType,
803        );
804
805        let message_types = Test(
806            MessageType::Request,
807            MessageType::RequestNoReturn,
808            MessageType::Notification,
809            MessageType::Response,
810            MessageType::Error,
811            MessageType::TpRequest,
812            MessageType::TpRequestNoReturn,
813            MessageType::TpNotification,
814            MessageType::TpResponse,
815            MessageType::TpError,
816        );
817
818        test_round_trip!(Test, message_types, EXPECTED_DATA);
819    }
820
821    #[test]
822    fn invalid_message_type() {
823        const USED_VALUES: &[u8] = &[0x00, 0x01, 0x02, 0x80, 0x81, 0x20, 0x21, 0x22, 0xA0, 0xA1];
824
825        for byte in 0x00..0xFF {
826            if !USED_VALUES.contains(&byte) {
827                assert!(matches!(
828                    MessageType::parse(&[byte]),
829                    Err(ParseError::MalformedMessage { .. })
830                ));
831            }
832        }
833    }
834
835    #[test]
836    fn return_codes() {
837        const EXPECTED_DATA: &[u8] =
838            &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32];
839
840        #[derive(Debug, Clone, Copy, PartialEq, Eq, Parse, Serialize)]
841        struct Test(
842            ReturnCode,
843            ReturnCode,
844            ReturnCode,
845            ReturnCode,
846            ReturnCode,
847            ReturnCode,
848            ReturnCode,
849            ReturnCode,
850            ReturnCode,
851            ReturnCode,
852            ReturnCode,
853            ReturnCode,
854            ReturnCode,
855            ReturnCode,
856            ReturnCode,
857            ReturnCode,
858            ReturnCode,
859            ReturnCode,
860        );
861
862        let return_codes = Test(
863            ReturnCode::Ok,
864            ReturnCode::NotOk,
865            ReturnCode::UnknownService,
866            ReturnCode::UnknownMethod,
867            ReturnCode::NotReady,
868            ReturnCode::NotReachable,
869            ReturnCode::Timeout,
870            ReturnCode::WrongProtocolVersion,
871            ReturnCode::WrongInterfaceVersion,
872            ReturnCode::MalformedMessage,
873            ReturnCode::WrongMessageType,
874            ReturnCode::E2ERepeated,
875            ReturnCode::E2EWrongSequence,
876            ReturnCode::E2E,
877            ReturnCode::E2ENotAvailable,
878            ReturnCode::E2ENoNewData,
879            ReturnCode::Reserved0(0x10),
880            ReturnCode::Reserved1(0x20),
881        );
882
883        test_round_trip!(Test, return_codes, EXPECTED_DATA);
884    }
885
886    #[test]
887    fn invalid_return_code() {
888        for byte in 0x5F..0xFF {
889            assert!(matches!(
890                ReturnCode::parse(&[byte]),
891                Err(ParseError::MalformedMessage { .. })
892            ));
893        }
894    }
895}