1use ace_macros::FrameCodec;
2use ace_proto::doip::constants::{
3 DEFAULT_VALUE, DOIP_ALIVE_CHECK_REQUEST, DOIP_ALIVE_CHECK_RESPONSE, DOIP_DIAGNOSTIC_MESSAGE,
4 DOIP_DIAGNOSTIC_MESSAGE_ACK, DOIP_DIAGNOSTIC_MESSAGE_NACK, DOIP_ENTITY_STATUS_REQUEST,
5 DOIP_ENTITY_STATUS_RESPONSE, DOIP_GENERIC_NACK, DOIP_POWER_INFORMATION_REQUEST,
6 DOIP_POWER_INFORMATION_RESPONSE, DOIP_ROUTING_ACTIVATION_REQUEST,
7 DOIP_ROUTING_ACTIVATION_RESPONSE, DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE,
8 DOIP_VEHICLE_IDENTIFICATION_REQ, DOIP_VEHICLE_IDENTIFICATION_REQ_EID,
9 DOIP_VEHICLE_IDENTIFICATION_REQ_VIN, ISO13400_2010, ISO13400_2012, ISO13400_2019,
10 ISO13400_2019_AMD1, RESERVED_VER,
11};
12
13use crate::error::DoipError;
14
15#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
16#[frame(error = DoipError)]
17pub struct DoipHeader {
18 pub protocol_version: ProtocolVersion,
19 pub inverse_protocol_version: u8,
20 pub payload_type: PayloadType,
21 pub payload_length: u32,
22}
23
24#[repr(u8)]
25#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
26#[frame(error = DoipError)]
27pub enum ProtocolVersion {
28 #[frame(id = RESERVED_VER)]
29 ReservedVer,
30 #[frame(id = ISO13400_2010)]
31 Iso13400_2010,
32 #[frame(id = ISO13400_2012)]
33 Iso13400_2012,
34 #[frame(id = ISO13400_2019)]
35 Iso13400_2019,
36 #[frame(id = ISO13400_2019_AMD1)]
37 Iso13400_2019Amd1,
38 #[frame(id = DEFAULT_VALUE)]
39 DefaultValue,
40}
41
42impl TryFrom<u8> for ProtocolVersion {
43 type Error = ();
44
45 fn try_from(value: u8) -> Result<Self, Self::Error> {
46 match value {
47 RESERVED_VER => Ok(Self::ReservedVer),
48 ISO13400_2010 => Ok(Self::Iso13400_2010),
49 ISO13400_2012 => Ok(Self::Iso13400_2012),
50 ISO13400_2019 => Ok(Self::Iso13400_2019),
51 ISO13400_2019_AMD1 => Ok(Self::Iso13400_2019Amd1),
52 DEFAULT_VALUE => Ok(Self::DefaultValue),
53 _ => Err(()),
54 }
55 }
56}
57
58#[repr(u16)]
59#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
60#[frame(error = DoipError)]
61pub enum PayloadType {
62 #[frame(id = DOIP_GENERIC_NACK)]
63 GenericNack,
64 #[frame(id = DOIP_VEHICLE_IDENTIFICATION_REQ)]
65 VehicleIdentificationRequest,
66 #[frame(id = DOIP_VEHICLE_IDENTIFICATION_REQ_EID)]
67 VehicleIdentificationRequestEid,
68 #[frame(id = DOIP_VEHICLE_IDENTIFICATION_REQ_VIN)]
69 VehicleIdentificationRequestVin,
70 #[frame(id = DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE)]
71 VehicleAnnouncementMessage,
72 #[frame(id = DOIP_ROUTING_ACTIVATION_REQUEST)]
73 RoutingActivationRequest,
74 #[frame(id = DOIP_ROUTING_ACTIVATION_RESPONSE)]
75 RoutingActivationResponse,
76 #[frame(id = DOIP_ALIVE_CHECK_REQUEST)]
77 AliveCheckRequest,
78 #[frame(id = DOIP_ALIVE_CHECK_RESPONSE)]
79 AliveCheckResponse,
80 #[frame(id = DOIP_ENTITY_STATUS_REQUEST)]
81 EntityStatusRequest,
82 #[frame(id = DOIP_ENTITY_STATUS_RESPONSE)]
83 EntityStatusResponse,
84 #[frame(id = DOIP_POWER_INFORMATION_REQUEST)]
85 PowerInformationRequest,
86 #[frame(id = DOIP_POWER_INFORMATION_RESPONSE)]
87 PowerInformationResponse,
88 #[frame(id = DOIP_DIAGNOSTIC_MESSAGE)]
89 DiagnosticMessage,
90 #[frame(id = DOIP_DIAGNOSTIC_MESSAGE_ACK)]
91 DiagnosticMessageAck,
92 #[frame(id = DOIP_DIAGNOSTIC_MESSAGE_NACK)]
93 DiagnosticMessageNack,
94}
95
96impl TryFrom<u16> for PayloadType {
97 type Error = ();
98
99 fn try_from(value: u16) -> Result<Self, Self::Error> {
100 match value {
101 DOIP_GENERIC_NACK => Ok(Self::GenericNack),
102 DOIP_VEHICLE_IDENTIFICATION_REQ => Ok(Self::VehicleIdentificationRequest),
103 DOIP_VEHICLE_IDENTIFICATION_REQ_EID => Ok(Self::VehicleIdentificationRequestEid),
104 DOIP_VEHICLE_IDENTIFICATION_REQ_VIN => Ok(Self::VehicleIdentificationRequestVin),
105 DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE => Ok(Self::VehicleAnnouncementMessage),
106 DOIP_ROUTING_ACTIVATION_REQUEST => Ok(Self::RoutingActivationRequest),
107 DOIP_ROUTING_ACTIVATION_RESPONSE => Ok(Self::RoutingActivationResponse),
108 DOIP_ALIVE_CHECK_REQUEST => Ok(Self::AliveCheckRequest),
109 DOIP_ALIVE_CHECK_RESPONSE => Ok(Self::AliveCheckResponse),
110 DOIP_ENTITY_STATUS_REQUEST => Ok(Self::EntityStatusRequest),
111 DOIP_ENTITY_STATUS_RESPONSE => Ok(Self::EntityStatusResponse),
112 DOIP_POWER_INFORMATION_REQUEST => Ok(Self::PowerInformationRequest),
113 DOIP_POWER_INFORMATION_RESPONSE => Ok(Self::PowerInformationResponse),
114 DOIP_DIAGNOSTIC_MESSAGE => Ok(Self::DiagnosticMessage),
115 DOIP_DIAGNOSTIC_MESSAGE_ACK => Ok(Self::DiagnosticMessageAck),
116 DOIP_DIAGNOSTIC_MESSAGE_NACK => Ok(Self::DiagnosticMessageNack),
117 _ => Err(()),
118 }
119 }
120}