mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-28 20:24:25 +00:00
Feat/0-cost hops for favorite routers (#7992)
Some checks are pending
CI / setup (check) (push) Waiting to run
CI / setup (esp32) (push) Waiting to run
CI / setup (esp32c3) (push) Waiting to run
CI / setup (esp32c6) (push) Waiting to run
CI / setup (esp32s3) (push) Waiting to run
CI / setup (nrf52840) (push) Waiting to run
CI / setup (rp2040) (push) Waiting to run
CI / setup (rp2350) (push) Waiting to run
CI / setup (stm32) (push) Waiting to run
CI / version (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32s3 (push) Blocked by required conditions
CI / build-esp32c3 (push) Blocked by required conditions
CI / build-esp32c6 (push) Blocked by required conditions
CI / build-nrf52840 (push) Blocked by required conditions
CI / build-rp2040 (push) Blocked by required conditions
CI / build-rp2350 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-deb-amd64 (push) Waiting to run
CI / docker-deb-amd64-tft (push) Waiting to run
CI / docker-alp-amd64 (push) Waiting to run
CI / docker-alp-amd64-tft (push) Waiting to run
CI / docker-deb-arm64 (push) Waiting to run
CI / docker-deb-armv7 (push) Waiting to run
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (rp2350) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (rp2350) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
CI / publish-firmware (push) Blocked by required conditions
Some checks are pending
CI / setup (check) (push) Waiting to run
CI / setup (esp32) (push) Waiting to run
CI / setup (esp32c3) (push) Waiting to run
CI / setup (esp32c6) (push) Waiting to run
CI / setup (esp32s3) (push) Waiting to run
CI / setup (nrf52840) (push) Waiting to run
CI / setup (rp2040) (push) Waiting to run
CI / setup (rp2350) (push) Waiting to run
CI / setup (stm32) (push) Waiting to run
CI / version (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32s3 (push) Blocked by required conditions
CI / build-esp32c3 (push) Blocked by required conditions
CI / build-esp32c6 (push) Blocked by required conditions
CI / build-nrf52840 (push) Blocked by required conditions
CI / build-rp2040 (push) Blocked by required conditions
CI / build-rp2350 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-deb-amd64 (push) Waiting to run
CI / docker-deb-amd64-tft (push) Waiting to run
CI / docker-alp-amd64 (push) Waiting to run
CI / docker-alp-amd64-tft (push) Waiting to run
CI / docker-deb-arm64 (push) Waiting to run
CI / docker-deb-armv7 (push) Waiting to run
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (rp2350) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (rp2350) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
CI / publish-firmware (push) Blocked by required conditions
* feat: implement router hop preservation for router-to-router communication - Preserve hop_limit when both local device and previous relay are routers/CLIENT_BASE - Only preserve hops for favorite routers to prevent abuse - Apply to both FloodingRouter and NextHopRouter - Update hop counting logic in MeshService for router-to-router communication This allows routers to communicate over longer distances without consuming hop limits, improving mesh network efficiency for infrastructure nodes. * chore: update protobufs submodule to latest * Optimized to check friend list first before nodedb. * Reverting unintended changes * revert: remove protobufs submodule update This reverts the protobufs submodule back to a84657c22 to remove unintended changes from this branch. * Slight rewrite to remove flawed NO_RELAY_NODE logic and added logic to add isFirstHop. If isFirstHop, always decrease hop_limit to avoid retry logic. * DRY code. Remove NodeInfo logic that was left over. * Trunk formatting
This commit is contained in:
parent
18058ef507
commit
fd5ca8b73c
@ -1,5 +1,6 @@
|
|||||||
#include "FloodingRouter.h"
|
#include "FloodingRouter.h"
|
||||||
|
#include "MeshTypes.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
|
|
||||||
@ -90,7 +91,12 @@ void FloodingRouter::perhapsRebroadcast(const meshtastic_MeshPacket *p)
|
|||||||
if (isRebroadcaster()) {
|
if (isRebroadcaster()) {
|
||||||
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
||||||
|
|
||||||
tosend->hop_limit--; // bump down the hop count
|
// Use shared logic to determine if hop_limit should be decremented
|
||||||
|
if (shouldDecrementHopLimit(p)) {
|
||||||
|
tosend->hop_limit--; // bump down the hop count
|
||||||
|
} else {
|
||||||
|
LOG_INFO("favorite-ROUTER/CLIENT_BASE-to-ROUTER/CLIENT_BASE flood: preserving hop_limit");
|
||||||
|
}
|
||||||
#if USERPREFS_EVENT_MODE
|
#if USERPREFS_EVENT_MODE
|
||||||
if (tosend->hop_limit > 2) {
|
if (tosend->hop_limit > 2) {
|
||||||
// if we are "correcting" the hop_limit, "correct" the hop_start by the same amount to preserve hops away.
|
// if we are "correcting" the hop_limit, "correct" the hop_start by the same amount to preserve hops away.
|
||||||
@ -98,6 +104,7 @@ void FloodingRouter::perhapsRebroadcast(const meshtastic_MeshPacket *p)
|
|||||||
tosend->hop_limit = 2;
|
tosend->hop_limit = 2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tosend->next_hop = NO_NEXT_HOP_PREFERENCE; // this should already be the case, but just in case
|
tosend->next_hop = NO_NEXT_HOP_PREFERENCE; // this should already be the case, but just in case
|
||||||
|
|
||||||
LOG_INFO("Rebroadcast received floodmsg");
|
LOG_INFO("Rebroadcast received floodmsg");
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "NextHopRouter.h"
|
#include "NextHopRouter.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
|
|
||||||
NextHopRouter::NextHopRouter() {}
|
NextHopRouter::NextHopRouter() {}
|
||||||
|
|
||||||
@ -108,7 +109,13 @@ bool NextHopRouter::perhapsRelay(const meshtastic_MeshPacket *p)
|
|||||||
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
||||||
LOG_INFO("Relaying received message coming from %x", p->relay_node);
|
LOG_INFO("Relaying received message coming from %x", p->relay_node);
|
||||||
|
|
||||||
tosend->hop_limit--; // bump down the hop count
|
// Use shared logic to determine if hop_limit should be decremented
|
||||||
|
if (shouldDecrementHopLimit(p)) {
|
||||||
|
tosend->hop_limit--; // bump down the hop count
|
||||||
|
} else {
|
||||||
|
LOG_INFO("Router/CLIENT_BASE-to-favorite-router/CLIENT_BASE relay: preserving hop_limit");
|
||||||
|
}
|
||||||
|
|
||||||
NextHopRouter::send(tosend);
|
NextHopRouter::send(tosend);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -69,6 +69,58 @@ Router::Router() : concurrency::OSThread("Router"), fromRadioQueue(MAX_RX_FROMRA
|
|||||||
cryptLock = new concurrency::Lock();
|
cryptLock = new concurrency::Lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Router::shouldDecrementHopLimit(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
// First hop MUST always decrement to prevent retry issues
|
||||||
|
bool isFirstHop = (p->hop_start != 0 && p->hop_start == p->hop_limit);
|
||||||
|
if (isFirstHop) {
|
||||||
|
return true; // Always decrement on first hop
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if both local device and previous relay are routers (including CLIENT_BASE)
|
||||||
|
bool localIsRouter =
|
||||||
|
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_ROUTER_LATE,
|
||||||
|
meshtastic_Config_DeviceConfig_Role_CLIENT_BASE);
|
||||||
|
|
||||||
|
// If local device isn't a router, always decrement
|
||||||
|
if (!localIsRouter) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For subsequent hops, check if previous relay is a favorite router
|
||||||
|
// Optimized search for favorite routers with matching last byte
|
||||||
|
// Check ordering optimized for IoT devices (cheapest checks first)
|
||||||
|
for (int i = 0; i < nodeDB->getNumMeshNodes(); i++) {
|
||||||
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
|
||||||
|
if (!node)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check 1: is_favorite (cheapest - single bool)
|
||||||
|
if (!node->is_favorite)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check 2: has_user (cheap - single bool)
|
||||||
|
if (!node->has_user)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check 3: role check (moderate cost - multiple comparisons)
|
||||||
|
if (!IS_ONE_OF(node->user.role, meshtastic_Config_DeviceConfig_Role_ROUTER,
|
||||||
|
meshtastic_Config_DeviceConfig_Role_ROUTER_LATE, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check 4: last byte extraction and comparison (most expensive)
|
||||||
|
if (nodeDB->getLastByteOfNodeNum(node->num) == p->relay_node) {
|
||||||
|
// Found a favorite router match
|
||||||
|
LOG_DEBUG("Identified favorite relay router 0x%x from last byte 0x%x", node->num, p->relay_node);
|
||||||
|
return false; // Don't decrement hop_limit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No favorite router match found, decrement hop_limit
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* do idle processing
|
* do idle processing
|
||||||
* Mostly looking in our incoming rxPacket queue and calling handleReceived.
|
* Mostly looking in our incoming rxPacket queue and calling handleReceived.
|
||||||
|
@ -104,6 +104,18 @@ class Router : protected concurrency::OSThread, protected PacketHistory
|
|||||||
*/
|
*/
|
||||||
virtual bool shouldFilterReceived(const meshtastic_MeshPacket *p) { return false; }
|
virtual bool shouldFilterReceived(const meshtastic_MeshPacket *p) { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if hop_limit should be decremented for a relay operation.
|
||||||
|
* Returns false (preserve hop_limit) only if all conditions are met:
|
||||||
|
* - It's NOT the first hop (first hop must always decrement)
|
||||||
|
* - Local device is a ROUTER, ROUTER_LATE, or CLIENT_BASE
|
||||||
|
* - Previous relay is a favorite ROUTER, ROUTER_LATE, or CLIENT_BASE
|
||||||
|
*
|
||||||
|
* @param p The packet being relayed
|
||||||
|
* @return true if hop_limit should be decremented, false to preserve it
|
||||||
|
*/
|
||||||
|
bool shouldDecrementHopLimit(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
||||||
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
||||||
|
Loading…
Reference in New Issue
Block a user