From d1d64dc6121d91b96c82010383ceea1bce83f43b Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Thu, 18 Jun 2026 23:20:23 +0200 Subject: [PATCH] feat(mesh): track actually-forwarded packet count, show in Diagnostics allowPacketForward() only gates permission; the packet can still be dropped afterward (hasSeen(), path-size limit). Add Mesh::n_forwarded, incremented at the 3 ACTION_RETRANSMIT_DELAYED return sites, so the Diagnostics screen can confirm a repeater is actually relaying traffic rather than just being configured to. Co-Authored-By: Claude Sonnet 4.6 --- examples/companion_radio/ui-new/DiagnosticsScreen.h | 5 ++++- src/Mesh.cpp | 6 +++++- src/Mesh.h | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/examples/companion_radio/ui-new/DiagnosticsScreen.h b/examples/companion_radio/ui-new/DiagnosticsScreen.h index 185c4e77..226999e6 100644 --- a/examples/companion_radio/ui-new/DiagnosticsScreen.h +++ b/examples/companion_radio/ui-new/DiagnosticsScreen.h @@ -20,7 +20,7 @@ class DiagnosticsScreen : public UIScreen { int _scroll = 0; struct Row { const char* label; char value[20]; }; - static const int MAX_ROWS = 12; + static const int MAX_ROWS = 13; Row _rows[MAX_ROWS]; int _row_count = 0; @@ -76,6 +76,9 @@ class DiagnosticsScreen : public UIScreen { addRxTxRow("Ack/Path", rte_rx, rte_tx); addRxTxRow("Other", oth_rx, oth_tx); + snprintf(buf, sizeof(buf), "%lu", (unsigned long)the_mesh.getNumForwarded()); + addRow("Forwarded", buf); + uint32_t heap_free, heap_total; DeviceDiag::getHeapStats(heap_free, heap_total); if (heap_total > 0) snprintf(buf, sizeof(buf), "%lu/%luKB", (unsigned long)(heap_free / 1024), (unsigned long)(heap_total / 1024)); diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 87ad61af..a6ed6068 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -5,6 +5,7 @@ namespace mesh { void Mesh::begin() { Dispatcher::begin(); + n_forwarded = 0; } void Mesh::loop() { @@ -60,6 +61,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) { pkt->path[pkt->path_len++] = (int8_t) (pkt->getSNR()*4); uint32_t d = getDirectRetransmitDelay(pkt); + n_forwarded++; return ACTION_RETRANSMIT_DELAYED(5, d); // schedule with priority 5 (for now), maybe make configurable? } } @@ -100,7 +102,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) { removeSelfFromPath(pkt); uint32_t d = getDirectRetransmitDelay(pkt); - return ACTION_RETRANSMIT_DELAYED(0, d); // Routed traffic is HIGHEST priority + n_forwarded++; + return ACTION_RETRANSMIT_DELAYED(0, d); // Routed traffic is HIGHEST priority } } return ACTION_RELEASE; // this node is NOT the next hop (OR this packet has already been forwarded), so discard. @@ -336,6 +339,7 @@ DispatcherAction Mesh::routeRecvPacket(Packet* packet) { packet->setPathHashCount(n + 1); uint32_t d = getRetransmitDelay(packet); + n_forwarded++; // as this propagates outwards, give it lower and lower priority return ACTION_RETRANSMIT_DELAYED(packet->getPathHashCount(), d); // give priority to closer sources, than ones further away } diff --git a/src/Mesh.h b/src/Mesh.h index 2302d6b5..9de0ccbf 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -27,6 +27,7 @@ class Mesh : public Dispatcher { RTCClock* _rtc; RNG* _rng; MeshTables* _tables; + uint32_t n_forwarded; // packets actually re-transmitted (repeater/transport role) void removeSelfFromPath(Packet* packet); void routeDirectRecvAcks(Packet* packet, uint32_t delay_millis); @@ -178,6 +179,10 @@ public: LocalIdentity self_id; + // packets actually re-transmitted (vs. just permitted by allowPacketForward()) — + // confirms a repeater/transport role is really forwarding, not just configured to. + uint32_t getNumForwarded() const { return n_forwarded; } + RNG* getRNG() const { return _rng; } RTCClock* getRTCClock() const { return _rtc; }