Kaynağa Gözat

Merge branch 'dev' into CommonCLI--gps-management

Florent de Lamotte 10 ay önce
ebeveyn
işleme
c9fd1827ef
33 değiştirilmiş dosya ile 508 ekleme ve 248 silme
  1. 26 6
      examples/simple_repeater/MyMesh.cpp
  2. 31 11
      examples/simple_repeater/MyMesh.h
  3. 6 0
      src/MeshCore.h
  4. 15 3
      src/helpers/AbstractBridge.h
  5. 156 53
      src/helpers/CommonCLI.cpp
  6. 42 23
      src/helpers/CommonCLI.h
  7. 13 1
      src/helpers/bridges/BridgeBase.cpp
  8. 17 9
      src/helpers/bridges/BridgeBase.h
  9. 62 39
      src/helpers/bridges/ESPNowBridge.cpp
  10. 17 16
      src/helpers/bridges/ESPNowBridge.h
  11. 64 60
      src/helpers/bridges/RS232Bridge.cpp
  12. 9 2
      src/helpers/bridges/RS232Bridge.h
  13. 4 2
      variants/generic-e22/platformio.ini
  14. 2 1
      variants/heltec_ct62/platformio.ini
  15. 2 1
      variants/heltec_e213/platformio.ini
  16. 2 1
      variants/heltec_e290/platformio.ini
  17. 2 1
      variants/heltec_t190/platformio.ini
  18. 2 1
      variants/heltec_tracker/platformio.ini
  19. 2 1
      variants/heltec_v2/platformio.ini
  20. 4 2
      variants/heltec_v3/platformio.ini
  21. 1 1
      variants/heltec_v4/platformio.ini
  22. 2 1
      variants/heltec_wireless_paper/platformio.ini
  23. 2 1
      variants/lilygo_t3s3/platformio.ini
  24. 2 1
      variants/lilygo_t3s3_sx1276/platformio.ini
  25. 2 1
      variants/lilygo_tbeam_SX1262/platformio.ini
  26. 2 1
      variants/lilygo_tbeam_SX1276/platformio.ini
  27. 2 1
      variants/lilygo_tbeam_supreme_SX1262/platformio.ini
  28. 2 1
      variants/lilygo_tlora_v2_1/platformio.ini
  29. 4 2
      variants/meshadventurer/platformio.ini
  30. 4 2
      variants/station_g2/platformio.ini
  31. 4 2
      variants/tenstar_c3/platformio.ini
  32. 1 0
      variants/waveshare_rp2040_lora/platformio.ini
  33. 2 1
      variants/xiao_s3_wio/platformio.ini

+ 26 - 6
examples/simple_repeater/MyMesh.cpp

@@ -331,6 +331,12 @@ void MyMesh::logRxRaw(float snr, float rssi, const uint8_t raw[], int len) {
 }
 
 void MyMesh::logRx(mesh::Packet *pkt, int len, float score) {
+#ifdef WITH_BRIDGE
+  if (_prefs.bridge_pkt_src == 1) {
+    bridge.sendPacket(pkt);
+  }
+#endif
+
   if (_logging) {
     File f = openAppend(PACKET_LOG_FILE);
     if (f) {
@@ -352,8 +358,11 @@ void MyMesh::logRx(mesh::Packet *pkt, int len, float score) {
 
 void MyMesh::logTx(mesh::Packet *pkt, int len) {
 #ifdef WITH_BRIDGE
-  bridge.onPacketTransmitted(pkt);
+  if (_prefs.bridge_pkt_src == 0) {
+    bridge.sendPacket(pkt);
+  }
 #endif
+
   if (_logging) {
     File f = openAppend(PACKET_LOG_FILE);
     if (f) {
@@ -582,9 +591,10 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
     : mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables),
       _cli(board, rtc, &_prefs, this), telemetry(MAX_PACKET_PAYLOAD - 4)
 #if defined(WITH_RS232_BRIDGE)
-      , bridge(WITH_RS232_BRIDGE, _mgr, &rtc)
-#elif defined(WITH_ESPNOW_BRIDGE)
-      , bridge(_mgr, &rtc)
+      , bridge(&_prefs, WITH_RS232_BRIDGE, _mgr, &rtc)
+#endif
+#if defined(WITH_ESPNOW_BRIDGE)
+      , bridge(&_prefs, _mgr, &rtc)
 #endif
 {
   next_local_advert = next_flood_advert = 0;
@@ -614,6 +624,14 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
   _prefs.flood_advert_interval = 12; // 12 hours
   _prefs.flood_max = 64;
   _prefs.interference_threshold = 0; // disabled
+
+  // bridge defaults
+  _prefs.bridge_enabled = 1;    // enabled
+  _prefs.bridge_delay   = 500;  // milliseconds
+  _prefs.bridge_pkt_src = 0;    // logTx
+  _prefs.bridge_baud = 115200;  // baud rate
+  _prefs.bridge_channel = 1;    // channel 1
+  StrHelper::strncpy(_prefs.bridge_secret, "LVSITANOS", sizeof(_prefs.bridge_secret));
 }
 
 void MyMesh::begin(FILESYSTEM *fs) {
@@ -624,8 +642,10 @@ void MyMesh::begin(FILESYSTEM *fs) {
 
   acl.load(_fs);
 
-#ifdef WITH_BRIDGE
-  bridge.begin();
+#if defined(WITH_BRIDGE)
+  if (_prefs.bridge_enabled) {
+    bridge.begin();
+  }
 #endif
 
   radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);

+ 31 - 11
examples/simple_repeater/MyMesh.h

@@ -2,7 +2,8 @@
 
 #include <Arduino.h>
 #include <Mesh.h>
-#include <helpers/CommonCLI.h>
+#include <RTClib.h>
+#include <target.h>
 
 #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
   #include <InternalFileSystem.h>
@@ -12,16 +13,6 @@
   #include <SPIFFS.h>
 #endif
 
-#include <helpers/ArduinoHelpers.h>
-#include <helpers/StaticPoolPacketManager.h>
-#include <helpers/SimpleMeshTables.h>
-#include <helpers/IdentityStore.h>
-#include <helpers/AdvertDataHelpers.h>
-#include <helpers/TxtDataHelpers.h>
-#include <helpers/ClientACL.h>
-#include <RTClib.h>
-#include <target.h>
-
 #ifdef WITH_RS232_BRIDGE
 #include "helpers/bridges/RS232Bridge.h"
 #define WITH_BRIDGE
@@ -32,6 +23,15 @@
 #define WITH_BRIDGE
 #endif
 
+#include <helpers/AdvertDataHelpers.h>
+#include <helpers/ArduinoHelpers.h>
+#include <helpers/ClientACL.h>
+#include <helpers/CommonCLI.h>
+#include <helpers/IdentityStore.h>
+#include <helpers/SimpleMeshTables.h>
+#include <helpers/StaticPoolPacketManager.h>
+#include <helpers/TxtDataHelpers.h>
+
 #ifdef WITH_BRIDGE
 extern AbstractBridge* bridge;
 #endif
@@ -182,4 +182,24 @@ public:
   void clearStats() override;
   void handleCommand(uint32_t sender_timestamp, char* command, char* reply);
   void loop();
+
+#if defined(WITH_BRIDGE)
+  void setBridgeState(bool enable) override {
+    if (enable == bridge.isRunning()) return;
+    if (enable)
+    {
+      bridge.begin();
+    }
+    else 
+    {
+      bridge.end();
+    }
+  }
+
+  void restartBridge() override {
+    if (!bridge.isRunning()) return;
+    bridge.end();
+    bridge.begin();
+  }
+#endif
 };

+ 6 - 0
src/MeshCore.h

@@ -28,6 +28,12 @@
   #define MESH_DEBUG_PRINTLN(...) {}
 #endif
 
+#if BRIDGE_DEBUG && ARDUINO
+#define BRIDGE_DEBUG_PRINTLN(F, ...) Serial.printf("%s BRIDGE: " F, getLogDateTime(), ##__VA_ARGS__)
+#else
+#define BRIDGE_DEBUG_PRINTLN(...) {}
+#endif
+
 namespace mesh {
 
 #define  BD_STARTUP_NORMAL     0  // getStartupReason() codes

+ 15 - 3
src/helpers/AbstractBridge.h

@@ -11,6 +11,18 @@ public:
    */
   virtual void begin() = 0;
 
+  /**
+   * @brief Stops the bridge.
+   */
+  virtual void end() = 0;
+
+  /**
+   * @brief Gets the current state of the bridge.
+   *
+   * @return true if the bridge is initialized and running, false otherwise.
+   */
+  virtual bool isRunning() const = 0;
+
   /**
    * @brief A method to be called on every main loop iteration.
    *        Used for tasks like checking for incoming data.
@@ -20,14 +32,14 @@ public:
   /**
    * @brief A callback that is triggered when the mesh transmits a packet.
    *        The bridge can use this to forward the packet.
-   * 
+   *
    * @param packet The packet that was transmitted.
    */
-  virtual void onPacketTransmitted(mesh::Packet* packet) = 0;
+  virtual void sendPacket(mesh::Packet* packet) = 0;
 
   /**
    * @brief Processes a received packet from the bridge's medium.
-   * 
+   *
    * @param packet The packet that was received.
    */
   virtual void onPacketReceived(mesh::Packet* packet) = 0;

+ 156 - 53
src/helpers/CommonCLI.cpp

@@ -32,32 +32,38 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
   if (file) {
     uint8_t pad[8];
 
-    file.read((uint8_t *) &_prefs->airtime_factor, sizeof(_prefs->airtime_factor));  // 0
-    file.read((uint8_t *) &_prefs->node_name, sizeof(_prefs->node_name));  // 4
-    file.read(pad, 4);   // 36
-    file.read((uint8_t *) &_prefs->node_lat, sizeof(_prefs->node_lat));  // 40
-    file.read((uint8_t *) &_prefs->node_lon, sizeof(_prefs->node_lon));  // 48
-    file.read((uint8_t *) &_prefs->password[0], sizeof(_prefs->password));  // 56
-    file.read((uint8_t *) &_prefs->freq, sizeof(_prefs->freq));   // 72
-    file.read((uint8_t *) &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm));  // 76
-    file.read((uint8_t *) &_prefs->disable_fwd, sizeof(_prefs->disable_fwd));  // 77
-    file.read((uint8_t *) &_prefs->advert_interval, sizeof(_prefs->advert_interval));  // 78
-    file.read((uint8_t *) pad, 1);  // 79  was 'unused'
-    file.read((uint8_t *) &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base));  // 80
-    file.read((uint8_t *) &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor));  // 84
-    file.read((uint8_t *) &_prefs->guest_password[0], sizeof(_prefs->guest_password));  // 88
-    file.read((uint8_t *) &_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor));  // 104
-    file.read(pad, 4);   // 108
-    file.read((uint8_t *) &_prefs->sf, sizeof(_prefs->sf));  // 112
-    file.read((uint8_t *) &_prefs->cr, sizeof(_prefs->cr));  // 113
-    file.read((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only));  // 114
-    file.read((uint8_t *) &_prefs->multi_acks, sizeof(_prefs->multi_acks));  // 115
-    file.read((uint8_t *) &_prefs->bw, sizeof(_prefs->bw));  // 116
-    file.read((uint8_t *) &_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval));  // 120
-    file.read(pad, 3);   // 121
-    file.read((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max));   // 124
-    file.read((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval));  // 125
-    file.read((uint8_t *) &_prefs->interference_threshold, sizeof(_prefs->interference_threshold));  // 126
+    file.read((uint8_t *)&_prefs->airtime_factor, sizeof(_prefs->airtime_factor));    // 0
+    file.read((uint8_t *)&_prefs->node_name, sizeof(_prefs->node_name));              // 4
+    file.read(pad, 4);                                                                // 36
+    file.read((uint8_t *)&_prefs->node_lat, sizeof(_prefs->node_lat));                // 40
+    file.read((uint8_t *)&_prefs->node_lon, sizeof(_prefs->node_lon));                // 48
+    file.read((uint8_t *)&_prefs->password[0], sizeof(_prefs->password));             // 56
+    file.read((uint8_t *)&_prefs->freq, sizeof(_prefs->freq));                        // 72
+    file.read((uint8_t *)&_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm));        // 76
+    file.read((uint8_t *)&_prefs->disable_fwd, sizeof(_prefs->disable_fwd));          // 77
+    file.read((uint8_t *)&_prefs->advert_interval, sizeof(_prefs->advert_interval));  // 78
+    file.read((uint8_t *)pad, 1);                                                     // 79  was 'unused'
+    file.read((uint8_t *)&_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base));      // 80
+    file.read((uint8_t *)&_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor));  // 84
+    file.read((uint8_t *)&_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
+    file.read((uint8_t *)&_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor)); // 104
+    file.read(pad, 4);                                                                             // 108
+    file.read((uint8_t *)&_prefs->sf, sizeof(_prefs->sf));                                         // 112
+    file.read((uint8_t *)&_prefs->cr, sizeof(_prefs->cr));                                         // 113
+    file.read((uint8_t *)&_prefs->allow_read_only, sizeof(_prefs->allow_read_only));               // 114
+    file.read((uint8_t *)&_prefs->multi_acks, sizeof(_prefs->multi_acks));                         // 115
+    file.read((uint8_t *)&_prefs->bw, sizeof(_prefs->bw));                                         // 116
+    file.read((uint8_t *)&_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval));         // 120
+    file.read(pad, 3);                                                                             // 121
+    file.read((uint8_t *)&_prefs->flood_max, sizeof(_prefs->flood_max));                           // 124
+    file.read((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval));   // 125
+    file.read((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
+    file.read((uint8_t *)&_prefs->bridge_enabled, sizeof(_prefs->bridge_enabled));                 // 127
+    file.read((uint8_t *)&_prefs->bridge_delay, sizeof(_prefs->bridge_delay));                     // 128
+    file.read((uint8_t *)&_prefs->bridge_pkt_src, sizeof(_prefs->bridge_pkt_src));                 // 130
+    file.read((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud));                       // 131
+    file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel));                 // 132
+    file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret));                   // 133
 
     // sanitise bad pref values
     _prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
@@ -71,6 +77,13 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
     _prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, 1, 30);
     _prefs->multi_acks = constrain(_prefs->multi_acks, 0, 1);
 
+    // sanitise bad bridge pref values
+    _prefs->bridge_enabled = constrain(_prefs->bridge_enabled, 0, 1);
+    _prefs->bridge_delay = constrain(_prefs->bridge_delay, 0, 10000);
+    _prefs->bridge_pkt_src = constrain(_prefs->bridge_pkt_src, 0, 1);
+    _prefs->bridge_baud = constrain(_prefs->bridge_baud, 9600, 115200);
+    _prefs->bridge_channel = constrain(_prefs->bridge_channel, 0, 14);
+
     file.close();
   }
 }
@@ -88,32 +101,38 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
     uint8_t pad[8];
     memset(pad, 0, sizeof(pad));
 
-    file.write((uint8_t *) &_prefs->airtime_factor, sizeof(_prefs->airtime_factor));  // 0
-    file.write((uint8_t *) &_prefs->node_name, sizeof(_prefs->node_name));  // 4
-    file.write(pad, 4);   // 36
-    file.write((uint8_t *) &_prefs->node_lat, sizeof(_prefs->node_lat));  // 40
-    file.write((uint8_t *) &_prefs->node_lon, sizeof(_prefs->node_lon));  // 48
-    file.write((uint8_t *) &_prefs->password[0], sizeof(_prefs->password));  // 56
-    file.write((uint8_t *) &_prefs->freq, sizeof(_prefs->freq));   // 72
-    file.write((uint8_t *) &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm));  // 76
-    file.write((uint8_t *) &_prefs->disable_fwd, sizeof(_prefs->disable_fwd));  // 77
-    file.write((uint8_t *) &_prefs->advert_interval, sizeof(_prefs->advert_interval));  // 78
-    file.write((uint8_t *) pad, 1);  // 79  was 'unused'
-    file.write((uint8_t *) &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base));  // 80
-    file.write((uint8_t *) &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor));  // 84
-    file.write((uint8_t *) &_prefs->guest_password[0], sizeof(_prefs->guest_password));  // 88
-    file.write((uint8_t *) &_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor));  // 104
-    file.write(pad, 4);   // 108
-    file.write((uint8_t *) &_prefs->sf, sizeof(_prefs->sf));  // 112
-    file.write((uint8_t *) &_prefs->cr, sizeof(_prefs->cr));  // 113
-    file.write((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only));  // 114
-    file.write((uint8_t *) &_prefs->multi_acks, sizeof(_prefs->multi_acks));  // 115
-    file.write((uint8_t *) &_prefs->bw, sizeof(_prefs->bw));  // 116
-    file.write((uint8_t *) &_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval));  // 120
-    file.write(pad, 3);   // 121
-    file.write((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max));   // 124
-    file.write((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval));  // 125
-    file.write((uint8_t *) &_prefs->interference_threshold, sizeof(_prefs->interference_threshold));  // 126
+    file.write((uint8_t *)&_prefs->airtime_factor, sizeof(_prefs->airtime_factor));    // 0
+    file.write((uint8_t *)&_prefs->node_name, sizeof(_prefs->node_name));              // 4
+    file.write(pad, 4);                                                                // 36
+    file.write((uint8_t *)&_prefs->node_lat, sizeof(_prefs->node_lat));                // 40
+    file.write((uint8_t *)&_prefs->node_lon, sizeof(_prefs->node_lon));                // 48
+    file.write((uint8_t *)&_prefs->password[0], sizeof(_prefs->password));             // 56
+    file.write((uint8_t *)&_prefs->freq, sizeof(_prefs->freq));                        // 72
+    file.write((uint8_t *)&_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm));        // 76
+    file.write((uint8_t *)&_prefs->disable_fwd, sizeof(_prefs->disable_fwd));          // 77
+    file.write((uint8_t *)&_prefs->advert_interval, sizeof(_prefs->advert_interval));  // 78
+    file.write((uint8_t *)pad, 1);                                                     // 79  was 'unused'
+    file.write((uint8_t *)&_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base));      // 80
+    file.write((uint8_t *)&_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor));  // 84
+    file.write((uint8_t *)&_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
+    file.write((uint8_t *)&_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor)); // 104
+    file.write(pad, 4);                                                                             // 108
+    file.write((uint8_t *)&_prefs->sf, sizeof(_prefs->sf));                                         // 112
+    file.write((uint8_t *)&_prefs->cr, sizeof(_prefs->cr));                                         // 113
+    file.write((uint8_t *)&_prefs->allow_read_only, sizeof(_prefs->allow_read_only));               // 114
+    file.write((uint8_t *)&_prefs->multi_acks, sizeof(_prefs->multi_acks));                         // 115
+    file.write((uint8_t *)&_prefs->bw, sizeof(_prefs->bw));                                         // 116
+    file.write((uint8_t *)&_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval));         // 120
+    file.write(pad, 3);                                                                             // 121
+    file.write((uint8_t *)&_prefs->flood_max, sizeof(_prefs->flood_max));                           // 124
+    file.write((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval));   // 125
+    file.write((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
+    file.write((uint8_t *)&_prefs->bridge_enabled, sizeof(_prefs->bridge_enabled));                 // 127
+    file.write((uint8_t *)&_prefs->bridge_delay, sizeof(_prefs->bridge_delay));                     // 128
+    file.write((uint8_t *)&_prefs->bridge_pkt_src, sizeof(_prefs->bridge_pkt_src));                 // 130
+    file.write((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud));                       // 131
+    file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel));                 // 132
+    file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret));                   // 133
 
     file.close();
   }
@@ -220,6 +239,9 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
     } else if (memcmp(command, "clear stats", 11) == 0) {
       _callbacks->clearStats();
       strcpy(reply, "(OK - stats reset)");
+    /*
+     * GET commands
+     */
     } else if (memcmp(command, "get ", 4) == 0) {
       const char* config = &command[4];
       if (memcmp(config, "af", 2) == 0) {
@@ -273,9 +295,40 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
         mesh::Utils::toHex(&reply[2], _callbacks->getSelfId().pub_key, PUB_KEY_SIZE);
       } else if (memcmp(config, "role", 4) == 0) {
         sprintf(reply, "> %s", _callbacks->getRole());
+      } else if (memcmp(config, "bridge.type", 11) == 0) {
+        sprintf(reply, "> %s",
+#ifdef WITH_RS232_BRIDGE
+                "rs232"
+#elif WITH_ESPNOW_BRIDGE
+                "espnow"
+#else
+                "none"
+#endif
+        );
+#ifdef WITH_BRIDGE
+      } else if (memcmp(config, "bridge.enabled", 14) == 0) {
+        sprintf(reply, "> %s", _prefs->bridge_enabled ? "on" : "off");
+      } else if (memcmp(config, "bridge.delay", 12) == 0) {
+        sprintf(reply, "> %d", (uint32_t)_prefs->bridge_delay);
+      } else if (memcmp(config, "bridge.source", 13) == 0) {
+        sprintf(reply, "> %s", _prefs->bridge_pkt_src ? "logRx" : "logTx");
+#endif
+#ifdef WITH_RS232_BRIDGE
+      } else if (memcmp(config, "bridge.baud", 11) == 0) {
+        sprintf(reply, "> %d", (uint32_t)_prefs->bridge_baud);
+#endif
+#ifdef WITH_ESPNOW_BRIDGE
+      } else if (memcmp(config, "bridge.channel", 14) == 0) {
+        sprintf(reply, "> %d", (uint32_t)_prefs->bridge_channel);
+      } else if (memcmp(config, "bridge.secret", 13) == 0) {
+        sprintf(reply, "> %s", _prefs->bridge_secret);
+#endif
       } else {
         sprintf(reply, "??: %s", config);
       }
+    /*
+     * SET commands
+     */
     } else if (memcmp(command, "set ", 4) == 0) {
       const char* config = &command[4];
       if (memcmp(config, "af ", 3) == 0) {
@@ -322,7 +375,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
         StrHelper::strncpy(_prefs->guest_password, &config[15], sizeof(_prefs->guest_password));
         savePrefs();
         strcpy(reply, "OK");
-      } else if (sender_timestamp == 0 && memcmp(config, "prv.key ", 8) == 0) {  // from serial command line only
+      } else if (sender_timestamp == 0 &&
+                 memcmp(config, "prv.key ", 8) == 0) { // from serial command line only
         uint8_t prv_key[PRV_KEY_SIZE];
         bool success = mesh::Utils::fromHex(prv_key, PRV_KEY_SIZE, &config[8]);
         if (success) {
@@ -412,6 +466,55 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
         _prefs->freq = atof(&config[5]);
         savePrefs();
         strcpy(reply, "OK - reboot to apply");
+#ifdef WITH_BRIDGE
+      } else if (memcmp(config, "bridge.enabled ", 15) == 0) {
+        _prefs->bridge_enabled = memcmp(&config[15], "on", 2) == 0;
+        _callbacks->setBridgeState(_prefs->bridge_enabled);
+        savePrefs();
+        strcpy(reply, "OK");
+      } else if (memcmp(config, "bridge.delay ", 13) == 0) {
+        int delay = _atoi(&config[13]);
+        if (delay >= 0 && delay <= 10000) {
+          _prefs->bridge_delay = (uint16_t)delay;
+          savePrefs();
+          strcpy(reply, "OK");
+        } else {
+          strcpy(reply, "Error: delay must be between 0-10000 ms");
+        }
+      } else if (memcmp(config, "bridge.source ", 14) == 0) {
+        _prefs->bridge_pkt_src = memcmp(&config[14], "rx", 2) == 0;
+        savePrefs();
+        strcpy(reply, "OK");
+#endif
+#ifdef WITH_RS232_BRIDGE
+      } else if (memcmp(config, "bridge.baud ", 12) == 0) {
+        uint32_t baud = atoi(&config[12]);
+        if (baud >= 9600 && baud <= 115200) {
+          _prefs->bridge_baud = (uint32_t)baud;
+          _callbacks->restartBridge();
+          savePrefs();
+          strcpy(reply, "OK");
+        } else {
+          strcpy(reply, "Error: baud rate must be between 9600-115200");
+        }
+#endif
+#ifdef WITH_ESPNOW_BRIDGE
+      } else if (memcmp(config, "bridge.channel ", 15) == 0) {
+        int ch = atoi(&config[15]);
+        if (ch > 0 && ch < 15) {
+          _prefs->bridge_channel = (uint8_t)ch;
+          _callbacks->restartBridge();
+          savePrefs();
+          strcpy(reply, "OK");
+        } else {
+          strcpy(reply, "Error: channel must be between 1-14");
+        }
+      } else if (memcmp(config, "bridge.secret ", 14) == 0) {
+        StrHelper::strncpy(_prefs->bridge_secret, &config[14], sizeof(_prefs->bridge_secret));
+        _callbacks->restartBridge();
+        savePrefs();
+        strcpy(reply, "OK");
+#endif
       } else {
         sprintf(reply, "unknown config: %s", config);
       }

+ 42 - 23
src/helpers/CommonCLI.h

@@ -4,29 +4,40 @@
 #include <helpers/IdentityStore.h>
 #include <target.h>
 
-struct NodePrefs {  // persisted to file
-    float airtime_factor;
-    char node_name[32];
-    double node_lat, node_lon;
-    char password[16];
-    float freq;
-    uint8_t tx_power_dbm;
-    uint8_t disable_fwd;
-    uint8_t advert_interval;   // minutes / 2
-    uint8_t flood_advert_interval;   // hours
-    float rx_delay_base;
-    float tx_delay_factor;
-    char guest_password[16];
-    float direct_tx_delay_factor;
-    uint32_t guard;
-    uint8_t sf;
-    uint8_t cr;
-    uint8_t allow_read_only;
-    uint8_t multi_acks;
-    float bw;
-    uint8_t flood_max;
-    uint8_t interference_threshold;
-    uint8_t agc_reset_interval;   // secs / 4
+#if defined(WITH_RS232_BRIDGE) || defined(WITH_ESPNOW_BRIDGE)
+#define WITH_BRIDGE
+#endif
+
+struct NodePrefs { // persisted to file
+  float airtime_factor;
+  char node_name[32];
+  double node_lat, node_lon;
+  char password[16];
+  float freq;
+  uint8_t tx_power_dbm;
+  uint8_t disable_fwd;
+  uint8_t advert_interval;       // minutes / 2
+  uint8_t flood_advert_interval; // hours
+  float rx_delay_base;
+  float tx_delay_factor;
+  char guest_password[16];
+  float direct_tx_delay_factor;
+  uint32_t guard;
+  uint8_t sf;
+  uint8_t cr;
+  uint8_t allow_read_only;
+  uint8_t multi_acks;
+  float bw;
+  uint8_t flood_max;
+  uint8_t interference_threshold;
+  uint8_t agc_reset_interval; // secs / 4
+  // Bridge settings
+  uint8_t bridge_enabled; // boolean
+  uint16_t bridge_delay;  // milliseconds (default 500 ms)
+  uint8_t bridge_pkt_src; // 0 = logTx, 1 = logRx (default logTx)
+  uint32_t bridge_baud;   // 9600, 19200, 38400, 57600, 115200 (default 115200)
+  uint8_t bridge_channel; // 1-14 (ESP-NOW only)
+  char bridge_secret[16]; // for XOR encryption of bridge packets (ESP-NOW only)
 };
 
 class CommonCLICallbacks {
@@ -51,6 +62,14 @@ public:
   virtual void saveIdentity(const mesh::LocalIdentity& new_id) = 0;
   virtual void clearStats() = 0;
   virtual void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) = 0;
+
+  virtual void setBridgeState(bool enable) {
+    // no op by default
+  };
+
+  virtual void restartBridge() {
+    // no op by default
+  };
 };
 
 class CommonCLI {

+ 13 - 1
src/helpers/bridges/BridgeBase.cpp

@@ -2,6 +2,10 @@
 
 #include <Arduino.h>
 
+bool BridgeBase::isRunning() const {
+  return _initialized;
+}
+
 const char *BridgeBase::getLogDateTime() {
   static char tmp[32];
   uint32_t now = _rtc->getCurrentTime();
@@ -28,8 +32,16 @@ bool BridgeBase::validateChecksum(const uint8_t *data, size_t len, uint16_t rece
 }
 
 void BridgeBase::handleReceivedPacket(mesh::Packet *packet) {
+  // Guard against uninitialized state
+  if (_initialized == false) {
+    BRIDGE_DEBUG_PRINTLN("RX packet received before initialization\n");
+    _mgr->free(packet);
+    return;
+  }
+
   if (!_seen_packets.hasSeen(packet)) {
-    _mgr->queueInbound(packet, millis() + BRIDGE_DELAY);
+    // bridge_delay provides a buffer to prevent immediate processing conflicts in the mesh network.
+    _mgr->queueInbound(packet, millis() + _prefs->bridge_delay);
   } else {
     _mgr->free(packet);
   }

+ 17 - 9
src/helpers/bridges/BridgeBase.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "helpers/AbstractBridge.h"
+#include "helpers/CommonCLI.h"
 #include "helpers/SimpleMeshTables.h"
 
 #include <RTClib.h>
@@ -21,6 +22,13 @@ class BridgeBase : public AbstractBridge {
 public:
   virtual ~BridgeBase() = default;
 
+  /**
+   * @brief Gets the current state of the bridge.
+   *
+   * @return true if the bridge is initialized and running, false otherwise.
+   */
+  bool isRunning() const override;
+
   /**
    * @brief Common magic number used by all bridge implementations for packet identification
    *
@@ -41,31 +49,31 @@ public:
   static constexpr uint16_t BRIDGE_LENGTH_SIZE = sizeof(uint16_t);
   static constexpr uint16_t BRIDGE_CHECKSUM_SIZE = sizeof(uint16_t);
 
-  /**
-   * @brief Default delay in milliseconds for scheduling inbound packet processing
-   *
-   * It provides a buffer to prevent immediate processing conflicts in the mesh network.
-   * Used in handleReceivedPacket() as: millis() + BRIDGE_DELAY
-   */
-  static constexpr uint16_t BRIDGE_DELAY = 500; // TODO: maybe too high ?
-
 protected:
+  /** Tracks bridge state */
+  bool _initialized = false;
+
   /** Packet manager for allocating and queuing mesh packets */
   mesh::PacketManager *_mgr;
 
   /** RTC clock for timestamping debug messages */
   mesh::RTCClock *_rtc;
 
+  /** Node preferences for configuration settings */
+  NodePrefs *_prefs;
+
   /** Tracks seen packets to prevent loops in broadcast communications */
   SimpleMeshTables _seen_packets;
 
   /**
    * @brief Constructs a BridgeBase instance
    *
+   * @param prefs Node preferences for configuration settings
    * @param mgr PacketManager for allocating and queuing packets
    * @param rtc RTCClock for timestamping debug messages
    */
-  BridgeBase(mesh::PacketManager *mgr, mesh::RTCClock *rtc) : _mgr(mgr), _rtc(rtc) {}
+  BridgeBase(NodePrefs *prefs, mesh::PacketManager *mgr, mesh::RTCClock *rtc)
+      : _prefs(prefs), _mgr(mgr), _rtc(rtc) {}
 
   /**
    * @brief Gets formatted date/time string for logging

+ 62 - 39
src/helpers/bridges/ESPNowBridge.cpp

@@ -21,18 +21,26 @@ void ESPNowBridge::send_cb(const uint8_t *mac, esp_now_send_status_t status) {
   }
 }
 
-ESPNowBridge::ESPNowBridge(mesh::PacketManager *mgr, mesh::RTCClock *rtc)
-    : BridgeBase(mgr, rtc), _rx_buffer_pos(0) {
+ESPNowBridge::ESPNowBridge(NodePrefs *prefs, mesh::PacketManager *mgr, mesh::RTCClock *rtc)
+    : BridgeBase(prefs, mgr, rtc), _rx_buffer_pos(0) {
   _instance = this;
 }
 
 void ESPNowBridge::begin() {
+  BRIDGE_DEBUG_PRINTLN("Initializing...\n");
+
   // Initialize WiFi in station mode
   WiFi.mode(WIFI_STA);
+  
+  // Set wifi channel
+  if (esp_wifi_set_channel(_prefs->bridge_channel, WIFI_SECOND_CHAN_NONE) != ESP_OK) {
+    BRIDGE_DEBUG_PRINTLN("Error setting WIFI channel to %d\n", _prefs->bridge_channel);
+    return;
+  }
 
   // Initialize ESP-NOW
   if (esp_now_init() != ESP_OK) {
-    Serial.printf("%s: ESPNOW BRIDGE: Error initializing ESP-NOW\n", getLogDateTime());
+    BRIDGE_DEBUG_PRINTLN("Error initializing ESP-NOW\n");
     return;
   }
 
@@ -44,13 +52,41 @@ void ESPNowBridge::begin() {
   esp_now_peer_info_t peerInfo = {};
   memset(&peerInfo, 0, sizeof(peerInfo));
   memset(peerInfo.peer_addr, 0xFF, ESP_NOW_ETH_ALEN); // Broadcast address
-  peerInfo.channel = 0;
+  peerInfo.channel = _prefs->bridge_channel;
   peerInfo.encrypt = false;
 
   if (esp_now_add_peer(&peerInfo) != ESP_OK) {
-    Serial.printf("%s: ESPNOW BRIDGE: Failed to add broadcast peer\n", getLogDateTime());
+    BRIDGE_DEBUG_PRINTLN("Failed to add broadcast peer\n");
     return;
   }
+
+  // Update bridge state
+  _initialized = true;
+}
+
+void ESPNowBridge::end() {
+  BRIDGE_DEBUG_PRINTLN("Stopping...\n");
+
+  // Remove broadcast peer
+  uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+  if (esp_now_del_peer(broadcastAddress) != ESP_OK) {
+    BRIDGE_DEBUG_PRINTLN("Error removing broadcast peer\n");
+  }
+
+  // Unregister callbacks
+  esp_now_register_recv_cb(nullptr);
+  esp_now_register_send_cb(nullptr);
+
+  // Deinitialize ESP-NOW
+  if (esp_now_deinit() != ESP_OK) {
+    BRIDGE_DEBUG_PRINTLN("Error deinitializing ESP-NOW\n");
+  }
+
+  // Turn off WiFi
+  WiFi.mode(WIFI_OFF);
+
+  // Update bridge state
+  _initialized = false;
 }
 
 void ESPNowBridge::loop() {
@@ -58,35 +94,29 @@ void ESPNowBridge::loop() {
 }
 
 void ESPNowBridge::xorCrypt(uint8_t *data, size_t len) {
-  size_t keyLen = strlen(_secret);
+  size_t keyLen = strlen(_prefs->bridge_secret);
   for (size_t i = 0; i < len; i++) {
-    data[i] ^= _secret[i % keyLen];
+    data[i] ^= _prefs->bridge_secret[i % keyLen];
   }
 }
 
 void ESPNowBridge::onDataRecv(const uint8_t *mac, const uint8_t *data, int32_t len) {
   // Ignore packets that are too small to contain header + checksum
   if (len < (BRIDGE_MAGIC_SIZE + BRIDGE_CHECKSUM_SIZE)) {
-#if MESH_PACKET_LOGGING
-    Serial.printf("%s: ESPNOW BRIDGE: RX packet too small, len=%d\n", getLogDateTime(), len);
-#endif
+    BRIDGE_DEBUG_PRINTLN("RX packet too small, len=%d\n", len);
     return;
   }
 
   // Validate total packet size
   if (len > MAX_ESPNOW_PACKET_SIZE) {
-#if MESH_PACKET_LOGGING
-    Serial.printf("%s: ESPNOW BRIDGE: RX packet too large, len=%d\n", getLogDateTime(), len);
-#endif
+    BRIDGE_DEBUG_PRINTLN("RX packet too large, len=%d\n", len);
     return;
   }
 
   // Check packet header magic
   uint16_t received_magic = (data[0] << 8) | data[1];
   if (received_magic != BRIDGE_PACKET_MAGIC) {
-#if MESH_PACKET_LOGGING
-    Serial.printf("%s: ESPNOW BRIDGE: RX invalid magic 0x%04X\n", getLogDateTime(), received_magic);
-#endif
+    BRIDGE_DEBUG_PRINTLN("RX invalid magic 0x%04X\n", received_magic);
     return;
   }
 
@@ -104,16 +134,11 @@ void ESPNowBridge::onDataRecv(const uint8_t *mac, const uint8_t *data, int32_t l
 
   if (!validateChecksum(decrypted + BRIDGE_CHECKSUM_SIZE, payloadLen, received_checksum)) {
     // Failed to decrypt - likely from a different network
-#if MESH_PACKET_LOGGING
-    Serial.printf("%s: ESPNOW BRIDGE: RX checksum mismatch, rcv=0x%04X\n", getLogDateTime(),
-                  received_checksum);
-#endif
+    BRIDGE_DEBUG_PRINTLN("RX checksum mismatch, rcv=0x%04X\n", received_checksum);
     return;
   }
 
-#if MESH_PACKET_LOGGING
-  Serial.printf("%s: ESPNOW BRIDGE: RX, payload_len=%d\n", getLogDateTime(), payloadLen);
-#endif
+  BRIDGE_DEBUG_PRINTLN("RX, payload_len=%d\n", payloadLen);
 
   // Create mesh packet
   mesh::Packet *pkt = _instance->_mgr->allocNew();
@@ -130,31 +155,27 @@ void ESPNowBridge::onDataSent(const uint8_t *mac_addr, esp_now_send_status_t sta
   // Could add transmission error handling here if needed
 }
 
-void ESPNowBridge::onPacketReceived(mesh::Packet *packet) {
-  handleReceivedPacket(packet);
-}
+void ESPNowBridge::sendPacket(mesh::Packet *packet) {
+  // Guard against uninitialized state
+  if (_initialized == false) {
+    return;
+  }
 
-void ESPNowBridge::onPacketTransmitted(mesh::Packet *packet) {
   // First validate the packet pointer
   if (!packet) {
-#if MESH_PACKET_LOGGING
-    Serial.printf("%s: ESPNOW BRIDGE: TX invalid packet pointer\n", getLogDateTime());
-#endif
+    BRIDGE_DEBUG_PRINTLN("TX invalid packet pointer\n");
     return;
   }
 
   if (!_seen_packets.hasSeen(packet)) {
-
     // Create a temporary buffer just for size calculation and reuse for actual writing
     uint8_t sizingBuffer[MAX_PAYLOAD_SIZE];
     uint16_t meshPacketLen = packet->writeTo(sizingBuffer);
 
     // Check if packet fits within our maximum payload size
     if (meshPacketLen > MAX_PAYLOAD_SIZE) {
-#if MESH_PACKET_LOGGING
-      Serial.printf("%s: ESPNOW BRIDGE: TX packet too large (payload=%d, max=%d)\n", getLogDateTime(),
-                    meshPacketLen, MAX_PAYLOAD_SIZE);
-#endif
+      BRIDGE_DEBUG_PRINTLN("TX packet too large (payload=%d, max=%d)\n", meshPacketLen,
+                           MAX_PAYLOAD_SIZE);
       return;
     }
 
@@ -183,14 +204,16 @@ void ESPNowBridge::onPacketTransmitted(mesh::Packet *packet) {
     uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
     esp_err_t result = esp_now_send(broadcastAddress, buffer, totalPacketSize);
 
-#if MESH_PACKET_LOGGING
     if (result == ESP_OK) {
-      Serial.printf("%s: ESPNOW BRIDGE: TX, len=%d\n", getLogDateTime(), meshPacketLen);
+      BRIDGE_DEBUG_PRINTLN("TX, len=%d\n", meshPacketLen);
     } else {
-      Serial.printf("%s: ESPNOW BRIDGE: TX FAILED!\n", getLogDateTime());
+      BRIDGE_DEBUG_PRINTLN("TX FAILED!\n");
     }
-#endif
   }
 }
 
+void ESPNowBridge::onPacketReceived(mesh::Packet *packet) {
+  handleReceivedPacket(packet);
+}
+
 #endif

+ 17 - 16
src/helpers/bridges/ESPNowBridge.h

@@ -6,10 +6,6 @@
 
 #ifdef WITH_ESPNOW_BRIDGE
 
-#ifndef WITH_ESPNOW_BRIDGE_SECRET
-#error WITH_ESPNOW_BRIDGE_SECRET must be defined to use ESPNowBridge
-#endif
-
 /**
  * @brief Bridge implementation using ESP-NOW protocol for packet transport
  *
@@ -36,11 +32,11 @@
  *
  * Configuration:
  * - Define WITH_ESPNOW_BRIDGE to enable this bridge
- * - Define WITH_ESPNOW_BRIDGE_SECRET with a string to set the network encryption key
+ * - Define _prefs->bridge_secret with a string to set the network encryption key
  *
  * Network Isolation:
  * Multiple independent mesh networks can coexist by using different
- * WITH_ESPNOW_BRIDGE_SECRET values. Packets encrypted with a different key will
+ * _prefs->bridge_secret values. Packets encrypted with a different key will
  * fail the checksum validation and be discarded.
  */
 class ESPNowBridge : public BridgeBase {
@@ -73,17 +69,11 @@ private:
   /** Current position in receive buffer */
   size_t _rx_buffer_pos;
 
-  /**
-   * Network encryption key from build define
-   * Must be defined with WITH_ESPNOW_BRIDGE_SECRET
-   * Used for XOR encryption to isolate different mesh networks
-   */
-  const char *_secret = WITH_ESPNOW_BRIDGE_SECRET;
-
   /**
    * Performs XOR encryption/decryption of data
+   * Used to isolate different mesh networks
    *
-   * Uses WITH_ESPNOW_BRIDGE_SECRET as the key in a simple XOR operation.
+   * Uses _prefs->bridge_secret as the key in a simple XOR operation.
    * The same operation is used for both encryption and decryption.
    * While not cryptographically secure, it provides basic network isolation.
    *
@@ -115,10 +105,11 @@ public:
   /**
    * Constructs an ESPNowBridge instance
    *
+   * @param prefs Node preferences for configuration settings
    * @param mgr PacketManager for allocating and queuing packets
    * @param rtc RTCClock for timestamping debug messages
    */
-  ESPNowBridge(mesh::PacketManager *mgr, mesh::RTCClock *rtc);
+  ESPNowBridge(NodePrefs *prefs, mesh::PacketManager *mgr, mesh::RTCClock *rtc);
 
   /**
    * Initializes the ESP-NOW bridge
@@ -130,6 +121,16 @@ public:
    */
   void begin() override;
 
+  /**
+   * Stops the ESP-NOW bridge
+   *
+   * - Removes broadcast peer
+   * - Unregisters callbacks
+   * - Deinitializes ESP-NOW protocol
+   * - Turns off WiFi to release radio resources
+   */
+  void end() override;
+
   /**
    * Main loop handler
    * ESP-NOW is callback-based, so this is currently empty
@@ -150,7 +151,7 @@ public:
    *
    * @param packet The mesh packet to transmit
    */
-  void onPacketTransmitted(mesh::Packet *packet) override;
+  void sendPacket(mesh::Packet *packet) override;
 };
 
 #endif

+ 64 - 60
src/helpers/bridges/RS232Bridge.cpp

@@ -4,10 +4,11 @@
 
 #ifdef WITH_RS232_BRIDGE
 
-RS232Bridge::RS232Bridge(Stream &serial, mesh::PacketManager *mgr, mesh::RTCClock *rtc)
-    : BridgeBase(mgr, rtc), _serial(&serial) {}
+RS232Bridge::RS232Bridge(NodePrefs *prefs, Stream &serial, mesh::PacketManager *mgr, mesh::RTCClock *rtc)
+    : BridgeBase(prefs, mgr, rtc), _serial(&serial) {}
 
 void RS232Bridge::begin() {
+  BRIDGE_DEBUG_PRINTLN("Initializing at %d baud...\n", _prefs->bridge_baud);
 #if !defined(WITH_RS232_BRIDGE_RX) || !defined(WITH_RS232_BRIDGE_TX)
 #error "WITH_RS232_BRIDGE_RX and WITH_RS232_BRIDGE_TX must be defined"
 #endif
@@ -25,53 +26,26 @@ void RS232Bridge::begin() {
 #else
 #error RS232Bridge was not tested on the current platform
 #endif
-  ((HardwareSerial *)_serial)->begin(115200);
-}
-
-void RS232Bridge::onPacketTransmitted(mesh::Packet *packet) {
-  // First validate the packet pointer
-  if (!packet) {
-#if MESH_PACKET_LOGGING
-    Serial.printf("%s: RS232 BRIDGE: TX invalid packet pointer\n", getLogDateTime());
-#endif
-    return;
-  }
-
-  if (!_seen_packets.hasSeen(packet)) {
-
-    uint8_t buffer[MAX_SERIAL_PACKET_SIZE];
-    uint16_t len = packet->writeTo(buffer + 4);
-
-    // Check if packet fits within our maximum payload size
-    if (len > (MAX_TRANS_UNIT + 1)) {
-#if MESH_PACKET_LOGGING
-      Serial.printf("%s: RS232 BRIDGE: TX packet too large (payload=%d, max=%d)\n", getLogDateTime(), len,
-                    MAX_TRANS_UNIT + 1);
-#endif
-      return;
-    }
-
-    // Build packet header
-    buffer[0] = (BRIDGE_PACKET_MAGIC >> 8) & 0xFF; // Magic high byte
-    buffer[1] = BRIDGE_PACKET_MAGIC & 0xFF;        // Magic low byte
-    buffer[2] = (len >> 8) & 0xFF;                 // Length high byte
-    buffer[3] = len & 0xFF;                        // Length low byte
+  ((HardwareSerial *)_serial)->begin(_prefs->bridge_baud);
 
-    // Calculate checksum over the payload
-    uint16_t checksum = fletcher16(buffer + 4, len);
-    buffer[4 + len] = (checksum >> 8) & 0xFF; // Checksum high byte
-    buffer[5 + len] = checksum & 0xFF;        // Checksum low byte
+  // Update bridge state
+  _initialized = true;
+}
 
-    // Send complete packet
-    _serial->write(buffer, len + SERIAL_OVERHEAD);
+void RS232Bridge::end() {
+  BRIDGE_DEBUG_PRINTLN("Stopping...\n");
+  ((HardwareSerial *)_serial)->end();
 
-#if MESH_PACKET_LOGGING
-    Serial.printf("%s: RS232 BRIDGE: TX, len=%d crc=0x%04x\n", getLogDateTime(), len, checksum);
-#endif
-  }
+  // Update bridge state
+  _initialized = false;
 }
 
 void RS232Bridge::loop() {
+  // Guard against uninitialized state
+  if (_initialized == false) {
+    return;
+  }
+
   while (_serial->available()) {
     uint8_t b = _serial->read();
 
@@ -97,9 +71,7 @@ void RS232Bridge::loop() {
 
         // Validate length field
         if (len > (MAX_TRANS_UNIT + 1)) {
-#if MESH_PACKET_LOGGING
-          Serial.printf("%s: RS232 BRIDGE: RX invalid length %d, resetting\n", getLogDateTime(), len);
-#endif
+          BRIDGE_DEBUG_PRINTLN("RX invalid length %d, resetting\n", len);
           _rx_buffer_pos = 0; // Invalid length, reset
           continue;
         }
@@ -108,30 +80,20 @@ void RS232Bridge::loop() {
           uint16_t received_checksum = (_rx_buffer[4 + len] << 8) | _rx_buffer[5 + len];
 
           if (validateChecksum(_rx_buffer + 4, len, received_checksum)) {
-#if MESH_PACKET_LOGGING
-            Serial.printf("%s: RS232 BRIDGE: RX, len=%d crc=0x%04x\n", getLogDateTime(), len,
-                          received_checksum);
-#endif
+            BRIDGE_DEBUG_PRINTLN("RX, len=%d crc=0x%04x\n", len, received_checksum);
             mesh::Packet *pkt = _mgr->allocNew();
             if (pkt) {
               if (pkt->readFrom(_rx_buffer + 4, len)) {
                 onPacketReceived(pkt);
               } else {
-#if MESH_PACKET_LOGGING
-                Serial.printf("%s: RS232 BRIDGE: RX failed to parse packet\n", getLogDateTime());
-#endif
+                BRIDGE_DEBUG_PRINTLN("RX failed to parse packet\n");
                 _mgr->free(pkt);
               }
             } else {
-#if MESH_PACKET_LOGGING
-              Serial.printf("%s: RS232 BRIDGE: RX failed to allocate packet\n", getLogDateTime());
-#endif
+              BRIDGE_DEBUG_PRINTLN("RX failed to allocate packet\n");
             }
           } else {
-#if MESH_PACKET_LOGGING
-            Serial.printf("%s: RS232 BRIDGE: RX checksum mismatch, rcv=0x%04x\n", getLogDateTime(),
-                          received_checksum);
-#endif
+            BRIDGE_DEBUG_PRINTLN("RX checksum mismatch, rcv=0x%04x\n", received_checksum);
           }
           _rx_buffer_pos = 0; // Reset for next packet
         }
@@ -140,6 +102,48 @@ void RS232Bridge::loop() {
   }
 }
 
+void RS232Bridge::sendPacket(mesh::Packet *packet) {
+  // Guard against uninitialized state
+  if (_initialized == false) {
+    return;
+  }
+
+  // First validate the packet pointer
+  if (!packet) {
+    BRIDGE_DEBUG_PRINTLN("TX invalid packet pointer\n");
+    return;
+  }
+
+  if (!_seen_packets.hasSeen(packet)) {
+
+    uint8_t buffer[MAX_SERIAL_PACKET_SIZE];
+    uint16_t len = packet->writeTo(buffer + 4);
+
+    // Check if packet fits within our maximum payload size
+    if (len > (MAX_TRANS_UNIT + 1)) {
+      BRIDGE_DEBUG_PRINTLN("TX packet too large (payload=%d, max=%d)\n", len,
+                           MAX_TRANS_UNIT + 1);
+      return;
+    }
+
+    // Build packet header
+    buffer[0] = (BRIDGE_PACKET_MAGIC >> 8) & 0xFF; // Magic high byte
+    buffer[1] = BRIDGE_PACKET_MAGIC & 0xFF;        // Magic low byte
+    buffer[2] = (len >> 8) & 0xFF;                 // Length high byte
+    buffer[3] = len & 0xFF;                        // Length low byte
+
+    // Calculate checksum over the payload
+    uint16_t checksum = fletcher16(buffer + 4, len);
+    buffer[4 + len] = (checksum >> 8) & 0xFF; // Checksum high byte
+    buffer[5 + len] = checksum & 0xFF;        // Checksum low byte
+
+    // Send complete packet
+    _serial->write(buffer, len + SERIAL_OVERHEAD);
+
+    BRIDGE_DEBUG_PRINTLN("TX, len=%d crc=0x%04x\n", len, checksum);
+  }
+}
+
 void RS232Bridge::onPacketReceived(mesh::Packet *packet) {
   handleReceivedPacket(packet);
 }

+ 9 - 2
src/helpers/bridges/RS232Bridge.h

@@ -49,11 +49,12 @@ public:
   /**
    * @brief Constructs an RS232Bridge instance
    *
+   * @param prefs Node preferences for configuration settings
    * @param serial The hardware serial port to use
    * @param mgr PacketManager for allocating and queuing packets
    * @param rtc RTCClock for timestamping debug messages
    */
-  RS232Bridge(Stream &serial, mesh::PacketManager *mgr, mesh::RTCClock *rtc);
+  RS232Bridge(NodePrefs *prefs, Stream &serial, mesh::PacketManager *mgr, mesh::RTCClock *rtc);
 
   /**
    * Initializes the RS232 bridge
@@ -65,6 +66,12 @@ public:
    */
   void begin() override;
 
+  /**
+   * Stops the RS232 bridge
+   *
+   */
+  void end() override;
+
   /**
    * @brief Main loop handler for processing incoming serial data
    *
@@ -90,7 +97,7 @@ public:
    *
    * @param packet The mesh packet to transmit
    */
-  void onPacketTransmitted(mesh::Packet *packet) override;
+  void sendPacket(mesh::Packet *packet) override;
 
   /**
    * @brief Called when a complete valid packet has been received from serial

+ 4 - 2
variants/generic-e22/platformio.ini

@@ -65,6 +65,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; lib_deps =
@@ -87,7 +88,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 lib_deps =
@@ -132,6 +133,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; lib_deps =
@@ -154,7 +156,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 lib_deps =

+ 2 - 1
variants/heltec_ct62/platformio.ini

@@ -61,6 +61,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${Heltec_ct62.build_src_filter}
@@ -80,7 +81,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_ct62.build_src_filter}

+ 2 - 1
variants/heltec_e213/platformio.ini

@@ -108,6 +108,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${Heltec_E213_base.build_src_filter}
@@ -129,7 +130,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_E213_base.build_src_filter}

+ 2 - 1
variants/heltec_e290/platformio.ini

@@ -104,6 +104,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${Heltec_E290_base.build_src_filter}
@@ -125,7 +126,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_E290_base.build_src_filter}

+ 2 - 1
variants/heltec_t190/platformio.ini

@@ -108,6 +108,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${Heltec_T190_base.build_src_filter}
@@ -127,7 +128,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_T190_base.build_src_filter}

+ 2 - 1
variants/heltec_tracker/platformio.ini

@@ -94,6 +94,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${Heltec_tracker_base.build_src_filter}
@@ -116,7 +117,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_tracker_base.build_src_filter}

+ 2 - 1
variants/heltec_v2/platformio.ini

@@ -53,6 +53,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${Heltec_lora32_v2.build_src_filter}
@@ -75,7 +76,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_lora32_v2.build_src_filter}

+ 4 - 2
variants/heltec_v3/platformio.ini

@@ -62,6 +62,7 @@ build_flags =
   -D WITH_RS232_BRIDGE=Serial2
   -D WITH_RS232_BRIDGE_RX=5
   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_lora32_v3.build_src_filter}
@@ -83,7 +84,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_lora32_v3.build_src_filter}
@@ -243,6 +244,7 @@ build_flags =
   -D WITH_RS232_BRIDGE=Serial2
   -D WITH_RS232_BRIDGE_RX=5
   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_lora32_v3.build_src_filter}
@@ -263,7 +265,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_lora32_v3.build_src_filter}

+ 1 - 1
variants/heltec_v4/platformio.ini

@@ -77,7 +77,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_lora32_v4.build_src_filter}

+ 2 - 1
variants/heltec_wireless_paper/platformio.ini

@@ -83,6 +83,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${Heltec_Wireless_Paper_base.build_src_filter}
@@ -104,7 +105,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Heltec_Wireless_Paper_base.build_src_filter}

+ 2 - 1
variants/lilygo_t3s3/platformio.ini

@@ -65,6 +65,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${LilyGo_T3S3_sx1262.build_src_filter}
@@ -86,7 +87,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${LilyGo_T3S3_sx1262.build_src_filter}

+ 2 - 1
variants/lilygo_t3s3_sx1276/platformio.ini

@@ -63,6 +63,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ;   ; -D MESH_PACKET_LOGGING=1
 ;   ; -D MESH_DEBUG=1
 ; build_src_filter = ${LilyGo_T3S3_sx1276.build_src_filter}
@@ -84,7 +85,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
   ; -D MESH_PACKET_LOGGING=1
   ; -D MESH_DEBUG=1
 build_src_filter = ${LilyGo_T3S3_sx1276.build_src_filter}

+ 2 - 1
variants/lilygo_tbeam_SX1262/platformio.ini

@@ -86,6 +86,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${LilyGo_TBeam_SX1262.build_src_filter}
@@ -105,7 +106,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${LilyGo_TBeam_SX1262.build_src_filter}

+ 2 - 1
variants/lilygo_tbeam_SX1276/platformio.ini

@@ -85,6 +85,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${LilyGo_TBeam_SX1276.build_src_filter}
@@ -105,7 +106,7 @@ build_flags =
   -D MAX_NEIGHBOURS=50
   -D PERSISTANT_GPS=1
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${LilyGo_TBeam_SX1276.build_src_filter}

+ 2 - 1
variants/lilygo_tbeam_supreme_SX1262/platformio.ini

@@ -64,6 +64,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${T_Beam_S3_Supreme_SX1262.build_src_filter}
@@ -83,7 +84,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${T_Beam_S3_Supreme_SX1262.build_src_filter}

+ 2 - 1
variants/lilygo_tlora_v2_1/platformio.ini

@@ -176,6 +176,7 @@ build_flags =
   -D WITH_RS232_BRIDGE=Serial2
   -D WITH_RS232_BRIDGE_RX=34
   -D WITH_RS232_BRIDGE_TX=25
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 ;  -D CORE_DEBUG_LEVEL=3
@@ -197,7 +198,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 ;  -D CORE_DEBUG_LEVEL=3

+ 4 - 2
variants/meshadventurer/platformio.ini

@@ -74,6 +74,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; lib_deps =
@@ -97,7 +98,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 lib_deps =
@@ -144,6 +145,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; lib_deps =
@@ -167,7 +169,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 lib_deps =

+ 4 - 2
variants/station_g2/platformio.ini

@@ -57,6 +57,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${Station_G2.build_src_filter}
@@ -76,7 +77,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Station_G2.build_src_filter}
@@ -119,6 +120,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_DEBUG=1
 ; build_src_filter = ${Station_G2.build_src_filter}
 ;   +<helpers/bridges/RS232Bridge.cpp>
@@ -139,7 +141,7 @@ build_flags =
   -D MESH_PACKET_LOGGING=1
   -D SX126X_RX_BOOSTED_GAIN=1
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${Station_G2.build_src_filter}
   +<helpers/bridges/ESPNowBridge.cpp>

+ 4 - 2
variants/tenstar_c3/platformio.ini

@@ -63,6 +63,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; lib_deps =
@@ -86,7 +87,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 lib_deps =
@@ -131,6 +132,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ;  ; -D MESH_PACKET_LOGGING=1
 ;  ; -D MESH_DEBUG=1
 ; lib_deps =
@@ -153,7 +155,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
  ; -D MESH_PACKET_LOGGING=1
  ; -D MESH_DEBUG=1
 lib_deps =

+ 1 - 0
variants/waveshare_rp2040_lora/platformio.ini

@@ -57,6 +57,7 @@ build_flags = ${waveshare_rp2040_lora.build_flags}
   -D WITH_RS232_BRIDGE=Serial2
   -D WITH_RS232_BRIDGE_RX=9
   -D WITH_RS232_BRIDGE_TX=8
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 build_src_filter = ${waveshare_rp2040_lora.build_src_filter}

+ 2 - 1
variants/xiao_s3_wio/platformio.ini

@@ -59,6 +59,7 @@ lib_deps =
 ;   -D WITH_RS232_BRIDGE=Serial2
 ;   -D WITH_RS232_BRIDGE_RX=5
 ;   -D WITH_RS232_BRIDGE_TX=6
+;  -D BRIDGE_DEBUG=1
 ; ;  -D MESH_PACKET_LOGGING=1
 ; ;  -D MESH_DEBUG=1
 ; lib_deps =
@@ -78,7 +79,7 @@ build_flags =
   -D ADMIN_PASSWORD='"password"'
   -D MAX_NEIGHBOURS=50
   -D WITH_ESPNOW_BRIDGE=1
-  -D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
+;  -D BRIDGE_DEBUG=1
 ;  -D MESH_PACKET_LOGGING=1
 ;  -D MESH_DEBUG=1
 lib_deps =