ace_server/handler.rs
1// region: Imports
2
3use crate::nrc::NrcError;
4
5// endregion: Imports
6
7// region: ServerHandler
8
9/// Application-level hook trait for UDS service handling.
10///
11/// The server state machine calls these hooks when a valid, session-permitted, security-cleared
12/// request arrives that requires application data or action. The server handles all protocol
13/// framing, session management, security access state, and periodic scheduling internally - the
14/// handler only sees the decoded parameters.
15///
16/// # Required vs Optional Hooks
17///
18/// Required hooks have no default implementation - the compiler enforces them. Optional hooks
19/// default to NRC 0x11 (Service Not Supported). Override only the services your ECU actually
20/// supports.
21///
22/// # Buffer Convention
23///
24/// Response data is written into the provided `buf` slice. The return value is the number of valid
25/// bytes written. The server sends only `buf[..len]`.
26///
27/// # Error Mapping
28///
29/// `type Error` must implement [`NrcError`] + `Into<u8>`. The server converts handler errors
30/// directly to NRC bytes in the negative response.
31pub trait ServerHandler {
32 type Error: NrcError;
33
34 // region: Required Hooks
35
36 /// Reads the value of a data identifier into `buf`.
37 ///
38 /// Called for `ReadDataByIdentifier` (0x22) and periodic scheduling (0x2A). Returns the number
39 /// of bytes written into `buf`.
40 fn read_did(&self, did: u16, buf: &mut [u8]) -> Result<usize, Self::Error>;
41
42 /// Writes a value to a data identifier.
43 ///
44 /// Called for `WriteDataByIdentifier` (0x2E).
45 fn write_did(&mut self, did: u16, data: &[u8]) -> Result<(), Self::Error>;
46
47 /// Executes an ECU Reset.
48 ///
49 /// Called for `EcuReset` (0x11). Reset Types: 0x01 Hard Reset, 0x02 KeyOffOnReset, 0x03
50 /// SoftReset. The positive response is sent before this hook is called.
51 fn ecu_reset(&mut self, reset_type: u8) -> Result<(), Self::Error>;
52
53 // endregion: Required Hooks
54
55 // region: Optional Hooks
56
57 /// Executes a routine control operation.
58 ///
59 /// Called for `Routine Control` (0x31). Sub-Functions: 0x01 Start Routine, 0x02 Stop Routine,
60 /// 0x03 Request Routine Results.
61 ///
62 /// Return the number of bytes written into `buf`.
63 fn routine_control(
64 &mut self,
65 _routine_id: u16,
66 _sub_function: u8,
67 _data: &[u8],
68 _buf: &mut [u8],
69 ) -> Result<usize, Self::Error> {
70 Err(Self::Error::service_not_supported())
71 }
72
73 /// Controls communication on a network channel.
74 ///
75 /// Called for `CommunicationControl` (0x28)
76 fn communication_control(
77 &mut self,
78 _control_type: u8,
79 _comm_type: u8,
80 ) -> Result<usize, Self::Error> {
81 Err(Self::Error::service_not_supported())
82 }
83
84 /// Initiates a data download session.
85 ///
86 /// Called for `RequestDownload` (0x34).
87 ///
88 /// Returns max block length encoded in `buf`.
89 fn request_download(
90 &mut self,
91 _memory_address: &[u8],
92 _memory_size: &[u8],
93 _compression_method: u8,
94 _encrypting_method: u8,
95 _buf: &mut [u8],
96 ) -> Result<usize, Self::Error> {
97 Err(Self::Error::service_not_supported())
98 }
99
100 /// Controls an input or output signal
101 ///
102 /// Called for `InputOutputControlByIdentifier` (0x2F).
103 ///
104 /// Returns the number of bytes written into `buf`.
105 fn io_control(
106 &mut self,
107 _did: u16,
108 _parameter: u8,
109 _control_state: &[u8],
110 _buf: &mut [u8],
111 ) -> Result<usize, Self::Error> {
112 Err(Self::Error::service_not_supported())
113 }
114
115 /// Transfers a block of data.
116 ///
117 /// Called for `TransferData` (0x36).
118 ///
119 /// Returns the number of bytes written into `buf`.
120 fn transfer_data(
121 &mut self,
122 _block_sequence_counter: u8,
123 _data: &[u8],
124 _buf: &mut [u8],
125 ) -> Result<usize, Self::Error> {
126 Err(Self::Error::service_not_supported())
127 }
128
129 /// Finalises a data transfer session.
130 ///
131 /// Called for `RequestTransferExit` (0x37).
132 ///
133 /// Returns the number of bytes written into `buf`.
134 fn request_transfer_exit(
135 &mut self,
136 _parameter_record: &[u8],
137 _buf: &mut [u8],
138 ) -> Result<usize, Self::Error> {
139 Err(Self::Error::service_not_supported())
140 }
141
142 /// Initiates a file transfer operation.
143 ///
144 /// Called for `RequestFileTransfer` (0x38).
145 ///
146 /// Returns the number of bytes written into `buf`.
147 fn request_file_transfer(
148 &mut self,
149 _operation: u8,
150 _path: &[u8],
151 _buf: &mut [u8],
152 ) -> Result<usize, Self::Error> {
153 Err(Self::Error::service_not_supported())
154 }
155
156 // endregion: Optional Hooks
157}
158
159// endregion: ServerHandler