blob: 64d541b1c89f38be398faded4094f61b2228ac02 [file] [log] [blame]
Jagpal Singh Gill9695bd22025-10-01 14:38:17 -07001#include "modbus_commands.hpp"
2
3#include "modbus_exception.hpp"
4
5#include <phosphor-logging/lg2.hpp>
6
7namespace phosphor::modbus::rtu
8{
9
10ReadHoldingRegistersRequest::ReadHoldingRegistersRequest(
11 uint8_t deviceAddress, uint16_t registerOffset, uint16_t registerCount) :
12 deviceAddress(deviceAddress), registerOffset(registerOffset),
13 registerCount(registerCount)
14{}
15
16auto ReadHoldingRegistersRequest::encode() -> void
17{
18 *this << deviceAddress << commandCode << registerOffset << registerCount;
19 appendCRC();
20}
21
22ReadHoldingRegistersResponse::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
34auto 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
49auto 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