Add repeater flood filters and transport scopes
This commit is contained in:
1 parent
5e030ce77b
commit
09c8aaba9c
25 files changed
+1222
-111
No files matched your search
@@ -39,7 +39,9 @@ void PacketQueue::rebuildNextTime() {
|
||||
}
|
||||
}
|
||||
|
||||
mesh::Packet* PacketQueue::get(uint32_t now) {
|
||||
mesh::Packet* PacketQueue::get(uint32_t now, bool resolve_flood_scope,
|
||||
FloodScopePreference scope_preference,
|
||||
void* scope_preference_context) {
|
||||
uint8_t min_pri = 0xFF;
|
||||
int best_idx = -1;
|
||||
for (int j = 0; j < _num; j++) {
|
||||
@@ -51,6 +53,10 @@ mesh::Packet* PacketQueue::get(uint32_t now) {
|
||||
}
|
||||
if (best_idx < 0) return NULL; // empty, or all items are still in the future
|
||||
|
||||
if (resolve_flood_scope) {
|
||||
applyBestFloodTransportScope(_table[best_idx], scope_preference,
|
||||
scope_preference_context);
|
||||
}
|
||||
return removeByIdx(best_idx);
|
||||
}
|
||||
|
||||
@@ -97,7 +103,52 @@ bool PacketQueue::add(mesh::Packet* packet, uint8_t priority, uint32_t scheduled
|
||||
return true;
|
||||
}
|
||||
|
||||
StaticPoolPacketManager::StaticPoolPacketManager(int pool_size): unused(pool_size), send_queue(pool_size), rx_queue(pool_size) {
|
||||
void PacketQueue::applyBestFloodTransportScope(mesh::Packet* packet,
|
||||
FloodScopePreference scope_preference,
|
||||
void* scope_preference_context) const {
|
||||
// Scope validity is application-specific. Without a validator there is no
|
||||
// safe way to distinguish a locally-allowed scope from arbitrary codes.
|
||||
if (packet == NULL || !packet->isRouteFlood()
|
||||
|| packet->getPayloadType() == PAYLOAD_TYPE_TRACE
|
||||
|| scope_preference == NULL) return;
|
||||
|
||||
uint8_t packet_hash[MAX_HASH_SIZE];
|
||||
packet->calculatePacketHash(packet_hash);
|
||||
|
||||
const mesh::Packet* best = NULL;
|
||||
uint8_t best_hops = 0xFF;
|
||||
uint8_t best_preference = 0;
|
||||
for (int i = 0; i < _num; i++) {
|
||||
const mesh::Packet* candidate = _table[i];
|
||||
if (candidate == NULL || candidate->getRouteType() != ROUTE_TYPE_TRANSPORT_FLOOD) continue;
|
||||
uint8_t candidate_hash[MAX_HASH_SIZE];
|
||||
candidate->calculatePacketHash(candidate_hash);
|
||||
if (memcmp(packet_hash, candidate_hash, sizeof(packet_hash)) != 0) continue;
|
||||
|
||||
uint8_t hops = candidate->getPathHashCount();
|
||||
uint8_t preference = scope_preference(candidate, scope_preference_context);
|
||||
if (preference == 0) continue; // unknown, denied, or otherwise unusable here
|
||||
if (best == NULL || hops < best_hops
|
||||
|| (hops == best_hops && preference > best_preference)) {
|
||||
best = candidate;
|
||||
best_hops = hops;
|
||||
best_preference = preference;
|
||||
}
|
||||
}
|
||||
if (best == NULL) return;
|
||||
|
||||
// Keep the receive-quality winner's path, SNR, and schedule, but give it the
|
||||
// scope carried by the shortest equivalent scoped copy. Equal paths prefer
|
||||
// the most specific locally-recognized scope supplied by the application.
|
||||
packet->header = (packet->header & (uint8_t)~PH_ROUTE_MASK) | ROUTE_TYPE_TRANSPORT_FLOOD;
|
||||
if (packet != best) {
|
||||
memcpy(packet->transport_codes, best->transport_codes, sizeof(packet->transport_codes));
|
||||
}
|
||||
}
|
||||
|
||||
StaticPoolPacketManager::StaticPoolPacketManager(int pool_size)
|
||||
: unused(pool_size), send_queue(pool_size), rx_queue(pool_size),
|
||||
flood_scope_preference(NULL), flood_scope_preference_context(NULL) {
|
||||
// load up our unusued Packet pool
|
||||
for (int i = 0; i < pool_size; i++) {
|
||||
unused.add(new mesh::Packet(), 0, 0);
|
||||
@@ -159,7 +210,8 @@ void StaticPoolPacketManager::queueInbound(mesh::Packet* packet, uint32_t schedu
|
||||
}
|
||||
}
|
||||
mesh::Packet* StaticPoolPacketManager::getNextInbound(uint32_t now) {
|
||||
return rx_queue.get(now);
|
||||
return rx_queue.get(now, true, flood_scope_preference,
|
||||
flood_scope_preference_context);
|
||||
}
|
||||
|
||||
bool StaticPoolPacketManager::getNextInboundTime(uint32_t now, uint32_t& scheduled_for) const {
|
||||
|
||||
Reference in new issue
Block a user