From 5d0113ce0ce63cdb84be349026e53a0d796184ff Mon Sep 17 00:00:00 2001 From: ford-jones Date: Fri, 10 Oct 2025 21:44:18 +1300 Subject: [PATCH 01/12] Conditionally delete favourited nodes on reset --- src/mesh/NodeDB.cpp | 18 +++++++++++++++++- src/mesh/NodeDB.h | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index dec8411fe..639e5bc45 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -402,6 +402,11 @@ NodeDB::NodeDB() config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED; config.position.gps_enabled = 0; } + if (config.device.role == meshtastic_Config_DeviceConfig_Role_CLIENT_BASE || + config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || + config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE) { + saveFavourites == true; + } #ifdef USERPREFS_FIRMWARE_EDITION myNodeInfo.firmware_edition = USERPREFS_FIRMWARE_EDITION; #endif @@ -983,7 +988,18 @@ void NodeDB::resetNodes() if (!config.position.fixed_position) clearLocalPosition(); numMeshNodes = 1; - std::fill(nodeDatabase.nodes.begin() + 1, nodeDatabase.nodes.end(), meshtastic_NodeInfoLite()); + if (saveFavourites) { + for (size_t i = 0; i < nodeDatabase.nodes.size(); i++) { + meshtastic_NodeInfoLite &node = nodeDatabase.nodes[i]; + if (i > 0 && !node.is_favorite) { + node = meshtastic_NodeInfoLite(); + } else { + numMeshNodes += 1; + } + }; + } else { + std::fill(nodeDatabase.nodes.begin() + 1, nodeDatabase.nodes.end(), meshtastic_NodeInfoLite()); + } devicestate.has_rx_text_message = false; devicestate.has_rx_waypoint = false; saveNodeDatabaseToDisk(); diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index e8724f2c9..a1722a403 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -144,6 +144,8 @@ class NodeDB bool keyIsLowEntropy = false; bool hasWarned = false; + bool saveFavourites = false; + /// don't do mesh based algorithm for node id assignment (initially) /// instead just store in flash - possibly even in the initial alpha release do this hack NodeDB(); From 29585aa1cbb1d88528dd0b1b9b40e8e84319daa8 Mon Sep 17 00:00:00 2001 From: ford-jones Date: Fri, 10 Oct 2025 21:44:31 +1300 Subject: [PATCH 02/12] trunk fmt --- src/detect/ScanI2CTwoWire.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 89a0610b4..d6daf7b7a 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -378,7 +378,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) case SHT31_4x_ADDR: // same as OPT3001_ADDR_ALT case SHT31_4x_ADDR_ALT: // same as OPT3001_ADDR registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2); - if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0x11f3 || registerValue == 0xe9c || registerValue == 0xc8d) { + if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0x11f3 || registerValue == 0xe9c || + registerValue == 0xc8d) { type = SHT4X; logFoundDevice("SHT4X", (uint8_t)addr.address); } else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) { From da8a3a328e234b16e438767963203b436800b994 Mon Sep 17 00:00:00 2001 From: ford-jones Date: Fri, 10 Oct 2025 22:16:11 +1300 Subject: [PATCH 03/12] Fix equality check, use existing macro for role validation --- src/mesh/NodeDB.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 639e5bc45..b3e96da22 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -402,10 +402,9 @@ NodeDB::NodeDB() config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED; config.position.gps_enabled = 0; } - if (config.device.role == meshtastic_Config_DeviceConfig_Role_CLIENT_BASE || - config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || - config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE) { - saveFavourites == true; + if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE, meshtastic_Config_DeviceConfig_Role_ROUTER, + meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) { + saveFavourites = true; } #ifdef USERPREFS_FIRMWARE_EDITION myNodeInfo.firmware_edition = USERPREFS_FIRMWARE_EDITION; From 39be63d7af7b67c201ff391408f93dc92244004b Mon Sep 17 00:00:00 2001 From: ford-jones Date: Sat, 11 Oct 2025 00:00:54 +1300 Subject: [PATCH 04/12] Extend favourite persistence setting to devices of all roles --- src/mesh/NodeDB.cpp | 3 ++- src/mesh/generated/meshtastic/config.pb.h | 12 ++++++++---- src/mesh/generated/meshtastic/deviceonly.pb.h | 2 +- src/mesh/generated/meshtastic/localonly.pb.h | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index b3e96da22..a2611dacf 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -402,7 +402,8 @@ NodeDB::NodeDB() config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED; config.position.gps_enabled = 0; } - if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE, meshtastic_Config_DeviceConfig_Role_ROUTER, + if (config.device.preserve_favourites || + IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE, meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) { saveFavourites = true; } diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 327568316..f74863536 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -357,6 +357,8 @@ typedef struct _meshtastic_Config_DeviceConfig { /* Controls buzzer behavior for audio feedback Defaults to ENABLED */ meshtastic_Config_DeviceConfig_BuzzerMode buzzer_mode; + /* Tell the node to persist favourited nodes following a NodeDB reset. */ + bool preserve_favourites; } meshtastic_Config_DeviceConfig; /* Position Config */ @@ -723,7 +725,7 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}} -#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN} +#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN, 0} #define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN} #define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0, 0} @@ -734,7 +736,7 @@ extern "C" { #define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0} #define meshtastic_Config_SessionkeyConfig_init_default {0} #define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}} -#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN} +#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN, 0} #define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN} #define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0, 0} @@ -758,6 +760,7 @@ extern "C" { #define meshtastic_Config_DeviceConfig_tzdef_tag 11 #define meshtastic_Config_DeviceConfig_led_heartbeat_disabled_tag 12 #define meshtastic_Config_DeviceConfig_buzzer_mode_tag 13 +#define meshtastic_Config_DeviceConfig_preserve_favourites_tag 14 #define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1 #define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2 #define meshtastic_Config_PositionConfig_fixed_position_tag 3 @@ -883,7 +886,8 @@ X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \ X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \ X(a, STATIC, SINGULAR, STRING, tzdef, 11) \ X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12) \ -X(a, STATIC, SINGULAR, UENUM, buzzer_mode, 13) +X(a, STATIC, SINGULAR, UENUM, buzzer_mode, 13) \ +X(a, STATIC, SINGULAR, BOOL, preserve_favourites, 14) #define meshtastic_Config_DeviceConfig_CALLBACK NULL #define meshtastic_Config_DeviceConfig_DEFAULT NULL @@ -1030,7 +1034,7 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size #define meshtastic_Config_BluetoothConfig_size 10 -#define meshtastic_Config_DeviceConfig_size 100 +#define meshtastic_Config_DeviceConfig_size 102 #define meshtastic_Config_DisplayConfig_size 34 #define meshtastic_Config_LoRaConfig_size 85 #define meshtastic_Config_NetworkConfig_IpV4Config_size 20 diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index b5b116137..76a3ee253 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -360,7 +360,7 @@ extern const pb_msgdesc_t meshtastic_BackupPreferences_msg; /* Maximum encoded size of messages (where known) */ /* meshtastic_NodeDatabase_size depends on runtime parameters */ #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size -#define meshtastic_BackupPreferences_size 2293 +#define meshtastic_BackupPreferences_size 2295 #define meshtastic_ChannelFile_size 734 #define meshtastic_DeviceState_size 1737 #define meshtastic_NodeInfoLite_size 196 diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 3ab6f02c1..2c0d889fc 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -187,7 +187,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size -#define meshtastic_LocalConfig_size 749 +#define meshtastic_LocalConfig_size 751 #define meshtastic_LocalModuleConfig_size 673 #ifdef __cplusplus From 0de61c398613789732f32f2fa3838c825bd870e6 Mon Sep 17 00:00:00 2001 From: ford-jones Date: Sat, 11 Oct 2025 13:45:31 +1300 Subject: [PATCH 05/12] Refactor: Decoupled role/config check and set role defaults appropriately --- src/mesh/NodeDB.cpp | 7 +------ src/mesh/NodeDB.h | 2 -- src/modules/AdminModule.cpp | 7 +++++++ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index a2611dacf..7f0e9b9c6 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -402,11 +402,6 @@ NodeDB::NodeDB() config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED; config.position.gps_enabled = 0; } - if (config.device.preserve_favourites || - IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE, meshtastic_Config_DeviceConfig_Role_ROUTER, - meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) { - saveFavourites = true; - } #ifdef USERPREFS_FIRMWARE_EDITION myNodeInfo.firmware_edition = USERPREFS_FIRMWARE_EDITION; #endif @@ -988,7 +983,7 @@ void NodeDB::resetNodes() if (!config.position.fixed_position) clearLocalPosition(); numMeshNodes = 1; - if (saveFavourites) { + if (config.device.preserve_favourites) { for (size_t i = 0; i < nodeDatabase.nodes.size(); i++) { meshtastic_NodeInfoLite &node = nodeDatabase.nodes[i]; if (i > 0 && !node.is_favorite) { diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index a1722a403..e8724f2c9 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -144,8 +144,6 @@ class NodeDB bool keyIsLowEntropy = false; bool hasWarned = false; - bool saveFavourites = false; - /// don't do mesh based algorithm for node id assignment (initially) /// instead just store in flash - possibly even in the initial alpha release do this hack NodeDB(); diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index d300ff53b..e5670f98a 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -634,6 +634,13 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) requiresReboot = true; } } + // Router, Router Late and Client Base roles persist their favourites through NodeDB reset by default. + // In accordance with the ability to preserve hops when relayed via a favorite added in + // https://github.com/meshtastic/firmware/pull/7992 + if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE, + meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) { + config.device.preserve_favourites = true; + }; #if USERPREFS_EVENT_MODE // If we're in event mode, nobody is a Router or Router Late if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || From a0df0a3aacd7dfe2202c91ccde9fbf3301660e93 Mon Sep 17 00:00:00 2001 From: ford-jones Date: Sat, 11 Oct 2025 13:46:44 +1300 Subject: [PATCH 06/12] Use American-English spelling --- protobufs | 2 +- src/mesh/NodeDB.cpp | 2 +- src/mesh/generated/meshtastic/config.pb.h | 8 ++++---- src/modules/AdminModule.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/protobufs b/protobufs index a1b8c3d17..9adb17d94 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit a1b8c3d171445b2eebfd4b5bd1e4876f3bbed605 +Subproject commit 9adb17d940c236625ab0bcf6fb3c4c6ddfc695e9 diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 7f0e9b9c6..4362a67a0 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -983,7 +983,7 @@ void NodeDB::resetNodes() if (!config.position.fixed_position) clearLocalPosition(); numMeshNodes = 1; - if (config.device.preserve_favourites) { + if (config.device.preserve_favorites) { for (size_t i = 0; i < nodeDatabase.nodes.size(); i++) { meshtastic_NodeInfoLite &node = nodeDatabase.nodes[i]; if (i > 0 && !node.is_favorite) { diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index f74863536..4d6b3ca9d 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -357,8 +357,8 @@ typedef struct _meshtastic_Config_DeviceConfig { /* Controls buzzer behavior for audio feedback Defaults to ENABLED */ meshtastic_Config_DeviceConfig_BuzzerMode buzzer_mode; - /* Tell the node to persist favourited nodes following a NodeDB reset. */ - bool preserve_favourites; + /* When true, favourited nodes are persisted through NodeDB resets. */ + bool preserve_favorites; } meshtastic_Config_DeviceConfig; /* Position Config */ @@ -760,7 +760,7 @@ extern "C" { #define meshtastic_Config_DeviceConfig_tzdef_tag 11 #define meshtastic_Config_DeviceConfig_led_heartbeat_disabled_tag 12 #define meshtastic_Config_DeviceConfig_buzzer_mode_tag 13 -#define meshtastic_Config_DeviceConfig_preserve_favourites_tag 14 +#define meshtastic_Config_DeviceConfig_preserve_favorites_tag 14 #define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1 #define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2 #define meshtastic_Config_PositionConfig_fixed_position_tag 3 @@ -887,7 +887,7 @@ X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \ X(a, STATIC, SINGULAR, STRING, tzdef, 11) \ X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12) \ X(a, STATIC, SINGULAR, UENUM, buzzer_mode, 13) \ -X(a, STATIC, SINGULAR, BOOL, preserve_favourites, 14) +X(a, STATIC, SINGULAR, BOOL, preserve_favorites, 14) #define meshtastic_Config_DeviceConfig_CALLBACK NULL #define meshtastic_Config_DeviceConfig_DEFAULT NULL diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index e5670f98a..cd24bbafe 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -639,7 +639,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) // https://github.com/meshtastic/firmware/pull/7992 if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE, meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) { - config.device.preserve_favourites = true; + config.device.preserve_favorites = true; }; #if USERPREFS_EVENT_MODE // If we're in event mode, nobody is a Router or Router Late From 8fbd1d10e990843ffaaae1190c9300bcea646857 Mon Sep 17 00:00:00 2001 From: ford-jones Date: Sun, 12 Oct 2025 12:24:36 +1300 Subject: [PATCH 07/12] Use existing reference --- protobufs | 2 +- src/mesh/NodeDB.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/protobufs b/protobufs index 9adb17d94..38d066501 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 9adb17d940c236625ab0bcf6fb3c4c6ddfc695e9 +Subproject commit 38d066501125b37d866cd01ea7d97c3ef6909041 diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 4362a67a0..84e15cb8d 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -984,8 +984,8 @@ void NodeDB::resetNodes() clearLocalPosition(); numMeshNodes = 1; if (config.device.preserve_favorites) { - for (size_t i = 0; i < nodeDatabase.nodes.size(); i++) { - meshtastic_NodeInfoLite &node = nodeDatabase.nodes[i]; + for (size_t i = 0; i < meshNodes->size(); i++) { + meshtastic_NodeInfoLite &node = meshNodes->at(i); if (i > 0 && !node.is_favorite) { node = meshtastic_NodeInfoLite(); } else { From eca3d2da7e39aed442bfaaf4ad4dabc653b27441 Mon Sep 17 00:00:00 2001 From: ford-jones Date: Sun, 12 Oct 2025 16:57:40 +1300 Subject: [PATCH 08/12] Convert reset to bool, regen protos --- src/mesh/generated/meshtastic/admin.pb.h | 7 ++++--- src/mesh/generated/meshtastic/config.pb.h | 12 ++++-------- src/mesh/generated/meshtastic/deviceonly.pb.h | 2 +- src/mesh/generated/meshtastic/localonly.pb.h | 2 +- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h index 7cc896292..a542cf29c 100644 --- a/src/mesh/generated/meshtastic/admin.pb.h +++ b/src/mesh/generated/meshtastic/admin.pb.h @@ -272,8 +272,9 @@ typedef struct _meshtastic_AdminMessage { int32_t shutdown_seconds; /* Tell the node to factory reset config; all device state and configuration will be returned to factory defaults; BLE bonds will be preserved. */ int32_t factory_reset_config; - /* Tell the node to reset the nodedb. */ - int32_t nodedb_reset; + /* Tell the node to reset the nodedb. + When true, favorites are preserved through reset. */ + bool nodedb_reset; }; /* The node generates this key and sends it with any get_x_response packets. The client MUST include the same key with any set_x commands. Key expires after 300 seconds. @@ -459,7 +460,7 @@ X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulato X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_seconds,reboot_seconds), 97) \ X(a, STATIC, ONEOF, INT32, (payload_variant,shutdown_seconds,shutdown_seconds), 98) \ X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_config,factory_reset_config), 99) \ -X(a, STATIC, ONEOF, INT32, (payload_variant,nodedb_reset,nodedb_reset), 100) \ +X(a, STATIC, ONEOF, BOOL, (payload_variant,nodedb_reset,nodedb_reset), 100) \ X(a, STATIC, SINGULAR, BYTES, session_passkey, 101) #define meshtastic_AdminMessage_CALLBACK NULL #define meshtastic_AdminMessage_DEFAULT NULL diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 4d6b3ca9d..327568316 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -357,8 +357,6 @@ typedef struct _meshtastic_Config_DeviceConfig { /* Controls buzzer behavior for audio feedback Defaults to ENABLED */ meshtastic_Config_DeviceConfig_BuzzerMode buzzer_mode; - /* When true, favourited nodes are persisted through NodeDB resets. */ - bool preserve_favorites; } meshtastic_Config_DeviceConfig; /* Position Config */ @@ -725,7 +723,7 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}} -#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN, 0} +#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN} #define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN} #define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0, 0} @@ -736,7 +734,7 @@ extern "C" { #define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0} #define meshtastic_Config_SessionkeyConfig_init_default {0} #define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}} -#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN, 0} +#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN} #define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN} #define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0, 0} @@ -760,7 +758,6 @@ extern "C" { #define meshtastic_Config_DeviceConfig_tzdef_tag 11 #define meshtastic_Config_DeviceConfig_led_heartbeat_disabled_tag 12 #define meshtastic_Config_DeviceConfig_buzzer_mode_tag 13 -#define meshtastic_Config_DeviceConfig_preserve_favorites_tag 14 #define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1 #define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2 #define meshtastic_Config_PositionConfig_fixed_position_tag 3 @@ -886,8 +883,7 @@ X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \ X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \ X(a, STATIC, SINGULAR, STRING, tzdef, 11) \ X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12) \ -X(a, STATIC, SINGULAR, UENUM, buzzer_mode, 13) \ -X(a, STATIC, SINGULAR, BOOL, preserve_favorites, 14) +X(a, STATIC, SINGULAR, UENUM, buzzer_mode, 13) #define meshtastic_Config_DeviceConfig_CALLBACK NULL #define meshtastic_Config_DeviceConfig_DEFAULT NULL @@ -1034,7 +1030,7 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size #define meshtastic_Config_BluetoothConfig_size 10 -#define meshtastic_Config_DeviceConfig_size 102 +#define meshtastic_Config_DeviceConfig_size 100 #define meshtastic_Config_DisplayConfig_size 34 #define meshtastic_Config_LoRaConfig_size 85 #define meshtastic_Config_NetworkConfig_IpV4Config_size 20 diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index 76a3ee253..b5b116137 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -360,7 +360,7 @@ extern const pb_msgdesc_t meshtastic_BackupPreferences_msg; /* Maximum encoded size of messages (where known) */ /* meshtastic_NodeDatabase_size depends on runtime parameters */ #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size -#define meshtastic_BackupPreferences_size 2295 +#define meshtastic_BackupPreferences_size 2293 #define meshtastic_ChannelFile_size 734 #define meshtastic_DeviceState_size 1737 #define meshtastic_NodeInfoLite_size 196 diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 2c0d889fc..3ab6f02c1 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -187,7 +187,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size -#define meshtastic_LocalConfig_size 751 +#define meshtastic_LocalConfig_size 749 #define meshtastic_LocalModuleConfig_size 673 #ifdef __cplusplus From 93ee451eb1f3bc963273d817d791bec635a5b802 Mon Sep 17 00:00:00 2001 From: ford-jones Date: Sun, 12 Oct 2025 16:59:14 +1300 Subject: [PATCH 09/12] Add optional arg to nodedb_reset in favor of additional device setting --- src/mesh/NodeDB.cpp | 4 ++-- src/mesh/NodeDB.h | 3 ++- src/modules/AdminModule.cpp | 14 ++++++-------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 84e15cb8d..db8c680b5 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -978,12 +978,12 @@ void NodeDB::installDefaultChannels() channelFile.version = DEVICESTATE_CUR_VER; } -void NodeDB::resetNodes() +void NodeDB::resetNodes(bool keepFavorites) { if (!config.position.fixed_position) clearLocalPosition(); numMeshNodes = 1; - if (config.device.preserve_favorites) { + if (keepFavorites) { for (size_t i = 0; i < meshNodes->size(); i++) { meshtastic_NodeInfoLite &node = meshNodes->at(i); if (i > 0 && !node.is_favorite) { diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index e8724f2c9..444ac13e4 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -229,7 +229,8 @@ class NodeDB */ size_t getNumOnlineMeshNodes(bool localOnly = false); - void initConfigIntervals(), initModuleConfigIntervals(), resetNodes(), removeNodeByNum(NodeNum nodeNum); + void initConfigIntervals(), initModuleConfigIntervals(), resetNodes(bool keepFavorites = false), + removeNodeByNum(NodeNum nodeNum); bool factoryReset(bool eraseBleBonds = false); diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index cd24bbafe..ddb7cacd3 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -280,7 +280,12 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta case meshtastic_AdminMessage_nodedb_reset_tag: { disableBluetooth(); LOG_INFO("Initiate node-db reset"); - nodeDB->resetNodes(); + // CLIENT_BASE, ROUTER and ROUTER_LATE are able to preserve the remaining hop count when relaying a packet via a + // favorited node, so ensure that their favorites are kept on reset + bool rolePreference = + isOneOf(config.device.role, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE, + meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_ROUTER_LATE); + nodeDB->resetNodes(rolePreference ? rolePreference : r->nodedb_reset); reboot(DEFAULT_REBOOT_SECONDS); break; } @@ -634,13 +639,6 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) requiresReboot = true; } } - // Router, Router Late and Client Base roles persist their favourites through NodeDB reset by default. - // In accordance with the ability to preserve hops when relayed via a favorite added in - // https://github.com/meshtastic/firmware/pull/7992 - if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE, - meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) { - config.device.preserve_favorites = true; - }; #if USERPREFS_EVENT_MODE // If we're in event mode, nobody is a Router or Router Late if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || From 1347c9c3818b49bef21a7a3972ffc6a290450014 Mon Sep 17 00:00:00 2001 From: ford-jones Date: Mon, 13 Oct 2025 11:24:55 +1300 Subject: [PATCH 10/12] Use correct proto commit ID --- protobufs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protobufs b/protobufs index 38d066501..68dee221b 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 38d066501125b37d866cd01ea7d97c3ef6909041 +Subproject commit 68dee221b201e99b3124be85953c834ade6f7cc1 From be93508e58cce117af74c0b7883677223a95efaf Mon Sep 17 00:00:00 2001 From: ford-jones Date: Mon, 13 Oct 2025 11:29:17 +1300 Subject: [PATCH 11/12] Regen protos --- protobufs | 2 +- src/mesh/generated/meshtastic/apponly.pb.h | 2 +- src/mesh/generated/meshtastic/channel.pb.h | 22 ++++++++----------- src/mesh/generated/meshtastic/deviceonly.pb.h | 4 ++-- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/protobufs b/protobufs index 68dee221b..a916c4929 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 68dee221b201e99b3124be85953c834ade6f7cc1 +Subproject commit a916c49299cd3739a33a8c08bfbbc8248b51476d diff --git a/src/mesh/generated/meshtastic/apponly.pb.h b/src/mesh/generated/meshtastic/apponly.pb.h index db9dedaaf..f4c33bd79 100644 --- a/src/mesh/generated/meshtastic/apponly.pb.h +++ b/src/mesh/generated/meshtastic/apponly.pb.h @@ -55,7 +55,7 @@ extern const pb_msgdesc_t meshtastic_ChannelSet_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size -#define meshtastic_ChannelSet_size 695 +#define meshtastic_ChannelSet_size 679 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/meshtastic/channel.pb.h b/src/mesh/generated/meshtastic/channel.pb.h index d5573a1e2..9dc757ab4 100644 --- a/src/mesh/generated/meshtastic/channel.pb.h +++ b/src/mesh/generated/meshtastic/channel.pb.h @@ -34,9 +34,9 @@ typedef enum _meshtastic_Channel_Role { typedef struct _meshtastic_ModuleSettings { /* Bits of precision for the location sent in position packets. */ uint32_t position_precision; - /* Controls whether or not the phone / clients should mute the current channel + /* Controls whether or not the client / device should mute the current channel Useful for noisy public channels you don't necessarily want to disable */ - bool is_client_muted; + bool is_muted; } meshtastic_ModuleSettings; typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t; @@ -97,8 +97,6 @@ typedef struct _meshtastic_ChannelSettings { /* Per-channel module settings. */ bool has_module_settings; meshtastic_ModuleSettings module_settings; - /* Whether or not we should receive notifactions / alerts through this channel */ - bool mute; } meshtastic_ChannelSettings; /* A pair of a channel number, mode and the (sharable) settings for that channel */ @@ -130,16 +128,16 @@ extern "C" { /* Initializer values for message structs */ -#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default, 0} +#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default} #define meshtastic_ModuleSettings_init_default {0, 0} #define meshtastic_Channel_init_default {0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN} -#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero, 0} +#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero} #define meshtastic_ModuleSettings_init_zero {0, 0} #define meshtastic_Channel_init_zero {0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN} /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_ModuleSettings_position_precision_tag 1 -#define meshtastic_ModuleSettings_is_client_muted_tag 2 +#define meshtastic_ModuleSettings_is_muted_tag 2 #define meshtastic_ChannelSettings_channel_num_tag 1 #define meshtastic_ChannelSettings_psk_tag 2 #define meshtastic_ChannelSettings_name_tag 3 @@ -147,7 +145,6 @@ extern "C" { #define meshtastic_ChannelSettings_uplink_enabled_tag 5 #define meshtastic_ChannelSettings_downlink_enabled_tag 6 #define meshtastic_ChannelSettings_module_settings_tag 7 -#define meshtastic_ChannelSettings_mute_tag 8 #define meshtastic_Channel_index_tag 1 #define meshtastic_Channel_settings_tag 2 #define meshtastic_Channel_role_tag 3 @@ -160,15 +157,14 @@ X(a, STATIC, SINGULAR, STRING, name, 3) \ X(a, STATIC, SINGULAR, FIXED32, id, 4) \ X(a, STATIC, SINGULAR, BOOL, uplink_enabled, 5) \ X(a, STATIC, SINGULAR, BOOL, downlink_enabled, 6) \ -X(a, STATIC, OPTIONAL, MESSAGE, module_settings, 7) \ -X(a, STATIC, SINGULAR, BOOL, mute, 8) +X(a, STATIC, OPTIONAL, MESSAGE, module_settings, 7) #define meshtastic_ChannelSettings_CALLBACK NULL #define meshtastic_ChannelSettings_DEFAULT NULL #define meshtastic_ChannelSettings_module_settings_MSGTYPE meshtastic_ModuleSettings #define meshtastic_ModuleSettings_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UINT32, position_precision, 1) \ -X(a, STATIC, SINGULAR, BOOL, is_client_muted, 2) +X(a, STATIC, SINGULAR, BOOL, is_muted, 2) #define meshtastic_ModuleSettings_CALLBACK NULL #define meshtastic_ModuleSettings_DEFAULT NULL @@ -191,8 +187,8 @@ extern const pb_msgdesc_t meshtastic_Channel_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_MAX_SIZE meshtastic_Channel_size -#define meshtastic_ChannelSettings_size 74 -#define meshtastic_Channel_size 89 +#define meshtastic_ChannelSettings_size 72 +#define meshtastic_Channel_size 87 #define meshtastic_ModuleSettings_size 8 #ifdef __cplusplus diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index b5b116137..7fab82ff7 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -360,8 +360,8 @@ extern const pb_msgdesc_t meshtastic_BackupPreferences_msg; /* Maximum encoded size of messages (where known) */ /* meshtastic_NodeDatabase_size depends on runtime parameters */ #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size -#define meshtastic_BackupPreferences_size 2293 -#define meshtastic_ChannelFile_size 734 +#define meshtastic_BackupPreferences_size 2277 +#define meshtastic_ChannelFile_size 718 #define meshtastic_DeviceState_size 1737 #define meshtastic_NodeInfoLite_size 196 #define meshtastic_PositionLite_size 28 From 30c3e974a6bd6fe8b5f2bcec2b3d6a6c3cc32732 Mon Sep 17 00:00:00 2001 From: ford-jones Date: Tue, 21 Oct 2025 15:59:46 +1300 Subject: [PATCH 12/12] Log preservation status --- src/mesh/NodeDB.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index db8c680b5..5936c4463 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -984,6 +984,7 @@ void NodeDB::resetNodes(bool keepFavorites) clearLocalPosition(); numMeshNodes = 1; if (keepFavorites) { + LOG_INFO("Clearing node database - preserving favorites"); for (size_t i = 0; i < meshNodes->size(); i++) { meshtastic_NodeInfoLite &node = meshNodes->at(i); if (i > 0 && !node.is_favorite) { @@ -993,6 +994,7 @@ void NodeDB::resetNodes(bool keepFavorites) } }; } else { + LOG_INFO("Clearing node database - removing favorites"); std::fill(nodeDatabase.nodes.begin() + 1, nodeDatabase.nodes.end(), meshtastic_NodeInfoLite()); } devicestate.has_rx_text_message = false;