@@ -46,6 +46,10 @@ RegionMap::RegionMap(TransportKeyStore& store) : _store(&store) {
4646 wildcard.id = wildcard.parent = 0 ;
4747 wildcard.flags = 0 ; // default behaviour, allow flood and direct
4848 strcpy (wildcard.name , " *" );
49+ any.id = ANY_REGION_ID;
50+ any.parent = 0 ;
51+ any.flags = 0 ;
52+ strcpy (any.name , DEFAULT_REGION_NAME);
4953}
5054
5155bool RegionMap::is_name_char (uint8_t c) {
@@ -81,7 +85,8 @@ bool RegionMap::load(FILESYSTEM* _fs, const char* path) {
8185
8286 num_regions = 0 ; next_id = 1 ; home_id = 0 ;
8387
84- bool success = file.read (pad, 5 ) == 5 ; // reserved header
88+ bool success = file.read (pad, 4 ) == 4 ; // reserved header
89+ success = success && file.read ((uint8_t *) &any.flags , sizeof (any.flags )) == sizeof (any.flags );
8590 success = success && file.read ((uint8_t *) &home_id, sizeof (home_id)) == sizeof (home_id);
8691 success = success && file.read ((uint8_t *) &wildcard.flags , sizeof (wildcard.flags )) == sizeof (wildcard.flags );
8792 success = success && file.read ((uint8_t *) &next_id, sizeof (next_id)) == sizeof (next_id);
@@ -117,7 +122,8 @@ bool RegionMap::save(FILESYSTEM* _fs, const char* path) {
117122 uint8_t pad[128 ];
118123 memset (pad, 0 , sizeof (pad));
119124
120- bool success = file.write (pad, 5 ) == 5 ; // reserved header
125+ bool success = file.write (pad, 4 ) == 4 ; // reserved header
126+ success = success && file.write ((uint8_t *) &any.flags , sizeof (any.flags )) == sizeof (any.flags );
121127 success = success && file.write ((uint8_t *) &home_id, sizeof (home_id)) == sizeof (home_id);
122128 success = success && file.write ((uint8_t *) &wildcard.flags , sizeof (wildcard.flags )) == sizeof (wildcard.flags );
123129 success = success && file.write ((uint8_t *) &next_id, sizeof (next_id)) == sizeof (next_id);
@@ -147,6 +153,10 @@ RegionEntry* RegionMap::putRegion(const char* name, uint16_t parent_id, uint16_t
147153 sp++;
148154 }
149155
156+ if ((strcmp (name, any.name ) == 0 ) || (strcmp (skip_hash (name), any.name ) == 0 )) { // protected default region
157+ return NULL ;
158+ }
159+
150160 auto region = findByName (name);
151161 if (region) {
152162 if (region->id == parent_id) return NULL ; // ERROR: invalid parent!
@@ -190,11 +200,15 @@ RegionEntry* RegionMap::findMatch(mesh::Packet* packet, uint8_t mask) {
190200 }
191201 }
192202 }
203+ if (any.flags == 0 ) {
204+ return &any;
205+ }
193206 return NULL ; // no matches
194207}
195208
196209RegionEntry* RegionMap::findByName (const char * name) {
197210 if (strcmp (name, " *" ) == 0 ) return &wildcard;
211+ if ((strcmp (name, any.name ) == 0 ) || (strcmp (skip_hash (name), any.name ) == 0 )) return &any; // default region scope
198212
199213 if (*name == ' #' ) { name++; } // ignore the '#' when matching by name
200214 for (int i = 0 ; i < num_regions; i++) {
@@ -206,6 +220,9 @@ RegionEntry* RegionMap::findByName(const char* name) {
206220
207221RegionEntry* RegionMap::findByNamePrefix (const char * prefix) {
208222 if (strcmp (prefix, " *" ) == 0 ) return &wildcard;
223+ if (((strcmp (prefix, any.name ) == 0 ) && (sizeof (prefix) == strlen (any.name ))) || ((strcmp (prefix, skip_hash (any.name )) == 0 ) && (sizeof (prefix) == (strlen (any.name ) + 1 ))) ) {
224+ return &any; // exact match default region scope
225+ }
209226
210227 if (*prefix == ' #' ) { prefix++; } // ignore the '#' when matching by name
211228 RegionEntry* partial = NULL ;
@@ -220,7 +237,8 @@ RegionEntry* RegionMap::findByNamePrefix(const char* prefix) {
220237}
221238
222239RegionEntry* RegionMap::findById (uint16_t id) {
223- if (id == 0 ) return &wildcard; // special root Region
240+ if (id == 0 ) return &wildcard; // special null Region
241+ if (id == ANY_REGION_ID) return &any; // special default region
224242
225243 for (int i = 0 ; i < num_regions; i++) {
226244 auto region = ®ions[i];
@@ -238,7 +256,8 @@ void RegionMap::setHomeRegion(const RegionEntry* home) {
238256}
239257
240258bool RegionMap::removeRegion (const RegionEntry& region) {
241- if (region.id == 0 ) return false ; // failed (cannot remove the wildcard Region)
259+ if (region.id == 0 ) return false ; // failed (cannot remove the null Region)
260+ if (region.id == ANY_REGION_ID) return false ; // failed (cannot remove the default region)
242261
243262 int i; // first check region has no child regions
244263 for (i = 0 ; i < num_regions; i++) {
@@ -286,6 +305,13 @@ void RegionMap::printChildRegions(int indent, const RegionEntry* parent, Stream&
286305
287306void RegionMap::exportTo (Stream& out) const {
288307 printChildRegions (0 , &wildcard, out); // recursive
308+
309+ // Append default (any) region
310+ if (any.flags & REGION_DENY_FLOOD) {
311+ out.printf (" any%s\n " , any.id == home_id ? " ^" : " " );
312+ } else {
313+ out.printf (" any%s F\n " , any.id == home_id ? " ^" : " " );
314+ }
289315}
290316
291317size_t RegionMap::exportTo (char *dest, size_t max_len) const {
@@ -306,7 +332,7 @@ int RegionMap::exportNamesTo(char *dest, int max_len, uint8_t mask, bool invert)
306332 *dp++ = ' ,' ;
307333 }
308334
309- for (int i = 0 ; i < num_regions; i++) {
335+ for (int i = 0 ; i < num_regions; i++) {
310336 auto region = ®ions[i];
311337
312338 // Check if region matches the filter criteria
@@ -322,6 +348,17 @@ int RegionMap::exportNamesTo(char *dest, int max_len, uint8_t mask, bool invert)
322348 }
323349 }
324350
351+ // Check default (any) region - do this after defined regions to emphasise it is "everything else"
352+ bool any_matches = invert ? (any.flags & mask) : !(any.flags & mask);
353+ if (any_matches) {
354+ int len = strlen (any.name );
355+ if ((dp - dest) + len + 1 < max_len) { // only append if it will fit
356+ memcpy (dp, any.name , len);
357+ dp += len;
358+ dp++;
359+ }
360+ }
361+
325362 if (dp > dest) { dp--; } // don't include trailing comma
326363
327364 *dp = 0 ; // set null terminator
0 commit comments