mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-27 09:05:11 +00:00
* new CLI commands: region, region load, region save, region get, region allow
This commit is contained in:
+120
-8
@@ -2,25 +2,106 @@
|
||||
#include <helpers/TxtDataHelpers.h>
|
||||
#include <SHA256.h>
|
||||
|
||||
void RegionMap::load(FILESYSTEM* _fs) {
|
||||
// TODO
|
||||
}
|
||||
void RegionMap::save(FILESYSTEM* _fs) {
|
||||
// TODO
|
||||
RegionMap::RegionMap(TransportKeyStore& store) : _store(&store) {
|
||||
next_id = 1; num_regions = 0;
|
||||
wildcard.id = wildcard.parent = 0;
|
||||
wildcard.flags = REGION_ALLOW_FLOOD; // default behaviour, allow flood
|
||||
strcpy(wildcard.name, "(*)");
|
||||
}
|
||||
|
||||
RegionEntry* RegionMap::putRegion(const char* name, uint16_t parent_id) {
|
||||
static File openWrite(FILESYSTEM* _fs, const char* filename) {
|
||||
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
||||
_fs->remove(filename);
|
||||
return _fs->open(filename, FILE_O_WRITE);
|
||||
#elif defined(RP2040_PLATFORM)
|
||||
return _fs->open(filename, "w");
|
||||
#else
|
||||
return _fs->open(filename, "w", true);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RegionMap::load(FILESYSTEM* _fs) {
|
||||
if (_fs->exists("/regions2")) {
|
||||
#if defined(RP2040_PLATFORM)
|
||||
File file = _fs->open("/regions2", "r");
|
||||
#else
|
||||
File file = _fs->open("/regions2");
|
||||
#endif
|
||||
|
||||
if (file) {
|
||||
uint8_t pad[128];
|
||||
|
||||
num_regions = 0; next_id = 1;
|
||||
|
||||
bool success = file.read(pad, 7) == 7; // reserved header
|
||||
success = success && file.read((uint8_t *) &wildcard.flags, sizeof(wildcard.flags)) == sizeof(wildcard.flags);
|
||||
success = success && file.read((uint8_t *) &next_id, sizeof(next_id)) == sizeof(next_id);
|
||||
|
||||
if (success) {
|
||||
while (num_regions < MAX_REGION_ENTRIES) {
|
||||
auto r = ®ions[num_regions];
|
||||
|
||||
success = file.read((uint8_t *) &r->id, sizeof(r->id)) == sizeof(r->id);
|
||||
success = success && file.read((uint8_t *) &r->parent, sizeof(r->parent)) == sizeof(r->parent);
|
||||
success = success && file.read((uint8_t *) r->name, sizeof(r->name)) == sizeof(r->name);
|
||||
success = success && file.read((uint8_t *) &r->flags, sizeof(r->flags)) == sizeof(r->flags);
|
||||
success = success && file.read(pad, sizeof(pad)) == sizeof(pad);
|
||||
|
||||
if (!success) break; // EOF
|
||||
|
||||
if (r->id >= next_id) { // make sure next_id is valid
|
||||
next_id = r->id + 1;
|
||||
}
|
||||
num_regions++;
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // failed
|
||||
}
|
||||
|
||||
bool RegionMap::save(FILESYSTEM* _fs) {
|
||||
File file = openWrite(_fs, "/regions2");
|
||||
if (file) {
|
||||
uint8_t pad[128];
|
||||
memset(pad, 0, sizeof(pad));
|
||||
|
||||
bool success = file.write(pad, 7) == 7; // reserved header
|
||||
success = success && file.write((uint8_t *) &wildcard.flags, sizeof(wildcard.flags)) == sizeof(wildcard.flags);
|
||||
success = success && file.write((uint8_t *) &next_id, sizeof(next_id)) == sizeof(next_id);
|
||||
|
||||
if (success) {
|
||||
for (int i = 0; i < num_regions; i++) {
|
||||
auto r = ®ions[i];
|
||||
|
||||
success = file.write((uint8_t *) &r->id, sizeof(r->id)) == sizeof(r->id);
|
||||
success = success && file.write((uint8_t *) &r->parent, sizeof(r->parent)) == sizeof(r->parent);
|
||||
success = success && file.write((uint8_t *) r->name, sizeof(r->name)) == sizeof(r->name);
|
||||
success = success && file.write((uint8_t *) &r->flags, sizeof(r->flags)) == sizeof(r->flags);
|
||||
success = success && file.write(pad, sizeof(pad)) == sizeof(pad);
|
||||
if (!success) break; // write failed
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false; // failed
|
||||
}
|
||||
|
||||
RegionEntry* RegionMap::putRegion(const char* name, uint16_t parent_id, uint16_t 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!
|
||||
if (id == 0 && num_regions >= MAX_REGION_ENTRIES) return NULL; // full!
|
||||
|
||||
region = ®ions[num_regions++]; // alloc new RegionEntry
|
||||
region->flags = 0;
|
||||
region->id = next_id++;
|
||||
region->id = id == 0 ? next_id++ : id;
|
||||
StrHelper::strncpy(region->name, name, sizeof(region->name));
|
||||
region->parent = parent_id;
|
||||
}
|
||||
@@ -58,6 +139,14 @@ RegionEntry* RegionMap::findByName(const char* name) {
|
||||
return NULL; // not found
|
||||
}
|
||||
|
||||
RegionEntry* RegionMap::findByNamePrefix(const char* prefix) {
|
||||
for (int i = 0; i < num_regions; i++) {
|
||||
auto region = ®ions[i];
|
||||
if (memcmp(prefix, region->name, strlen(prefix)) == 0) return region;
|
||||
}
|
||||
return NULL; // not found
|
||||
}
|
||||
|
||||
RegionEntry* RegionMap::findById(uint16_t id) {
|
||||
if (id == 0) return &wildcard; // special root Region
|
||||
|
||||
@@ -94,3 +183,26 @@ bool RegionMap::clear() {
|
||||
num_regions = 0;
|
||||
return true; // success
|
||||
}
|
||||
|
||||
void RegionMap::printChildRegions(int indent, const RegionEntry* parent, Stream& out) const {
|
||||
for (int i = 0; i < indent; i++) {
|
||||
out.print(' ');
|
||||
}
|
||||
|
||||
if (parent->flags & REGION_ALLOW_FLOOD) {
|
||||
out.printf("%s F\n", parent->name);
|
||||
} else {
|
||||
out.printf("%s\n", parent->name);
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_regions; i++) {
|
||||
auto r = ®ions[i];
|
||||
if (r->parent == parent->id) {
|
||||
printChildRegions(indent + 1, r, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegionMap::exportTo(Stream& out) const {
|
||||
printChildRegions(0, &wildcard, out); // recursive
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user