Skip to content

Commit 0051cce

Browse files
committed
Refactor bridge implementations to inherit from BridgeBase
1 parent 537449e commit 0051cce

File tree

7 files changed

+281
-154
lines changed

7 files changed

+281
-154
lines changed

platformio.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ build_src_filter =
4747
+<*.cpp>
4848
+<helpers/*.cpp>
4949
+<helpers/radiolib/*.cpp>
50+
+<helpers/bridges/BridgeBase.cpp>
5051
+<helpers/ui/MomentaryButton.cpp>
5152

5253
; ----------------- ESP32 ---------------------

src/helpers/bridges/BridgeBase.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include "BridgeBase.h"
2+
3+
const char *BridgeBase::getLogDateTime() {
4+
static char tmp[32];
5+
uint32_t now = _rtc->getCurrentTime();
6+
DateTime dt = DateTime(now);
7+
sprintf(tmp, "%02d:%02d:%02d - %d/%d/%d U", dt.hour(), dt.minute(), dt.second(), dt.day(), dt.month(),
8+
dt.year());
9+
return tmp;
10+
}
11+
12+
uint16_t BridgeBase::fletcher16(const uint8_t *data, size_t len) {
13+
uint8_t sum1 = 0, sum2 = 0;
14+
15+
for (size_t i = 0; i < len; i++) {
16+
sum1 = (sum1 + data[i]) % 255;
17+
sum2 = (sum2 + sum1) % 255;
18+
}
19+
20+
return (sum2 << 8) | sum1;
21+
}
22+
23+
bool BridgeBase::validateChecksum(const uint8_t *data, size_t len, uint16_t received_checksum) {
24+
uint16_t calculated_checksum = fletcher16(data, len);
25+
return received_checksum == calculated_checksum;
26+
}
27+
28+
void BridgeBase::handleReceivedPacket(mesh::Packet *packet) {
29+
if (!_seen_packets.hasSeen(packet)) {
30+
_mgr->queueInbound(packet, 0);
31+
} else {
32+
_mgr->free(packet);
33+
}
34+
}

src/helpers/bridges/BridgeBase.h

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#pragma once
2+
3+
#include "helpers/AbstractBridge.h"
4+
#include "helpers/SimpleMeshTables.h"
5+
6+
#include <RTClib.h>
7+
8+
/**
9+
* @brief Base class implementing common bridge functionality
10+
*
11+
* This class provides common functionality used by different bridge implementations
12+
* like packet tracking, checksum calculation, timestamping, and duplicate detection.
13+
*
14+
* Features:
15+
* - Fletcher-16 checksum calculation for data integrity
16+
* - Packet duplicate detection using SimpleMeshTables
17+
* - Common timestamp formatting for debug logging
18+
* - Shared packet management and queuing logic
19+
*/
20+
class BridgeBase : public AbstractBridge {
21+
public:
22+
virtual ~BridgeBase() = default;
23+
24+
protected:
25+
/** Packet manager for allocating and queuing mesh packets */
26+
mesh::PacketManager *_mgr;
27+
28+
/** RTC clock for timestamping debug messages */
29+
mesh::RTCClock *_rtc;
30+
31+
/** Tracks seen packets to prevent loops in broadcast communications */
32+
SimpleMeshTables _seen_packets;
33+
34+
/**
35+
* @brief Constructs a BridgeBase instance
36+
*
37+
* @param mgr PacketManager for allocating and queuing packets
38+
* @param rtc RTCClock for timestamping debug messages
39+
*/
40+
BridgeBase(mesh::PacketManager *mgr, mesh::RTCClock *rtc) : _mgr(mgr), _rtc(rtc) {}
41+
42+
/**
43+
* @brief Gets formatted date/time string for logging
44+
*
45+
* Format: "HH:MM:SS - DD/MM/YYYY U"
46+
*
47+
* @return Formatted date/time string
48+
*/
49+
const char *getLogDateTime();
50+
51+
/**
52+
* @brief Calculate Fletcher-16 checksum
53+
*
54+
* Based on: https://en.wikipedia.org/wiki/Fletcher%27s_checksum
55+
* Used to verify data integrity of received packets
56+
*
57+
* @param data Pointer to data to calculate checksum for
58+
* @param len Length of data in bytes
59+
* @return Calculated Fletcher-16 checksum
60+
*/
61+
static uint16_t fletcher16(const uint8_t *data, size_t len);
62+
63+
/**
64+
* @brief Validate received checksum against calculated checksum
65+
*
66+
* @param data Pointer to data to validate
67+
* @param len Length of data in bytes
68+
* @param received_checksum Checksum received with data
69+
* @return true if checksum is valid, false otherwise
70+
*/
71+
bool validateChecksum(const uint8_t *data, size_t len, uint16_t received_checksum);
72+
73+
/**
74+
* @brief Common packet handling for received packets
75+
*
76+
* Implements the standard pattern used by all bridges:
77+
* - Check if packet was seen before using _seen_packets.hasSeen()
78+
* - Queue packet for mesh processing if not seen before
79+
* - Free packet if already seen to prevent duplicates
80+
*
81+
* @param packet The received mesh packet
82+
*/
83+
void handleReceivedPacket(mesh::Packet *packet);
84+
};

src/helpers/bridges/ESPNowBridge.cpp

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "ESPNowBridge.h"
22

3-
#include <RTClib.h>
43
#include <WiFi.h>
54
#include <esp_wifi.h>
65

@@ -22,21 +21,8 @@ void ESPNowBridge::send_cb(const uint8_t *mac, esp_now_send_status_t status) {
2221
}
2322
}
2423

25-
// Fletcher16 checksum calculation
26-
static uint16_t fletcher16(const uint8_t *data, size_t len) {
27-
uint16_t sum1 = 0;
28-
uint16_t sum2 = 0;
29-
30-
while (len--) {
31-
sum1 = (sum1 + *data++) % 255;
32-
sum2 = (sum2 + sum1) % 255;
33-
}
34-
35-
return (sum2 << 8) | sum1;
36-
}
37-
3824
ESPNowBridge::ESPNowBridge(mesh::PacketManager *mgr, mesh::RTCClock *rtc)
39-
: _mgr(mgr), _rtc(rtc), _rx_buffer_pos(0) {
25+
: BridgeBase(mgr, rtc), _rx_buffer_pos(0) {
4026
_instance = this;
4127
}
4228

@@ -115,13 +101,12 @@ void ESPNowBridge::onDataRecv(const uint8_t *mac, const uint8_t *data, int32_t l
115101
// Validate checksum
116102
uint16_t received_checksum = (decrypted[0] << 8) | decrypted[1];
117103
const size_t payloadLen = encryptedDataLen - CHECKSUM_SIZE;
118-
uint16_t calculated_checksum = fletcher16(decrypted + CHECKSUM_SIZE, payloadLen);
119104

120-
if (received_checksum != calculated_checksum) {
105+
if (!validateChecksum(decrypted + CHECKSUM_SIZE, payloadLen, received_checksum)) {
121106
// Failed to decrypt - likely from a different network
122107
#if MESH_PACKET_LOGGING
123-
Serial.printf("%s: ESPNOW BRIDGE: RX checksum mismatch, rcv=0x%04X calc=0x%04X\n", getLogDateTime(),
124-
received_checksum, calculated_checksum);
108+
Serial.printf("%s: ESPNOW BRIDGE: RX checksum mismatch, rcv=0x%04X\n", getLogDateTime(),
109+
received_checksum);
125110
#endif
126111
return;
127112
}
@@ -146,23 +131,19 @@ void ESPNowBridge::onDataSent(const uint8_t *mac_addr, esp_now_send_status_t sta
146131
}
147132

148133
void ESPNowBridge::onPacketReceived(mesh::Packet *packet) {
149-
if (!_seen_packets.hasSeen(packet)) {
150-
_mgr->queueInbound(packet, 0);
151-
} else {
152-
_mgr->free(packet);
153-
}
134+
handleReceivedPacket(packet);
154135
}
155136

156137
void ESPNowBridge::onPacketTransmitted(mesh::Packet *packet) {
157-
if (!_seen_packets.hasSeen(packet)) {
158-
159-
// First validate the packet pointer
160-
if (!packet) {
138+
// First validate the packet pointer
139+
if (!packet) {
161140
#if MESH_PACKET_LOGGING
162-
Serial.printf("%s: ESPNOW BRIDGE: TX invalid packet pointer\n", getLogDateTime());
141+
Serial.printf("%s: ESPNOW BRIDGE: TX invalid packet pointer\n", getLogDateTime());
163142
#endif
164-
return;
165-
}
143+
return;
144+
}
145+
146+
if (!_seen_packets.hasSeen(packet)) {
166147

167148
// Create a temporary buffer just for size calculation and reuse for actual writing
168149
uint8_t sizingBuffer[MAX_PAYLOAD_SIZE];
@@ -212,13 +193,4 @@ void ESPNowBridge::onPacketTransmitted(mesh::Packet *packet) {
212193
}
213194
}
214195

215-
const char *ESPNowBridge::getLogDateTime() {
216-
static char tmp[32];
217-
uint32_t now = _rtc->getCurrentTime();
218-
DateTime dt = DateTime(now);
219-
sprintf(tmp, "%02d:%02d:%02d - %d/%d/%d U", dt.hour(), dt.minute(), dt.second(), dt.day(), dt.month(),
220-
dt.year());
221-
return tmp;
222-
}
223-
224196
#endif

src/helpers/bridges/ESPNowBridge.h

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
#include "MeshCore.h"
44
#include "esp_now.h"
5-
#include "helpers/AbstractBridge.h"
6-
#include "helpers/SimpleMeshTables.h"
5+
#include "helpers/bridges/BridgeBase.h"
76

87
#ifdef WITH_ESPNOW_BRIDGE
98

@@ -44,21 +43,12 @@
4443
* WITH_ESPNOW_BRIDGE_SECRET values. Packets encrypted with a different key will
4544
* fail the checksum validation and be discarded.
4645
*/
47-
class ESPNowBridge : public AbstractBridge {
46+
class ESPNowBridge : public BridgeBase {
4847
private:
4948
static ESPNowBridge *_instance;
5049
static void recv_cb(const uint8_t *mac, const uint8_t *data, int32_t len);
5150
static void send_cb(const uint8_t *mac, esp_now_send_status_t status);
5251

53-
/** Packet manager for allocating and queuing mesh packets */
54-
mesh::PacketManager *_mgr;
55-
56-
/** RTC clock for timestamping debug messages */
57-
mesh::RTCClock *_rtc;
58-
59-
/** Tracks seen packets to prevent loops in broadcast communications */
60-
SimpleMeshTables _seen_packets;
61-
6252
/**
6353
* ESP-NOW Protocol Structure:
6454
* - ESP-NOW header: 20 bytes (handled by ESP-NOW protocol)
@@ -168,14 +158,6 @@ class ESPNowBridge : public AbstractBridge {
168158
* @param packet The mesh packet to transmit
169159
*/
170160
void onPacketTransmitted(mesh::Packet *packet) override;
171-
172-
/**
173-
* Gets formatted date/time string for logging
174-
* Format: "HH:MM:SS - DD/MM/YYYY U"
175-
*
176-
* @return Formatted date/time string
177-
*/
178-
const char *getLogDateTime();
179161
};
180162

181163
#endif

0 commit comments

Comments
 (0)