From bdb3fb1477e5e9f8492c7c266181bab77d157389 Mon Sep 17 00:00:00 2001 From: Ford Jones <107664313+ford-jones@users.noreply.github.com> Date: Fri, 7 Nov 2025 11:06:37 +1300 Subject: [PATCH] Persist favourites on NodeDB reset (#8292) * Conditionally delete favourited nodes on reset * trunk fmt * Fix equality check, use existing macro for role validation * Extend favourite persistence setting to devices of all roles * Refactor: Decoupled role/config check and set role defaults appropriately * Use American-English spelling * Use existing reference * Convert reset to bool, regen protos * Add optional arg to nodedb_reset in favor of additional device setting * Use correct proto commit ID * Regen protos * Log preservation status * Pull latest from master --- src/mesh/NodeDB.cpp | 17 +++++++++++++++-- src/mesh/NodeDB.h | 3 ++- src/modules/AdminModule.cpp | 7 ++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 8d30fb824..bda6f4ea4 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -978,12 +978,25 @@ void NodeDB::installDefaultChannels() channelFile.version = DEVICESTATE_CUR_VER; } -void NodeDB::resetNodes() +void NodeDB::resetNodes(bool keepFavorites) { if (!config.position.fixed_position) clearLocalPosition(); numMeshNodes = 1; - std::fill(nodeDatabase.nodes.begin() + 1, nodeDatabase.nodes.end(), meshtastic_NodeInfoLite()); + 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) { + node = meshtastic_NodeInfoLite(); + } else { + numMeshNodes += 1; + } + }; + } 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; devicestate.has_rx_waypoint = false; saveNodeDatabaseToDisk(); 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 24fb8f1f9..a98515059 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -289,7 +289,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; }