Skip to content

Commit 8edcb46

Browse files
committed
Bridge: enhance CLI configuration options
1 parent aa946bb commit 8edcb46

File tree

11 files changed

+162
-118
lines changed

11 files changed

+162
-118
lines changed

examples/simple_repeater/MyMesh.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,12 @@ void MyMesh::logRxRaw(float snr, float rssi, const uint8_t raw[], int len) {
231231
}
232232

233233
void MyMesh::logRx(mesh::Packet *pkt, int len, float score) {
234+
#ifdef WITH_BRIDGE
235+
if (_prefs.bridge_pkt_src == 1) {
236+
bridge.sendPacket(pkt);
237+
}
238+
#endif
239+
234240
if (_logging) {
235241
File f = openAppend(PACKET_LOG_FILE);
236242
if (f) {
@@ -252,8 +258,11 @@ void MyMesh::logRx(mesh::Packet *pkt, int len, float score) {
252258

253259
void MyMesh::logTx(mesh::Packet *pkt, int len) {
254260
#ifdef WITH_BRIDGE
255-
bridge.onPacketTransmitted(pkt);
261+
if (_prefs.bridge_pkt_src == 0) {
262+
bridge.sendPacket(pkt);
263+
}
256264
#endif
265+
257266
if (_logging) {
258267
File f = openAppend(PACKET_LOG_FILE);
259268
if (f) {
@@ -481,9 +490,10 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
481490
: mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables),
482491
_cli(board, rtc, &_prefs, this), telemetry(MAX_PACKET_PAYLOAD - 4)
483492
#if defined(WITH_RS232_BRIDGE)
484-
, bridge(WITH_RS232_BRIDGE, _mgr, &rtc)
485-
#elif defined(WITH_ESPNOW_BRIDGE)
486-
, bridge(_mgr, &rtc)
493+
, bridge(&_prefs, WITH_RS232_BRIDGE, _mgr, &rtc)
494+
#endif
495+
#if defined(WITH_ESPNOW_BRIDGE)
496+
, bridge(&_prefs, _mgr, &rtc)
487497
#endif
488498
{
489499
next_local_advert = next_flood_advert = 0;
@@ -513,8 +523,14 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
513523
_prefs.flood_advert_interval = 12; // 12 hours
514524
_prefs.flood_max = 64;
515525
_prefs.interference_threshold = 0; // disabled
516-
_prefs.bridge_enabled = 1; // enabled
517-
_prefs.bridge_channel = 0; // auto
526+
527+
// bridge defaults
528+
_prefs.bridge_enabled = 1; // enabled
529+
_prefs.bridge_delay = 500; // milliseconds
530+
_prefs.bridge_pkt_src = 0; // logTx
531+
_prefs.bridge_baud = 115200; // baud rate
532+
_prefs.bridge_channel = 1; // channel 1
533+
StrHelper::strncpy(_prefs.bridge_secret, "LVSITANOS", sizeof(_prefs.bridge_secret));
518534
}
519535

520536
void MyMesh::begin(FILESYSTEM *fs) {
@@ -525,9 +541,6 @@ void MyMesh::begin(FILESYSTEM *fs) {
525541

526542
acl.load(_fs);
527543

528-
#if defined(WITH_ESPNOW_BRIDGE)
529-
bridge.setChannel(_prefs.bridge_channel);
530-
#endif
531544
#if defined(WITH_BRIDGE)
532545
if (_prefs.bridge_enabled) {
533546
bridge.begin();

examples/simple_repeater/MyMesh.h

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -165,23 +165,6 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
165165
void updateAdvertTimer() override;
166166
void updateFloodAdvertTimer() override;
167167

168-
#if defined(WITH_BRIDGE)
169-
void setBridgeState(bool enable) {
170-
if (enable == bridge.getState()) return;
171-
enable ? bridge.begin() : bridge.end();
172-
}
173-
174-
#if defined(WITH_ESPNOW_BRIDGE)
175-
void updateBridgeChannel(int ch) override {
176-
bridge.setChannel(ch);
177-
if (bridge.getState()) {
178-
bridge.end();
179-
bridge.begin();
180-
}
181-
}
182-
#endif
183-
#endif
184-
185168
void setLoggingOn(bool enable) override { _logging = enable; }
186169

187170
void eraseLogFile() override {
@@ -199,4 +182,17 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
199182
void clearStats() override;
200183
void handleCommand(uint32_t sender_timestamp, char* command, char* reply);
201184
void loop();
185+
186+
#if defined(WITH_BRIDGE)
187+
void setBridgeState(bool enable) override {
188+
if (enable == bridge.getState()) return;
189+
enable ? bridge.begin() : bridge.end();
190+
}
191+
192+
void restartBridge() override {
193+
if (!bridge.getState()) return;
194+
bridge.end();
195+
bridge.begin();
196+
}
197+
#endif
202198
};

src/helpers/AbstractBridge.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class AbstractBridge {
3535
*
3636
* @param packet The packet that was transmitted.
3737
*/
38-
virtual void onPacketTransmitted(mesh::Packet* packet) = 0;
38+
virtual void sendPacket(mesh::Packet* packet) = 0;
3939

4040
/**
4141
* @brief Processes a received packet from the bridge's medium.

src/helpers/CommonCLI.cpp

Lines changed: 81 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
5959
file.read((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
6060
file.read((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
6161
file.read((uint8_t *)&_prefs->bridge_enabled, sizeof(_prefs->bridge_enabled)); // 127
62-
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 128
62+
file.read((uint8_t *)&_prefs->bridge_delay, sizeof(_prefs->bridge_delay)); // 128
63+
file.read((uint8_t *)&_prefs->bridge_pkt_src, sizeof(_prefs->bridge_pkt_src)); // 130
64+
file.read((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
65+
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 132
66+
file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 133
6367

6468
// sanitise bad pref values
6569
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
@@ -72,7 +76,12 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
7276
_prefs->cr = constrain(_prefs->cr, 5, 8);
7377
_prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, 1, 30);
7478
_prefs->multi_acks = constrain(_prefs->multi_acks, 0, 1);
79+
80+
// sanitise bad bridge pref values
7581
_prefs->bridge_enabled = constrain(_prefs->bridge_enabled, 0, 1);
82+
_prefs->bridge_delay = constrain(_prefs->bridge_delay, 0, 10000);
83+
_prefs->bridge_pkt_src = constrain(_prefs->bridge_pkt_src, 0, 1);
84+
_prefs->bridge_baud = constrain(_prefs->bridge_baud, 9600, 115200);
7685
_prefs->bridge_channel = constrain(_prefs->bridge_channel, 0, 14);
7786

7887
file.close();
@@ -119,7 +128,11 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
119128
file.write((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
120129
file.write((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
121130
file.write((uint8_t *)&_prefs->bridge_enabled, sizeof(_prefs->bridge_enabled)); // 127
122-
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 128
131+
file.write((uint8_t *)&_prefs->bridge_delay, sizeof(_prefs->bridge_delay)); // 128
132+
file.write((uint8_t *)&_prefs->bridge_pkt_src, sizeof(_prefs->bridge_pkt_src)); // 130
133+
file.write((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
134+
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 132
135+
file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 133
123136

124137
file.close();
125138
}
@@ -205,6 +218,9 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
205218
} else if (memcmp(command, "clear stats", 11) == 0) {
206219
_callbacks->clearStats();
207220
strcpy(reply, "(OK - stats reset)");
221+
/*
222+
* GET commands
223+
*/
208224
} else if (memcmp(command, "get ", 4) == 0) {
209225
const char* config = &command[4];
210226
if (memcmp(config, "af", 2) == 0) {
@@ -261,38 +277,29 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
261277
#ifdef WITH_BRIDGE
262278
} else if (memcmp(config, "bridge.enabled", 14) == 0) {
263279
sprintf(reply, "> %s", _prefs->bridge_enabled ? "on" : "off");
280+
} else if (memcmp(config, "bridge.delay", 12) == 0) {
281+
sprintf(reply, "> %d", (uint32_t)_prefs->bridge_delay);
282+
} else if (memcmp(config, "bridge.source", 13) == 0) {
283+
sprintf(reply, "> %s", _prefs->bridge_pkt_src ? "logRx" : "logTx");
284+
#endif
285+
#ifdef WITH_RS232_BRIDGE
286+
} else if (memcmp(config, "bridge.baud", 11) == 0) {
287+
sprintf(reply, "> %d", (uint32_t)_prefs->bridge_baud);
288+
#endif
264289
#ifdef WITH_ESPNOW_BRIDGE
265290
} else if (memcmp(config, "bridge.channel", 14) == 0) {
266291
sprintf(reply, "> %d", (uint32_t)_prefs->bridge_channel);
267-
#endif
292+
} else if (memcmp(config, "bridge.secret", 13) == 0) {
293+
sprintf(reply, "> %s", _prefs->bridge_secret);
268294
#endif
269295
} else {
270296
sprintf(reply, "??: %s", config);
271297
}
298+
/*
299+
* SET commands
300+
*/
272301
} else if (memcmp(command, "set ", 4) == 0) {
273302
const char* config = &command[4];
274-
#ifdef WITH_BRIDGE
275-
if (memcmp(config, "bridge.enabled ", 15) == 0) {
276-
_prefs->bridge_enabled = memcmp(&config[15], "on", 2) == 0;
277-
_callbacks->setBridgeState(_prefs->bridge_enabled);
278-
savePrefs();
279-
strcpy(reply, "OK");
280-
}
281-
else
282-
#ifdef WITH_ESPNOW_BRIDGE
283-
if (memcmp(config, "bridge.channel ", 15) == 0) {
284-
int ch = atoi(&config[15]);
285-
if (ch > 0 && ch < 15) {
286-
_prefs->bridge_channel = (uint8_t)ch;
287-
_callbacks->updateBridgeChannel(ch);
288-
savePrefs();
289-
strcpy(reply, "OK");
290-
} else {
291-
strcpy(reply, "Error: channel must be 0 (AUTO) or 1-14");
292-
}
293-
} else
294-
#endif
295-
#endif
296303
if (memcmp(config, "af ", 3) == 0) {
297304
_prefs->airtime_factor = atof(&config[3]);
298305
savePrefs();
@@ -428,6 +435,55 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
428435
_prefs->freq = atof(&config[5]);
429436
savePrefs();
430437
strcpy(reply, "OK - reboot to apply");
438+
#ifdef WITH_BRIDGE
439+
} else if (memcmp(config, "bridge.enabled ", 15) == 0) {
440+
_prefs->bridge_enabled = memcmp(&config[15], "on", 2) == 0;
441+
_callbacks->setBridgeState(_prefs->bridge_enabled);
442+
savePrefs();
443+
strcpy(reply, "OK");
444+
} else if (memcmp(config, "bridge.delay ", 13) == 0) {
445+
int delay = _atoi(&config[13]);
446+
if (delay >= 0 && delay <= 10000) {
447+
_prefs->bridge_delay = (uint16_t)delay;
448+
savePrefs();
449+
strcpy(reply, "OK");
450+
} else {
451+
strcpy(reply, "Error: delay must be between 0-10000 ms");
452+
}
453+
} else if (memcmp(config, "bridge.source ", 14) == 0) {
454+
_prefs->bridge_pkt_src = memcmp(&config[14], "rx", 2) == 0;
455+
savePrefs();
456+
strcpy(reply, "OK");
457+
#endif
458+
#ifdef WITH_RS232_BRIDGE
459+
} else if (memcmp(config, "bridge.baud ", 12) == 0) {
460+
uint32_t baud = atoi(&config[12]);
461+
if (baud >= 9600 && baud <= 115200) {
462+
_prefs->bridge_baud = (uint32_t)baud;
463+
_callbacks->restartBridge();
464+
savePrefs();
465+
strcpy(reply, "OK");
466+
} else {
467+
strcpy(reply, "Error: baud rate must be between 9600-115200");
468+
}
469+
#endif
470+
#ifdef WITH_ESPNOW_BRIDGE
471+
} else if (memcmp(config, "bridge.channel ", 15) == 0) {
472+
int ch = atoi(&config[15]);
473+
if (ch > 0 && ch < 15) {
474+
_prefs->bridge_channel = (uint8_t)ch;
475+
_callbacks->restartBridge();
476+
savePrefs();
477+
strcpy(reply, "OK");
478+
} else {
479+
strcpy(reply, "Error: channel must be between 1-14");
480+
}
481+
} else if (memcmp(config, "bridge.secret ", 14) == 0) {
482+
StrHelper::strncpy(_prefs->bridge_secret, &config[14], sizeof(_prefs->bridge_secret));
483+
_callbacks->restartBridge();
484+
savePrefs();
485+
strcpy(reply, "OK");
486+
#endif
431487
} else {
432488
sprintf(reply, "unknown config: %s", config);
433489
}

src/helpers/CommonCLI.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@ struct NodePrefs { // persisted to file
3030
uint8_t flood_max;
3131
uint8_t interference_threshold;
3232
uint8_t agc_reset_interval; // secs / 4
33-
uint8_t bridge_enabled; // boolean
34-
uint8_t bridge_channel; // 1-14
33+
// Bridge settings
34+
uint8_t bridge_enabled; // boolean
35+
uint16_t bridge_delay; // milliseconds (default 500 ms)
36+
uint8_t bridge_pkt_src; // 0 = logTx, 1 = logRx (default logTx)
37+
uint32_t bridge_baud; // 9600, 19200, 38400, 57600, 115200 (default 115200)
38+
uint8_t bridge_channel; // 1-14 (ESP-NOW only)
39+
char bridge_secret[16]; // for XOR encryption of bridge packets (ESP-NOW only)
3540
};
3641

3742
class CommonCLICallbacks {
@@ -57,12 +62,13 @@ class CommonCLICallbacks {
5762
virtual void clearStats() = 0;
5863
virtual void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) = 0;
5964

60-
#ifdef WITH_BRIDGE
61-
virtual void setBridgeState(bool enable) = 0;
62-
#ifdef WITH_ESPNOW_BRIDGE
63-
virtual void updateBridgeChannel(int ch) = 0;
64-
#endif
65-
#endif
65+
virtual void setBridgeState(bool enable) {
66+
// no op by default
67+
};
68+
69+
virtual void restartBridge() {
70+
// no op by default
71+
};
6672
};
6773

6874
class CommonCLI {

src/helpers/bridges/BridgeBase.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ void BridgeBase::handleReceivedPacket(mesh::Packet *packet) {
4040
}
4141

4242
if (!_seen_packets.hasSeen(packet)) {
43-
_mgr->queueInbound(packet, millis() + BRIDGE_DELAY);
43+
// bridge_delay provides a buffer to prevent immediate processing conflicts in the mesh network.
44+
_mgr->queueInbound(packet, millis() + _prefs->bridge_delay);
4445
} else {
4546
_mgr->free(packet);
4647
}

src/helpers/bridges/BridgeBase.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "helpers/AbstractBridge.h"
4+
#include "helpers/CommonCLI.h"
45
#include "helpers/SimpleMeshTables.h"
56

67
#include <RTClib.h>
@@ -48,34 +49,31 @@ class BridgeBase : public AbstractBridge {
4849
static constexpr uint16_t BRIDGE_LENGTH_SIZE = sizeof(uint16_t);
4950
static constexpr uint16_t BRIDGE_CHECKSUM_SIZE = sizeof(uint16_t);
5051

51-
/**
52-
* @brief Default delay in milliseconds for scheduling inbound packet processing
53-
*
54-
* It provides a buffer to prevent immediate processing conflicts in the mesh network.
55-
* Used in handleReceivedPacket() as: millis() + BRIDGE_DELAY
56-
*/
57-
static constexpr uint16_t BRIDGE_DELAY = 500; // TODO: maybe too high ?
58-
5952
protected:
6053
/** Tracks bridge state */
6154
bool _initialized = false;
62-
55+
6356
/** Packet manager for allocating and queuing mesh packets */
6457
mesh::PacketManager *_mgr;
6558

6659
/** RTC clock for timestamping debug messages */
6760
mesh::RTCClock *_rtc;
6861

62+
/** Node preferences for configuration settings */
63+
NodePrefs *_prefs;
64+
6965
/** Tracks seen packets to prevent loops in broadcast communications */
7066
SimpleMeshTables _seen_packets;
7167

7268
/**
7369
* @brief Constructs a BridgeBase instance
7470
*
71+
* @param prefs Node preferences for configuration settings
7572
* @param mgr PacketManager for allocating and queuing packets
7673
* @param rtc RTCClock for timestamping debug messages
7774
*/
78-
BridgeBase(mesh::PacketManager *mgr, mesh::RTCClock *rtc) : _mgr(mgr), _rtc(rtc) {}
75+
BridgeBase(NodePrefs *prefs, mesh::PacketManager *mgr, mesh::RTCClock *rtc)
76+
: _prefs(prefs), _mgr(mgr), _rtc(rtc) {}
7977

8078
/**
8179
* @brief Gets formatted date/time string for logging

0 commit comments

Comments
 (0)