From efdd2b6a6cd56979202625e7686933079e4cebf9 Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Mon, 13 Apr 2026 23:11:21 +1000 Subject: [PATCH] * companion: simplified the CMD_GET / CMD_SET _DEFAULT_FLOOD_SCOPE --- examples/companion_radio/DataStore.cpp | 12 ++--- examples/companion_radio/DataStore.h | 5 -- examples/companion_radio/MyMesh.cpp | 74 ++++++++++++++------------ examples/companion_radio/MyMesh.h | 2 +- examples/companion_radio/NodePrefs.h | 2 + 5 files changed, 49 insertions(+), 46 deletions(-) diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index 4676fdac..c7988bb3 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -15,7 +15,6 @@ DataStore::DataStore(FILESYSTEM& fs, mesh::RTCClock& clock) : _fs(&fs), _fsExtra #else identity_store(fs, "/identity") #endif - , regions(keystore) { } @@ -28,7 +27,6 @@ DataStore::DataStore(FILESYSTEM& fs, FILESYSTEM& fsExtra, mesh::RTCClock& clock) #else identity_store(fs, "/identity") #endif - , regions(keystore) { } #endif @@ -63,8 +61,6 @@ void DataStore::begin() { // init 'blob store' support _fs->mkdir("/bl"); #endif - - regions.load(_fs); } #if defined(ESP32) @@ -234,7 +230,9 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no file.read((uint8_t *)&_prefs.gps_interval, sizeof(_prefs.gps_interval)); // 86 file.read((uint8_t *)&_prefs.autoadd_config, sizeof(_prefs.autoadd_config)); // 87 file.read((uint8_t *)&_prefs.autoadd_max_hops, sizeof(_prefs.autoadd_max_hops)); // 88 - file.read((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89 + file.read((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89 + file.read((uint8_t *)_prefs.default_scope_name, sizeof(_prefs.default_scope_name)); // 90 + file.read((uint8_t *)_prefs.default_scope_key, sizeof(_prefs.default_scope_key)); // 121 file.close(); } @@ -272,7 +270,9 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_ file.write((uint8_t *)&_prefs.gps_interval, sizeof(_prefs.gps_interval)); // 86 file.write((uint8_t *)&_prefs.autoadd_config, sizeof(_prefs.autoadd_config)); // 87 file.write((uint8_t *)&_prefs.autoadd_max_hops, sizeof(_prefs.autoadd_max_hops)); // 88 - file.write((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89 + file.write((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89 + file.write((uint8_t *)_prefs.default_scope_name, sizeof(_prefs.default_scope_name)); // 90 + file.write((uint8_t *)_prefs.default_scope_key, sizeof(_prefs.default_scope_key)); // 121 file.close(); } diff --git a/examples/companion_radio/DataStore.h b/examples/companion_radio/DataStore.h index e004fbda..58b4d5d2 100644 --- a/examples/companion_radio/DataStore.h +++ b/examples/companion_radio/DataStore.h @@ -3,7 +3,6 @@ #include #include #include -#include #include "NodePrefs.h" class DataStoreHost { @@ -19,8 +18,6 @@ class DataStore { FILESYSTEM* _fsExtra; mesh::RTCClock* _clock; IdentityStore identity_store; - TransportKeyStore keystore; - RegionMap regions; void loadPrefsInt(const char *filename, NodePrefs& prefs, double& node_lat, double& node_lon); #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM) @@ -52,8 +49,6 @@ public: bool removeFile(FILESYSTEM* fs, const char* filename); uint32_t getStorageUsedKb() const; uint32_t getStorageTotalKb() const; - RegionMap& getRegions() { return regions; } - bool saveRegions() { return regions.save(_fs); } private: FILESYSTEM* _getContactsChannelsFS() const { if (_fsExtra) return _fsExtra; return _fs;}; diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index df349a67..e8c1914b 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -60,6 +60,7 @@ #define CMD_SET_PATH_HASH_MODE 61 #define CMD_SEND_CHANNEL_DATA 62 #define CMD_SET_DEFAULT_FLOOD_SCOPE 63 +#define CMD_GET_DEFAULT_FLOOD_SCOPE 64 // Stats sub-types for CMD_GET_STATS #define STATS_TYPE_CORE 0 @@ -94,6 +95,7 @@ #define RESP_CODE_AUTOADD_CONFIG 25 #define RESP_ALLOWED_REPEAT_FREQ 26 #define RESP_CODE_CHANNEL_DATA_RECV 27 +#define RESP_CODE_DEFAULT_FLOOD_SCOPE 28 #define MAX_CHANNEL_DATA_LENGTH (MAX_FRAME_SIZE - 9) @@ -493,11 +495,17 @@ void MyMesh::sendFloodScoped(const TransportKey& scope, mesh::Packet* pkt, uint3 void MyMesh::sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis) { // TODO: dynamic send_scope, depending on recipient and current 'home' Region + TransportKey default_scope; + memcpy(&default_scope.key, _prefs.default_scope_key, sizeof(default_scope.key)); + auto scope = send_scope.isNull() ? &default_scope : &send_scope; sendFloodScoped(*scope, pkt, delay_millis); } void MyMesh::sendFloodScoped(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t delay_millis) { // TODO: have per-channel send_scope + TransportKey default_scope; + memcpy(&default_scope.key, _prefs.default_scope_key, sizeof(default_scope.key)); + auto scope = send_scope.isNull() ? &default_scope : &send_scope; sendFloodScoped(*scope, pkt, delay_millis); } @@ -848,7 +856,6 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe dirty_contacts_expiry = 0; memset(advert_paths, 0, sizeof(advert_paths)); memset(send_scope.key, 0, sizeof(send_scope.key)); - memset(default_scope.key, 0, sizeof(default_scope.key)); // defaults memset(&_prefs, 0, sizeof(_prefs)); @@ -894,6 +901,17 @@ void MyMesh::begin(bool has_display) { strcpy(_prefs.node_name, pub_key_hex); #endif + // if build provides default-scope, init with that +#ifdef DEFAULT_FLOOD_SCOPE_NAME + strcpy(_prefs.default_scope_name, DEFAULT_FLOOD_SCOPE_NAME); + { + TransportKeyStore temp; + TransportKey key; + temp.getAutoKeyFor(0, "#" DEFAULT_FLOOD_SCOPE_NAME, key); + memcpy(_prefs.default_scope_key, key.key, sizeof(key.key)); + } +#endif + // load persisted prefs _store->loadPrefs(_prefs, sensors.node_lat, sensors.node_lon); @@ -938,25 +956,6 @@ void MyMesh::begin(bool has_display) { radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain); MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s", radio_driver.getRxBoostedGainMode() ? "Enabled" : "Disabled"); - - { - RegionEntry* r = _store->getRegions().getDefaultRegion(); - if (r) { - _store->getRegions().getTransportKeysFor(*r, &default_scope, 1); - } else { -#ifdef DEFAULT_FLOOD_SCOPE - r = _store->getRegions().findByName(DEFAULT_FLOOD_SCOPE); - if (r == NULL) { - r = _store->getRegions().putRegion(DEFAULT_FLOOD_SCOPE, 0); // auto-create the default scope region - if (r) { r->flags = 0; } // Allow-flood - } - if (r) { - _store->getRegions().setDefaultRegion(r); - _store->getRegions().getTransportKeysFor(*r, &default_scope, 1); - } -#endif - } - } } const char *MyMesh::getNodeName() { @@ -1230,6 +1229,8 @@ void MyMesh::handleCmdFrame(size_t len) { if (pkt) { if (len >= 2 && cmd_frame[1] == 1) { // optional param (1 = flood, 0 = zero hop) unsigned long delay_millis = 0; + TransportKey default_scope; + memcpy(&default_scope.key, _prefs.default_scope_key, sizeof(default_scope.key)); sendFloodScoped(default_scope, pkt, delay_millis); } else { sendZeroHop(pkt); @@ -1890,26 +1891,31 @@ void MyMesh::handleCmdFrame(size_t len) { } writeOKFrame(); } else if (cmd_frame[0] == CMD_SET_DEFAULT_FLOOD_SCOPE && len >= 1) { - if (len > 1) { - cmd_frame[len] = 0; // make C string - RegionEntry* r = _store->getRegions().findByName((char *) &cmd_frame[1]); - if (r == NULL) { - r = _store->getRegions().putRegion((char *) &cmd_frame[1], 0); // auto-create region - if (r) { r->flags = 0; } // Allow-flood - } - if (r) { - _store->getRegions().setDefaultRegion(r); - _store->getRegions().getTransportKeysFor(*r, &default_scope, 1); + if (len >= 1+31+16) { + int n = strlen((char *) &cmd_frame[1]); + if (n > 0 && n < 31) { + strcpy(_prefs.default_scope_name, (char *) &cmd_frame[1]); + memcpy(_prefs.default_scope_key, &cmd_frame[1+31], 16); + savePrefs(); writeOKFrame(); } else { - writeErrFrame(ERR_CODE_NOT_FOUND); + writeErrFrame(ERR_CODE_ILLEGAL_ARG); } } else { - _store->getRegions().setDefaultRegion(NULL); - memset(default_scope.key, 0, sizeof(default_scope.key)); // set default scope to null + memset(_prefs.default_scope_name, 0, sizeof(_prefs.default_scope_name)); // set default scope to null + memset(_prefs.default_scope_key, 0, sizeof(_prefs.default_scope_key)); + savePrefs(); writeOKFrame(); } - _store->saveRegions(); + } else if (cmd_frame[0] == CMD_GET_DEFAULT_FLOOD_SCOPE) { + out_frame[0] = RESP_CODE_DEFAULT_FLOOD_SCOPE; + if (strlen(_prefs.default_scope_name) > 0) { + memcpy(&out_frame[1], _prefs.default_scope_name, 31); + memcpy(&out_frame[1+31], _prefs.default_scope_key, 16); + _serial->writeFrame(out_frame, 1+31+16); + } else { + _serial->writeFrame(out_frame, 1); // no name or key means null + } } else if (cmd_frame[0] == CMD_SEND_CONTROL_DATA && len >= 2 && (cmd_frame[1] & 0x80) != 0) { auto resp = createControlData(&cmd_frame[1], len - 1); if (resp) { diff --git a/examples/companion_radio/MyMesh.h b/examples/companion_radio/MyMesh.h index a4fc831c..e261a2e0 100644 --- a/examples/companion_radio/MyMesh.h +++ b/examples/companion_radio/MyMesh.h @@ -221,7 +221,7 @@ private: uint32_t sign_data_len; unsigned long dirty_contacts_expiry; - TransportKey send_scope, default_scope; + TransportKey send_scope; uint8_t cmd_frame[MAX_FRAME_SIZE + 1]; uint8_t out_frame[MAX_FRAME_SIZE + 1]; diff --git a/examples/companion_radio/NodePrefs.h b/examples/companion_radio/NodePrefs.h index 557be306..48c381ce 100644 --- a/examples/companion_radio/NodePrefs.h +++ b/examples/companion_radio/NodePrefs.h @@ -32,4 +32,6 @@ struct NodePrefs { // persisted to file uint8_t client_repeat; uint8_t path_hash_mode; // which path mode to use when sending uint8_t autoadd_max_hops; // 0 = no limit, 1 = direct (0 hops), N = up to N-1 hops (max 64) + char default_scope_name[31]; + uint8_t default_scope_key[16]; }; \ No newline at end of file