modbus_relay/errors/kinds/
protocol_error.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum ProtocolErrorKind {
3    InvalidFunction,
4    InvalidDataAddress,
5    InvalidDataValue,
6    ServerFailure,
7    Acknowledge,
8    ServerBusy,
9    GatewayPathUnavailable,
10    GatewayTargetFailedToRespond,
11    InvalidProtocolId,
12    InvalidTransactionId,
13    InvalidUnitId,
14    InvalidPdu,
15}
16
17impl std::fmt::Display for ProtocolErrorKind {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        match self {
20            Self::InvalidFunction => write!(f, "Invalid function code"),
21            Self::InvalidDataAddress => write!(f, "Invalid data address"),
22            Self::InvalidDataValue => write!(f, "Invalid data value"),
23            Self::ServerFailure => write!(f, "Server device failure"),
24            Self::Acknowledge => write!(f, "Acknowledge"),
25            Self::ServerBusy => write!(f, "Server device busy"),
26            Self::GatewayPathUnavailable => write!(f, "Gateway path unavailable"),
27            Self::GatewayTargetFailedToRespond => {
28                write!(f, "Gateway target device failed to respond")
29            }
30            Self::InvalidProtocolId => write!(f, "Invalid protocol ID"),
31            Self::InvalidTransactionId => write!(f, "Invalid transaction ID"),
32            Self::InvalidUnitId => write!(f, "Invalid unit ID"),
33            Self::InvalidPdu => write!(f, "Invalid PDU format"),
34        }
35    }
36}
37
38impl ProtocolErrorKind {
39    pub fn to_exception_code(&self) -> u8 {
40        match self {
41            Self::InvalidFunction => 0x01,
42            Self::InvalidDataAddress => 0x02,
43            Self::InvalidDataValue => 0x03,
44            Self::ServerFailure => 0x04,
45            Self::Acknowledge => 0x05,
46            Self::ServerBusy => 0x06,
47            Self::GatewayPathUnavailable => 0x0A,
48            Self::GatewayTargetFailedToRespond => 0x0B,
49            _ => 0x04, // Map unknown errors to server failure
50        }
51    }
52
53    pub fn from_exception_code(code: u8) -> Option<Self> {
54        match code {
55            0x01 => Some(Self::InvalidFunction),
56            0x02 => Some(Self::InvalidDataAddress),
57            0x03 => Some(Self::InvalidDataValue),
58            0x04 => Some(Self::ServerFailure),
59            0x05 => Some(Self::Acknowledge),
60            0x06 => Some(Self::ServerBusy),
61            0x0A => Some(Self::GatewayPathUnavailable),
62            0x0B => Some(Self::GatewayTargetFailedToRespond),
63            _ => None,
64        }
65    }
66}