doip_codec/
decoder.rs

1use doip_definitions::{definitions::DOIP_HEADER_LEN, header::PayloadType, DoipMessage};
2use heapless::Vec;
3
4use crate::{
5    doip_message::{
6        header::HeaderCodec,
7        payload::{
8            alive_check_request::AliveCheckRequestCodec as AlivChecReqCodec,
9            alive_check_response::AliveCheckResponseCodec as AlivChecResCodec,
10            diagnostic_message::DiagnosticMessageCodec as DiagMsgCodec,
11            diagnostic_message_ack::DiagnosticMessageAckCodec as DiagMsgAckCodec,
12            diagnostic_message_nack::DiagnosticMessageNackCodec as DiagMsgNackCodec,
13            entity_status_request::EntityStatusRequestCodec as EntStatReqCodec,
14            entity_status_response::EntityStatusResponseCodec as EntStatResCodec,
15            generic_nack::GenericNackCodec,
16            power_information_request::PowerInformationRequestCodec as PowInfoReqCodec,
17            power_information_response::PowerInformationResponseCodec as PowInfoResCodec,
18            routing_activation_request::RoutingActivationRequestCodec as RoutActReqCodec,
19            routing_activation_response::RoutingActivationResponseCodec as RoutActResCodec,
20            vehicle_announcement_message::VehicleAnnouncementMessageCodec as VehAnnMsgCodec,
21            vehicle_identification_request::VehicleIdentificationRequestCodec as VehIDReqCodec,
22            vehicle_identification_request_eid::VehicleIdentificationRequestEidCodec as VehIDReqEidCodec,
23            vehicle_identification_request_vin::VehicleIdentificationRequestVinCodec as VehIDReqVinCodec,
24        },
25    },
26    error::DecodeError,
27    Decoder, DoipCodec,
28};
29
30impl<const N: usize> Decoder<N> for DoipCodec<N> {
31    type Item = DoipMessage<N>;
32    type Error = DecodeError;
33
34    fn from_bytes(&mut self, src: &mut Vec<u8, N>) -> Result<Option<Self::Item>, Self::Error> {
35        if src.len() < DOIP_HEADER_LEN {
36            return Err(DecodeError::TooShort);
37        }
38
39        let mut h_codec = HeaderCodec {};
40
41        let header = h_codec
42            .from_bytes(src)?
43            .expect("Should never return Ok(None)");
44
45        let payload = match header.payload_type {
46            PayloadType::GenericNack => GenericNackCodec {}.from_bytes(src)?,
47            PayloadType::VehicleIdentificationRequest => VehIDReqCodec {}.from_bytes(src)?,
48            PayloadType::VehicleIdentificationRequestEid => VehIDReqEidCodec {}.from_bytes(src)?,
49            PayloadType::VehicleIdentificationRequestVin => VehIDReqVinCodec {}.from_bytes(src)?,
50            PayloadType::VehicleAnnouncementMessage => VehAnnMsgCodec {}.from_bytes(src)?,
51            PayloadType::RoutingActivationRequest => RoutActReqCodec {}.from_bytes(src)?,
52            PayloadType::RoutingActivationResponse => RoutActResCodec {}.from_bytes(src)?,
53            PayloadType::AliveCheckRequest => AlivChecReqCodec {}.from_bytes(src)?,
54            PayloadType::AliveCheckResponse => AlivChecResCodec {}.from_bytes(src)?,
55            PayloadType::EntityStatusRequest => EntStatReqCodec {}.from_bytes(src)?,
56            PayloadType::EntityStatusResponse => EntStatResCodec {}.from_bytes(src)?,
57            PayloadType::PowerInformationRequest => PowInfoReqCodec {}.from_bytes(src)?,
58            PayloadType::PowerInformationResponse => PowInfoResCodec {}.from_bytes(src)?,
59            PayloadType::DiagnosticMessage => DiagMsgCodec {}.from_bytes(src)?,
60            PayloadType::DiagnosticMessageAck => DiagMsgAckCodec {}.from_bytes(src)?,
61            PayloadType::DiagnosticMessageNack => DiagMsgNackCodec {}.from_bytes(src)?,
62        }
63        .expect("Should never fail, this means header has been mutated during runtime");
64
65        Ok(Some(DoipMessage { header, payload }))
66    }
67}
68
69#[cfg(feature = "std")]
70impl<const N: usize> tokio_util::codec::Decoder for DoipCodec<N> {
71    type Item = DoipMessage<N>;
72    type Error = DecodeError;
73
74    fn decode(
75        &mut self,
76        src: &mut tokio_util::bytes::BytesMut,
77    ) -> Result<Option<Self::Item>, Self::Error> {
78        let mut heapless_src = heapless::Vec::<u8, N>::new();
79        heapless_src
80            .extend_from_slice(&src)
81            .map_err(|_| DecodeError::BufferTooSmall)?;
82
83        let decoder = DoipCodec {}.from_bytes(&mut heapless_src)?;
84
85        Ok(decoder)
86    }
87}