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