Prevent packet loops and duplicates

Implement a "seen packets" table to track packets that have already been processed by the serial bridge.

This prevents packets from being re-transmitted over the serial link if they have already been seen, and it stops inbound packets from serial from being re-injected into the mesh if they are duplicates.

Duplicate inbound packets are now freed to prevent memory leaks.
This commit is contained in:
João Brázio 2025-09-04 23:50:13 +01:00
parent 1948d284a0
commit ee3c4baea5
No known key found for this signature in database
GPG key ID: 56A1490716A324DD
2 changed files with 13 additions and 5 deletions

View file

@ -42,10 +42,12 @@ void SerialBridge::begin() {
} }
void SerialBridge::onPacketTransmitted(mesh::Packet* packet) { void SerialBridge::onPacketTransmitted(mesh::Packet* packet) {
SerialPacket spkt; if (!_seen_packets.hasSeen(packet)) {
spkt.len = packet->writeTo(spkt.payload); SerialPacket spkt;
spkt.crc = fletcher16(spkt.payload, spkt.len); spkt.len = packet->writeTo(spkt.payload);
_serial->write((uint8_t *)&spkt, sizeof(SerialPacket)); spkt.crc = fletcher16(spkt.payload, spkt.len);
_serial->write((uint8_t *)&spkt, sizeof(SerialPacket));
}
} }
void SerialBridge::loop() { void SerialBridge::loop() {
@ -92,7 +94,11 @@ void SerialBridge::onPacketReceived() {
} }
new_pkt->readFrom(bytes, len); new_pkt->readFrom(bytes, len);
_mgr->queueInbound(new_pkt, 0); if (!_seen_packets.hasSeen(new_pkt)) {
_mgr->queueInbound(new_pkt, 0);
} else {
_mgr->free(new_pkt);
}
} }
#endif #endif

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "helpers/AbstractBridge.h" #include "helpers/AbstractBridge.h"
#include "helpers/SimpleMeshTables.h"
#include <Stream.h> #include <Stream.h>
#ifdef BRIDGE_OVER_SERIAL #ifdef BRIDGE_OVER_SERIAL
@ -25,6 +26,7 @@ public:
private: private:
Stream* _serial; Stream* _serial;
mesh::PacketManager* _mgr; mesh::PacketManager* _mgr;
SimpleMeshTables _seen_packets;
}; };
#endif #endif