[modbus] Frame accessors, PDU-relative lengths, and span-based send_pdu (#17846)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bonne Eggleston
2026-07-25 03:09:05 +00:00
committed by GitHub
co-authored by Claude Fable 5
parent 58385bebff
commit eaa79b3696
10 changed files with 366 additions and 81 deletions
@@ -94,8 +94,9 @@ TEST(ModbusClientHubNoResponse, RetryRequeuesWaitingFrame) {
EXPECT_EQ(requeued.device, &device);
// address + PDU + CRC
ASSERT_EQ(requeued.frame.size(), sizeof(READ_PDU) + 3);
EXPECT_EQ(requeued.frame.data.data()[0], 0x02);
EXPECT_EQ(0, memcmp(requeued.frame.data.data() + 1, READ_PDU, sizeof(READ_PDU)));
EXPECT_EQ(requeued.frame.address(), 0x02);
ASSERT_EQ(requeued.frame.pdu().size(), sizeof(READ_PDU));
EXPECT_EQ(0, memcmp(requeued.frame.pdu().data(), READ_PDU, sizeof(READ_PDU)));
}
// A device that declines the retry has the frame dropped.
@@ -208,4 +209,15 @@ TEST(ModbusClientHubCompat, LegacyCallbackNamesStillForward) {
EXPECT_EQ(device.legacy_not_sent_, 1);
}
// The send_pdu() capacity bound: a PDU larger than MAX_PDU_SIZE would build a frame past the RTU
// 256-byte limit, so it is refused up front and signalled like any other failed send.
TEST(ModbusClientHub, OversizedPduIsRefusedWithNotSent) {
NoResponseProbeHub hub;
LegacyNameDevice device(&hub, 0x02);
std::vector<uint8_t> big(MAX_PDU_SIZE + 1, 0x41);
device.send_pdu(big);
EXPECT_EQ(device.legacy_not_sent_, 1); // on_not_sent, observed via the legacy forward
EXPECT_TRUE(hub.tx_buffer_empty());
}
} // namespace esphome::modbus::testing