mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
* refactored the hasSeen(Packet) stuff.
This commit is contained in:
parent
8983584dd8
commit
20fccac2b7
10 changed files with 68 additions and 133 deletions
20
src/Mesh.cpp
20
src/Mesh.cpp
|
|
@ -36,6 +36,8 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
|||
|
||||
if (pkt->isRouteDirect() && pkt->path_len >= PATH_HASH_SIZE) {
|
||||
if (self_id.isHashMatch(pkt->path) && allowPacketForward(pkt)) {
|
||||
if (_tables->hasSeen(pkt)) return ACTION_RELEASE; // don't retransmit!
|
||||
|
||||
// remove our hash from 'path', then re-broadcast
|
||||
pkt->path_len -= PATH_HASH_SIZE;
|
||||
memcpy(pkt->path, &pkt->path[PATH_HASH_SIZE], pkt->path_len);
|
||||
|
|
@ -53,7 +55,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
|||
memcpy(&ack_crc, &pkt->payload[i], 4); i += 4;
|
||||
if (i > pkt->payload_len) {
|
||||
MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete ACK packet");
|
||||
} else {
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
onAckRecv(pkt, ack_crc);
|
||||
action = routeRecvPacket(pkt);
|
||||
}
|
||||
|
|
@ -70,7 +72,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
|||
uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
|
||||
if (i + 2 >= pkt->payload_len) {
|
||||
MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete data packet");
|
||||
} else {
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
if (self_id.isHashMatch(&dest_hash)) {
|
||||
// scan contacts DB, for all matching hashes of 'src_hash' (max 4 matches supported ATM)
|
||||
int num = searchPeersByHash(&src_hash);
|
||||
|
|
@ -115,7 +117,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
|||
uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
|
||||
if (i + 2 >= pkt->payload_len) {
|
||||
MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete data packet");
|
||||
} else {
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
if (self_id.isHashMatch(&dest_hash)) {
|
||||
Identity sender(sender_pub_key);
|
||||
|
||||
|
|
@ -141,7 +143,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
|||
uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
|
||||
if (i + 2 >= pkt->payload_len) {
|
||||
MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete data packet");
|
||||
} else {
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
// scan channels DB, for all matching hashes of 'channel_hash' (max 2 matches supported ATM)
|
||||
GroupChannel channels[2];
|
||||
int num = searchChannelsByHash(&channel_hash, channels, 2);
|
||||
|
|
@ -170,7 +172,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
|||
|
||||
if (i > pkt->payload_len) {
|
||||
MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete advertisement packet");
|
||||
} else {
|
||||
} else if (!_tables->hasSeen(pkt)) {
|
||||
uint8_t* app_data = &pkt->payload[i];
|
||||
int app_data_len = pkt->payload_len - i;
|
||||
if (app_data_len > MAX_ADVERT_DATA_SIZE) { app_data_len = MAX_ADVERT_DATA_SIZE; }
|
||||
|
|
@ -198,7 +200,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
|||
}
|
||||
default:
|
||||
MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): unknown payload type, header: %d", (int) pkt->header);
|
||||
action = routeRecvPacket(pkt);
|
||||
// Don't flood route unknown packet types! action = routeRecvPacket(pkt);
|
||||
break;
|
||||
}
|
||||
return action;
|
||||
|
|
@ -382,7 +384,7 @@ void Mesh::sendFlood(Packet* packet, uint32_t delay_millis) {
|
|||
packet->header |= ROUTE_TYPE_FLOOD;
|
||||
packet->path_len = 0;
|
||||
|
||||
allowPacketForward(packet); // mark this packet as already sent in case it is rebroadcast back to us
|
||||
_tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
|
||||
|
||||
uint8_t pri;
|
||||
if (packet->getPayloadType() == PAYLOAD_TYPE_PATH) {
|
||||
|
|
@ -401,7 +403,7 @@ void Mesh::sendDirect(Packet* packet, const uint8_t* path, uint8_t path_len, uin
|
|||
|
||||
memcpy(packet->path, path, packet->path_len = path_len);
|
||||
|
||||
allowPacketForward(packet); // mark this packet as already sent in case it is rebroadcast back to us
|
||||
_tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
|
||||
|
||||
sendPacket(packet, 0, delay_millis);
|
||||
}
|
||||
|
|
@ -412,7 +414,7 @@ void Mesh::sendZeroHop(Packet* packet, uint32_t delay_millis) {
|
|||
|
||||
packet->path_len = 0; // path_len of zero means Zero Hop
|
||||
|
||||
allowPacketForward(packet); // mark this packet as already sent in case it is rebroadcast back to us
|
||||
_tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
|
||||
|
||||
sendPacket(packet, 0, delay_millis);
|
||||
}
|
||||
|
|
|
|||
13
src/Mesh.h
13
src/Mesh.h
|
|
@ -26,6 +26,14 @@ public:
|
|||
uint8_t secret[PUB_KEY_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* An abstraction of the data tables needed to be maintained
|
||||
*/
|
||||
class MeshTables {
|
||||
public:
|
||||
virtual bool hasSeen(const Packet* packet) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief The next layer in the basic Dispatcher task, Mesh recognises the particular Payload TYPES,
|
||||
* and provides virtual methods for sub-classes on handling incoming, and also preparing outbound Packets.
|
||||
|
|
@ -33,6 +41,7 @@ public:
|
|||
class Mesh : public Dispatcher {
|
||||
RTCClock* _rtc;
|
||||
RNG* _rng;
|
||||
MeshTables* _tables;
|
||||
|
||||
protected:
|
||||
DispatcherAction onRecvPacket(Packet* pkt) override;
|
||||
|
|
@ -117,8 +126,8 @@ protected:
|
|||
*/
|
||||
virtual void onAckRecv(Packet* packet, uint32_t ack_crc) { }
|
||||
|
||||
Mesh(Radio& radio, MillisecondClock& ms, RNG& rng, RTCClock& rtc, PacketManager& mgr)
|
||||
: Dispatcher(radio, ms, mgr), _rng(&rng), _rtc(&rtc)
|
||||
Mesh(Radio& radio, MillisecondClock& ms, RNG& rng, RTCClock& rtc, PacketManager& mgr, MeshTables& tables)
|
||||
: Dispatcher(radio, ms, mgr), _rng(&rng), _rtc(&rtc), _tables(&tables)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Mesh.h>
|
||||
|
||||
namespace mesh {
|
||||
|
||||
/**
|
||||
* An abstraction of the data tables needed to be maintained, for the routing engine.
|
||||
*/
|
||||
class MeshTables {
|
||||
public:
|
||||
virtual bool hasForwarded(const uint8_t* packet_hash) const = 0;
|
||||
virtual void setHasForwarded(const uint8_t* packet_hash) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#include <MeshTables.h>
|
||||
#include <Mesh.h>
|
||||
|
||||
#ifdef ESP32
|
||||
#include <FS.h>
|
||||
#endif
|
||||
|
||||
#define MAX_PACKET_HASHES 64
|
||||
#define MAX_PACKET_HASHES 128
|
||||
|
||||
class SimpleMeshTables : public mesh::MeshTables {
|
||||
uint8_t _fwd_hashes[MAX_PACKET_HASHES*MAX_HASH_SIZE];
|
||||
int _next_fwd_idx;
|
||||
|
||||
int lookupHashIndex(const uint8_t* hash) const {
|
||||
const uint8_t* sp = _fwd_hashes;
|
||||
for (int i = 0; i < MAX_PACKET_HASHES; i++, sp += MAX_HASH_SIZE) {
|
||||
if (memcmp(hash, sp, MAX_HASH_SIZE) == 0) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
uint8_t _hashes[MAX_PACKET_HASHES*MAX_HASH_SIZE];
|
||||
int _next_idx;
|
||||
|
||||
public:
|
||||
SimpleMeshTables() {
|
||||
memset(_fwd_hashes, 0, sizeof(_fwd_hashes));
|
||||
_next_fwd_idx = 0;
|
||||
memset(_hashes, 0, sizeof(_hashes));
|
||||
_next_idx = 0;
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
void restoreFrom(File f) {
|
||||
f.read(_fwd_hashes, sizeof(_fwd_hashes));
|
||||
f.read((uint8_t *) &_next_fwd_idx, sizeof(_next_fwd_idx));
|
||||
f.read(_hashes, sizeof(_hashes));
|
||||
f.read((uint8_t *) &_next_idx, sizeof(_next_idx));
|
||||
}
|
||||
void saveTo(File f) {
|
||||
f.write(_fwd_hashes, sizeof(_fwd_hashes));
|
||||
f.write((const uint8_t *) &_next_fwd_idx, sizeof(_next_fwd_idx));
|
||||
f.write(_hashes, sizeof(_hashes));
|
||||
f.write((const uint8_t *) &_next_idx, sizeof(_next_idx));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hasForwarded(const uint8_t* packet_hash) const override {
|
||||
int i = lookupHashIndex(packet_hash);
|
||||
return i >= 0;
|
||||
}
|
||||
bool hasSeen(const mesh::Packet* packet) override {
|
||||
uint8_t hash[MAX_HASH_SIZE];
|
||||
packet->calculatePacketHash(hash);
|
||||
|
||||
void setHasForwarded(const uint8_t* packet_hash) override {
|
||||
int i = lookupHashIndex(packet_hash);
|
||||
if (i >= 0) {
|
||||
// already in table
|
||||
} else {
|
||||
memcpy(&_fwd_hashes[_next_fwd_idx*MAX_HASH_SIZE], packet_hash, MAX_HASH_SIZE);
|
||||
|
||||
_next_fwd_idx = (_next_fwd_idx + 1) % MAX_PACKET_HASHES; // cyclic table
|
||||
const uint8_t* sp = _hashes;
|
||||
for (int i = 0; i < MAX_PACKET_HASHES; i++, sp += MAX_HASH_SIZE) {
|
||||
if (memcmp(hash, sp, MAX_HASH_SIZE) == 0) return true;
|
||||
}
|
||||
|
||||
memcpy(&_hashes[_next_idx*MAX_HASH_SIZE], hash, MAX_HASH_SIZE);
|
||||
_next_idx = (_next_idx + 1) % MAX_PACKET_HASHES; // cyclic table
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Packet.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_PACKET_HASHES 64
|
||||
|
||||
class SimpleSeenTable {
|
||||
uint8_t _hashes[MAX_PACKET_HASHES*MAX_HASH_SIZE];
|
||||
int _next_idx;
|
||||
|
||||
public:
|
||||
SimpleSeenTable() {
|
||||
memset(_hashes, 0, sizeof(_hashes));
|
||||
_next_idx = 0;
|
||||
}
|
||||
|
||||
bool hasSeenPacket(const mesh::Packet* packet) {
|
||||
uint8_t hash[MAX_HASH_SIZE];
|
||||
packet->calculatePacketHash(hash);
|
||||
|
||||
const uint8_t* sp = _hashes;
|
||||
for (int i = 0; i < MAX_PACKET_HASHES; i++, sp += MAX_HASH_SIZE) {
|
||||
if (memcmp(hash, sp, MAX_HASH_SIZE) == 0) return true;
|
||||
}
|
||||
|
||||
memcpy(&_hashes[_next_idx*MAX_HASH_SIZE], hash, MAX_HASH_SIZE);
|
||||
_next_idx = (_next_idx + 1) % MAX_PACKET_HASHES; // cyclic table
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue