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

* RegionMap: inverted 'flags' to _deny_ bits
* Mesh: new filterRecvFloodPacket() for overriding
* repeater CLI: 'allow' -> 'allowf' or 'denyf'

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

+ 6 - 0
examples/companion_radio/MyMesh.cpp

@@ -378,6 +378,12 @@ void MyMesh::queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packe
 #endif
 }
 
+bool MyMesh::filterRecvFloodPacket(mesh::Packet* packet) {
+  // REVISIT: try to determine which Region (from transport_codes[1]) that Sender is indicating for replies/responses
+  //    if unknown, fallback to finding Region from transport_codes[0], the 'scope' used by Sender
+  return false;
+}
+
 void MyMesh::sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis) {
   // TODO: dynamic send_scope, depending on recipient and current 'home' Region
   if (send_scope.isNull()) {

+ 1 - 0
examples/companion_radio/MyMesh.h

@@ -107,6 +107,7 @@ protected:
   int getInterferenceThreshold() const override;
   int calcRxDelay(float score, uint32_t air_time) const override;
   uint8_t getExtraAckTransmitCount() const override;
+  bool filterRecvFloodPacket(mesh::Packet* packet) override;
 
   void sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis=0) override;
   void sendFloodScoped(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t delay_millis=0) override;

+ 20 - 18
examples/simple_repeater/MyMesh.cpp

@@ -404,21 +404,21 @@ uint32_t MyMesh::getDirectRetransmitDelay(const mesh::Packet *packet) {
   return getRNG()->nextInt(0, 5*t + 1);
 }
 
-mesh::DispatcherAction MyMesh::onRecvPacket(mesh::Packet* pkt) {
+bool MyMesh::filterRecvFloodPacket(mesh::Packet* pkt) {
   if (pkt->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD) {
-    auto region = region_map.findMatch(pkt, REGION_ALLOW_FLOOD);
+    auto region = region_map.findMatch(pkt, REGION_DENY_FLOOD);
     if (region == NULL) {
       MESH_DEBUG_PRINTLN("onRecvPacket: unknown transport code for FLOOD packet");
-      return ACTION_RELEASE;
+      return true;
     }
   } else if (pkt->getRouteType() == ROUTE_TYPE_FLOOD) {
-    if ((region_map.getWildcard().flags & REGION_ALLOW_FLOOD) == 0) {
+    if (region_map.getWildcard().flags & REGION_DENY_FLOOD) {
       MESH_DEBUG_PRINTLN("onRecvPacket: wildcard FLOOD packet not allowed");
-      return ACTION_RELEASE;
+      return true;
     }
   }
   // otherwise do normal processing
-  return mesh::Mesh::onRecvPacket(pkt);
+  return false;
 }
 
 void MyMesh::onAnonDataRecv(mesh::Packet *packet, const uint8_t *secret, const mesh::Identity &sender,
@@ -867,7 +867,7 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply
       while (is_name_char(*ep)) ep++;
       if (*ep) { *ep++ = 0; }  // set null terminator for end of name
 
-      while (*ep && *ep != 'F') ep++;  // look for (optional flags)
+      while (*ep && *ep != 'F') ep++;  // look for (optional) flags
 
       if (indent > 0 && indent < 8) {
         auto parent = load_stack[indent - 1];
@@ -875,7 +875,7 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply
           auto old = region_map.findByName(np);
           auto nw = temp_map.putRegion(np, parent->id, old ? old->id : 0);  // carry-over the current ID (if name already exists)
           if (nw) {
-            nw->flags = old ? old->flags : (*ep == 'F' ? REGION_ALLOW_FLOOD : 0);   // carry-over flags from curr
+            nw->flags = old ? old->flags : (*ep == 'F' ? 0 : REGION_DENY_FLOOD);   // carry-over flags from curr
 
             load_stack[indent] = nw;  // keep pointers to parent regions, to resolve parent_id's
           }
@@ -943,24 +943,26 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply
     } else if (n >= 2 && strcmp(parts[1], "save") == 0) {
       bool success = region_map.save(_fs);
       strcpy(reply, success ? "OK" : "Err - save failed");
-    } else if (n >= 3 && strcmp(parts[1], "allow") == 0) {
-      auto region = n >= 4 ? region_map.findByNamePrefix(parts[3]) : &region_map.getWildcard();
+    } else if (n >= 2 && strcmp(parts[1], "allowf") == 0) {
+      auto region = n >= 3 ? region_map.findByNamePrefix(parts[2]) : &region_map.getWildcard();
       if (region) {
+        region->flags &= ~REGION_DENY_FLOOD;
+        strcpy(reply, "OK");
+      } else {
+        strcpy(reply, "Err - unknown region");
+      }
+    } else if (n >= 2 && strcmp(parts[1], "denyf") == 0) {
+      auto region = n >= 3 ? region_map.findByNamePrefix(parts[2]) : &region_map.getWildcard();
+      if (region) {
+        region->flags |= REGION_DENY_FLOOD;
         strcpy(reply, "OK");
-        if (strcmp(parts[2], "F") == 0) {
-          region->flags = REGION_ALLOW_FLOOD;
-        } else if (strcmp(parts[2], "0") == 0) {
-          region->flags = 0;
-        } else {
-          sprintf(reply, "Err - invalid flag: %s", parts[2]);
-        }
       } else {
         strcpy(reply, "Err - unknown region");
       }
     } else if (n >= 3 && strcmp(parts[1], "get") == 0) {
       auto region = region_map.findByNamePrefix(parts[2]);
       if (region) {
-        sprintf(reply, " %s %s", region->name, region->flags == REGION_ALLOW_FLOOD ? "F" : "");
+        sprintf(reply, " %s %s", region->name, (region->flags & REGION_DENY_FLOOD) ? "" : "F");
       } else {
         strcpy(reply, "Err - unknown region");
       }

+ 1 - 1
examples/simple_repeater/MyMesh.h

@@ -149,7 +149,7 @@ protected:
   }
 #endif
 
-  mesh::DispatcherAction onRecvPacket(mesh::Packet* pkt) override;
+  bool filterRecvFloodPacket(mesh::Packet* pkt) override;
 
   void onAnonDataRecv(mesh::Packet* packet, const uint8_t* secret, const mesh::Identity& sender, uint8_t* data, size_t len) override;
   int searchPeersByHash(const uint8_t* hash) override;

+ 2 - 0
src/Mesh.cpp

@@ -90,6 +90,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
     return ACTION_RELEASE;   // this node is NOT the next hop (OR this packet has already been forwarded), so discard.
   }
 
+  if (pkt->isRouteFlood() && filterRecvFloodPacket(pkt)) return ACTION_RELEASE;
+
   DispatcherAction action = ACTION_RELEASE;
 
   switch (pkt->getPayloadType()) {

+ 5 - 0
src/Mesh.h

@@ -43,6 +43,11 @@ protected:
    */
   DispatcherAction routeRecvPacket(Packet* packet);
 
+  /**
+   * \returns  true, if given packet should be NOT be processed.
+   */
+  virtual bool filterRecvFloodPacket(Packet* packet) { return false; }
+
   /**
    * \brief  Check whether this packet should be forwarded (re-transmitted) or not.
    *     Is sub-classes responsibility to make sure given packet is only transmitted ONCE (by this node)

+ 6 - 6
src/helpers/RegionMap.cpp

@@ -5,7 +5,7 @@
 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
+  wildcard.flags = 0;  // default behaviour, allow flood and direct
   strcpy(wildcard.name, "(*)");
 }
 
@@ -100,7 +100,7 @@ RegionEntry* RegionMap::putRegion(const char* name, uint16_t parent_id, uint16_t
     if (id == 0 && num_regions >= MAX_REGION_ENTRIES) return NULL;  // full!
 
     region = &regions[num_regions++];   // alloc new RegionEntry
-    region->flags = 0;
+    region->flags = REGION_DENY_FLOOD;     // DENY by default
     region->id = id == 0 ? next_id++ : id;
     StrHelper::strncpy(region->name, name, sizeof(region->name));
     region->parent = parent_id;
@@ -111,7 +111,7 @@ RegionEntry* RegionMap::putRegion(const char* name, uint16_t parent_id, uint16_t
 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) == mask) {   // does region allow this? (per 'mask' param)
+    if ((region->flags & mask) == 0) {   // does region allow this? (per 'mask' param)
       TransportKey keys[4];
       int num;
       if (region->name[0] == '#') {   // auto hashtag region
@@ -189,10 +189,10 @@ void RegionMap::printChildRegions(int indent, const RegionEntry* parent, Stream&
     out.print(' ');
   }
 
-  if (parent->flags & REGION_ALLOW_FLOOD) {
-    out.printf("%s F\n", parent->name);
-  } else {
+  if (parent->flags & REGION_DENY_FLOOD) {
     out.printf("%s\n", parent->name);
+  } else {
+    out.printf("%s F\n", parent->name);
   }
 
   for (int i = 0; i < num_regions; i++) {

+ 2 - 1
src/helpers/RegionMap.h

@@ -8,7 +8,8 @@
   #define MAX_REGION_ENTRIES  32
 #endif
 
-#define REGION_ALLOW_FLOOD  0x01
+#define REGION_DENY_FLOOD   0x01
+#define REGION_DENY_DIRECT  0x02   // reserved for future
 
 struct RegionEntry {
   uint16_t id;