Improve repeater alerts and delivery reliability

This commit is contained in:
mikecarper committed 2026-07-13 09:54:16 -07:00
1 parent da00a00436
commit 5a2aa592ea
13 files changed
+338 -23

No files matched your search

@@ -9,7 +9,7 @@ using namespace mesh;
// header selects ROUTE_TYPE_FLOOD so isRouteDirect() returns false.
static Packet makeFloodPacket(uint8_t seed) {
Packet p;
p.header = ROUTE_TYPE_FLOOD | (PAYLOAD_TYPE_ACK << PH_TYPE_SHIFT);
p.header = ROUTE_TYPE_FLOOD | (PAYLOAD_TYPE_RAW_CUSTOM << PH_TYPE_SHIFT);
p.payload[0] = seed;
p.payload_len = 1;
p.path_len = 0;
@@ -18,13 +18,23 @@ static Packet makeFloodPacket(uint8_t seed) {
static Packet makeDirectPacket(uint8_t seed) {
Packet p;
p.header = ROUTE_TYPE_DIRECT | (PAYLOAD_TYPE_ACK << PH_TYPE_SHIFT);
p.header = ROUTE_TYPE_DIRECT | (PAYLOAD_TYPE_RAW_CUSTOM << PH_TYPE_SHIFT);
p.payload[0] = seed;
p.payload_len = 1;
p.path_len = 0;
return p;
}
static Packet makeAckPacket(uint32_t crc, bool direct = true) {
Packet p;
p.header = (direct ? ROUTE_TYPE_DIRECT : ROUTE_TYPE_FLOOD)
| (PAYLOAD_TYPE_ACK << PH_TYPE_SHIFT);
memcpy(p.payload, &crc, sizeof(crc));
p.payload_len = sizeof(crc);
p.path_len = 0;
return p;
}
// ── wasSeen: pure query ───────────────────────────────────────────────────────
TEST(SimpleMeshTables, WasSeen_ReturnsFalseForUnseen) {
@@ -99,6 +109,55 @@ TEST(SimpleMeshTables, Clear_RemovesSeenPacket) {
EXPECT_FALSE(t.wasSeen(&p));
}
TEST(SimpleMeshTables, AckCrcZeroIsAValidUnseenValue) {
SimpleMeshTables t;
Packet p = makeAckPacket(0);
EXPECT_FALSE(t.wasSeen(&p));
t.markSeen(&p);
EXPECT_TRUE(t.wasSeen(&p));
}
TEST(SimpleMeshTables, AckDedupUsesCrcAndIgnoresOptionalSuffix) {
SimpleMeshTables t;
Packet first = makeAckPacket(0xC3B2A141);
Packet repeated = first;
first.payload[4] = 0x10;
first.payload[5] = 0x20;
first.payload_len = 6;
repeated.payload[4] = 0x99;
repeated.payload[5] = 0x88;
repeated.payload_len = 6;
t.markSeen(&first);
EXPECT_TRUE(t.wasSeen(&repeated));
}
TEST(SimpleMeshTables, AckTrafficDoesNotEvictGeneralPacketHashes) {
SimpleMeshTables t;
Packet retained = makeFloodPacket(0x5A);
t.markSeen(&retained);
for (int i = 0; i < MAX_PACKET_HASHES + 1; i++) {
Packet ack = makeAckPacket((uint32_t)i);
t.markSeen(&ack);
}
EXPECT_TRUE(t.wasSeen(&retained));
}
TEST(SimpleMeshTables, ShortAckPayloadFallsBackToSafeGeneralDedup) {
SimpleMeshTables t;
Packet p = makeAckPacket(0x7B);
p.payload_len = 1;
EXPECT_FALSE(t.wasSeen(&p));
t.markSeen(&p);
EXPECT_TRUE(t.wasSeen(&p));
t.clear(&p);
EXPECT_FALSE(t.wasSeen(&p));
}
TEST(RouteHashPrefixes, MatchesSharedOneTwoOrThreeBytes) {
const uint8_t configured[] = {0x86, 0x0c, 0xca};
const uint8_t one_byte[] = {0x86};
@@ -22,6 +22,36 @@ TEST(RxReservePacketManager, RejectedOutboundRemainsOwnedByCaller) {
EXPECT_EQ(manager.getFreeCount(), 8);
}
TEST(RxReservePacketManager, PeekMatchesDequeueWithoutRemovingPacket) {
RxReservePacketManager manager(8, 4);
mesh::Packet* low = manager.allocNew();
mesh::Packet* high = manager.allocNew();
ASSERT_NE(low, nullptr);
ASSERT_NE(high, nullptr);
ASSERT_TRUE(manager.queueOutbound(low, 2, 100));
ASSERT_TRUE(manager.queueOutbound(high, 0, 100));
EXPECT_EQ(high, manager.peekNextOutbound(100));
EXPECT_EQ(2, manager.getOutboundTotal());
EXPECT_EQ(high, manager.getNextOutbound(100));
manager.free(high);
EXPECT_EQ(low, manager.getNextOutbound(100));
manager.free(low);
}
TEST(RxReservePacketManager, PeekExpiresStalePacketBeforeChannelSelection) {
RxReservePacketManager manager(8, 4);
mesh::Packet* stale = manager.allocNew();
ASSERT_NE(stale, nullptr);
ASSERT_TRUE(manager.queueOutbound(stale, 0, 0));
ASSERT_EQ(7, manager.getFreeCount());
EXPECT_EQ(nullptr, manager.peekNextOutbound(30001));
EXPECT_EQ(0, manager.getOutboundTotal());
EXPECT_EQ(8, manager.getFreeCount());
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();