Skip to main content

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