1*9695bd28SJagpal Singh Gill #include "modbus/modbus_commands.hpp"
2*9695bd28SJagpal Singh Gill #include "modbus/modbus_exception.hpp"
3*9695bd28SJagpal Singh Gill
4*9695bd28SJagpal Singh Gill #include <cstring>
5*9695bd28SJagpal Singh Gill
6*9695bd28SJagpal Singh Gill #include <gmock/gmock.h>
7*9695bd28SJagpal Singh Gill #include <gtest/gtest.h>
8*9695bd28SJagpal Singh Gill
9*9695bd28SJagpal Singh Gill namespace RTUIntf = phosphor::modbus::rtu;
10*9695bd28SJagpal Singh Gill
11*9695bd28SJagpal Singh Gill class ReadHoldingRegistersResponseTest :
12*9695bd28SJagpal Singh Gill public RTUIntf::ReadHoldingRegistersResponse
13*9695bd28SJagpal Singh Gill {
14*9695bd28SJagpal Singh Gill public:
ReadHoldingRegistersResponseTest(uint8_t address,std::vector<uint16_t> & registers)15*9695bd28SJagpal Singh Gill ReadHoldingRegistersResponseTest(uint8_t address,
16*9695bd28SJagpal Singh Gill std::vector<uint16_t>& registers) :
17*9695bd28SJagpal Singh Gill RTUIntf::ReadHoldingRegistersResponse(address, registers)
18*9695bd28SJagpal Singh Gill {}
19*9695bd28SJagpal Singh Gill
20*9695bd28SJagpal Singh Gill template <std::size_t Length>
operator =(const std::array<uint8_t,Length> & expectedMessage)21*9695bd28SJagpal Singh Gill ReadHoldingRegistersResponseTest& operator=(
22*9695bd28SJagpal Singh Gill const std::array<uint8_t, Length>& expectedMessage)
23*9695bd28SJagpal Singh Gill {
24*9695bd28SJagpal Singh Gill len = Length;
25*9695bd28SJagpal Singh Gill std::copy(expectedMessage.begin(), expectedMessage.end(), raw.begin());
26*9695bd28SJagpal Singh Gill return *this;
27*9695bd28SJagpal Singh Gill }
28*9695bd28SJagpal Singh Gill };
29*9695bd28SJagpal Singh Gill
30*9695bd28SJagpal Singh Gill class ModbusCommandTest : public ::testing::Test
31*9695bd28SJagpal Singh Gill {
32*9695bd28SJagpal Singh Gill public:
33*9695bd28SJagpal Singh Gill ModbusCommandTest() = default;
34*9695bd28SJagpal Singh Gill
35*9695bd28SJagpal Singh Gill static constexpr auto failureMessageLength = 11;
36*9695bd28SJagpal Singh Gill
37*9695bd28SJagpal Singh Gill template <typename ExceptionType, std::size_t Length>
TestReadHoldingRegisterResponseFailure(const std::array<uint8_t,Length> & expectedMessage)38*9695bd28SJagpal Singh Gill void TestReadHoldingRegisterResponseFailure(
39*9695bd28SJagpal Singh Gill const std::array<uint8_t, Length>& expectedMessage)
40*9695bd28SJagpal Singh Gill {
41*9695bd28SJagpal Singh Gill constexpr uint8_t expectedAddress = 0xa;
42*9695bd28SJagpal Singh Gill constexpr size_t expectedRegisterSize = 3;
43*9695bd28SJagpal Singh Gill std::vector<uint16_t> registers(expectedRegisterSize);
44*9695bd28SJagpal Singh Gill ReadHoldingRegistersResponseTest response(expectedAddress, registers);
45*9695bd28SJagpal Singh Gill response = expectedMessage;
46*9695bd28SJagpal Singh Gill
47*9695bd28SJagpal Singh Gill EXPECT_THROW(response.decode(), ExceptionType);
48*9695bd28SJagpal Singh Gill }
49*9695bd28SJagpal Singh Gill };
50*9695bd28SJagpal Singh Gill
TEST_F(ModbusCommandTest,TestReadHoldingRegistersRequestSucess)51*9695bd28SJagpal Singh Gill TEST_F(ModbusCommandTest, TestReadHoldingRegistersRequestSucess)
52*9695bd28SJagpal Singh Gill {
53*9695bd28SJagpal Singh Gill constexpr size_t expectedLength = 8;
54*9695bd28SJagpal Singh Gill constexpr uint8_t expectedAddress = 0x1;
55*9695bd28SJagpal Singh Gill constexpr std::array<uint8_t, expectedLength> expectedMessage = {
56*9695bd28SJagpal Singh Gill expectedAddress, // addr(1) = 0x01
57*9695bd28SJagpal Singh Gill 0x03, // func(1) = 0x03
58*9695bd28SJagpal Singh Gill 0x12, // reg_off(2) = 0x1234
59*9695bd28SJagpal Singh Gill 0x34,
60*9695bd28SJagpal Singh Gill 0x00, // reg_cnt(2) = 0x0020,
61*9695bd28SJagpal Singh Gill 0x20,
62*9695bd28SJagpal Singh Gill 0x00, // crc(2) (Pre-computed) = 0xa4
63*9695bd28SJagpal Singh Gill 0xa4};
64*9695bd28SJagpal Singh Gill
65*9695bd28SJagpal Singh Gill RTUIntf::ReadHoldingRegistersRequest request(expectedAddress, 0x1234, 0x20);
66*9695bd28SJagpal Singh Gill request.encode();
67*9695bd28SJagpal Singh Gill
68*9695bd28SJagpal Singh Gill std::array<uint8_t, expectedLength> actualMessage;
69*9695bd28SJagpal Singh Gill std::memcpy(actualMessage.data(), request.raw.data(), expectedLength);
70*9695bd28SJagpal Singh Gill
71*9695bd28SJagpal Singh Gill EXPECT_EQ(actualMessage, expectedMessage);
72*9695bd28SJagpal Singh Gill EXPECT_EQ(request.address, expectedAddress);
73*9695bd28SJagpal Singh Gill }
74*9695bd28SJagpal Singh Gill
TEST_F(ModbusCommandTest,TestReadHoldingRegistersResponseSucess)75*9695bd28SJagpal Singh Gill TEST_F(ModbusCommandTest, TestReadHoldingRegistersResponseSucess)
76*9695bd28SJagpal Singh Gill {
77*9695bd28SJagpal Singh Gill constexpr size_t expectedLength = 11;
78*9695bd28SJagpal Singh Gill constexpr uint8_t expectedAddress = 0xa;
79*9695bd28SJagpal Singh Gill constexpr size_t expectedRegisterSize = 3;
80*9695bd28SJagpal Singh Gill constexpr std::array<uint8_t, expectedLength> expectedMessage = {
81*9695bd28SJagpal Singh Gill expectedAddress, // addr(1) = 0x0a
82*9695bd28SJagpal Singh Gill 0x03, // func(1) = 0x03
83*9695bd28SJagpal Singh Gill 0x06, // bytes(1) = 0x06
84*9695bd28SJagpal Singh Gill 0x11, // regs(3*2) = 0x1122, 0x3344, 0x5566
85*9695bd28SJagpal Singh Gill 0x22,
86*9695bd28SJagpal Singh Gill 0x33,
87*9695bd28SJagpal Singh Gill 0x44,
88*9695bd28SJagpal Singh Gill 0x55,
89*9695bd28SJagpal Singh Gill 0x66,
90*9695bd28SJagpal Singh Gill 0x59, // crc(2) = 0x5928 (pre-computed)
91*9695bd28SJagpal Singh Gill 0x28};
92*9695bd28SJagpal Singh Gill const std::vector<uint16_t> expectedRegisters{0x1122, 0x3344, 0x5566};
93*9695bd28SJagpal Singh Gill std::vector<uint16_t> registers(expectedRegisterSize);
94*9695bd28SJagpal Singh Gill
95*9695bd28SJagpal Singh Gill RTUIntf::ReadHoldingRegistersResponse response(expectedAddress, registers);
96*9695bd28SJagpal Singh Gill EXPECT_EQ(response.len, expectedLength);
97*9695bd28SJagpal Singh Gill
98*9695bd28SJagpal Singh Gill std::copy(expectedMessage.begin(), expectedMessage.end(),
99*9695bd28SJagpal Singh Gill response.raw.begin());
100*9695bd28SJagpal Singh Gill
101*9695bd28SJagpal Singh Gill EXPECT_EQ(response.len, expectedLength);
102*9695bd28SJagpal Singh Gill response.decode();
103*9695bd28SJagpal Singh Gill EXPECT_EQ(registers, expectedRegisters);
104*9695bd28SJagpal Singh Gill }
105*9695bd28SJagpal Singh Gill
TEST_F(ModbusCommandTest,TestReadHoldingRegistersResponseError)106*9695bd28SJagpal Singh Gill TEST_F(ModbusCommandTest, TestReadHoldingRegistersResponseError)
107*9695bd28SJagpal Singh Gill {
108*9695bd28SJagpal Singh Gill constexpr std::array<uint8_t, 5> expectedMessage = {
109*9695bd28SJagpal Singh Gill 0xa, // addr(1) = 0x0a
110*9695bd28SJagpal Singh Gill 0x83, // func(1) = 0x83
111*9695bd28SJagpal Singh Gill 0x03, // exception code(1) = 0x03
112*9695bd28SJagpal Singh Gill 0x70, // crc(2) = 0x70f3 (pre-computed)
113*9695bd28SJagpal Singh Gill 0xf3};
114*9695bd28SJagpal Singh Gill
115*9695bd28SJagpal Singh Gill TestReadHoldingRegisterResponseFailure<RTUIntf::ModbusException>(
116*9695bd28SJagpal Singh Gill expectedMessage);
117*9695bd28SJagpal Singh Gill }
118*9695bd28SJagpal Singh Gill
TEST_F(ModbusCommandTest,TestReadHoldingRegistersResponseBadAddress)119*9695bd28SJagpal Singh Gill TEST_F(ModbusCommandTest, TestReadHoldingRegistersResponseBadAddress)
120*9695bd28SJagpal Singh Gill {
121*9695bd28SJagpal Singh Gill constexpr std::array<uint8_t, failureMessageLength> expectedMessage = {
122*9695bd28SJagpal Singh Gill 0x1, // Bad address(1), should be 0x0a
123*9695bd28SJagpal Singh Gill 0x03, // func(1) = 0x03
124*9695bd28SJagpal Singh Gill 0x06, // bytes(1) = 0x06
125*9695bd28SJagpal Singh Gill 0x11, // regs(3*2) = 0x1122, 0x3344, 0x5566
126*9695bd28SJagpal Singh Gill 0x22, 0x33, 0x44, 0x55, 0x66,
127*9695bd28SJagpal Singh Gill 0x2a, // crc(2) = 0x2a18 (pre-computed)
128*9695bd28SJagpal Singh Gill 0x18};
129*9695bd28SJagpal Singh Gill
130*9695bd28SJagpal Singh Gill TestReadHoldingRegisterResponseFailure<RTUIntf::ModbusBadResponseException>(
131*9695bd28SJagpal Singh Gill expectedMessage);
132*9695bd28SJagpal Singh Gill }
133*9695bd28SJagpal Singh Gill
TEST_F(ModbusCommandTest,TestReadHoldingRegistersResponseBadCRC)134*9695bd28SJagpal Singh Gill TEST_F(ModbusCommandTest, TestReadHoldingRegistersResponseBadCRC)
135*9695bd28SJagpal Singh Gill {
136*9695bd28SJagpal Singh Gill constexpr std::array<uint8_t, failureMessageLength> expectedMessage = {
137*9695bd28SJagpal Singh Gill 0xa, // addr(1) = 0x0a
138*9695bd28SJagpal Singh Gill 0x03, // func(1) = 0x03
139*9695bd28SJagpal Singh Gill 0x06, // bytes(1) = 0x06
140*9695bd28SJagpal Singh Gill 0x11, // regs(3*2) = 0x1122, 0x3344, 0x5566
141*9695bd28SJagpal Singh Gill 0x22, 0x33, 0x44, 0x55, 0x66,
142*9695bd28SJagpal Singh Gill 0x59, // Bad crc(2), should be 0x5928
143*9695bd28SJagpal Singh Gill 0x29};
144*9695bd28SJagpal Singh Gill
145*9695bd28SJagpal Singh Gill TestReadHoldingRegisterResponseFailure<RTUIntf::ModbusCRCException>(
146*9695bd28SJagpal Singh Gill expectedMessage);
147*9695bd28SJagpal Singh Gill }
148*9695bd28SJagpal Singh Gill
TEST_F(ModbusCommandTest,TestReadHoldingRegistersResponseBadFunctionCode)149*9695bd28SJagpal Singh Gill TEST_F(ModbusCommandTest, TestReadHoldingRegistersResponseBadFunctionCode)
150*9695bd28SJagpal Singh Gill {
151*9695bd28SJagpal Singh Gill constexpr std::array<uint8_t, failureMessageLength> expectedMessage = {
152*9695bd28SJagpal Singh Gill 0xa, // addr(1) = 0x0a
153*9695bd28SJagpal Singh Gill 0x04, // Bad function code(1), should be 0x03
154*9695bd28SJagpal Singh Gill 0x06, // bytes(1) = 0x06
155*9695bd28SJagpal Singh Gill 0x11, // regs(3*2) = 0x1122, 0x3344, 0x5566
156*9695bd28SJagpal Singh Gill 0x22, 0x33, 0x44, 0x55, 0x66,
157*9695bd28SJagpal Singh Gill 0x18, // crc(2) = 0x18ce (pre-computed)
158*9695bd28SJagpal Singh Gill 0xce};
159*9695bd28SJagpal Singh Gill
160*9695bd28SJagpal Singh Gill TestReadHoldingRegisterResponseFailure<RTUIntf::ModbusBadResponseException>(
161*9695bd28SJagpal Singh Gill expectedMessage);
162*9695bd28SJagpal Singh Gill }
163*9695bd28SJagpal Singh Gill
TEST_F(ModbusCommandTest,TestReadHoldingRegistersResponseBadByteCount)164*9695bd28SJagpal Singh Gill TEST_F(ModbusCommandTest, TestReadHoldingRegistersResponseBadByteCount)
165*9695bd28SJagpal Singh Gill {
166*9695bd28SJagpal Singh Gill constexpr std::array<uint8_t, failureMessageLength> expectedMessage = {
167*9695bd28SJagpal Singh Gill 0xa, // addr(1) = 0x0a
168*9695bd28SJagpal Singh Gill 0x03, // func(1) = 0x03
169*9695bd28SJagpal Singh Gill 0x04, // Bad bytes(1), should be 0x06
170*9695bd28SJagpal Singh Gill 0x11, // regs(3*2) = 0x1122, 0x3344, 0x5566
171*9695bd28SJagpal Singh Gill 0x22, 0x33, 0x44, 0x55, 0x66,
172*9695bd28SJagpal Singh Gill 0x7a, // crc(2) = 0x7ae8 (pre-computed)
173*9695bd28SJagpal Singh Gill 0xe8};
174*9695bd28SJagpal Singh Gill
175*9695bd28SJagpal Singh Gill TestReadHoldingRegisterResponseFailure<RTUIntf::ModbusBadResponseException>(
176*9695bd28SJagpal Singh Gill expectedMessage);
177*9695bd28SJagpal Singh Gill }
178