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