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}