diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 5fb1a729f..87a2c3c4a 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -415,6 +415,30 @@ uint32_t MyMesh::getDirectRetransmitDelay(const mesh::Packet *packet) { return getRNG()->nextInt(0, 5*t + 1); } +uint8_t MyMesh::getForwardPriority(const mesh::Packet* packet, uint8_t default_priority) { + // check admin-relevant packet types only + uint8_t type = packet->getPayloadType(); + if (type != PAYLOAD_TYPE_REQ && + type != PAYLOAD_TYPE_RESPONSE && + type != PAYLOAD_TYPE_TXT_MSG && + type != PAYLOAD_TYPE_PATH) { + return default_priority; + } + + if (packet->payload_len < 2) return default_priority; + uint8_t src_hash = packet->payload[1]; // payload[0] is dest_hash + + // check ACL for admin sender + for (int i = 0; i < acl.getNumClients(); i++) { + auto client = acl.getClientByIdx(i); + if (client->id.isHashMatch(&src_hash) && client->isAdmin()) { + return 0; // highest priority + } + } + + return default_priority; +} + bool MyMesh::filterRecvFloodPacket(mesh::Packet* pkt) { // just try to determine region for packet (apply later in allowPacketForward()) if (pkt->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD) { diff --git a/examples/simple_repeater/MyMesh.h b/examples/simple_repeater/MyMesh.h index ed9f0c5fc..abbf2818c 100644 --- a/examples/simple_repeater/MyMesh.h +++ b/examples/simple_repeater/MyMesh.h @@ -146,6 +146,8 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { return _prefs.multi_acks; } + uint8_t getForwardPriority(const mesh::Packet* packet, uint8_t default_priority) override; + #if ENV_INCLUDE_GPS == 1 void applyGpsPrefs() { sensors.setSettingValue("gps", _prefs.gps_enabled?"1":"0"); diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 1bda9e962..2c97e9826 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -30,6 +30,10 @@ uint32_t Mesh::getCADFailRetryDelay() const { return _rng->nextInt(1, 4)*120; } +uint8_t Mesh::getForwardPriority(const Packet* packet, uint8_t default_priority) { + return default_priority; +} + int Mesh::searchPeersByHash(const uint8_t* hash) { return 0; // not found } @@ -330,8 +334,10 @@ DispatcherAction Mesh::routeRecvPacket(Packet* packet) { packet->path_len += self_id.copyHashTo(&packet->path[packet->path_len]); uint32_t d = getRetransmitDelay(packet); - // as this propagates outwards, give it lower and lower priority - return ACTION_RETRANSMIT_DELAYED(packet->path_len, d); // give priority to closer sources, than ones further away + // lower priority as this propagates outward (closer sources forwarded first) + uint8_t default_priority = packet->path_len; + uint8_t priority = getForwardPriority(packet, default_priority); + return ACTION_RETRANSMIT_DELAYED(priority, d); } return ACTION_RELEASE; } diff --git a/src/Mesh.h b/src/Mesh.h index 00f7ed00f..598bddc66 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -70,6 +70,14 @@ class Mesh : public Dispatcher { */ virtual uint8_t getExtraAckTransmitCount() const; + /** + * \brief Override to adjust packet forwarding priority + * \param packet packet being routed + * \param default_priority priority from base routing (lower = higher priority) + * \returns adjusted priority + */ + virtual uint8_t getForwardPriority(const Packet* packet, uint8_t default_priority); + /** * \brief Perform search of local DB of peers/contacts. * \returns Number of peers with matching hash