Skip to content

Commit 08f91f8

Browse files
author
Scott Powell
committed
Merge branch 'dev' into rep-room-acl
# Conflicts: # examples/simple_repeater/main.cpp
2 parents f2e8fb0 + ea33f39 commit 08f91f8

File tree

35 files changed

+1970
-15
lines changed

35 files changed

+1970
-15
lines changed

examples/simple_repeater/MyMesh.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ void MyMesh::logRx(mesh::Packet *pkt, int len, float score) {
207207
}
208208

209209
void MyMesh::logTx(mesh::Packet *pkt, int len) {
210+
#ifdef WITH_BRIDGE
211+
bridge->onPacketTransmitted(pkt);
212+
#endif
210213
if (_logging) {
211214
File f = openAppend(PACKET_LOG_FILE);
212215
if (f) {
@@ -471,6 +474,15 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
471474
mesh::RTCClock &rtc, mesh::MeshTables &tables)
472475
: mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables),
473476
_cli(board, rtc, &_prefs, this), telemetry(MAX_PACKET_PAYLOAD - 4) {
477+
#ifdef WITH_BRIDGE
478+
#if defined(WITH_RS232_BRIDGE)
479+
bridge = new RS232Bridge(WITH_RS232_BRIDGE, _mgr, &rtc);
480+
#elif defined(WITH_ESPNOW_BRIDGE)
481+
bridge = new ESPNowBridge(_mgr, &rtc);
482+
#else
483+
#error "You must choose either RS232 or ESPNow bridge"
484+
#endif
485+
#endif
474486
memset(known_clients, 0, sizeof(known_clients));
475487
next_local_advert = next_flood_advert = 0;
476488
set_radio_at = revert_radio_at = 0;
@@ -655,6 +667,10 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply
655667
}
656668

657669
void MyMesh::loop() {
670+
#ifdef WITH_BRIDGE
671+
bridge->loop();
672+
#endif
673+
658674
mesh::Mesh::loop();
659675

660676
if (next_flood_advert && millisHasNowPassed(next_flood_advert)) {

examples/simple_repeater/MyMesh.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,20 @@
2121
#include <RTClib.h>
2222
#include <target.h>
2323

24+
#ifdef WITH_RS232_BRIDGE
25+
#include "helpers/bridges/RS232Bridge.h"
26+
#define WITH_BRIDGE
27+
#endif
28+
29+
#ifdef WITH_ESPNOW_BRIDGE
30+
#include "helpers/bridges/ESPNowBridge.h"
31+
#define WITH_BRIDGE
32+
#endif
33+
34+
#ifdef WITH_BRIDGE
35+
extern AbstractBridge* bridge;
36+
#endif
37+
2438
struct RepeaterStats {
2539
uint16_t batt_milli_volts;
2640
uint16_t curr_tx_queue_len;

examples/simple_repeater/main.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
static UITask ui_task(display);
99
#endif
1010

11+
#ifdef WITH_BRIDGE
12+
AbstractBridge* bridge;
13+
#endif
14+
1115
StdRNG fast_rng;
1216
SimpleMeshTables tables;
1317

@@ -23,6 +27,10 @@ void setup() {
2327
Serial.begin(115200);
2428
delay(1000);
2529

30+
#ifdef WITH_BRIDGE
31+
bridge->begin();
32+
#endif
33+
2634
board.begin();
2735

2836
#ifdef DISPLAY_CLASS
@@ -34,7 +42,9 @@ void setup() {
3442
}
3543
#endif
3644

37-
if (!radio_init()) { halt(); }
45+
if (!radio_init()) {
46+
halt();
47+
}
3848

3949
fast_rng.begin(radio_get_rng_seed());
4050

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/AbstractBridge.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#include <Mesh.h>
4+
5+
class AbstractBridge {
6+
public:
7+
virtual ~AbstractBridge() {}
8+
9+
/**
10+
* @brief Initializes the bridge.
11+
*/
12+
virtual void begin() = 0;
13+
14+
/**
15+
* @brief A method to be called on every main loop iteration.
16+
* Used for tasks like checking for incoming data.
17+
*/
18+
virtual void loop() = 0;
19+
20+
/**
21+
* @brief A callback that is triggered when the mesh transmits a packet.
22+
* The bridge can use this to forward the packet.
23+
*
24+
* @param packet The packet that was transmitted.
25+
*/
26+
virtual void onPacketTransmitted(mesh::Packet* packet) = 0;
27+
28+
/**
29+
* @brief Processes a received packet from the bridge's medium.
30+
*
31+
* @param packet The packet that was received.
32+
*/
33+
virtual void onPacketReceived(mesh::Packet* packet) = 0;
34+
};

src/helpers/bridges/BridgeBase.cpp

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

src/helpers/bridges/BridgeBase.h

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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+
/**
25+
* @brief Common magic number used by all bridge implementations for packet identification
26+
*
27+
* This magic number is placed at the beginning of bridge packets to identify
28+
* them as mesh bridge packets and provide frame synchronization.
29+
*/
30+
static constexpr uint16_t BRIDGE_PACKET_MAGIC = 0xC03E;
31+
32+
/**
33+
* @brief Common field sizes used by bridge implementations
34+
*
35+
* These constants define the size of common packet fields used across bridges.
36+
* BRIDGE_MAGIC_SIZE is used by all bridges for packet identification.
37+
* BRIDGE_LENGTH_SIZE is used by bridges that need explicit length fields (like RS232).
38+
* BRIDGE_CHECKSUM_SIZE is used by all bridges for Fletcher-16 checksums.
39+
*/
40+
static constexpr uint16_t BRIDGE_MAGIC_SIZE = sizeof(BRIDGE_PACKET_MAGIC);
41+
static constexpr uint16_t BRIDGE_LENGTH_SIZE = sizeof(uint16_t);
42+
static constexpr uint16_t BRIDGE_CHECKSUM_SIZE = sizeof(uint16_t);
43+
44+
/**
45+
* @brief Default delay in milliseconds for scheduling inbound packet processing
46+
*
47+
* It provides a buffer to prevent immediate processing conflicts in the mesh network.
48+
* Used in handleReceivedPacket() as: millis() + BRIDGE_DELAY
49+
*/
50+
static constexpr uint16_t BRIDGE_DELAY = 500; // TODO: maybe too high ?
51+
52+
protected:
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+
62+
/**
63+
* @brief Constructs a BridgeBase instance
64+
*
65+
* @param mgr PacketManager for allocating and queuing packets
66+
* @param rtc RTCClock for timestamping debug messages
67+
*/
68+
BridgeBase(mesh::PacketManager *mgr, mesh::RTCClock *rtc) : _mgr(mgr), _rtc(rtc) {}
69+
70+
/**
71+
* @brief Gets formatted date/time string for logging
72+
*
73+
* Format: "HH:MM:SS - DD/MM/YYYY U"
74+
*
75+
* @return Formatted date/time string
76+
*/
77+
const char *getLogDateTime();
78+
79+
/**
80+
* @brief Calculate Fletcher-16 checksum
81+
*
82+
* Based on: https://en.wikipedia.org/wiki/Fletcher%27s_checksum
83+
* Used to verify data integrity of received packets
84+
*
85+
* @param data Pointer to data to calculate checksum for
86+
* @param len Length of data in bytes
87+
* @return Calculated Fletcher-16 checksum
88+
*/
89+
static uint16_t fletcher16(const uint8_t *data, size_t len);
90+
91+
/**
92+
* @brief Validate received checksum against calculated checksum
93+
*
94+
* @param data Pointer to data to validate
95+
* @param len Length of data in bytes
96+
* @param received_checksum Checksum received with data
97+
* @return true if checksum is valid, false otherwise
98+
*/
99+
bool validateChecksum(const uint8_t *data, size_t len, uint16_t received_checksum);
100+
101+
/**
102+
* @brief Common packet handling for received packets
103+
*
104+
* Implements the standard pattern used by all bridges:
105+
* - Check if packet was seen before using _seen_packets.hasSeen()
106+
* - Queue packet for mesh processing if not seen before
107+
* - Free packet if already seen to prevent duplicates
108+
*
109+
* @param packet The received mesh packet
110+
*/
111+
void handleReceivedPacket(mesh::Packet *packet);
112+
};

0 commit comments

Comments
 (0)