Skip to main content

ace_uds/message/
service.rs

1use crate::UdsError;
2use ace_macros::FrameCodec;
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6#[frame(error = "UdsError")]
7#[repr(u8)]
8pub enum ServiceIdentifier {
9    #[frame(
10        id_pat = "0x00 | 0x3F | 0x40 | 0x80..=0x83 | 0x89..=0xB9 | 0xBF..=0xC2 | 0xC9..=0xF9 | 0xFF"
11    )]
12    NotApplicable(u8),
13
14    #[frame(id_pat = "0x01..=0x0F")]
15    EmissionsSpecificServiceRequest(u8),
16
17    #[frame(id_pat = "0x10..=0x3E", decode_inner)]
18    UdsServiceRequest(UdsServiceRequest),
19
20    #[frame(id_pat = "0x41..=0x4F")]
21    EmissionsSpecificServicePositiveResponse(u8),
22
23    #[frame(id_pat = "0x50..=0x7E", decode_inner)]
24    UdsServiceResponse(UdsServiceResponse),
25
26    #[frame(id = "0x7F")]
27    NegativeResponse,
28
29    #[frame(id_pat = "0x84..=0x88")]
30    ServiceRequests(u8),
31
32    #[frame(id_pat = "0xBA..=0xBE")]
33    SystemSupplierServiceRequests(u8),
34
35    #[frame(id_pat = "0xC3..=0xC8")]
36    ServiceRequestsPositiveResponse(u8),
37
38    #[frame(id_pat = "0xFA..=0xFE")]
39    SystemSupplierServiceRequestsPositiveResponse(u8),
40}
41
42#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
43#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
44#[frame(error = "UdsError")]
45#[repr(u8)]
46pub enum UdsServiceResponse {
47    #[frame(id = 0x50)]
48    DiagnosticSessionControl = 0x50,
49    #[frame(id = 0x51)]
50    EcuReset = 0x51,
51    #[frame(id = 0x67)]
52    SecurityAccess = 0x67,
53    #[frame(id = 0x68)]
54    CommunicationControl = 0x68,
55    #[frame(id = 0x69)]
56    Authentication = 0x69,
57    #[frame(id = 0x7e)]
58    TesterPresent = 0x7e,
59    #[frame(id = 0xc5)]
60    ControlDtcSetting = 0xc5,
61    #[frame(id = 0xc6)]
62    ResponseOnEvent = 0xc6,
63    #[frame(id = 0xc7)]
64    LinkControl = 0xc7,
65    #[frame(id = 0x62)]
66    ReadDataByIdentifier = 0x62,
67    #[frame(id = 0x63)]
68    ReadMemoryByAddress = 0x63,
69    #[frame(id = 0x64)]
70    ReadScalingDataByIdentifier = 0x64,
71    #[frame(id = 0x6a)]
72    ReadDataByPeriodicIdentifier = 0x6a,
73    #[frame(id = 0x6c)]
74    DynamicallyDefineDataIdentifier = 0x6c,
75    #[frame(id = 0x6e)]
76    WriteDataByIdentifier = 0x6e,
77    #[frame(id = 0x7d)]
78    WriteMemoryByAddress = 0x7d,
79    #[frame(id = 0x54)]
80    ClearDiagnosticInformation = 0x54,
81    #[frame(id = 0x59)]
82    ReadDtcInformation = 0x59,
83    #[frame(id = 0x6f)]
84    InputOutputControlByIdentifier = 0x6f,
85    #[frame(id = 0x71)]
86    RoutineControl = 0x71,
87    #[frame(id = 0x74)]
88    RequestDownload = 0x74,
89    #[frame(id = 0x75)]
90    RequestUpload = 0x75,
91    #[frame(id = 0x76)]
92    TransferData = 0x76,
93    #[frame(id = 0x77)]
94    RequestTransferExit = 0x77,
95    #[frame(id = 0x78)]
96    RequestFileTransfer = 0x78,
97    #[frame(id = 0xc4)]
98    SecuredDataTransmission = 0xc4,
99}
100
101#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
102#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
103#[frame(error = "UdsError")]
104#[repr(u8)]
105pub enum UdsServiceRequest {
106    #[frame(id = 0x10)]
107    DiagnosticSessionControl = 0x10,
108    #[frame(id = 0x11)]
109    EcuReset = 0x11,
110    #[frame(id = 0x27)]
111    SecurityAccess = 0x27,
112    #[frame(id = 0x28)]
113    CommunicationControl = 0x28,
114    #[frame(id = 0x29)]
115    Authentication = 0x29,
116    #[frame(id = 0x3e)]
117    TesterPresent = 0x3e,
118    #[frame(id = 0x85)]
119    ControlDtcSetting = 0x85,
120    #[frame(id = 0x86)]
121    ResponseOnEvent = 0x86,
122    #[frame(id = 0x87)]
123    LinkControl = 0x87,
124    #[frame(id = 0x22)]
125    ReadDataByIdentifier = 0x22,
126    #[frame(id = 0x23)]
127    ReadMemoryByAddress = 0x23,
128    #[frame(id = 0x24)]
129    ReadScalingDataByIdentifier = 0x24,
130    #[frame(id = 0x2a)]
131    ReadDataByPeriodicIdentifier = 0x2a,
132    #[frame(id = 0x2c)]
133    DynamicallyDefineDataIdentifier = 0x2c,
134    #[frame(id = 0x2e)]
135    WriteDataByIdentifier = 0x2e,
136    #[frame(id = 0x3d)]
137    WriteMemoryByAddress = 0x3d,
138    #[frame(id = 0x14)]
139    ClearDiagnosticInformation = 0x14,
140    #[frame(id = 0x19)]
141    ReadDTCInformation = 0x19,
142    #[frame(id = 0x2f)]
143    InputOutputControlByIdentifier = 0x2f,
144    #[frame(id = 0x31)]
145    RoutineControl = 0x31,
146    #[frame(id = 0x34)]
147    RequestDownload = 0x34,
148    #[frame(id = 0x35)]
149    RequestUpload = 0x35,
150    #[frame(id = 0x36)]
151    TransferData = 0x36,
152    #[frame(id = 0x37)]
153    RequestTransferExit = 0x37,
154    #[frame(id = 0x38)]
155    RequestFileTransfer = 0x38,
156    #[frame(id = 0x84)]
157    SecuredDataTransmission = 0x84,
158}
159
160impl ServiceIdentifier {
161    pub fn discriminant(&self) -> u8 {
162        match self {
163            ServiceIdentifier::UdsServiceRequest(s) => *s as u8,
164            ServiceIdentifier::UdsServiceResponse(s) => *s as u8,
165            ServiceIdentifier::NegativeResponse => 0x7F,
166            ServiceIdentifier::NotApplicable(v)
167            | ServiceIdentifier::EmissionsSpecificServiceRequest(v)
168            | ServiceIdentifier::EmissionsSpecificServicePositiveResponse(v)
169            | ServiceIdentifier::ServiceRequests(v)
170            | ServiceIdentifier::SystemSupplierServiceRequests(v)
171            | ServiceIdentifier::ServiceRequestsPositiveResponse(v)
172            | ServiceIdentifier::SystemSupplierServiceRequestsPositiveResponse(v) => *v,
173        }
174    }
175    /// Returns `true` if this service defines a sub-function byte at offset 1.
176    ///
177    /// Per ISO 14229, the following services carry a sub-function byte.
178    /// Services excluded are those whose second byte is a data parameter
179    /// rather than a sub-function - for example `ReadDataByIdentifier`
180    /// uses a 2-byte DID, not a sub-function.
181    #[must_use]
182    pub fn has_sub_function(&self) -> bool {
183        matches!(
184            self,
185            ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::DiagnosticSessionControl)
186                | ServiceIdentifier::UdsServiceResponse(
187                    UdsServiceResponse::DiagnosticSessionControl
188                )
189                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::EcuReset)
190                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::EcuReset)
191                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::SecurityAccess)
192                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::SecurityAccess)
193                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::CommunicationControl)
194                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::CommunicationControl)
195                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::Authentication)
196                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::Authentication)
197                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::TesterPresent)
198                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::TesterPresent)
199                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::ControlDtcSetting)
200                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::ControlDtcSetting)
201                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::ResponseOnEvent)
202                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::ResponseOnEvent)
203                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::LinkControl)
204                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::LinkControl)
205                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::ReadDTCInformation)
206                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::ReadDtcInformation)
207                | ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::RoutineControl)
208                | ServiceIdentifier::UdsServiceResponse(UdsServiceResponse::RoutineControl)
209        )
210    }
211}