Merge branch 'master' into tft-gui-work

This commit is contained in:
Manuel 2024-11-14 22:49:03 +01:00 committed by GitHub
commit 573d2dc300
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 240 additions and 70 deletions

View File

@ -1,6 +1,6 @@
version: 0.1 version: 0.1
cli: cli:
version: 1.22.7 version: 1.22.8
plugins: plugins:
sources: sources:
- id: trunk - id: trunk
@ -8,20 +8,20 @@ plugins:
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- trufflehog@3.83.2 - trufflehog@3.83.6
- yamllint@1.35.1 - yamllint@1.35.1
- bandit@1.7.10 - bandit@1.7.10
- checkov@3.2.277 - checkov@3.2.287
- terrascan@1.19.9 - terrascan@1.19.9
- trivy@0.56.2 - trivy@0.56.2
#- trufflehog@3.63.2-rc0 #- trufflehog@3.63.2-rc0
- taplo@0.9.3 - taplo@0.9.3
- ruff@0.7.2 - ruff@0.7.3
- isort@5.13.2 - isort@5.13.2
- markdownlint@0.42.0 - markdownlint@0.42.0
- oxipng@9.1.2 - oxipng@9.1.2
- svgo@3.3.2 - svgo@3.3.2
- actionlint@1.7.3 - actionlint@1.7.4
- flake8@7.1.1 - flake8@7.1.1
- hadolint@2.12.0 - hadolint@2.12.0
- shfmt@3.6.0 - shfmt@3.6.0

View File

@ -15,6 +15,7 @@ build_flags =
-Isrc/platform/nrf52 -Isrc/platform/nrf52
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818 -DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
-DMESHTASTIC_EXCLUDE_AUDIO=1 -DMESHTASTIC_EXCLUDE_AUDIO=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> ${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>

@ -1 +1 @@
Subproject commit 04f21f5c7238b8e02f794d9282c4786752634b3c Subproject commit af2fea10fe2eba5857fb8e27975bbcea9c10af8e

View File

@ -1,4 +1,5 @@
#include "ButtonThread.h" #include "ButtonThread.h"
#include "../userPrefs.h"
#include "configuration.h" #include "configuration.h"
#if !MESHTASTIC_EXCLUDE_GPS #if !MESHTASTIC_EXCLUDE_GPS
#include "GPS.h" #include "GPS.h"
@ -26,12 +27,12 @@ using namespace concurrency;
ButtonThread *buttonThread; // Declared extern in header ButtonThread *buttonThread; // Declared extern in header
volatile ButtonThread::ButtonEventType ButtonThread::btnEvent = ButtonThread::BUTTON_EVENT_NONE; volatile ButtonThread::ButtonEventType ButtonThread::btnEvent = ButtonThread::BUTTON_EVENT_NONE;
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
OneButton ButtonThread::userButton; // Get reference to static member OneButton ButtonThread::userButton; // Get reference to static member
#endif #endif
ButtonThread::ButtonThread() : OSThread("Button") ButtonThread::ButtonThread() : OSThread("Button")
{ {
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
#if defined(ARCH_PORTDUINO) #if defined(ARCH_PORTDUINO)
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) { if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) {
@ -39,7 +40,12 @@ ButtonThread::ButtonThread() : OSThread("Button")
LOG_DEBUG("Use GPIO%02d for button", settingsMap[user]); LOG_DEBUG("Use GPIO%02d for button", settingsMap[user]);
} }
#elif defined(BUTTON_PIN) #elif defined(BUTTON_PIN)
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin #if !defined(USERPREFS_BUTTON_PIN)
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
#endif
#ifdef USERPREFS_BUTTON_PIN
int pin = config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN; // Resolved button pin
#endif
#if defined(HELTEC_CAPSULE_SENSOR_V3) #if defined(HELTEC_CAPSULE_SENSOR_V3)
this->userButton = OneButton(pin, false, false); this->userButton = OneButton(pin, false, false);
#elif defined(BUTTON_ACTIVE_LOW) #elif defined(BUTTON_ACTIVE_LOW)
@ -59,7 +65,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
#endif #endif
#endif #endif
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
userButton.attachClick(userButtonPressed); userButton.attachClick(userButtonPressed);
userButton.setClickMs(BUTTON_CLICK_MS); userButton.setClickMs(BUTTON_CLICK_MS);
userButton.setPressMs(BUTTON_LONGPRESS_MS); userButton.setPressMs(BUTTON_LONGPRESS_MS);
@ -102,7 +108,7 @@ int32_t ButtonThread::runOnce()
// If the button is pressed we suppress CPU sleep until release // If the button is pressed we suppress CPU sleep until release
canSleep = true; // Assume we should not keep the board awake canSleep = true; // Assume we should not keep the board awake
#if defined(BUTTON_PIN) #if defined(BUTTON_PIN) || defined(USERPREFS_BUTTON_PIN)
userButton.tick(); userButton.tick();
canSleep &= userButton.isIdle(); canSleep &= userButton.isIdle();
#elif defined(ARCH_PORTDUINO) #elif defined(ARCH_PORTDUINO)
@ -130,7 +136,12 @@ int32_t ButtonThread::runOnce()
return 50; return 50;
} }
#ifdef BUTTON_PIN #ifdef BUTTON_PIN
#if !defined(USERPREFS_BUTTON_PIN)
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) != if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
#endif
#if defined(USERPREFS_BUTTON_PIN)
if (((config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN) !=
#endif
moduleConfig.canned_message.inputbroker_pin_press) || moduleConfig.canned_message.inputbroker_pin_press) ||
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) || !(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
!moduleConfig.canned_message.enabled) { !moduleConfig.canned_message.enabled) {
@ -244,7 +255,12 @@ void ButtonThread::attachButtonInterrupts()
#elif defined(BUTTON_PIN) #elif defined(BUTTON_PIN)
// Interrupt for user button, during normal use. Improves responsiveness. // Interrupt for user button, during normal use. Improves responsiveness.
attachInterrupt( attachInterrupt(
#if !defined(USERPREFS_BUTTON_PIN)
config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN,
#endif
#if defined(USERPREFS_BUTTON_PIN)
config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN,
#endif
[]() { []() {
ButtonThread::userButton.tick(); ButtonThread::userButton.tick();
runASAP = true; runASAP = true;
@ -273,8 +289,13 @@ void ButtonThread::detachButtonInterrupts()
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC)
detachInterrupt(settingsMap[user]); detachInterrupt(settingsMap[user]);
#elif defined(BUTTON_PIN) #elif defined(BUTTON_PIN)
#if !defined(USERPREFS_BUTTON_PIN)
detachInterrupt(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN); detachInterrupt(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
#endif #endif
#if defined(USERPREFS_BUTTON_PIN)
detachInterrupt(config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN);
#endif
#endif
#ifdef BUTTON_PIN_ALT #ifdef BUTTON_PIN_ALT
detachInterrupt(BUTTON_PIN_ALT); detachInterrupt(BUTTON_PIN_ALT);
@ -315,7 +336,7 @@ void ButtonThread::userButtonMultiPressed(void *callerThread)
// Non-static method, runs during callback. Grabs info while still valid // Non-static method, runs during callback. Grabs info while still valid
void ButtonThread::storeClickCount() void ButtonThread::storeClickCount()
{ {
#ifdef BUTTON_PIN #if defined(BUTTON_PIN) || defined(USERPREFS_BUTTON_PIN)
multipressClickCount = userButton.getNumberClicks(); multipressClickCount = userButton.getNumberClicks();
#endif #endif
} }

View File

@ -38,7 +38,7 @@ class ButtonThread : public concurrency::OSThread
void storeClickCount(); void storeClickCount();
private: private:
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
static OneButton userButton; // Static - accessed from an interrupt static OneButton userButton; // Static - accessed from an interrupt
#endif #endif
#ifdef BUTTON_PIN_ALT #ifdef BUTTON_PIN_ALT

View File

@ -251,7 +251,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \ #if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (hasINA()) { if (hasINA()) {
LOG_DEBUG("Use INA on I2C addr 0x%x for device battery voltage", config.power.device_battery_ina_address);
return getINAVoltage(); return getINAVoltage();
} }
#endif #endif
@ -271,7 +270,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER; config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER;
// Do not call analogRead() often. // Do not call analogRead() often.
const uint32_t min_read_interval = 5000; const uint32_t min_read_interval = 5000;
if (!Throttle::isWithinTimespanMs(last_read_time_ms, min_read_interval)) { if (!initial_read_done || !Throttle::isWithinTimespanMs(last_read_time_ms, min_read_interval)) {
last_read_time_ms = millis(); last_read_time_ms = millis();
uint32_t raw = 0; uint32_t raw = 0;
@ -614,7 +613,7 @@ void Power::shutdown()
#ifdef PIN_LED3 #ifdef PIN_LED3
ledOff(PIN_LED3); ledOff(PIN_LED3);
#endif #endif
doDeepSleep(DELAY_FOREVER, false); doDeepSleep(DELAY_FOREVER, false, false);
#endif #endif
} }

View File

@ -55,9 +55,14 @@ static void sdsEnter()
{ {
LOG_DEBUG("State: SDS"); LOG_DEBUG("State: SDS");
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw // FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false); doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false, false);
} }
static void lowBattSDSEnter()
{
LOG_DEBUG("State: Lower batt SDS");
doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false, true);
}
extern Power *power; extern Power *power;
static void shutdownEnter() static void shutdownEnter()
@ -247,6 +252,7 @@ static void bootEnter()
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN"); State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
State stateSDS(sdsEnter, NULL, NULL, "SDS"); State stateSDS(sdsEnter, NULL, NULL, "SDS");
State stateLowBattSDS(lowBattSDSEnter, NULL, NULL, "SDS");
State stateLS(lsEnter, lsIdle, lsExit, "LS"); State stateLS(lsEnter, lsIdle, lsExit, "LS");
State stateNB(nbEnter, NULL, NULL, "NB"); State stateNB(nbEnter, NULL, NULL, "NB");
State stateDARK(darkEnter, NULL, NULL, "DARK"); State stateDARK(darkEnter, NULL, NULL, "DARK");
@ -291,12 +297,12 @@ void PowerFSM_setup()
"Press"); // Allow button to work while in serial API "Press"); // Allow button to work while in serial API
// Handle critically low power battery by forcing deep sleep // Handle critically low power battery by forcing deep sleep
powerFSM.add_transition(&stateBOOT, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateBOOT, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateLS, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateLS, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateNB, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateNB, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateDARK, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateDARK, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateON, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateON, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateSERIAL, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateSERIAL, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
// Handle being told to power off // Handle being told to power off
powerFSM.add_transition(&stateBOOT, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown"); powerFSM.add_transition(&stateBOOT, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");

View File

@ -29,6 +29,17 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
if (Router::cancelSending(p->from, p->id)) if (Router::cancelSending(p->from, p->id))
txRelayCanceled++; txRelayCanceled++;
} }
/* If the original transmitter is doing retransmissions (hopStart equals hopLimit) for a reliable transmission, e.g., when
the ACK got lost, we will handle the packet again to make sure it gets an ACK to its packet. */
bool isRepeated = p->hop_start > 0 && p->hop_start == p->hop_limit;
if (isRepeated) {
LOG_DEBUG("Repeated reliable tx");
if (!perhapsRebroadcast(p) && isToUs(p) && p->want_ack) {
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, 0);
}
}
return true; return true;
} }
@ -41,14 +52,8 @@ bool FloodingRouter::isRebroadcaster()
config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_NONE; config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_NONE;
} }
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) bool FloodingRouter::perhapsRebroadcast(const meshtastic_MeshPacket *p)
{ {
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
if (isAckorReply && !isToUs(p) && !isBroadcast(p->to)) {
// do not flood direct message that is ACKed or replied to
LOG_DEBUG("Rxd an ACK/reply not for me, cancel rebroadcast");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
}
if (!isToUs(p) && (p->hop_limit > 0) && !isFromUs(p)) { if (!isToUs(p) && (p->hop_limit > 0) && !isFromUs(p)) {
if (p->id != 0) { if (p->id != 0) {
if (isRebroadcaster()) { if (isRebroadcaster()) {
@ -67,6 +72,8 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
// Note: we are careful to resend using the original senders node id // Note: we are careful to resend using the original senders node id
// We are careful not to call our hooked version of send() - because we don't want to check this again // We are careful not to call our hooked version of send() - because we don't want to check this again
Router::send(tosend); Router::send(tosend);
return true;
} else { } else {
LOG_DEBUG("No rebroadcast: Role = CLIENT_MUTE or Rebroadcast Mode = NONE"); LOG_DEBUG("No rebroadcast: Role = CLIENT_MUTE or Rebroadcast Mode = NONE");
} }
@ -74,6 +81,21 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
LOG_DEBUG("Ignore 0 id broadcast"); LOG_DEBUG("Ignore 0 id broadcast");
} }
} }
return false;
}
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
{
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
if (isAckorReply && !isToUs(p) && !isBroadcast(p->to)) {
// do not flood direct message that is ACKed or replied to
LOG_DEBUG("Rxd an ACK/reply not for me, cancel rebroadcast");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
}
perhapsRebroadcast(p);
// handle the packet as normal // handle the packet as normal
Router::sniffReceived(p, c); Router::sniffReceived(p, c);
} }

View File

@ -31,6 +31,10 @@ class FloodingRouter : public Router, protected PacketHistory
private: private:
bool isRebroadcaster(); bool isRebroadcaster();
/** Check if we should rebroadcast this packet, and do so if needed
* @return true if rebroadcasted */
bool perhapsRebroadcast(const meshtastic_MeshPacket *p);
public: public:
/** /**
* Constructor * Constructor

View File

@ -247,6 +247,31 @@ NodeDB::NodeDB()
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED; config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
config.position.gps_enabled = 0; config.position.gps_enabled = 0;
} }
#ifdef USERPREFS_FIXED_GPS
if (myNodeInfo.reboot_count == 1) { // Check if First boot ever or after Factory Reset.
meshtastic_Position fixedGPS = meshtastic_Position_init_default;
#ifdef USERPREFS_FIXED_GPS_LAT
fixedGPS.latitude_i = (int32_t)(USERPREFS_FIXED_GPS_LAT * 1e7);
fixedGPS.has_latitude_i = true;
#endif
#ifdef USERPREFS_FIXED_GPS_LON
fixedGPS.longitude_i = (int32_t)(USERPREFS_FIXED_GPS_LON * 1e7);
fixedGPS.has_longitude_i = true;
#endif
#ifdef USERPREFS_FIXED_GPS_ALT
fixedGPS.altitude = USERPREFS_FIXED_GPS_ALT;
fixedGPS.has_altitude = true;
#endif
#if defined(USERPREFS_FIXED_GPS_LAT) && defined(USERPREFS_FIXED_GPS_LON)
fixedGPS.location_source = meshtastic_Position_LocSource_LOC_MANUAL;
config.has_position = true;
info->has_position = true;
info->position = TypeConversions::ConvertToPositionLite(fixedGPS);
nodeDB->setLocalPosition(fixedGPS);
config.position.fixed_position = true;
#endif
}
#endif
saveToDisk(saveWhat); saveToDisk(saveWhat);
} }
@ -446,8 +471,13 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
#else #else
bool hasScreen = screen_found.port != ScanI2C::I2CPort::NO_I2C; bool hasScreen = screen_found.port != ScanI2C::I2CPort::NO_I2C;
#endif #endif
#ifdef USERPREFS_FIXED_BLUETOOTH
config.bluetooth.fixed_pin = USERPREFS_FIXED_BLUETOOTH;
config.bluetooth.mode = meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
#else
config.bluetooth.mode = hasScreen ? meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN config.bluetooth.mode = hasScreen ? meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
: meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN; : meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
#endif
// for backward compat, default position flags are ALT+MSL // for backward compat, default position flags are ALT+MSL
config.position.position_flags = config.position.position_flags =
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL | (meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL |
@ -803,7 +833,7 @@ void NodeDB::loadFromDisk()
// disk we will still factoryReset to restore things. // disk we will still factoryReset to restore things.
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM // static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES * sizeof(meshtastic_NodeInfo), auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES_FS * sizeof(meshtastic_NodeInfo),
sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate); sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate);
// See https://github.com/meshtastic/firmware/issues/4184#issuecomment-2269390786 // See https://github.com/meshtastic/firmware/issues/4184#issuecomment-2269390786
@ -822,6 +852,10 @@ void NodeDB::loadFromDisk()
meshNodes = &devicestate.node_db_lite; meshNodes = &devicestate.node_db_lite;
numMeshNodes = devicestate.node_db_lite.size(); numMeshNodes = devicestate.node_db_lite.size();
} }
if (numMeshNodes > MAX_NUM_NODES) {
LOG_WARN("Node count %d exceeds MAX_NUM_NODES %d, truncating", numMeshNodes, MAX_NUM_NODES);
numMeshNodes = MAX_NUM_NODES;
}
meshNodes->resize(MAX_NUM_NODES); meshNodes->resize(MAX_NUM_NODES);
state = loadProto(configFileName, meshtastic_LocalConfig_size, sizeof(meshtastic_LocalConfig), &meshtastic_LocalConfig_msg, state = loadProto(configFileName, meshtastic_LocalConfig_size, sizeof(meshtastic_LocalConfig), &meshtastic_LocalConfig_msg,
@ -1246,12 +1280,12 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
int oldestBoringIndex = -1; int oldestBoringIndex = -1;
for (int i = 1; i < numMeshNodes; i++) { for (int i = 1; i < numMeshNodes; i++) {
// Simply the oldest non-favorite node // Simply the oldest non-favorite node
if (!meshNodes->at(i).is_favorite && meshNodes->at(i).last_heard < oldest) { if (!meshNodes->at(i).is_favorite && !meshNodes->at(i).is_ignored && meshNodes->at(i).last_heard < oldest) {
oldest = meshNodes->at(i).last_heard; oldest = meshNodes->at(i).last_heard;
oldestIndex = i; oldestIndex = i;
} }
// The oldest "boring" node // The oldest "boring" node
if (!meshNodes->at(i).is_favorite && meshNodes->at(i).user.public_key.size == 0 && if (!meshNodes->at(i).is_favorite && !meshNodes->at(i).is_ignored && meshNodes->at(i).user.public_key.size == 0 &&
meshNodes->at(i).last_heard < oldestBoring) { meshNodes->at(i).last_heard < oldestBoring) {
oldestBoring = meshNodes->at(i).last_heard; oldestBoring = meshNodes->at(i).last_heard;
oldestBoringIndex = i; oldestBoringIndex = i;

View File

@ -38,13 +38,6 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd
seenRecently = false; seenRecently = false;
} }
/* If the original transmitter is doing retransmissions (hopStart equals hopLimit) for a reliable transmission, e.g., when the
ACK got lost, we will handle the packet again to make sure it gets an ACK/response to its packet. */
if (seenRecently && p->hop_start > 0 && p->hop_start == p->hop_limit) {
LOG_DEBUG("Repeated reliable tx");
seenRecently = false;
}
if (seenRecently) { if (seenRecently) {
LOG_DEBUG("Found existing packet record for fr=0x%x,to=0x%x,id=0x%x", p->from, p->to, p->id); LOG_DEBUG("Found existing packet record for fr=0x%x,to=0x%x,id=0x%x", p->from, p->to, p->id);
} }

View File

@ -176,9 +176,9 @@ bool ReliableRouter::stopRetransmission(GlobalPacketId key)
if (old->numRetransmissions < NUM_RETRANSMISSIONS - 1) { if (old->numRetransmissions < NUM_RETRANSMISSIONS - 1) {
// 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);
// now free the pooled copy for retransmission too
packetPool.release(p);
} }
// now free the pooled copy for retransmission too
packetPool.release(p);
auto numErased = pending.erase(key); auto numErased = pending.erase(key);
assert(numErased == 1); assert(numErased == 1);
return true; return true;

View File

@ -651,6 +651,13 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
return; return;
} }
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->from);
if (node != NULL && node->is_ignored) {
LOG_DEBUG("Ignore msg, 0x%x is ignored", p->from);
packetPool.release(p);
return;
}
if (p->from == NODENUM_BROADCAST) { if (p->from == NODENUM_BROADCAST) {
LOG_DEBUG("Ignore msg from broadcast address"); LOG_DEBUG("Ignore msg from broadcast address");
packetPool.release(p); packetPool.release(p);

View File

@ -12,6 +12,7 @@ meshtastic_NodeInfo TypeConversions::ConvertToNodeInfo(const meshtastic_NodeInfo
info.channel = lite->channel; info.channel = lite->channel;
info.via_mqtt = lite->via_mqtt; info.via_mqtt = lite->via_mqtt;
info.is_favorite = lite->is_favorite; info.is_favorite = lite->is_favorite;
info.is_ignored = lite->is_ignored;
if (lite->has_hops_away) { if (lite->has_hops_away) {
info.has_hops_away = true; info.has_hops_away = true;

View File

@ -180,6 +180,10 @@ typedef struct _meshtastic_AdminMessage {
meshtastic_DeviceUIConfig get_ui_config_response; meshtastic_DeviceUIConfig get_ui_config_response;
/* Tell the node to store UI data persistently. */ /* Tell the node to store UI data persistently. */
meshtastic_DeviceUIConfig store_ui_config; meshtastic_DeviceUIConfig store_ui_config;
/* Set specified node-num to be ignored on the NodeDB on the device */
uint32_t set_ignored_node;
/* Set specified node-num to be un-ignored on the NodeDB on the device */
uint32_t remove_ignored_node;
/* Begins an edit transaction for config, module config, owner, and channel settings changes /* Begins an edit transaction for config, module config, owner, and channel settings changes
This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) */ This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) */
bool begin_edit_settings; bool begin_edit_settings;
@ -279,6 +283,8 @@ extern "C" {
#define meshtastic_AdminMessage_get_ui_config_request_tag 44 #define meshtastic_AdminMessage_get_ui_config_request_tag 44
#define meshtastic_AdminMessage_get_ui_config_response_tag 45 #define meshtastic_AdminMessage_get_ui_config_response_tag 45
#define meshtastic_AdminMessage_store_ui_config_tag 46 #define meshtastic_AdminMessage_store_ui_config_tag 46
#define meshtastic_AdminMessage_set_ignored_node_tag 47
#define meshtastic_AdminMessage_remove_ignored_node_tag 48
#define meshtastic_AdminMessage_begin_edit_settings_tag 64 #define meshtastic_AdminMessage_begin_edit_settings_tag 64
#define meshtastic_AdminMessage_commit_edit_settings_tag 65 #define meshtastic_AdminMessage_commit_edit_settings_tag 65
#define meshtastic_AdminMessage_factory_reset_device_tag 94 #define meshtastic_AdminMessage_factory_reset_device_tag 94
@ -329,6 +335,8 @@ X(a, STATIC, ONEOF, FIXED32, (payload_variant,set_time_only,set_time_only)
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_ui_config_request,get_ui_config_request), 44) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,get_ui_config_request,get_ui_config_request), 44) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_ui_config_response,get_ui_config_response), 45) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_ui_config_response,get_ui_config_response), 45) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,store_ui_config,store_ui_config), 46) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,store_ui_config,store_ui_config), 46) \
X(a, STATIC, ONEOF, UINT32, (payload_variant,set_ignored_node,set_ignored_node), 47) \
X(a, STATIC, ONEOF, UINT32, (payload_variant,remove_ignored_node,remove_ignored_node), 48) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_device,factory_reset_device), 94) \ X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_device,factory_reset_device), 94) \

View File

@ -87,6 +87,9 @@ typedef struct _meshtastic_NodeInfoLite {
/* True if node is in our favorites list /* True if node is in our favorites list
Persists between NodeDB internal clean ups */ Persists between NodeDB internal clean ups */
bool is_favorite; bool is_favorite;
/* True if node is in our ignored list
Persists between NodeDB internal clean ups */
bool is_ignored;
} meshtastic_NodeInfoLite; } meshtastic_NodeInfoLite;
/* This message is never sent over the wire, but it is used for serializing DB /* This message is never sent over the wire, but it is used for serializing DB
@ -150,12 +153,12 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN} #define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}} #define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0} #define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0}
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {0}} #define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {0}}
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0} #define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN} #define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}} #define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0} #define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0}
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {0}} #define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {0}}
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0} #define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
@ -182,6 +185,7 @@ extern "C" {
#define meshtastic_NodeInfoLite_via_mqtt_tag 8 #define meshtastic_NodeInfoLite_via_mqtt_tag 8
#define meshtastic_NodeInfoLite_hops_away_tag 9 #define meshtastic_NodeInfoLite_hops_away_tag 9
#define meshtastic_NodeInfoLite_is_favorite_tag 10 #define meshtastic_NodeInfoLite_is_favorite_tag 10
#define meshtastic_NodeInfoLite_is_ignored_tag 11
#define meshtastic_DeviceState_my_node_tag 2 #define meshtastic_DeviceState_my_node_tag 2
#define meshtastic_DeviceState_owner_tag 3 #define meshtastic_DeviceState_owner_tag 3
#define meshtastic_DeviceState_receive_queue_tag 5 #define meshtastic_DeviceState_receive_queue_tag 5
@ -226,7 +230,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
X(a, STATIC, SINGULAR, UINT32, channel, 7) \ X(a, STATIC, SINGULAR, UINT32, channel, 7) \
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \
X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \
X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \
X(a, STATIC, SINGULAR, BOOL, is_ignored, 11)
#define meshtastic_NodeInfoLite_CALLBACK NULL #define meshtastic_NodeInfoLite_CALLBACK NULL
#define meshtastic_NodeInfoLite_DEFAULT NULL #define meshtastic_NodeInfoLite_DEFAULT NULL
#define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_UserLite #define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_UserLite
@ -279,7 +284,7 @@ extern const pb_msgdesc_t meshtastic_ChannelFile_msg;
/* meshtastic_DeviceState_size depends on runtime parameters */ /* meshtastic_DeviceState_size depends on runtime parameters */
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_ChannelFile_size #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_ChannelFile_size
#define meshtastic_ChannelFile_size 718 #define meshtastic_ChannelFile_size 718
#define meshtastic_NodeInfoLite_size 183 #define meshtastic_NodeInfoLite_size 185
#define meshtastic_PositionLite_size 28 #define meshtastic_PositionLite_size 28
#define meshtastic_UserLite_size 96 #define meshtastic_UserLite_size 96

View File

@ -797,6 +797,9 @@ typedef struct _meshtastic_NodeInfo {
/* True if node is in our favorites list /* True if node is in our favorites list
Persists between NodeDB internal clean ups */ Persists between NodeDB internal clean ups */
bool is_favorite; bool is_favorite;
/* True if node is in our ignored list
Persists between NodeDB internal clean ups */
bool is_ignored;
} meshtastic_NodeInfo; } meshtastic_NodeInfo;
typedef PB_BYTES_ARRAY_T(16) meshtastic_MyNodeInfo_device_id_t; typedef PB_BYTES_ARRAY_T(16) meshtastic_MyNodeInfo_device_id_t;
@ -1157,7 +1160,7 @@ extern "C" {
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0} #define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0} #define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0}
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0} #define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0}
#define meshtastic_MyNodeInfo_init_default {0, 0, 0, {0, {0}}, ""} #define meshtastic_MyNodeInfo_init_default {0, 0, 0, {0, {0}}, ""}
#define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN} #define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_default {0, 0, 0, 0} #define meshtastic_QueueStatus_init_default {0, 0, 0, 0}
@ -1182,7 +1185,7 @@ extern "C" {
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0} #define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0} #define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0}
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0} #define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0}
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, {0, {0}}, ""} #define meshtastic_MyNodeInfo_init_zero {0, 0, 0, {0, {0}}, ""}
#define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN} #define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_zero {0, 0, 0, 0} #define meshtastic_QueueStatus_init_zero {0, 0, 0, 0}
@ -1287,6 +1290,7 @@ extern "C" {
#define meshtastic_NodeInfo_via_mqtt_tag 8 #define meshtastic_NodeInfo_via_mqtt_tag 8
#define meshtastic_NodeInfo_hops_away_tag 9 #define meshtastic_NodeInfo_hops_away_tag 9
#define meshtastic_NodeInfo_is_favorite_tag 10 #define meshtastic_NodeInfo_is_favorite_tag 10
#define meshtastic_NodeInfo_is_ignored_tag 11
#define meshtastic_MyNodeInfo_my_node_num_tag 1 #define meshtastic_MyNodeInfo_my_node_num_tag 1
#define meshtastic_MyNodeInfo_reboot_count_tag 8 #define meshtastic_MyNodeInfo_reboot_count_tag 8
#define meshtastic_MyNodeInfo_min_app_version_tag 11 #define meshtastic_MyNodeInfo_min_app_version_tag 11
@ -1485,7 +1489,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
X(a, STATIC, SINGULAR, UINT32, channel, 7) \ X(a, STATIC, SINGULAR, UINT32, channel, 7) \
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \
X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \
X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \
X(a, STATIC, SINGULAR, BOOL, is_ignored, 11)
#define meshtastic_NodeInfo_CALLBACK NULL #define meshtastic_NodeInfo_CALLBACK NULL
#define meshtastic_NodeInfo_DEFAULT NULL #define meshtastic_NodeInfo_DEFAULT NULL
#define meshtastic_NodeInfo_user_MSGTYPE meshtastic_User #define meshtastic_NodeInfo_user_MSGTYPE meshtastic_User
@ -1724,7 +1729,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
#define meshtastic_MyNodeInfo_size 77 #define meshtastic_MyNodeInfo_size 77
#define meshtastic_NeighborInfo_size 258 #define meshtastic_NeighborInfo_size 258
#define meshtastic_Neighbor_size 22 #define meshtastic_Neighbor_size 22
#define meshtastic_NodeInfo_size 317 #define meshtastic_NodeInfo_size 319
#define meshtastic_NodeRemoteHardwarePin_size 29 #define meshtastic_NodeRemoteHardwarePin_size 29
#define meshtastic_Position_size 144 #define meshtastic_Position_size 144
#define meshtastic_QueueStatus_size 23 #define meshtastic_QueueStatus_size 23

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include "architecture.h"
#include "mesh/generated/meshtastic/admin.pb.h" #include "mesh/generated/meshtastic/admin.pb.h"
#include "mesh/generated/meshtastic/deviceonly.pb.h" #include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "mesh/generated/meshtastic/localonly.pb.h" #include "mesh/generated/meshtastic/localonly.pb.h"
@ -20,8 +21,14 @@
/// max number of nodes allowed in the mesh /// max number of nodes allowed in the mesh
#ifndef MAX_NUM_NODES #ifndef MAX_NUM_NODES
#ifdef ARCH_NRF52
#define MAX_NUM_NODES 80
#else
#define MAX_NUM_NODES 100 #define MAX_NUM_NODES 100
#endif #endif
#endif
#define MAX_NUM_NODES_FS 100
/// Max number of channels allowed /// Max number of channels allowed
#define MAX_NUM_CHANNELS (member_size(meshtastic_ChannelFile, channels) / member_size(meshtastic_ChannelFile, channels[0])) #define MAX_NUM_CHANNELS (member_size(meshtastic_ChannelFile, channels) / member_size(meshtastic_ChannelFile, channels[0]))

View File

@ -295,6 +295,28 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
} }
break; break;
} }
case meshtastic_AdminMessage_set_ignored_node_tag: {
LOG_INFO("Client received set_ignored_node command");
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(r->set_ignored_node);
if (node != NULL) {
node->is_ignored = true;
node->has_device_metrics = false;
node->has_position = false;
node->user.public_key.size = 0;
node->user.public_key.bytes[0] = 0;
saveChanges(SEGMENT_DEVICESTATE, false);
}
break;
}
case meshtastic_AdminMessage_remove_ignored_node_tag: {
LOG_INFO("Client received remove_ignored_node command");
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(r->remove_ignored_node);
if (node != NULL) {
node->is_ignored = false;
saveChanges(SEGMENT_DEVICESTATE, false);
}
break;
}
case meshtastic_AdminMessage_set_fixed_position_tag: { case meshtastic_AdminMessage_set_fixed_position_tag: {
LOG_INFO("Client received set_fixed_position command"); LOG_INFO("Client received set_fixed_position command");
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
@ -516,6 +538,11 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
requiresReboot = false; requiresReboot = false;
} }
config.power = c.payload_variant.power; config.power = c.payload_variant.power;
if (c.payload_variant.power.on_battery_shutdown_after_secs > 0 &&
c.payload_variant.power.on_battery_shutdown_after_secs < 30) {
LOG_WARN("Tried to set on_battery_shutdown_after_secs too low, set to min 30 seconds");
config.power.on_battery_shutdown_after_secs = 30;
}
break; break;
case meshtastic_Config_network_tag: case meshtastic_Config_network_tag:
LOG_INFO("Set config: WiFi"); LOG_INFO("Set config: WiFi");

View File

@ -58,7 +58,7 @@ int32_t DetectionSensorModule::runOnce()
// moduleConfig.detection_sensor.minimum_broadcast_secs = 30; // moduleConfig.detection_sensor.minimum_broadcast_secs = 30;
// moduleConfig.detection_sensor.state_broadcast_secs = 120; // moduleConfig.detection_sensor.state_broadcast_secs = 120;
// moduleConfig.detection_sensor.detection_trigger_type = // moduleConfig.detection_sensor.detection_trigger_type =
// meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH; // meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH;
// strcpy(moduleConfig.detection_sensor.name, "Motion"); // strcpy(moduleConfig.detection_sensor.name, "Motion");
if (moduleConfig.detection_sensor.enabled == false) if (moduleConfig.detection_sensor.enabled == false)
@ -130,9 +130,12 @@ void DetectionSensorModule::sendDetectionMessage()
p->decoded.payload.bytes[p->decoded.payload.size + 1] = '\0'; // Bell character p->decoded.payload.bytes[p->decoded.payload.size + 1] = '\0'; // Bell character
p->decoded.payload.size++; p->decoded.payload.size++;
} }
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
lastSentToMesh = millis(); lastSentToMesh = millis();
service->sendToMesh(p); if (!channels.isDefaultChannel(0)) {
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
service->sendToMesh(p);
} else
LOG_ERROR("Message not allow on Public channel");
delete[] message; delete[] message;
} }
@ -140,14 +143,16 @@ void DetectionSensorModule::sendCurrentStateMessage(bool state)
{ {
char *message = new char[40]; char *message = new char[40];
sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, state); sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, state);
meshtastic_MeshPacket *p = allocDataPacket(); meshtastic_MeshPacket *p = allocDataPacket();
p->want_ack = false; p->want_ack = false;
p->decoded.payload.size = strlen(message); p->decoded.payload.size = strlen(message);
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size); memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
lastSentToMesh = millis(); lastSentToMesh = millis();
service->sendToMesh(p); if (!channels.isDefaultChannel(0)) {
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
service->sendToMesh(p);
} else
LOG_ERROR("Message not allow on Public channel");
delete[] message; delete[] message;
} }
@ -156,4 +161,4 @@ bool DetectionSensorModule::hasDetectionEvent()
bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin); bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin);
// LOG_DEBUG("Detection Sensor Module: Current state: %i", currentState); // LOG_DEBUG("Detection Sensor Module: Current state: %i", currentState);
return (moduleConfig.detection_sensor.detection_trigger_type & 1) ? currentState : !currentState; return (moduleConfig.detection_sensor.detection_trigger_type & 1) ? currentState : !currentState;
} }

View File

@ -364,7 +364,7 @@ int32_t PositionModule::runOnce()
sleepOnNextExecution = false; sleepOnNextExecution = false;
uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(config.position.position_broadcast_secs); uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(config.position.position_broadcast_secs);
LOG_DEBUG("Sleep for %ims, then awaking to send position again", nightyNightMs); LOG_DEBUG("Sleep for %ims, then awaking to send position again", nightyNightMs);
doDeepSleep(nightyNightMs, false); doDeepSleep(nightyNightMs, false, false);
} }
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());

View File

@ -111,7 +111,7 @@ int32_t PowerStressModule::runOnce()
setBluetoothEnable(true); setBluetoothEnable(true);
break; break;
case meshtastic_PowerStressMessage_Opcode_CPU_DEEPSLEEP: case meshtastic_PowerStressMessage_Opcode_CPU_DEEPSLEEP:
doDeepSleep(sleep_msec, true); doDeepSleep(sleep_msec, true, true);
break; break;
case meshtastic_PowerStressMessage_Opcode_CPU_FULLON: { case meshtastic_PowerStressMessage_Opcode_CPU_FULLON: {
uint32_t start_msec = millis(); uint32_t start_msec = millis();

View File

@ -74,7 +74,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval, uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval,
default_telemetry_broadcast_interval_secs); default_telemetry_broadcast_interval_secs);
LOG_DEBUG("Sleep for %ims, then awake to send metrics again", nightyNightMs); LOG_DEBUG("Sleep for %ims, then awake to send metrics again", nightyNightMs);
doDeepSleep(nightyNightMs, true); doDeepSleep(nightyNightMs, true, false);
} }
uint32_t result = UINT32_MAX; uint32_t result = UINT32_MAX;

View File

@ -40,7 +40,7 @@ int32_t HealthTelemetryModule::runOnce()
uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.health_update_interval, uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.health_update_interval,
default_telemetry_broadcast_interval_secs); default_telemetry_broadcast_interval_secs);
LOG_DEBUG("Sleep for %ims, then awake to send metrics again", nightyNightMs); LOG_DEBUG("Sleep for %ims, then awake to send metrics again", nightyNightMs);
doDeepSleep(nightyNightMs, true); doDeepSleep(nightyNightMs, true, false);
} }
uint32_t result = UINT32_MAX; uint32_t result = UINT32_MAX;

View File

@ -28,7 +28,7 @@ int32_t PowerTelemetryModule::runOnce()
uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.power_update_interval, uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.power_update_interval,
default_telemetry_broadcast_interval_secs); default_telemetry_broadcast_interval_secs);
LOG_DEBUG("Sleep for %ims, then awake to send metrics again", nightyNightMs); LOG_DEBUG("Sleep for %ims, then awake to send metrics again", nightyNightMs);
doDeepSleep(nightyNightMs, true); doDeepSleep(nightyNightMs, true, false);
} }
uint32_t result = UINT32_MAX; uint32_t result = UINT32_MAX;

View File

@ -187,7 +187,7 @@ static void waitEnterSleep(bool skipPreflight = false)
notifySleep.notifyObservers(NULL); notifySleep.notifyObservers(NULL);
} }
void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false) void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveNodeDb = false)
{ {
if (INCLUDE_vTaskSuspend && (msecToWake == portMAX_DELAY)) { if (INCLUDE_vTaskSuspend && (msecToWake == portMAX_DELAY)) {
LOG_INFO("Enter deep sleep forever"); LOG_INFO("Enter deep sleep forever");
@ -219,7 +219,9 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false)
screen->doDeepSleep(); // datasheet says this will draw only 10ua screen->doDeepSleep(); // datasheet says this will draw only 10ua
nodeDB->saveToDisk(); if (!skipSaveNodeDb) {
nodeDB->saveToDisk();
}
#ifdef PIN_POWER_EN #ifdef PIN_POWER_EN
pinMode(PIN_POWER_EN, INPUT); // power off peripherals pinMode(PIN_POWER_EN, INPUT); // power off peripherals

View File

@ -4,7 +4,7 @@
#include "Observer.h" #include "Observer.h"
#include "configuration.h" #include "configuration.h"
void doDeepSleep(uint32_t msecToWake, bool skipPreflight), cpuDeepSleep(uint32_t msecToWake); void doDeepSleep(uint32_t msecToWake, bool skipPreflight, bool skipSaveNodeDb), cpuDeepSleep(uint32_t msecToWake);
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "esp_sleep.h" #include "esp_sleep.h"

View File

@ -74,4 +74,25 @@ static unsigned char USERPREFS_ADMIN_KEY[] = {0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24
0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, 0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a,
0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c}; 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c};
*/ */
/*
* USERPREF_FIXED_GPS_LAT and USERPREF_FIXED_GPS_LON must be set, USERPREF_FIXED_GPS_ALT is optional
*
* Fixed GPS is Eiffel Tower, Paris, France
*/
// #define USERPREFS_FIXED_GPS
// #define USERPREFS_FIXED_GPS_LAT 48.85873920
// #define USERPREFS_FIXED_GPS_LON 2.294508368
// #define USERPREFS_FIXED_GPS_ALT 0
/*
* Set Fixed Bluetooth paring code
*/
// #define USERPREFS_FIXED_BLUETOOTH 121212
/*
* Will overwrite BUTTON_PIN if set
*/
// #define USERPREFS_BUTTON_PIN 36
#endif #endif

View File

@ -1,7 +1,6 @@
; The very slick RAK wireless RAK10701 Field Tester device. Note you will have to flash to Arduino bootloader to use this firmware. Be aware touch is not currently working. ; The very slick RAK wireless RAK10701 Field Tester device. Note you will have to flash to Arduino bootloader to use this firmware. Be aware touch is not currently working.
[env:rak_wismeshtap] [env:rak_wismeshtap]
extends = nrf52840_base extends = nrf52840_base
board_level = extra
board = wiscore_rak4631 board = wiscore_rak4631
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak_wismeshtap -D RAK_4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/rak_wismeshtap -D RAK_4631
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard" -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
@ -10,8 +9,11 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/rak_wismeshtap -D RAK_4631
-DEINK_WIDTH=250 -DEINK_WIDTH=250
-DEINK_HEIGHT=122 -DEINK_HEIGHT=122
-DMESHTASTIC_EXCLUDE_WIFI=1 -DMESHTASTIC_EXCLUDE_WIFI=1
-DMESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION=1
-DMESHTASTIC_EXCLUDE_WAYPOINT=1 -DMESHTASTIC_EXCLUDE_WAYPOINT=1
-DMESHTASTIC_EXCLUDE_DETECTIONSENSOR=1
-DMESHTASTIC_EXCLUDE_STOREFORWARD=1
-DMESHTASTIC_EXCLUDE_POWER_TELEMETRY=1
-DMESHTASTIC_EXCLUDE_ATAK=1
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak_wismeshtap> +<mesh/eth/> +<mesh/api/> +<mqtt/> build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak_wismeshtap> +<mesh/eth/> +<mesh/api/> +<mqtt/>
lib_deps = lib_deps =
${nrf52840_base.lib_deps} ${nrf52840_base.lib_deps}
@ -24,4 +26,4 @@ lib_deps =
beegee-tokyo/RAK14014-FT6336U @ 1.0.1 beegee-tokyo/RAK14014-FT6336U @ 1.0.1
debug_tool = jlink debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink ;upload_protocol = jlink

View File

@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 2 major = 2
minor = 5 minor = 5
build = 12 build = 14