| Jagpal Singh Gill | 9695bd2 | 2025-10-01 14:38:17 -0700 | [diff] [blame^] | 1 | #include "modbus_commands.hpp" |
| 2 | |
| 3 | #include "modbus_exception.hpp" |
| 4 | |
| 5 | #include <phosphor-logging/lg2.hpp> |
| 6 | |
| 7 | namespace phosphor::modbus::rtu |
| 8 | { |
| 9 | |
| 10 | ReadHoldingRegistersRequest::ReadHoldingRegistersRequest( |
| 11 | uint8_t deviceAddress, uint16_t registerOffset, uint16_t registerCount) : |
| 12 | deviceAddress(deviceAddress), registerOffset(registerOffset), |
| 13 | registerCount(registerCount) |
| 14 | {} |
| 15 | |
| 16 | auto ReadHoldingRegistersRequest::encode() -> void |
| 17 | { |
| 18 | *this << deviceAddress << commandCode << registerOffset << registerCount; |
| 19 | appendCRC(); |
| 20 | } |
| 21 | |
| 22 | ReadHoldingRegistersResponse::ReadHoldingRegistersResponse( |
| 23 | uint8_t deviceAddress, std::vector<uint16_t>& registers) : |
| 24 | expectedDeviceAddress(deviceAddress), registers(registers) |
| 25 | { |
| 26 | if (registers.empty()) |
| 27 | { |
| 28 | throw std::underflow_error("Response registers are empty"); |
| 29 | } |
| 30 | // addr(1), func(1), bytecount(1), <2 * count regs>, crc(2) |
| 31 | len = 5 + (2 * registers.size()); |
| 32 | } |
| 33 | |
| 34 | auto Response::decode() -> void |
| 35 | { |
| 36 | validate(); |
| 37 | |
| 38 | // Error response is structured as: |
| 39 | // addr(1), errorFunctionCode(1), exceptionCode(1) |
| 40 | // Where errorFunctionCode is the response function with |
| 41 | // MSB set to 1, hence mask of 0x80. |
| 42 | bool isError = (len == 3 && (functionCode & 0x80) != 0); |
| 43 | if (isError) |
| 44 | { |
| 45 | throw ModbusException(raw[2]); |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | auto ReadHoldingRegistersResponse::decode() -> void |
| 50 | { |
| 51 | Response::decode(); |
| 52 | uint8_t byteCount, responseCode, deviceAddress; |
| 53 | *this >> registers >> byteCount >> responseCode >> deviceAddress; |
| 54 | verifyValue("Device Address", deviceAddress, expectedDeviceAddress); |
| 55 | verifyValue("Response Function Code", responseCode, expectedCommandCode); |
| 56 | verifyValue("Byte Count", byteCount, registers.size() * 2); |
| 57 | } |
| 58 | |
| 59 | } // namespace phosphor::modbus::rtu |