Skip to content

Commit 0805a47

Browse files
committed
Add output of region cmd via lora cli
Add cli commands "region list {allowed|denied}"
1 parent 7ae1642 commit 0805a47

3 files changed

Lines changed: 86 additions & 11 deletions

File tree

examples/simple_repeater/MyMesh.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,8 +1068,8 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply
10681068

10691069
const char* parts[4];
10701070
int n = mesh::Utils::parseTextParts(command, parts, 4, ' ');
1071-
if (n == 1 && sender_timestamp == 0) {
1072-
region_map.exportTo(Serial);
1071+
if (n == 1) {
1072+
region_map.exportTo(reply, 160);
10731073
} else if (n >= 2 && strcmp(parts[1], "load") == 0) {
10741074
temp_map.resetFrom(region_map); // rebuild regions in a temp instance
10751075
memset(load_stack, 0, sizeof(load_stack));
@@ -1142,6 +1142,25 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply
11421142
} else {
11431143
strcpy(reply, "Err - not found");
11441144
}
1145+
} else if (n >= 3 && strcmp(parts[1], "list") == 0) {
1146+
uint8_t mask = 0;
1147+
bool invert = false;
1148+
1149+
if (strcmp(parts[2], "allowed") == 0) {
1150+
mask = REGION_DENY_FLOOD;
1151+
invert = false; // list regions that DON'T have DENY flag
1152+
} else if (strcmp(parts[2], "denied") == 0) {
1153+
mask = REGION_DENY_FLOOD;
1154+
invert = true; // list regions that DO have DENY flag
1155+
} else {
1156+
strcpy(reply, "Err - use 'allowed' or 'denied'");
1157+
return;
1158+
}
1159+
1160+
int len = region_map.exportNamesTo(reply, 160, mask, invert);
1161+
if (len == 0) {
1162+
strcpy(reply, "-none-");
1163+
}
11451164
} else {
11461165
strcpy(reply, "Err - ??");
11471166
}

src/helpers/RegionMap.cpp

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,45 @@
22
#include <helpers/TxtDataHelpers.h>
33
#include <SHA256.h>
44

5+
// helper class for region map exporter, we emulate Stream with a safe buffer writer.
6+
7+
class BufStream : public Stream {
8+
public:
9+
BufStream(char *buf, size_t max)
10+
: _buf(buf), _max(max), _pos(0) {
11+
if (_max > 0) _buf[0] = 0;
12+
}
13+
14+
size_t write(uint8_t c) override {
15+
if (_pos + 1 >= _max) return 0;
16+
_buf[_pos++] = c;
17+
_buf[_pos] = 0;
18+
return 1;
19+
}
20+
21+
size_t write(const uint8_t *buffer, size_t size) override {
22+
size_t written = 0;
23+
while (written < size) {
24+
if (!write(buffer[written])) break;
25+
written++;
26+
}
27+
return written;
28+
}
29+
30+
int available() override { return 0; }
31+
int read() override { return -1; }
32+
int peek() override { return -1; }
33+
void flush() override {}
34+
35+
size_t length() const { return _pos; }
36+
37+
private:
38+
char *_buf;
39+
size_t _max;
40+
size_t _pos;
41+
};
42+
43+
544
RegionMap::RegionMap(TransportKeyStore& store) : _store(&store) {
645
next_id = 1; num_regions = 0; home_id = 0;
746
wildcard.id = wildcard.parent = 0;
@@ -249,25 +288,40 @@ void RegionMap::exportTo(Stream& out) const {
249288
printChildRegions(0, &wildcard, out); // recursive
250289
}
251290

252-
int RegionMap::exportNamesTo(char *dest, int max_len, uint8_t mask) {
291+
size_t RegionMap::exportTo(char *dest, size_t max_len) const {
292+
if (!dest || max_len == 0) return 0;
293+
294+
BufStream bs(dest, max_len);
295+
exportTo(bs); // ← reuse existing logic
296+
return bs.length();
297+
}
298+
299+
int RegionMap::exportNamesTo(char *dest, int max_len, uint8_t mask, bool invert) {
253300
char *dp = dest;
254-
if ((wildcard.flags & mask) == 0) {
301+
302+
// Check wildcard region
303+
bool wildcard_matches = invert ? (wildcard.flags & mask) : !(wildcard.flags & mask);
304+
if (wildcard_matches) {
255305
*dp++ = '*';
256306
*dp++ = ',';
257307
}
258308

259-
for (int i = 0; i < num_regions; i++) {
309+
for (int i = 0; i < num_regions; i++) {
260310
auto region = &regions[i];
261-
if ((region->flags & mask) == 0) { // region allowed? (per 'mask' param)
262-
const char* name = skip_hash(region->name);
263-
int len = strlen(name);
311+
312+
// Check if region matches the filter criteria
313+
bool region_matches = invert ? (region->flags & mask) : !(region->flags & mask);
314+
315+
if (region_matches) {
316+
int len = strlen(skip_hash(region->name));
264317
if ((dp - dest) + len + 2 < max_len) { // only append if name will fit
265-
memcpy(dp, name, len);
318+
memcpy(dp, skip_hash(region->name), len);
266319
dp += len;
267320
*dp++ = ',';
268321
}
269322
}
270323
}
324+
271325
if (dp > dest) { dp--; } // don't include trailing comma
272326

273327
*dp = 0; // set null terminator

src/helpers/RegionMap.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ class RegionMap {
4949
int getCount() const { return num_regions; }
5050
const RegionEntry* getByIdx(int i) const { return &regions[i]; }
5151
const RegionEntry* getRoot() const { return &wildcard; }
52-
int exportNamesTo(char *dest, int max_len, uint8_t mask);
52+
int exportNamesTo(char *dest, int max_len, uint8_t mask, bool invert = false);
5353

54-
void exportTo(Stream& out) const;
54+
void exportTo(Stream& out) const;
55+
size_t exportTo(char *dest, size_t max_len) const;
56+
5557
};

0 commit comments

Comments
 (0)