mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-21 01:04:01 +00:00
Merge pull request #7873 from compumike/compumike/client-base-role
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
Add `CLIENT_BASE` role: `ROUTER` for favorites, `CLIENT` otherwise (for attic/roof nodes!)
This commit is contained in:
parent
68ba3b315c
commit
b14e5770d5
@ -39,3 +39,48 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *DisplayFormatters::getDeviceRole(meshtastic_Config_DeviceConfig_Role role)
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_CLIENT:
|
||||||
|
return "Client";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE:
|
||||||
|
return "Client Mute";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN:
|
||||||
|
return "Client Hidden";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_CLIENT_BASE:
|
||||||
|
return "Client Base";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND:
|
||||||
|
return "Lost and Found";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_TRACKER:
|
||||||
|
return "Tracker";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_SENSOR:
|
||||||
|
return "Sensor";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_TAK:
|
||||||
|
return "TAK";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_TAK_TRACKER:
|
||||||
|
return "TAK Tracker";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_ROUTER:
|
||||||
|
return "Router";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_ROUTER_LATE:
|
||||||
|
return "Router Late";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_DeviceConfig_Role_REPEATER:
|
||||||
|
return "Repeater";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "PowerMon.h"
|
#include "PowerMon.h"
|
||||||
#include "Throttle.h"
|
#include "Throttle.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "meshUtils.h"
|
||||||
#if HAS_SCREEN
|
#if HAS_SCREEN
|
||||||
#include <OLEDDisplay.h>
|
#include <OLEDDisplay.h>
|
||||||
|
|
||||||
@ -58,7 +59,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include "mesh/Channels.h"
|
#include "mesh/Channels.h"
|
||||||
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
||||||
#include "meshUtils.h"
|
|
||||||
#include "modules/ExternalNotificationModule.h"
|
#include "modules/ExternalNotificationModule.h"
|
||||||
#include "modules/TextMessageModule.h"
|
#include "modules/TextMessageModule.h"
|
||||||
#include "modules/WaypointModule.h"
|
#include "modules/WaypointModule.h"
|
||||||
@ -1562,13 +1562,15 @@ bool shouldWakeOnReceivedMessage()
|
|||||||
/*
|
/*
|
||||||
The goal here is to determine when we do NOT wake up the screen on message received:
|
The goal here is to determine when we do NOT wake up the screen on message received:
|
||||||
- Any ext. notifications are turned on
|
- Any ext. notifications are turned on
|
||||||
- If role is not client / client_mute
|
- If role is not CLIENT / CLIENT_MUTE / CLIENT_HIDDEN / CLIENT_BASE
|
||||||
- If the battery level is very low
|
- If the battery level is very low
|
||||||
*/
|
*/
|
||||||
if (moduleConfig.external_notification.enabled) {
|
if (moduleConfig.external_notification.enabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!meshtastic_Config_DeviceConfig_Role_CLIENT && !meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE) {
|
if (!IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_CLIENT,
|
||||||
|
meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE, meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN,
|
||||||
|
meshtastic_Config_DeviceConfig_Role_CLIENT_BASE)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (powerStatus && powerStatus->getBatteryChargePercent() < 10) {
|
if (powerStatus && powerStatus->getBatteryChargePercent() < 10) {
|
||||||
|
@ -43,12 +43,30 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
return Router::shouldFilterReceived(p);
|
return Router::shouldFilterReceived(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FloodingRouter::roleAllowsCancelingDupe(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
||||||
|
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER ||
|
||||||
|
config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE) {
|
||||||
|
// ROUTER, REPEATER, ROUTER_LATE should never cancel relaying a packet (i.e. we should always rebroadcast),
|
||||||
|
// even if we've heard another station rebroadcast it already.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_CLIENT_BASE) {
|
||||||
|
// CLIENT_BASE: if the packet is from or to a favorited node,
|
||||||
|
// we should act like a ROUTER and should never cancel a rebroadcast (i.e. we should always rebroadcast),
|
||||||
|
// even if we've heard another station rebroadcast it already.
|
||||||
|
return !nodeDB->isFromOrToFavoritedNode(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// All other roles (such as CLIENT) should cancel a rebroadcast if they hear another station's rebroadcast.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void FloodingRouter::perhapsCancelDupe(const meshtastic_MeshPacket *p)
|
void FloodingRouter::perhapsCancelDupe(const meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER &&
|
if (p->transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA && roleAllowsCancelingDupe(p)) {
|
||||||
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER &&
|
|
||||||
config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER_LATE &&
|
|
||||||
p->transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA) {
|
|
||||||
// cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater!
|
// cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater!
|
||||||
// But only LoRa packets should be able to trigger this.
|
// But only LoRa packets should be able to trigger this.
|
||||||
if (Router::cancelSending(p->from, p->id))
|
if (Router::cancelSending(p->from, p->id))
|
||||||
|
@ -59,6 +59,10 @@ class FloodingRouter : public Router
|
|||||||
*/
|
*/
|
||||||
virtual void sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) override;
|
virtual void sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) override;
|
||||||
|
|
||||||
|
// Return false for roles like ROUTER or REPEATER which should always rebroadcast even when we've heard another rebroadcast of
|
||||||
|
// the same packet
|
||||||
|
bool roleAllowsCancelingDupe(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
/* Call when receiving a duplicate packet to check whether we should cancel a packet in the Tx queue */
|
/* Call when receiving a duplicate packet to check whether we should cancel a packet in the Tx queue */
|
||||||
void perhapsCancelDupe(const meshtastic_MeshPacket *p);
|
void perhapsCancelDupe(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
|
@ -161,6 +161,15 @@ bool NextHopRouter::stopRetransmission(NodeNum from, PacketId id)
|
|||||||
return stopRetransmission(key);
|
return stopRetransmission(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NextHopRouter::roleAllowsCancelingFromTxQueue(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
// Return true if we're allowed to cancel a packet in the txQueue (so we may never transmit it even once)
|
||||||
|
|
||||||
|
// Return false for roles like ROUTER, REPEATER, ROUTER_LATE which should always transmit the packet at least once.
|
||||||
|
|
||||||
|
return roleAllowsCancelingDupe(p); // same logic as FloodingRouter::roleAllowsCancelingDupe
|
||||||
|
}
|
||||||
|
|
||||||
bool NextHopRouter::stopRetransmission(GlobalPacketId key)
|
bool NextHopRouter::stopRetransmission(GlobalPacketId key)
|
||||||
{
|
{
|
||||||
auto old = findPendingPacket(key);
|
auto old = findPendingPacket(key);
|
||||||
@ -170,9 +179,7 @@ bool NextHopRouter::stopRetransmission(GlobalPacketId key)
|
|||||||
to avoid canceling a transmission if it was ACKed super fast via MQTT */
|
to avoid canceling a transmission if it was ACKed super fast via MQTT */
|
||||||
if (old->numRetransmissions < NUM_RELIABLE_RETX - 1) {
|
if (old->numRetransmissions < NUM_RELIABLE_RETX - 1) {
|
||||||
// We only cancel it if we are the original sender or if we're not a router(_late)/repeater
|
// We only cancel it if we are the original sender or if we're not a router(_late)/repeater
|
||||||
if (isFromUs(p) || (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER &&
|
if (isFromUs(p) || roleAllowsCancelingFromTxQueue(p)) {
|
||||||
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER &&
|
|
||||||
config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) {
|
|
||||||
// remove the 'original' (identified by originator and packet->id) from the txqueue and free it
|
// remove the 'original' (identified by originator and packet->id) from the txqueue and free it
|
||||||
cancelSending(getFrom(p), p->id);
|
cancelSending(getFrom(p), p->id);
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,9 @@ class NextHopRouter : public FloodingRouter
|
|||||||
*/
|
*/
|
||||||
PendingPacket *startRetransmission(meshtastic_MeshPacket *p, uint8_t numReTx = NUM_INTERMEDIATE_RETX);
|
PendingPacket *startRetransmission(meshtastic_MeshPacket *p, uint8_t numReTx = NUM_INTERMEDIATE_RETX);
|
||||||
|
|
||||||
|
// Return true if we're allowed to cancel a packet in the txQueue (so we may never transmit it even once)
|
||||||
|
bool roleAllowsCancelingFromTxQueue(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop any retransmissions we are doing of the specified node/packet ID pair
|
* Stop any retransmissions we are doing of the specified node/packet ID pair
|
||||||
*
|
*
|
||||||
|
@ -1750,6 +1750,65 @@ void NodeDB::set_favorite(bool is_favorite, uint32_t nodeId)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NodeDB::isFavorite(uint32_t nodeId)
|
||||||
|
{
|
||||||
|
// returns true if nodeId is_favorite; false if not or not found
|
||||||
|
|
||||||
|
// NODENUM_BROADCAST will never be in the DB
|
||||||
|
if (nodeId == NODENUM_BROADCAST)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
meshtastic_NodeInfoLite *lite = getMeshNode(nodeId);
|
||||||
|
|
||||||
|
if (lite) {
|
||||||
|
return lite->is_favorite;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NodeDB::isFromOrToFavoritedNode(const meshtastic_MeshPacket &p)
|
||||||
|
{
|
||||||
|
// This method is logically equivalent to:
|
||||||
|
// return isFavorite(p.from) || isFavorite(p.to);
|
||||||
|
// but is more efficient by:
|
||||||
|
// 1. doing only one pass through the database, instead of two
|
||||||
|
// 2. exiting early when a favorite is found, or if both from and to have been seen
|
||||||
|
|
||||||
|
if (p.to == NODENUM_BROADCAST)
|
||||||
|
return isFavorite(p.from); // we never store NODENUM_BROADCAST in the DB, so we only need to check p.from
|
||||||
|
|
||||||
|
meshtastic_NodeInfoLite *lite = NULL;
|
||||||
|
|
||||||
|
bool seenFrom = false;
|
||||||
|
bool seenTo = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < numMeshNodes; i++) {
|
||||||
|
lite = &meshNodes->at(i);
|
||||||
|
|
||||||
|
if (lite->num == p.from) {
|
||||||
|
if (lite->is_favorite)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
seenFrom = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lite->num == p.to) {
|
||||||
|
if (lite->is_favorite)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
seenTo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seenFrom && seenTo)
|
||||||
|
return false; // we've seen both, and neither is a favorite, so we can stop searching early
|
||||||
|
|
||||||
|
// Note: if we knew that sortMeshDB was always called after any change to is_favorite, we could exit early after searching
|
||||||
|
// all favorited nodes first.
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void NodeDB::pause_sort(bool paused)
|
void NodeDB::pause_sort(bool paused)
|
||||||
{
|
{
|
||||||
sortingIsPaused = paused;
|
sortingIsPaused = paused;
|
||||||
|
@ -185,6 +185,16 @@ class NodeDB
|
|||||||
*/
|
*/
|
||||||
void set_favorite(bool is_favorite, uint32_t nodeId);
|
void set_favorite(bool is_favorite, uint32_t nodeId);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if the node is in the NodeDB and marked as favorite
|
||||||
|
*/
|
||||||
|
bool isFavorite(uint32_t nodeId);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if p->from or p->to is a favorited node
|
||||||
|
*/
|
||||||
|
bool isFromOrToFavoritedNode(const meshtastic_MeshPacket &p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Other functions like the node picker can request a pause in the node sorting
|
* Other functions like the node picker can request a pause in the node sorting
|
||||||
*/
|
*/
|
||||||
|
@ -311,16 +311,33 @@ uint32_t RadioInterface::getTxDelayMsecWeightedWorst(float snr)
|
|||||||
return (2 * CWmax * slotTimeMsec) + pow_of_2(CWsize) * slotTimeMsec;
|
return (2 * CWmax * slotTimeMsec) + pow_of_2(CWsize) * slotTimeMsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns true if we should rebroadcast early like a ROUTER */
|
||||||
|
bool RadioInterface::shouldRebroadcastEarlyLikeRouter(meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
// If we are a ROUTER or REPEATER, we always rebroadcast early
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
||||||
|
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are a CLIENT_BASE and the packet is from or to a favorited node, we should rebroadcast early
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_CLIENT_BASE) {
|
||||||
|
return nodeDB->isFromOrToFavoritedNode(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** The delay to use when we want to flood a message */
|
/** The delay to use when we want to flood a message */
|
||||||
uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
|
uint32_t RadioInterface::getTxDelayMsecWeighted(meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
// high SNR = large CW size (Long Delay)
|
// high SNR = large CW size (Long Delay)
|
||||||
// low SNR = small CW size (Short Delay)
|
// low SNR = small CW size (Short Delay)
|
||||||
|
float snr = p->rx_snr;
|
||||||
uint32_t delay = 0;
|
uint32_t delay = 0;
|
||||||
uint8_t CWsize = getCWsize(snr);
|
uint8_t CWsize = getCWsize(snr);
|
||||||
// LOG_DEBUG("rx_snr of %f so setting CWsize to:%d", snr, CWsize);
|
// LOG_DEBUG("rx_snr of %f so setting CWsize to:%d", snr, CWsize);
|
||||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
if (shouldRebroadcastEarlyLikeRouter(p)) {
|
||||||
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
|
||||||
delay = random(0, 2 * CWsize) * slotTimeMsec;
|
delay = random(0, 2 * CWsize) * slotTimeMsec;
|
||||||
LOG_DEBUG("rx_snr found in packet. Router: setting tx delay:%d", delay);
|
LOG_DEBUG("rx_snr found in packet. Router: setting tx delay:%d", delay);
|
||||||
} else {
|
} else {
|
||||||
|
@ -180,8 +180,11 @@ class RadioInterface
|
|||||||
/** The worst-case SNR_based packet delay */
|
/** The worst-case SNR_based packet delay */
|
||||||
uint32_t getTxDelayMsecWeightedWorst(float snr);
|
uint32_t getTxDelayMsecWeightedWorst(float snr);
|
||||||
|
|
||||||
|
/** Returns true if we should rebroadcast early like a ROUTER */
|
||||||
|
bool shouldRebroadcastEarlyLikeRouter(meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
/** The delay to use when we want to flood a message. Use a weighted scale based on SNR */
|
/** The delay to use when we want to flood a message. Use a weighted scale based on SNR */
|
||||||
uint32_t getTxDelayMsecWeighted(float snr);
|
uint32_t getTxDelayMsecWeighted(meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
/** If the packet is not already in the late rebroadcast window, move it there */
|
/** If the packet is not already in the late rebroadcast window, move it there */
|
||||||
virtual void clampToLateRebroadcastWindow(NodeNum from, PacketId id) { return; }
|
virtual void clampToLateRebroadcastWindow(NodeNum from, PacketId id) { return; }
|
||||||
|
@ -310,7 +310,7 @@ void RadioLibInterface::setTransmitDelay()
|
|||||||
// So we want to make sure the other side has had a chance to reconfigure its radio.
|
// So we want to make sure the other side has had a chance to reconfigure its radio.
|
||||||
|
|
||||||
if (p->tx_after) {
|
if (p->tx_after) {
|
||||||
unsigned long add_delay = p->rx_rssi ? getTxDelayMsecWeighted(p->rx_snr) : getTxDelayMsec();
|
unsigned long add_delay = p->rx_rssi ? getTxDelayMsecWeighted(p) : getTxDelayMsec();
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
p->tx_after = min(max(p->tx_after + add_delay, now + add_delay), now + 2 * getTxDelayMsecWeightedWorst(p->rx_snr));
|
p->tx_after = min(max(p->tx_after + add_delay, now + add_delay), now + 2 * getTxDelayMsecWeightedWorst(p->rx_snr));
|
||||||
notifyLater(p->tx_after - now, TRANSMIT_DELAY_COMPLETED, false);
|
notifyLater(p->tx_after - now, TRANSMIT_DELAY_COMPLETED, false);
|
||||||
@ -323,7 +323,7 @@ void RadioLibInterface::setTransmitDelay()
|
|||||||
} else {
|
} else {
|
||||||
// If there is a SNR, start a timer scaled based on that SNR.
|
// If there is a SNR, start a timer scaled based on that SNR.
|
||||||
LOG_DEBUG("rx_snr found. hop_limit:%d rx_snr:%f", p->hop_limit, p->rx_snr);
|
LOG_DEBUG("rx_snr found. hop_limit:%d rx_snr:%f", p->hop_limit, p->rx_snr);
|
||||||
startTransmitTimerSNR(p->rx_snr);
|
startTransmitTimerRebroadcast(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,11 +336,11 @@ void RadioLibInterface::startTransmitTimer(bool withDelay)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadioLibInterface::startTransmitTimerSNR(float snr)
|
void RadioLibInterface::startTransmitTimerRebroadcast(meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
// If we have work to do and the timer wasn't already scheduled, schedule it now
|
// If we have work to do and the timer wasn't already scheduled, schedule it now
|
||||||
if (!txQueue.empty()) {
|
if (!txQueue.empty()) {
|
||||||
uint32_t delay = getTxDelayMsecWeighted(snr);
|
uint32_t delay = getTxDelayMsecWeighted(p);
|
||||||
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
|
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
|||||||
* timer scaled to SNR of to be flooded packet
|
* timer scaled to SNR of to be flooded packet
|
||||||
* @return Timestamp after which the packet may be sent
|
* @return Timestamp after which the packet may be sent
|
||||||
*/
|
*/
|
||||||
void startTransmitTimerSNR(float snr);
|
void startTransmitTimerRebroadcast(meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
void handleTransmitInterrupt();
|
void handleTransmitInterrupt();
|
||||||
void handleReceiveInterrupt();
|
void handleReceiveInterrupt();
|
||||||
|
@ -43,7 +43,7 @@ void SimRadio::setTransmitDelay()
|
|||||||
} else {
|
} else {
|
||||||
// If there is a SNR, start a timer scaled based on that SNR.
|
// If there is a SNR, start a timer scaled based on that SNR.
|
||||||
LOG_DEBUG("rx_snr found. hop_limit:%d rx_snr:%f", p->hop_limit, p->rx_snr);
|
LOG_DEBUG("rx_snr found. hop_limit:%d rx_snr:%f", p->hop_limit, p->rx_snr);
|
||||||
startTransmitTimerSNR(p->rx_snr);
|
startTransmitTimerRebroadcast(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,11 +57,11 @@ void SimRadio::startTransmitTimer(bool withDelay)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimRadio::startTransmitTimerSNR(float snr)
|
void SimRadio::startTransmitTimerRebroadcast(meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
// If we have work to do and the timer wasn't already scheduled, schedule it now
|
// If we have work to do and the timer wasn't already scheduled, schedule it now
|
||||||
if (!txQueue.empty()) {
|
if (!txQueue.empty()) {
|
||||||
uint32_t delayMsec = getTxDelayMsecWeighted(snr);
|
uint32_t delayMsec = getTxDelayMsecWeighted(p);
|
||||||
// LOG_DEBUG("xmit timer %d", delay);
|
// LOG_DEBUG("xmit timer %d", delay);
|
||||||
notifyLater(delayMsec, TRANSMIT_DELAY_COMPLETED, false);
|
notifyLater(delayMsec, TRANSMIT_DELAY_COMPLETED, false);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ class SimRadio : public RadioInterface, protected concurrency::NotifiedWorkerThr
|
|||||||
void startTransmitTimer(bool withDelay = true);
|
void startTransmitTimer(bool withDelay = true);
|
||||||
|
|
||||||
/** timer scaled to SNR of to be flooded packet */
|
/** timer scaled to SNR of to be flooded packet */
|
||||||
void startTransmitTimerSNR(float snr);
|
void startTransmitTimerRebroadcast(meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
void handleTransmitInterrupt();
|
void handleTransmitInterrupt();
|
||||||
void handleReceiveInterrupt();
|
void handleReceiveInterrupt();
|
||||||
|
Loading…
Reference in New Issue
Block a user