Просмотр исходного кода

* misc RegionMap and key store methods

Scott Powell 9 месяцев назад
Родитель
Сommit
f797744f7c

+ 64 - 3
src/helpers/RegionMap.cpp

@@ -1,4 +1,5 @@
 #include "RegionMap.h"
+#include <helpers/TxtDataHelpers.h>
 #include <SHA256.h>
 
 void RegionMap::load(FILESYSTEM* _fs) {
@@ -8,12 +9,36 @@ void RegionMap::save(FILESYSTEM* _fs) {
   // TODO
 }
 
+RegionEntry* RegionMap::putRegion(const char* name, uint16_t parent_id) {
+  auto region = findByName(name);
+  if (region) {
+    if (region->id == parent_id) return NULL;   // ERROR: invalid parent!
+
+    region->parent = parent_id;   // re-parent / move this region in the hierarchy
+  } else {
+    if (num_regions >= MAX_REGION_ENTRIES) return NULL;  // full!
+
+    region = &regions[num_regions++];   // alloc new RegionEntry
+    region->flags = 0;
+    region->id = next_id++;
+    StrHelper::strncpy(region->name, name, sizeof(region->name));
+    region->parent = parent_id;
+  }
+  return region;
+}
+
 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) {   // does region allow this? (per 'mask' param)
+    if ((region->flags & mask) == mask) {   // does region allow this? (per 'mask' param)
       TransportKey keys[4];
-      int num = _store->loadKeysFor(region->name, region->id, keys, 4);
+      int num;
+      if (region->name[0] == '#') {   // auto hashtag region
+        _store->getAutoKeyFor(region->id, region->name, keys[0]);
+        num = 1;
+      } else {
+        num = _store->loadKeysFor(region->id, keys, 4);
+      }
       for (int j = 0; j < num; j++) {
         uint16_t code = keys[j].calcTransportCode(packet);
         if (packet->transport_codes[0] == code) {   // a match!!
@@ -25,7 +50,7 @@ RegionEntry* RegionMap::findMatch(mesh::Packet* packet, uint8_t mask) {
   return NULL;  // no matches
 }
 
-const RegionEntry* RegionMap::findName(const char* name) const {
+RegionEntry* RegionMap::findByName(const char* name) {
   for (int i = 0; i < num_regions; i++) {
     auto region = &regions[i];
     if (strcmp(name, region->name) == 0) return region;
@@ -33,3 +58,39 @@ const RegionEntry* RegionMap::findName(const char* name) const {
   return NULL;  // not found
 }
 
+RegionEntry* RegionMap::findById(uint16_t id) {
+  if (id == 0) return &wildcard;   // special root Region
+
+  for (int i = 0; i < num_regions; i++) {
+    auto region = &regions[i];
+    if (region->id == id) return region;
+  }
+  return NULL;  // not found
+}
+
+bool RegionMap::removeRegion(const RegionEntry& region) {
+  if (region.id == 0) return false;  // failed (cannot remove the wildcard Region)
+
+  int i;     // first check region has no child regions
+  for (i = 0; i < num_regions; i++) {
+    if (regions[i].parent == region.id) return false;   // failed (must remove child Regions first)
+  }
+
+  i = 0;
+  while (i < num_regions) {
+    if (region.id == regions[i].id) break;
+    i++;
+  }
+  if (i >= num_regions) return false;  // failed (not found)
+
+  num_regions--;    // remove from regions array
+  while (i + 1 < num_regions) {
+    regions[i] = regions[i + 1];
+  }
+  return true;  // success
+}
+
+bool RegionMap::clear() {
+  num_regions = 0;
+  return true;  // success
+}

+ 6 - 2
src/helpers/RegionMap.h

@@ -33,7 +33,11 @@ public:
   void load(FILESYSTEM* _fs);
   void save(FILESYSTEM* _fs);
 
+  RegionEntry* putRegion(const char* name, uint16_t parent_id);
   RegionEntry* findMatch(mesh::Packet* packet, uint8_t mask);
-  const RegionEntry& getWildcard() const { return wildcard; }
-  const RegionEntry* findName(const char* name) const;
+  RegionEntry& getWildcard() { return wildcard; }
+  RegionEntry* findByName(const char* name);
+  RegionEntry* findById(uint16_t id);
+  bool removeRegion(const RegionEntry& region);
+  bool clear();
 };

+ 52 - 16
src/helpers/TransportKeyStore.cpp

@@ -12,7 +12,32 @@ uint16_t TransportKey::calcTransportCode(const mesh::Packet* packet) const {
   return code;
 }
 
-int TransportKeyStore::loadKeysFor(const char* name, uint16_t id, TransportKey keys[], int max_num) {
+void TransportKeyStore::putCache(uint16_t id, const TransportKey& key) {
+  if (num_cache < MAX_TKS_ENTRIES) {
+    cache_ids[num_cache] = id;
+    cache_keys[num_cache] = key;
+    num_cache++;
+  } else {
+    // TODO: evict oldest cache entry
+  }
+}
+
+void TransportKeyStore::getAutoKeyFor(uint16_t id, const char* name, TransportKey& dest) {
+  for (int i = 0; i < num_cache; i++) {  // first, check cache
+    if (cache_ids[i] == id) {   // cache hit!
+      dest = cache_keys[i];
+      return;
+    }
+  }
+  // calc key for publicly-known hashtag region name
+  SHA256 sha;
+  sha.update(name, strlen(name));
+  sha.finalize(&dest.key, sizeof(dest.key));
+
+  putCache(id, dest);
+}
+
+int TransportKeyStore::loadKeysFor(uint16_t id, TransportKey keys[], int max_num) {
   int n = 0;
   for (int i = 0; i < num_cache && n < max_num; i++) {  // first, check cache
     if (cache_ids[i] == id) {
@@ -21,24 +46,35 @@ int TransportKeyStore::loadKeysFor(const char* name, uint16_t id, TransportKey k
   }
   if (n > 0) return n;   // cache hit!
 
-  if (*name == '#') {   // is a publicly-known hashtag region
-    SHA256 sha;
-    sha.update(name, strlen(name));
-    sha.finalize(&keys[0], sizeof(keys[0].key));
-    n = 1;
-  } else {
-    // TODO:  retrieve from difficult-to-copy keystore
-  }
+  // TODO:  retrieve from difficult-to-copy keystore
 
   // store in cache (if room)
   for (int i = 0; i < n; i++) {
-    if (num_cache < MAX_TKS_ENTRIES) {
-      cache_ids[num_cache] = id;
-      cache_keys[num_cache] = keys[i];
-      num_cache++;
-    } else {
-      // TODO: evict oldest cache entry
-    }
+    putCache(id, keys[i]);
   }
   return n;
 }
+
+bool TransportKeyStore::saveKeysFor(uint16_t id, const TransportKey keys[], int num) {
+  invalidateCache();
+
+  // TODO: update hardware keystore
+
+  return false;  // failed
+}
+
+bool TransportKeyStore::removeKeys(uint16_t id) {
+  invalidateCache();
+
+  // TODO: remove from hardware keystore
+
+  return false;  // failed
+}
+
+bool TransportKeyStore::clear() {
+  invalidateCache();
+
+  // TODO: clear hardware keystore
+
+  return false;  // failed
+}

+ 8 - 1
src/helpers/TransportKeyStore.h

@@ -17,7 +17,14 @@ class TransportKeyStore {
   TransportKey cache_keys[MAX_TKS_ENTRIES];
   int num_cache;
 
+  void putCache(uint16_t id, const TransportKey& key);
+  void invalidateCache() { num_cache = 0; }
+
 public:
   TransportKeyStore() { num_cache = 0; }
-  int loadKeysFor(const char* name, uint16_t id, TransportKey keys[], int max_num);
+  void getAutoKeyFor(uint16_t id, const char* name, TransportKey& dest);
+  int loadKeysFor(uint16_t id, TransportKey keys[], int max_num);
+  bool saveKeysFor(uint16_t id, const TransportKey keys[], int num);
+  bool removeKeys(uint16_t id);
+  bool clear();
 };