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