Merge branch 'develop' into assymRelay

This commit is contained in:
Ben Meadors 2025-09-25 05:18:56 -05:00 committed by GitHub
commit 9b3d76967b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 83 additions and 8 deletions

View File

@ -9,7 +9,7 @@ plugins:
lint: lint:
enabled: enabled:
- checkov@3.2.471 - checkov@3.2.471
- renovate@41.125.3 - renovate@41.127.2
- prettier@3.6.2 - prettier@3.6.2
- trufflehog@3.90.8 - trufflehog@3.90.8
- yamllint@1.37.1 - yamllint@1.37.1

View File

@ -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
// Use shared logic to determine if hop_limit should be decremented
if (shouldDecrementHopLimit(p)) {
tosend->hop_limit--; // bump down the hop count 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");

View File

@ -155,7 +155,7 @@ template <typename T> bool LR11x0Interface<T>::reconfigure()
if (err != RADIOLIB_ERR_NONE) if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
err = lora.setBandwidth(bw); err = lora.setBandwidth(bw, wideLora() && (getFreq() > 1000.0f));
if (err != RADIOLIB_ERR_NONE) if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);

View File

@ -1,4 +1,5 @@
#include "NextHopRouter.h" #include "NextHopRouter.h"
#include "NodeDB.h"
NextHopRouter::NextHopRouter() {} NextHopRouter::NextHopRouter() {}
@ -111,7 +112,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);
// Use shared logic to determine if hop_limit should be decremented
if (shouldDecrementHopLimit(p)) {
tosend->hop_limit--; // bump down the hop count 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;

View File

@ -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.

View File

@ -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)

View File

@ -69,7 +69,6 @@ No longer populated on PCB
#define WIRE_INTERFACES_COUNT 2 #define WIRE_INTERFACES_COUNT 2
#ifndef HELTEC_MESH_SOLAR_OLED
#ifndef HELTEC_MESH_SOLAR_OLED #ifndef HELTEC_MESH_SOLAR_OLED
// I2C bus 0 // I2C bus 0
#define PIN_WIRE_SDA (0 + 6) #define PIN_WIRE_SDA (0 + 6)
@ -80,8 +79,6 @@ No longer populated on PCB
// Available on header pins, for general use // Available on header pins, for general use
#define PIN_WIRE1_SDA (0 + 30) #define PIN_WIRE1_SDA (0 + 30)
#define PIN_WIRE1_SCL (0 + 5) #define PIN_WIRE1_SCL (0 + 5)
#define PIN_WIRE1_SDA (0 + 30)
#define PIN_WIRE1_SCL (0 + 5)
/* /*
* Lora radio * Lora radio