xref: /openbmc/phosphor-modbus/rtu/modbus/modbus_exception.hpp (revision 9695bd284570b51677c11529103929c8e51da6b6)
1*9695bd28SJagpal Singh Gill #pragma once
2*9695bd28SJagpal Singh Gill 
3*9695bd28SJagpal Singh Gill #include <format>
4*9695bd28SJagpal Singh Gill #include <stdexcept>
5*9695bd28SJagpal Singh Gill #include <string>
6*9695bd28SJagpal Singh Gill 
7*9695bd28SJagpal Singh Gill namespace phosphor::modbus::rtu
8*9695bd28SJagpal Singh Gill {
9*9695bd28SJagpal Singh Gill 
10*9695bd28SJagpal Singh Gill enum class ModbusExceptionCode
11*9695bd28SJagpal Singh Gill {
12*9695bd28SJagpal Singh Gill     // The Modbus function code in the request is not supported or is an invalid
13*9695bd28SJagpal Singh Gill     // action for the server.
14*9695bd28SJagpal Singh Gill     illegalFunctionCode = 1,
15*9695bd28SJagpal Singh Gill 
16*9695bd28SJagpal Singh Gill     // The requested data address is not valid or authorized for the server.
17*9695bd28SJagpal Singh Gill     illegalDataAddress = 2,
18*9695bd28SJagpal Singh Gill 
19*9695bd28SJagpal Singh Gill     // The value provided in the request is not an allowable value for the
20*9695bd28SJagpal Singh Gill     // server, or the data field is structured incorrectly.
21*9695bd28SJagpal Singh Gill     illegalDataValue = 3,
22*9695bd28SJagpal Singh Gill 
23*9695bd28SJagpal Singh Gill     // The server encountered an internal error and cannot perform the requested
24*9695bd28SJagpal Singh Gill     // operation.
25*9695bd28SJagpal Singh Gill     slaveDeviceFailure = 4,
26*9695bd28SJagpal Singh Gill 
27*9695bd28SJagpal Singh Gill     //  The server has accepted the request but needs more time to process it.
28*9695bd28SJagpal Singh Gill     acknowledge = 5,
29*9695bd28SJagpal Singh Gill 
30*9695bd28SJagpal Singh Gill     // The server is currently busy and cannot respond to the request.
31*9695bd28SJagpal Singh Gill     slaveDeviceBusy = 6,
32*9695bd28SJagpal Singh Gill 
33*9695bd28SJagpal Singh Gill     // The server cannot perform the program function received in the query.
34*9695bd28SJagpal Singh Gill     // This code is returned for an unsuccessful programming request using
35*9695bd28SJagpal Singh Gill     // function code 13 or 14 decimal. The client should request diagnostic or
36*9695bd28SJagpal Singh Gill     // error information from the server.
37*9695bd28SJagpal Singh Gill     negativeAcknowledge = 7,
38*9695bd28SJagpal Singh Gill 
39*9695bd28SJagpal Singh Gill     // The server attempted to read extended memory, but detected a parity error
40*9695bd28SJagpal Singh Gill     // in the memory. The client can retry the request, but service may be
41*9695bd28SJagpal Singh Gill     // required on the server device.
42*9695bd28SJagpal Singh Gill     memoryParityError = 8,
43*9695bd28SJagpal Singh Gill     unknownError = 255,
44*9695bd28SJagpal Singh Gill };
45*9695bd28SJagpal Singh Gill 
46*9695bd28SJagpal Singh Gill class ModbusException : public std::runtime_error
47*9695bd28SJagpal Singh Gill {
48*9695bd28SJagpal Singh Gill   public:
49*9695bd28SJagpal Singh Gill     const ModbusExceptionCode code;
50*9695bd28SJagpal Singh Gill 
ModbusException(uint8_t code,const std::string & message="")51*9695bd28SJagpal Singh Gill     explicit ModbusException(uint8_t code, const std::string& message = "") :
52*9695bd28SJagpal Singh Gill         std::runtime_error(std::format(
53*9695bd28SJagpal Singh Gill             "{} ({})", toString(static_cast<ModbusExceptionCode>(code)),
54*9695bd28SJagpal Singh Gill             message)),
55*9695bd28SJagpal Singh Gill         code(static_cast<ModbusExceptionCode>(code))
56*9695bd28SJagpal Singh Gill     {}
57*9695bd28SJagpal Singh Gill 
toString(ModbusExceptionCode code)58*9695bd28SJagpal Singh Gill     static auto toString(ModbusExceptionCode code) -> std::string
59*9695bd28SJagpal Singh Gill     {
60*9695bd28SJagpal Singh Gill         switch (code)
61*9695bd28SJagpal Singh Gill         {
62*9695bd28SJagpal Singh Gill             case ModbusExceptionCode::illegalFunctionCode:
63*9695bd28SJagpal Singh Gill                 return "Illegal Function Code";
64*9695bd28SJagpal Singh Gill             case ModbusExceptionCode::illegalDataAddress:
65*9695bd28SJagpal Singh Gill                 return "Illegal Data Address";
66*9695bd28SJagpal Singh Gill             case ModbusExceptionCode::illegalDataValue:
67*9695bd28SJagpal Singh Gill                 return "Illegal Data Value";
68*9695bd28SJagpal Singh Gill             case ModbusExceptionCode::slaveDeviceFailure:
69*9695bd28SJagpal Singh Gill                 return "Slave Device Failure";
70*9695bd28SJagpal Singh Gill             case ModbusExceptionCode::acknowledge:
71*9695bd28SJagpal Singh Gill                 return "Acknowledge";
72*9695bd28SJagpal Singh Gill             case ModbusExceptionCode::slaveDeviceBusy:
73*9695bd28SJagpal Singh Gill                 return "Slave Device Busy";
74*9695bd28SJagpal Singh Gill             case ModbusExceptionCode::negativeAcknowledge:
75*9695bd28SJagpal Singh Gill                 return "Negative Acknowledge";
76*9695bd28SJagpal Singh Gill             case ModbusExceptionCode::memoryParityError:
77*9695bd28SJagpal Singh Gill                 return "Memory Parity Error";
78*9695bd28SJagpal Singh Gill             default:
79*9695bd28SJagpal Singh Gill                 return "Unknown Modbus Error";
80*9695bd28SJagpal Singh Gill         }
81*9695bd28SJagpal Singh Gill     }
82*9695bd28SJagpal Singh Gill };
83*9695bd28SJagpal Singh Gill 
84*9695bd28SJagpal Singh Gill class ModbusCRCException : public std::runtime_error
85*9695bd28SJagpal Singh Gill {
86*9695bd28SJagpal Singh Gill   public:
ModbusCRCException(uint16_t expectedCRC,uint16_t crc)87*9695bd28SJagpal Singh Gill     explicit ModbusCRCException(uint16_t expectedCRC, uint16_t crc) :
88*9695bd28SJagpal Singh Gill         std::runtime_error(
89*9695bd28SJagpal Singh Gill             "CRC mismatch, expected: " + std::to_string(expectedCRC) +
90*9695bd28SJagpal Singh Gill             " received: " + std::to_string(crc))
91*9695bd28SJagpal Singh Gill     {}
92*9695bd28SJagpal Singh Gill };
93*9695bd28SJagpal Singh Gill 
94*9695bd28SJagpal Singh Gill class ModbusBadResponseException : public std::runtime_error
95*9695bd28SJagpal Singh Gill {
96*9695bd28SJagpal Singh Gill   public:
ModbusBadResponseException(const std::string & fieldName,uint32_t expectedValue,uint32_t currentValue)97*9695bd28SJagpal Singh Gill     explicit ModbusBadResponseException(const std::string& fieldName,
98*9695bd28SJagpal Singh Gill                                         uint32_t expectedValue,
99*9695bd28SJagpal Singh Gill                                         uint32_t currentValue) :
100*9695bd28SJagpal Singh Gill         std::runtime_error(
101*9695bd28SJagpal Singh Gill             "Value mismatch for " + fieldName +
102*9695bd28SJagpal Singh Gill             ", expected value: " + std::to_string(expectedValue) +
103*9695bd28SJagpal Singh Gill             ", current value: " + std::to_string(currentValue))
104*9695bd28SJagpal Singh Gill     {}
105*9695bd28SJagpal Singh Gill };
106*9695bd28SJagpal Singh Gill 
107*9695bd28SJagpal Singh Gill } // namespace phosphor::modbus::rtu
108