Merge remote-tracking branch 'origin/master' into NextHopRouter

This commit is contained in:
GUVWAF 2024-11-14 19:00:45 +01:00
commit dbe520c3ab
44 changed files with 327 additions and 88 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

@ -43,6 +43,7 @@ lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${radiolib_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.2 h2zero/NimBLE-Arduino@^1.4.2
https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587 https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587

View File

@ -23,6 +23,7 @@ lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${radiolib_base.lib_deps}
lewisxhe/XPowersLib@^0.2.6 lewisxhe/XPowersLib@^0.2.6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0

View File

@ -15,12 +15,14 @@ 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>
lib_deps= lib_deps=
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${radiolib_base.lib_deps}
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
lib_ignore = lib_ignore =

View File

@ -23,6 +23,7 @@ build_src_filter =
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
${radiolib_base.lib_deps}
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805 https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805

View File

@ -22,4 +22,5 @@ lib_ignore =
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${radiolib_base.lib_deps}
rweather/Crypto rweather/Crypto

View File

@ -21,4 +21,5 @@ lib_ignore =
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${radiolib_base.lib_deps}
rweather/Crypto rweather/Crypto

View File

@ -30,8 +30,9 @@ upload_protocol = stlink
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
charlesbaynham/OSFS@^1.2.3 charlesbaynham/OSFS@^1.2.3
jgromes/RadioLib@7.0.2
https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
lib_ignore = lib_ignore =
mathertel/OneButton@~2.6.1 mathertel/OneButton@2.6.1
Wire Wire

View File

@ -29,7 +29,7 @@ default_envs = tbeam
;default_envs = rak4631 ;default_envs = rak4631
;default_envs = rak4631_eth_gw ;default_envs = rak4631_eth_gw
;default_envs = rak2560 ;default_envs = rak2560
;default_envs = rak10701 ;default_envs = rak_wismeshtap
;default_envs = wio-e5 ;default_envs = wio-e5
;default_envs = radiomaster_900_bandit_nano ;default_envs = radiomaster_900_bandit_nano
;default_envs = radiomaster_900_bandit_micro ;default_envs = radiomaster_900_bandit_micro
@ -88,7 +88,6 @@ build_flags = -Wno-missing-field-initializers
monitor_speed = 115200 monitor_speed = 115200
monitor_filters = direct monitor_filters = direct
lib_deps = lib_deps =
jgromes/RadioLib@7.0.2
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95
mathertel/OneButton@2.6.1 mathertel/OneButton@2.6.1
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
@ -96,6 +95,7 @@ lib_deps =
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0 https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
nanopb/Nanopb@0.4.9 nanopb/Nanopb@0.4.9
erriez/ErriezCRC32@1.0.1 erriez/ErriezCRC32@1.0.1
; Used for the code analysis in PIO Home / Inspect ; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck check_tool = cppcheck
check_skip_packages = yes check_skip_packages = yes
@ -121,6 +121,10 @@ lib_deps =
arduino-libraries/NTPClient@3.1.0 arduino-libraries/NTPClient@3.1.0
arcao/Syslog@2.0.0 arcao/Syslog@2.0.0
[radiolib_base]
lib_deps =
jgromes/RadioLib@7.1.0
; Common libs for environmental measurements in telemetry module ; Common libs for environmental measurements in telemetry module
; (not included in native / portduino) ; (not included in native / portduino)
[environmental_base] [environmental_base]

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

@ -1,6 +1,10 @@
#include "TouchScreenBase.h" #include "TouchScreenBase.h"
#include "main.h" #include "main.h"
#if defined(RAK14014) && !defined(MESHTASTIC_EXCLUDE_CANNEDMESSAGES)
#include "modules/CannedMessageModule.h"
#endif
#ifndef TIME_LONG_PRESS #ifndef TIME_LONG_PRESS
#define TIME_LONG_PRESS 400 #define TIME_LONG_PRESS 400
#endif #endif
@ -102,12 +106,30 @@ int32_t TouchScreenBase::runOnce()
} }
_touchedOld = touched; _touchedOld = touched;
#if defined RAK14014
// Speed up the processing speed of the keyboard in virtual keyboard mode
auto state = cannedMessageModule->getRunState();
if (state == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
if (_tapped) {
_tapped = false;
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y);
}
} else {
if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) {
_tapped = false;
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y);
}
}
#else
// fire TAP event when no 2nd tap occured within time // fire TAP event when no 2nd tap occured within time
if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) { if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) {
_tapped = false; _tapped = false;
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP); e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
LOG_DEBUG("action TAP(%d/%d)", _last_x, _last_y); LOG_DEBUG("action TAP(%d/%d)", _last_x, _last_y);
} }
#endif
// fire LONG_PRESS event without the need for release // fire LONG_PRESS event without the need for release
if (touched && (time_t(millis()) - _start) > TIME_LONG_PRESS) { if (touched && (time_t(millis()) - _start) > TIME_LONG_PRESS) {

View File

@ -30,6 +30,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;
} }
@ -42,14 +53,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()) {
@ -68,6 +73,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");
} }
@ -75,6 +82,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

@ -28,6 +28,10 @@
class FloodingRouter : public Router class FloodingRouter : public Router
{ {
private: private:
/** 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

@ -231,6 +231,9 @@ NodeDB::NodeDB()
moduleConfig.telemetry.health_update_interval = Default::getConfiguredOrMinimumValue( moduleConfig.telemetry.health_update_interval = Default::getConfiguredOrMinimumValue(
moduleConfig.telemetry.health_update_interval, min_default_telemetry_interval_secs); moduleConfig.telemetry.health_update_interval, min_default_telemetry_interval_secs);
} }
// Ensure that the neighbor info update interval is coerced to the minimum
moduleConfig.neighbor_info.update_interval =
Default::getConfiguredOrMinimumValue(moduleConfig.neighbor_info.update_interval, min_neighbor_info_broadcast_secs);
if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate))) if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate)))
saveWhat |= SEGMENT_DEVICESTATE; saveWhat |= SEGMENT_DEVICESTATE;
@ -243,6 +246,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);
} }
@ -435,8 +463,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 |
@ -473,7 +506,7 @@ void NodeDB::initConfigIntervals()
config.display.screen_on_secs = default_screen_on_secs; config.display.screen_on_secs = default_screen_on_secs;
#if defined(T_WATCH_S3) || defined(T_DECK) #if defined(T_WATCH_S3) || defined(T_DECK) || defined(RAK14014)
config.power.is_power_saving = true; config.power.is_power_saving = true;
config.display.screen_on_secs = 30; config.display.screen_on_secs = 30;
config.power.wait_bluetooth_secs = 30; config.power.wait_bluetooth_secs = 30;
@ -791,7 +824,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
@ -810,6 +843,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,
@ -1228,12 +1265,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

@ -41,13 +41,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) {
// If it was seen with a next-hop not set to us and now it's NO_NEXT_HOP_PREFERENCE, and the relayer relayed already // If it was seen with a next-hop not set to us and now it's NO_NEXT_HOP_PREFERENCE, and the relayer relayed already
// before, it's a fallback to flooding. If we didn't already relay and the next-hop neither, consider it unseen because we // before, it's a fallback to flooding. If we didn't already relay and the next-hop neither, consider it unseen because we

View File

@ -219,62 +219,70 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
} }
case STATE_SEND_METADATA: case STATE_SEND_METADATA:
LOG_DEBUG("Send Metadata"); LOG_DEBUG("Send device metadata");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag;
fromRadioScratch.metadata = getDeviceMetadata(); fromRadioScratch.metadata = getDeviceMetadata();
state = STATE_SEND_CHANNELS; state = STATE_SEND_CHANNELS;
break; break;
case STATE_SEND_CHANNELS: case STATE_SEND_CHANNELS:
LOG_DEBUG("Send Channels");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_channel_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_channel_tag;
fromRadioScratch.channel = channels.getByIndex(config_state); fromRadioScratch.channel = channels.getByIndex(config_state);
config_state++; config_state++;
// Advance when we have sent all of our Channels // Advance when we have sent all of our Channels
if (config_state >= MAX_NUM_CHANNELS) { if (config_state >= MAX_NUM_CHANNELS) {
LOG_DEBUG("Send channels %d", config_state);
state = STATE_SEND_CONFIG; state = STATE_SEND_CONFIG;
config_state = _meshtastic_AdminMessage_ConfigType_MIN + 1; config_state = _meshtastic_AdminMessage_ConfigType_MIN + 1;
} }
break; break;
case STATE_SEND_CONFIG: case STATE_SEND_CONFIG:
LOG_DEBUG("Send Radio config");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_tag;
switch (config_state) { switch (config_state) {
case meshtastic_Config_device_tag: case meshtastic_Config_device_tag:
LOG_DEBUG("Send config: device");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_device_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_device_tag;
fromRadioScratch.config.payload_variant.device = config.device; fromRadioScratch.config.payload_variant.device = config.device;
break; break;
case meshtastic_Config_position_tag: case meshtastic_Config_position_tag:
LOG_DEBUG("Send config: position");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_position_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_position_tag;
fromRadioScratch.config.payload_variant.position = config.position; fromRadioScratch.config.payload_variant.position = config.position;
break; break;
case meshtastic_Config_power_tag: case meshtastic_Config_power_tag:
LOG_DEBUG("Send config: power");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_power_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_power_tag;
fromRadioScratch.config.payload_variant.power = config.power; fromRadioScratch.config.payload_variant.power = config.power;
fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs; fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs;
break; break;
case meshtastic_Config_network_tag: case meshtastic_Config_network_tag:
LOG_DEBUG("Send config: network");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_network_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_network_tag;
fromRadioScratch.config.payload_variant.network = config.network; fromRadioScratch.config.payload_variant.network = config.network;
break; break;
case meshtastic_Config_display_tag: case meshtastic_Config_display_tag:
LOG_DEBUG("Send config: display");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_display_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_display_tag;
fromRadioScratch.config.payload_variant.display = config.display; fromRadioScratch.config.payload_variant.display = config.display;
break; break;
case meshtastic_Config_lora_tag: case meshtastic_Config_lora_tag:
LOG_DEBUG("Send config: lora");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_lora_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_lora_tag;
fromRadioScratch.config.payload_variant.lora = config.lora; fromRadioScratch.config.payload_variant.lora = config.lora;
break; break;
case meshtastic_Config_bluetooth_tag: case meshtastic_Config_bluetooth_tag:
LOG_DEBUG("Send config: bluetooth");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_bluetooth_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_bluetooth_tag;
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth; fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
break; break;
case meshtastic_Config_security_tag: case meshtastic_Config_security_tag:
LOG_DEBUG("Send config: security");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_security_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_security_tag;
fromRadioScratch.config.payload_variant.security = config.security; fromRadioScratch.config.payload_variant.security = config.security;
break; break;
case meshtastic_Config_sessionkey_tag: case meshtastic_Config_sessionkey_tag:
LOG_DEBUG("Send config: sessionkey");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_sessionkey_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_sessionkey_tag;
break; break;
default: default:
@ -293,58 +301,70 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
break; break;
case STATE_SEND_MODULECONFIG: case STATE_SEND_MODULECONFIG:
LOG_DEBUG("Send Module Config");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_moduleConfig_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_moduleConfig_tag;
switch (config_state) { switch (config_state) {
case meshtastic_ModuleConfig_mqtt_tag: case meshtastic_ModuleConfig_mqtt_tag:
LOG_DEBUG("Send module config: mqtt");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_mqtt_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_mqtt_tag;
fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt; fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt;
break; break;
case meshtastic_ModuleConfig_serial_tag: case meshtastic_ModuleConfig_serial_tag:
LOG_DEBUG("Send module config: serial");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_serial_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_serial_tag;
fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial; fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial;
break; break;
case meshtastic_ModuleConfig_external_notification_tag: case meshtastic_ModuleConfig_external_notification_tag:
LOG_DEBUG("Send module config: ext notification");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_external_notification_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_external_notification_tag;
fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification; fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification;
break; break;
case meshtastic_ModuleConfig_store_forward_tag: case meshtastic_ModuleConfig_store_forward_tag:
LOG_DEBUG("Send module config: store forward");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_store_forward_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_store_forward_tag;
fromRadioScratch.moduleConfig.payload_variant.store_forward = moduleConfig.store_forward; fromRadioScratch.moduleConfig.payload_variant.store_forward = moduleConfig.store_forward;
break; break;
case meshtastic_ModuleConfig_range_test_tag: case meshtastic_ModuleConfig_range_test_tag:
LOG_DEBUG("Send module config: range test");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_range_test_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_range_test_tag;
fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test; fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test;
break; break;
case meshtastic_ModuleConfig_telemetry_tag: case meshtastic_ModuleConfig_telemetry_tag:
LOG_DEBUG("Send module config: telemetry");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_telemetry_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_telemetry_tag;
fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry; fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry;
break; break;
case meshtastic_ModuleConfig_canned_message_tag: case meshtastic_ModuleConfig_canned_message_tag:
LOG_DEBUG("Send module config: canned message");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_canned_message_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_canned_message_tag;
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message; fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
break; break;
case meshtastic_ModuleConfig_audio_tag: case meshtastic_ModuleConfig_audio_tag:
LOG_DEBUG("Send module config: audio");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_audio_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_audio_tag;
fromRadioScratch.moduleConfig.payload_variant.audio = moduleConfig.audio; fromRadioScratch.moduleConfig.payload_variant.audio = moduleConfig.audio;
break; break;
case meshtastic_ModuleConfig_remote_hardware_tag: case meshtastic_ModuleConfig_remote_hardware_tag:
LOG_DEBUG("Send module config: remote hardware");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_remote_hardware_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_remote_hardware_tag;
fromRadioScratch.moduleConfig.payload_variant.remote_hardware = moduleConfig.remote_hardware; fromRadioScratch.moduleConfig.payload_variant.remote_hardware = moduleConfig.remote_hardware;
break; break;
case meshtastic_ModuleConfig_neighbor_info_tag: case meshtastic_ModuleConfig_neighbor_info_tag:
LOG_DEBUG("Send module config: neighbor info");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag;
fromRadioScratch.moduleConfig.payload_variant.neighbor_info = moduleConfig.neighbor_info; fromRadioScratch.moduleConfig.payload_variant.neighbor_info = moduleConfig.neighbor_info;
break; break;
case meshtastic_ModuleConfig_detection_sensor_tag: case meshtastic_ModuleConfig_detection_sensor_tag:
LOG_DEBUG("Send module config: detection sensor");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
fromRadioScratch.moduleConfig.payload_variant.detection_sensor = moduleConfig.detection_sensor; fromRadioScratch.moduleConfig.payload_variant.detection_sensor = moduleConfig.detection_sensor;
break; break;
case meshtastic_ModuleConfig_ambient_lighting_tag: case meshtastic_ModuleConfig_ambient_lighting_tag:
LOG_DEBUG("Send module config: ambient lighting");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_ambient_lighting_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_ambient_lighting_tag;
fromRadioScratch.moduleConfig.payload_variant.ambient_lighting = moduleConfig.ambient_lighting; fromRadioScratch.moduleConfig.payload_variant.ambient_lighting = moduleConfig.ambient_lighting;
break; break;
case meshtastic_ModuleConfig_paxcounter_tag: case meshtastic_ModuleConfig_paxcounter_tag:
LOG_DEBUG("Send module config: paxcounter");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_paxcounter_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_paxcounter_tag;
fromRadioScratch.moduleConfig.payload_variant.paxcounter = moduleConfig.paxcounter; fromRadioScratch.moduleConfig.payload_variant.paxcounter = moduleConfig.paxcounter;
break; break;
@ -444,7 +464,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
return numbytes; return numbytes;
} }
LOG_DEBUG("no FromRadio packet available"); LOG_DEBUG("No FromRadio packet available");
return 0; return 0;
} }

View File

@ -657,6 +657,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,8 +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;
/* Last byte of the node number of the node that should be used as the next hop to reach this node. */ /* True if node is in our ignored list
uint8_t next_hop; 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
@ -184,7 +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_next_hop_tag 11 #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
@ -230,7 +231,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, UINT32, next_hop, 11) 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
@ -283,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 186 #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
@ -291,4 +292,4 @@ extern const pb_msgdesc_t meshtastic_ChannelFile_msg;
} /* extern "C" */ } /* extern "C" */
#endif #endif
#endif #endif

View File

@ -801,6 +801,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;
@ -1160,8 +1163,8 @@ extern "C" {
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} #define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#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, 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}
@ -1185,8 +1188,8 @@ extern "C" {
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} #define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#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, 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}
@ -1293,6 +1296,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
@ -1493,7 +1497,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
@ -1732,7 +1737,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
@ -1746,4 +1751,4 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
} /* extern "C" */ } /* extern "C" */
#endif #endif
#endif #endif

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

@ -283,6 +283,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());
@ -504,6 +526,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

@ -325,7 +325,9 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
this->shift = !this->shift; this->shift = !this->shift;
} else if (keyTapped == "") { } else if (keyTapped == "") {
#ifndef RAK14014
this->highlight = keyTapped[0]; this->highlight = keyTapped[0];
#endif
this->payload = 0x08; this->payload = 0x08;
@ -341,7 +343,9 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
validEvent = true; validEvent = true;
} else if (keyTapped == " ") { } else if (keyTapped == " ") {
#ifndef RAK14014
this->highlight = keyTapped[0]; this->highlight = keyTapped[0];
#endif
this->payload = keyTapped[0]; this->payload = keyTapped[0];
@ -361,7 +365,9 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
this->shift = false; this->shift = false;
} else if (keyTapped != "") { } else if (keyTapped != "") {
#ifndef RAK14014
this->highlight = keyTapped[0]; this->highlight = keyTapped[0];
#endif
this->payload = this->shift ? keyTapped[0] : std::tolower(keyTapped[0]); this->payload = this->shift ? keyTapped[0] : std::tolower(keyTapped[0]);
@ -830,6 +836,11 @@ void CannedMessageModule::drawKeyboard(OLEDDisplay *display, OLEDDisplayUiState
Letter updatedLetter = {letter.character, letter.width, xOffset, yOffset, cellWidth, cellHeight}; Letter updatedLetter = {letter.character, letter.width, xOffset, yOffset, cellWidth, cellHeight};
#ifdef RAK14014 // Optimize the touch range of the virtual keyboard in the bottom row
if (outerIndex == outerSize - 1) {
updatedLetter.rectHeight = 240 - yOffset;
}
#endif
this->keyboard[this->charSet][outerIndex][innerIndex] = updatedLetter; this->keyboard[this->charSet][outerIndex][innerIndex] = updatedLetter;
float characterOffset = ((cellWidth / 2) - (letter.width / 2)); float characterOffset = ((cellWidth / 2) - (letter.width / 2));

View File

@ -68,6 +68,10 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
String drawWithCursor(String text, int cursor); String drawWithCursor(String text, int cursor);
#ifdef RAK14014
cannedMessageModuleRunState getRunState() const { return runState; }
#endif
/* /*
-Override the wantPacket method. We need the Routing Messages to look for ACKs. -Override the wantPacket method. We need the Routing Messages to look for ACKs.
*/ */

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

@ -580,6 +580,7 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp_encrypted, const meshtastic_Me
LOG_DEBUG("portnum %i message", env->packet->decoded.portnum); LOG_DEBUG("portnum %i message", env->packet->decoded.portnum);
} else { } else {
LOG_DEBUG("nothing, pkt not decrypted"); LOG_DEBUG("nothing, pkt not decrypted");
mqttPool.release(env);
return; // Don't upload a still-encrypted PKI packet if not encryption_enabled return; // Don't upload a still-encrypted PKI packet if not encryption_enabled
} }
@ -768,4 +769,4 @@ bool MQTT::isPrivateIpAddress(const char address[])
int octet2Num = atoi(octet2); int octet2Num = atoi(octet2);
return octet2Num >= 16 && octet2Num <= 31; return octet2Num >= 16 && octet2Num <= 31;
} }

View File

@ -170,8 +170,6 @@
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_VISION_MASTER_E213 #define HW_VENDOR meshtastic_HardwareModel_HELTEC_VISION_MASTER_E213
#elif defined(HELTEC_VISION_MASTER_E290) #elif defined(HELTEC_VISION_MASTER_E290)
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_VISION_MASTER_E290 #define HW_VENDOR meshtastic_HardwareModel_HELTEC_VISION_MASTER_E290
#elif defined(HELTEC_MESH_NODE_T114)
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T114
#elif defined(SENSECAP_INDICATOR) #elif defined(SENSECAP_INDICATOR)
#define HW_VENDOR meshtastic_HardwareModel_SENSECAP_INDICATOR #define HW_VENDOR meshtastic_HardwareModel_SENSECAP_INDICATOR
#elif defined(SEEED_XIAO_S3) #elif defined(SEEED_XIAO_S3)

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,15 +1,20 @@
; 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:rak10701] [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/rak10701 -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"
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely. -DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN -DEINK_DISPLAY_MODEL=GxEPD2_213_BN
-DEINK_WIDTH=250 -DEINK_WIDTH=250
-DEINK_HEIGHT=122 -DEINK_HEIGHT=122
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak10701> +<mesh/eth/> +<mesh/api/> +<mqtt/> -DMESHTASTIC_EXCLUDE_WIFI=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/>
lib_deps = lib_deps =
${nrf52840_base.lib_deps} ${nrf52840_base.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
@ -21,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

@ -243,7 +243,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
// Therefore must be 1 to keep peripherals powered // Therefore must be 1 to keep peripherals powered
// Power is on the controllable 3V3_S rail // Power is on the controllable 3V3_S rail
// #define PIN_GPS_RESET (34) // #define PIN_GPS_RESET (34)
#define PIN_GPS_EN PIN_3V3_EN // #define PIN_GPS_EN PIN_3V3_EN
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS #define PIN_GPS_PPS (17) // Pulse per second input from the GPS
#define GPS_RX_PIN PIN_SERIAL1_RX #define GPS_RX_PIN PIN_SERIAL1_RX

View File

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