1use heapless::format;
4
5#[derive(Debug)]
6pub enum UdsError {
7 Transport(ace_core::DiagError),
8 NegativeResponse(u8),
9 Parse(heapless::String<64>),
10 ResponsePending,
11 Validation(ValidationError),
12}
13
14impl core::fmt::Display for UdsError {
19 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20 match self {
21 UdsError::Transport(e) => write!(f, "transport error: {:?}", e),
22 UdsError::NegativeResponse(nrc) => {
23 write!(f, "negative response: 0x{:02X}", nrc)
24 }
25 UdsError::Parse(msg) => write!(f, "parse error: {}", msg),
26 UdsError::ResponsePending => write!(f, "response pending (NRC 0x78)"),
27 UdsError::Validation(e) => write!(f, "validation error: {}", e),
28 }
29 }
30}
31
32impl From<ace_core::DiagError> for UdsError {
37 fn from(e: ace_core::DiagError) -> Self {
38 UdsError::Transport(e)
39 }
40}
41
42impl From<ValidationError> for UdsError {
43 fn from(e: ValidationError) -> Self {
44 UdsError::Validation(e)
45 }
46}
47
48impl From<UdsError> for ace_core::DiagError {
49 fn from(e: UdsError) -> Self {
50 match e {
51 UdsError::Transport(diag) => diag,
52 UdsError::Parse(msg) => ace_core::DiagError::InvalidFrame(msg),
53 UdsError::NegativeResponse(nrc) => ace_core::DiagError::InvalidFrame(
54 format!("negative response: {nrc}").unwrap_or_default(),
55 ),
56 UdsError::ResponsePending => ace_core::DiagError::InvalidFrame(
57 heapless::String::try_from("response pending").unwrap_or_default(),
58 ),
59 UdsError::Validation(e) => ace_core::DiagError::InvalidFrame(
60 format!("validation error: {e}").unwrap_or_default(),
61 ),
62 }
63 }
64}
65
66#[derive(Debug, Clone, PartialEq, Eq)]
71pub enum ValidationError {
72 InvalidEventType(u8),
73 UnsupportedService(u8),
74 InvalidSubFunction(u8),
75 InvalidLength { expected: usize, actual: usize },
76 InvalidSessionType(u8),
77 InvalidAddressAndLengthFormat(u8),
78 InvalidDataIdentifier(u16),
79 InvalidSecurityAccessType(u8),
80 InvalidCommunicationTypeValue(u8),
81 InvalidCommunicationReserved(u8),
82 InvalidSubnet(u8),
83 ServiceSpecific(heapless::String<64>),
84 InvalidDtcGroup(u32),
85}
86
87impl core::fmt::Display for ValidationError {
92 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
93 match self {
94 ValidationError::UnsupportedService(sid) => {
95 write!(f, "invalid service identifier: {:?}", sid)
96 }
97 ValidationError::InvalidSubFunction(sf) => {
98 write!(f, "invalid sub-function: 0x{:02X}", sf)
99 }
100 ValidationError::InvalidLength { expected, actual } => {
101 write!(f, "invalid length: expected {}, got {}", expected, actual)
102 }
103 ValidationError::InvalidSessionType(st) => {
104 write!(f, "invalid session type: 0x{:02X}", st)
105 }
106 ValidationError::InvalidAddressAndLengthFormat(byte) => {
107 write!(
108 f,
109 "invalid addressAndLengthFormatIdentifier: 0x{:02X}",
110 byte
111 )
112 }
113 ValidationError::InvalidDataIdentifier(did) => {
114 write!(f, "invalid data identifier: 0x{:04X}", did)
115 }
116 ValidationError::ServiceSpecific(msg) => {
117 write!(f, "service validation error: {}", msg)
118 }
119 ValidationError::InvalidSecurityAccessType(byte) => {
120 write!(f, "invalid securityAccessType: 0x{:02X}", byte)
121 }
122 ValidationError::InvalidCommunicationReserved(byte) => {
123 write!(f, "invalid communicationReserved: 0x{:02X}", byte)
124 }
125 ValidationError::InvalidSubnet(byte) => {
126 write!(f, "invalid subnet: 0x{:02X}", byte)
127 }
128 ValidationError::InvalidCommunicationTypeValue(byte) => {
129 write!(f, "invalid communicationTypeValue: 0x{:02X}", byte)
130 }
131 ValidationError::InvalidEventType(byte) => {
132 write!(f, "invalid eventType: 0x{:02X}", byte)
133 }
134 ValidationError::InvalidDtcGroup(byte) => {
135 write!(f, "invalid dtcGroup: 0x{:02X}", byte)
136 }
137 }
138 }
139}
140
141