Эх сурвалжийг харах

* companion: RegionMap now used in Datastore
* companion: new CMD_SET_DEFAULT_FLOOD_SCOPE
* support for regional builds with DEFAULT_REGION_SCOPE

Scott Powell 4 сар өмнө
parent
commit
d131e8ae35

+ 4 - 0
examples/companion_radio/DataStore.cpp

@@ -15,6 +15,7 @@ DataStore::DataStore(FILESYSTEM& fs, mesh::RTCClock& clock) : _fs(&fs), _fsExtra
 #else
     identity_store(fs, "/identity")
 #endif
+    , regions(keystore)
 {
 }
 
@@ -27,6 +28,7 @@ DataStore::DataStore(FILESYSTEM& fs, FILESYSTEM& fsExtra, mesh::RTCClock& clock)
 #else
     identity_store(fs, "/identity")
 #endif
+    , regions(keystore)
 {
 }
 #endif
@@ -61,6 +63,8 @@ void DataStore::begin() {
   // init 'blob store' support
   _fs->mkdir("/bl");
 #endif
+
+  regions.load(_fs);
 }
 
 #if defined(ESP32)

+ 5 - 0
examples/companion_radio/DataStore.h

@@ -3,6 +3,7 @@
 #include <helpers/IdentityStore.h>
 #include <helpers/ContactInfo.h>
 #include <helpers/ChannelDetails.h>
+#include <helpers/RegionMap.h>
 #include "NodePrefs.h"
 
 class DataStoreHost {
@@ -18,6 +19,8 @@ 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)
@@ -49,6 +52,8 @@ 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;};

+ 40 - 6
examples/companion_radio/MyMesh.cpp

@@ -50,7 +50,7 @@
 #define CMD_SEND_BINARY_REQ           50
 #define CMD_FACTORY_RESET             51
 #define CMD_SEND_PATH_DISCOVERY_REQ   52
-#define CMD_SET_FLOOD_SCOPE           54   // v8+
+#define CMD_SET_FLOOD_SCOPE_KEY       54   // v8+
 #define CMD_SEND_CONTROL_DATA         55   // v8+
 #define CMD_GET_STATS                 56   // v8+, second byte is stats type
 #define CMD_SEND_ANON_REQ             57
@@ -59,6 +59,7 @@
 #define CMD_GET_ALLOWED_REPEAT_FREQ   60
 #define CMD_SET_PATH_HASH_MODE        61
 #define CMD_SEND_CHANNEL_DATA         62
+#define CMD_SET_DEFAULT_FLOOD_SCOPE   63
 
 // Stats sub-types for CMD_GET_STATS
 #define STATS_TYPE_CORE               0
@@ -937,6 +938,25 @@ 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() {
@@ -1862,20 +1882,34 @@ void MyMesh::handleCmdFrame(size_t len) {
     } else {
       writeErrFrame(ERR_CODE_FILE_IO_ERROR);
     }
-  } else if (cmd_frame[0] == CMD_SET_FLOOD_SCOPE && len >= 2 && cmd_frame[1] == 0) {
+  } else if (cmd_frame[0] == CMD_SET_FLOOD_SCOPE_KEY && len >= 2 && cmd_frame[1] == 0) {
     if (len >= 2 + 16) {
       memcpy(send_scope.key, &cmd_frame[2], sizeof(send_scope.key));  // set curr scope TransportKey
     } else {
       memset(send_scope.key, 0, sizeof(send_scope.key));  // set scope to null
     }
     writeOKFrame();
-  } else if (cmd_frame[0] == CMD_SET_FLOOD_SCOPE && len >= 2 && cmd_frame[1] == 1) {
-    if (len >= 2 + 16) {
-      memcpy(default_scope.key, &cmd_frame[2], sizeof(default_scope.key));  // set default scope TransportKey
+  } 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);
+        writeOKFrame();
+      } else {
+        writeErrFrame(ERR_CODE_NOT_FOUND);
+      }
     } else {
+      _store->getRegions().setDefaultRegion(NULL);
       memset(default_scope.key, 0, sizeof(default_scope.key));  // set default scope to null
+      writeOKFrame();
     }
-    writeOKFrame();
+    _store->saveRegions();
   } 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) {

+ 18 - 13
src/helpers/RegionMap.cpp

@@ -168,24 +168,29 @@ RegionEntry* RegionMap::putRegion(const char* name, uint16_t parent_id, uint16_t
   return region;
 }
 
+int RegionMap::getTransportKeysFor(const RegionEntry& src, TransportKey dest[], int max_num) {
+  int num;
+  if (src.name[0] == '$') {   // private region
+    num = _store->loadKeysFor(src.id, dest, max_num);
+  } else if (src.name[0] == '#') {   // auto hashtag region
+    _store->getAutoKeyFor(src.id, src.name, dest[0]);
+    num = 1;
+  } else {   // new: implicit auto hashtag region
+    char tmp[sizeof(src.name)];
+    tmp[0] = '#';
+    strcpy(&tmp[1], src.name);
+    _store->getAutoKeyFor(src.id, tmp, dest[0]);
+    num = 1;
+  }
+  return num;
+}
+
 RegionEntry* RegionMap::findMatch(mesh::Packet* packet, uint8_t mask) {
   for (int i = 0; i < num_regions; i++) {
     auto region = &regions[i];
     if ((region->flags & mask) == 0) {   // does region allow this? (per 'mask' param)
       TransportKey keys[4];
-      int num;
-      if (region->name[0] == '$') {   // private region
-        num = _store->loadKeysFor(region->id, keys, 4);
-      } else if (region->name[0] == '#') {   // auto hashtag region
-        _store->getAutoKeyFor(region->id, region->name, keys[0]);
-        num = 1;
-      } else {   // new: implicit auto hashtag region
-        char tmp[sizeof(region->name)];
-        tmp[0] = '#';
-        strcpy(&tmp[1], region->name);
-        _store->getAutoKeyFor(region->id, tmp, keys[0]);
-        num = 1;
-      }
+      int num = getTransportKeysFor(*region, keys, 4);
       for (int j = 0; j < num; j++) {
         uint16_t code = keys[j].calcTransportCode(packet);
         if (packet->transport_codes[0] == code) {   // a match!!

+ 1 - 0
src/helpers/RegionMap.h

@@ -52,6 +52,7 @@ public:
   const RegionEntry* getByIdx(int i) const { return &regions[i]; }
   const RegionEntry* getRoot() const { return &wildcard; }
   int exportNamesTo(char *dest, int max_len, uint8_t mask, bool invert = false);
+  int getTransportKeysFor(const RegionEntry& src, TransportKey dest[], int max_num);
 
   void    exportTo(Stream& out) const;
   size_t  exportTo(char *dest, size_t max_len) const;