1#[cfg(all(feature = "defmt-format", target_os = "none"))]
14use defmt;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21#[repr(u8)]
22pub enum ExceptionCode {
23 IllegalFunction = 0x01,
25 IllegalDataAddress = 0x02,
27 IllegalDataValue = 0x03,
29 ServerDeviceFailure = 0x04,
31}
32
33impl From<ExceptionCode> for u8 {
34 fn from(code: ExceptionCode) -> Self {
35 code as u8
36 }
37}
38
39#[derive(Debug, PartialEq, Eq, Clone, Copy)]
41pub enum MbusError {
42 ParseError,
44 BasicParseError,
46 Timeout,
48 ModbusException(u8),
50 IoError,
52 Unexpected,
54 ConnectionLost,
56 UnsupportedFunction(u8),
58 ReservedSubFunction(u16),
60 InvalidPduLength,
62 InvalidAduLength,
64 ConnectionFailed,
66 ConnectionClosed,
68 BufferTooSmall,
70 BufferLenMissmatch,
72 SendFailed,
74 InvalidAddress,
76 InvalidOffset,
78 TooManyRequests,
80 InvalidFunctionCode,
82 NoRetriesLeft,
84 TooManyFileReadSubRequests,
86 FileReadPduOverflow,
88 UnexpectedResponse,
90 InvalidTransport,
92 InvalidSlaveAddress,
94 ChecksumError,
96 InvalidConfiguration,
98 InvalidNumOfExpectedRsps,
103 InvalidDataLen,
105 InvalidQuantity,
107 InvalidValue,
109 InvalidAndMask,
111 InvalidOrMask,
113 InvalidByteCount,
115 InvalidDeviceIdentification,
117 InvalidDeviceIdCode,
119 InvalidMeiType,
121 InvalidBroadcastAddress,
124 BroadcastNotAllowed,
129}
130
131impl MbusError {
132 pub const fn broadcast_not_allowed() -> Self {
137 Self::BroadcastNotAllowed
138 }
139}
140
141#[cfg(all(feature = "defmt-format", target_os = "none"))]
142impl defmt::Format for MbusError {
143 fn format(&self, f: defmt::Formatter) {
144 match self {
145 MbusError::ParseError => defmt::write!(
146 f,
147 "Parse error: An error occurred while parsing the Modbus ADU"
148 ),
149 MbusError::BasicParseError => defmt::write!(
150 f,
151 "Basic parse error: The received frame is fundamentally malformed"
152 ),
153 MbusError::Timeout => defmt::write!(
154 f,
155 "Timeout: The transaction timed out waiting for a response"
156 ),
157 MbusError::ModbusException(code) => defmt::write!(
158 f,
159 "Modbus exception: The server responded with exception code 0x{:02X}",
160 code
161 ),
162 MbusError::IoError => defmt::write!(
163 f,
164 "I/O error: An I/O error occurred during TCP communication"
165 ),
166 MbusError::Unexpected => {
167 defmt::write!(f, "Unexpected error: An unexpected error occurred")
168 }
169 MbusError::ConnectionLost => defmt::write!(
170 f,
171 "Connection lost: The connection was lost during an active transaction"
172 ),
173 MbusError::UnsupportedFunction(code) => defmt::write!(
174 f,
175 "Unsupported function: Function code 0x{:02X} is not supported",
176 code
177 ),
178 MbusError::ReservedSubFunction(code) => defmt::write!(
179 f,
180 "Reserved sub-function: Sub-function code 0x{:04X} is not available",
181 code
182 ),
183 MbusError::InvalidPduLength => {
184 defmt::write!(f, "Invalid PDU length: The PDU length is invalid")
185 }
186 MbusError::InvalidAduLength => {
187 defmt::write!(f, "Invalid ADU length: The ADU length is invalid")
188 }
189 MbusError::ConnectionFailed => defmt::write!(f, "Connection failed"),
190 MbusError::ConnectionClosed => defmt::write!(f, "Connection closed"),
191 MbusError::BufferTooSmall => {
192 defmt::write!(f, "Buffer too small: The data was too large for the buffer")
193 }
194 MbusError::BufferLenMissmatch => {
195 defmt::write!(f, "Buffer length mismatch: Buffer length is not matching")
196 }
197 MbusError::SendFailed => defmt::write!(f, "Send failed: Failed to send data"),
198 MbusError::InvalidAddress => defmt::write!(f, "Invalid address"),
199 MbusError::TooManyRequests => {
200 defmt::write!(f, "Too many requests: Expected responses buffer is full")
201 }
202 MbusError::InvalidFunctionCode => defmt::write!(f, "Invalid function code"),
203 MbusError::NoRetriesLeft => defmt::write!(f, "No retries left for the transaction"),
204 MbusError::TooManyFileReadSubRequests => defmt::write!(
205 f,
206 "Too many sub-requests: Maximum of 35 sub-requests per PDU allowed"
207 ),
208 MbusError::FileReadPduOverflow => defmt::write!(
209 f,
210 "File read PDU overflow: Total length of file read sub-requests exceeds maximum allowed bytes per PDU"
211 ),
212 MbusError::UnexpectedResponse => defmt::write!(
213 f,
214 "Unexpected response: An unexpected response was received"
215 ),
216 MbusError::InvalidTransport => defmt::write!(
217 f,
218 "Invalid transport: The transport is invalid for the requested operation"
219 ),
220 MbusError::InvalidSlaveAddress => defmt::write!(
221 f,
222 "Invalid slave address: The provided slave address is invalid"
223 ),
224 MbusError::ChecksumError => defmt::write!(
225 f,
226 "Checksum error: The received frame has an invalid checksum"
227 ),
228 MbusError::InvalidConfiguration => defmt::write!(
229 f,
230 "Invalid configuration: The provided configuration is invalid"
231 ),
232 MbusError::InvalidNumOfExpectedRsps => defmt::write!(
233 f,
234 "Invalid number of expected responses: for serial transports the queue size N must be exactly 1"
235 ),
236 MbusError::InvalidDataLen => defmt::write!(
237 f,
238 "Invalid data length: The provided data length is invalid"
239 ),
240 MbusError::InvalidQuantity => {
241 defmt::write!(f, "Invalid quantity: The provided quantity is invalid")
242 }
243 MbusError::InvalidValue => {
244 defmt::write!(f, "Invalid value: The provided value is invalid")
245 }
246 MbusError::InvalidAndMask => {
247 defmt::write!(f, "Invalid AND mask: The provided AND mask is invalid")
248 }
249 MbusError::InvalidOrMask => {
250 defmt::write!(f, "Invalid OR mask: The provided OR mask is invalid")
251 }
252 MbusError::InvalidByteCount => {
253 defmt::write!(f, "Invalid byte count: The provided byte count is invalid")
254 }
255 MbusError::InvalidDeviceIdentification => defmt::write!(
256 f,
257 "Invalid device identification: The provided device identification is invalid"
258 ),
259 MbusError::InvalidDeviceIdCode => defmt::write!(
260 f,
261 "Invalid device ID code: The provided device ID code is invalid"
262 ),
263 MbusError::InvalidMeiType => {
264 defmt::write!(f, "Invalid MEI type: The provided MEI type is invalid")
265 }
266 MbusError::InvalidBroadcastAddress => defmt::write!(
267 f,
268 "Invalid broadcast address: The provided broadcast address (0) is invalid. Must use UnitIdOrSlaveAddr::new_broadcast_address() instead."
269 ),
270 MbusError::BroadcastNotAllowed => {
271 defmt::write!(f, "Broadcast not allowed: Broadcast not allowed")
272 }
273 MbusError::InvalidOffset => {
274 defmt::write!(f, "Invalid offset: The provided offset is invalid")
275 }
276 }
277 }
278}
279
280#[cfg(feature = "error-trait")]
281impl core::fmt::Display for MbusError {
282 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
283 match self {
284 MbusError::ParseError => write!(f, "Parse error"),
285 MbusError::BasicParseError => write!(f, "Basic parse error"),
286 MbusError::Timeout => write!(f, "Timeout"),
287 MbusError::ModbusException(code) => write!(f, "Modbus exception 0x{code:02X}"),
288 MbusError::IoError => write!(f, "I/O error"),
289 MbusError::Unexpected => write!(f, "Unexpected error"),
290 MbusError::ConnectionLost => write!(f, "Connection lost"),
291 MbusError::UnsupportedFunction(code) => write!(f, "Unsupported function 0x{code:02X}"),
292 MbusError::ReservedSubFunction(code) => write!(f, "Reserved sub-function 0x{code:04X}"),
293 MbusError::InvalidPduLength => write!(f, "Invalid PDU length"),
294 MbusError::InvalidAduLength => write!(f, "Invalid ADU length"),
295 MbusError::ConnectionFailed => write!(f, "Connection failed"),
296 MbusError::ConnectionClosed => write!(f, "Connection closed"),
297 MbusError::BufferTooSmall => write!(f, "Buffer too small"),
298 MbusError::BufferLenMissmatch => write!(f, "Buffer length mismatch"),
299 MbusError::SendFailed => write!(f, "Send failed"),
300 MbusError::InvalidAddress => write!(f, "Invalid address"),
301 MbusError::InvalidOffset => write!(f, "Invalid offset"),
302 MbusError::TooManyRequests => write!(f, "Too many requests"),
303 MbusError::InvalidFunctionCode => write!(f, "Invalid function code"),
304 MbusError::NoRetriesLeft => write!(f, "No retries left"),
305 MbusError::TooManyFileReadSubRequests => write!(f, "Too many file read sub-requests"),
306 MbusError::FileReadPduOverflow => write!(f, "File read PDU overflow"),
307 MbusError::UnexpectedResponse => write!(f, "Unexpected response"),
308 MbusError::InvalidTransport => write!(f, "Invalid transport"),
309 MbusError::InvalidSlaveAddress => write!(f, "Invalid slave address"),
310 MbusError::ChecksumError => write!(f, "Checksum error"),
311 MbusError::InvalidConfiguration => write!(f, "Invalid configuration"),
312 MbusError::InvalidNumOfExpectedRsps => {
313 write!(f, "Invalid number of expected responses")
314 }
315 MbusError::InvalidDataLen => write!(f, "Invalid data length"),
316 MbusError::InvalidQuantity => write!(f, "Invalid quantity"),
317 MbusError::InvalidValue => write!(f, "Invalid value"),
318 MbusError::InvalidAndMask => write!(f, "Invalid AND mask"),
319 MbusError::InvalidOrMask => write!(f, "Invalid OR mask"),
320 MbusError::InvalidByteCount => write!(f, "Invalid byte count"),
321 MbusError::InvalidDeviceIdentification => write!(f, "Invalid device identification"),
322 MbusError::InvalidDeviceIdCode => write!(f, "Invalid device ID code"),
323 MbusError::InvalidMeiType => write!(f, "Invalid MEI type"),
324 MbusError::InvalidBroadcastAddress => write!(f, "Invalid broadcast address"),
325 MbusError::BroadcastNotAllowed => write!(f, "Broadcast not allowed"),
326 }
327 }
328}
329
330#[cfg(feature = "error-trait")]
331impl core::error::Error for MbusError {}