mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
Support ESPNow and improve documentation
This commit is contained in:
parent
cb99eb4ae8
commit
5b9d11ac8f
6 changed files with 510 additions and 59 deletions
|
|
@ -80,30 +80,36 @@
|
|||
|
||||
#ifdef WITH_RS232_BRIDGE
|
||||
#include "helpers/bridges/RS232Bridge.h"
|
||||
#define WITH_BRIDGE
|
||||
#endif
|
||||
|
||||
#define REQ_TYPE_GET_STATUS 0x01 // same as _GET_STATS
|
||||
#define REQ_TYPE_KEEP_ALIVE 0x02
|
||||
#define REQ_TYPE_GET_TELEMETRY_DATA 0x03
|
||||
#ifdef WITH_ESPNOW_BRIDGE
|
||||
#include "helpers/bridges/ESPNowBridge.h"
|
||||
#define WITH_BRIDGE
|
||||
#endif
|
||||
|
||||
#define RESP_SERVER_LOGIN_OK 0 // response to ANON_REQ
|
||||
#define REQ_TYPE_GET_STATUS 0x01 // same as _GET_STATS
|
||||
#define REQ_TYPE_KEEP_ALIVE 0x02
|
||||
#define REQ_TYPE_GET_TELEMETRY_DATA 0x03
|
||||
|
||||
struct RepeaterStats {
|
||||
uint16_t batt_milli_volts;
|
||||
uint16_t curr_tx_queue_len;
|
||||
int16_t noise_floor;
|
||||
int16_t last_rssi;
|
||||
uint32_t n_packets_recv;
|
||||
uint32_t n_packets_sent;
|
||||
uint32_t total_air_time_secs;
|
||||
uint32_t total_up_time_secs;
|
||||
uint32_t n_sent_flood, n_sent_direct;
|
||||
uint32_t n_recv_flood, n_recv_direct;
|
||||
uint16_t err_events; // was 'n_full_events'
|
||||
int16_t last_snr; // x 4
|
||||
uint16_t n_direct_dups, n_flood_dups;
|
||||
uint32_t total_rx_air_time_secs;
|
||||
};
|
||||
#define RESP_SERVER_LOGIN_OK 0 // response to ANON_REQ
|
||||
|
||||
struct RepeaterStats {
|
||||
uint16_t batt_milli_volts;
|
||||
uint16_t curr_tx_queue_len;
|
||||
int16_t noise_floor;
|
||||
int16_t last_rssi;
|
||||
uint32_t n_packets_recv;
|
||||
uint32_t n_packets_sent;
|
||||
uint32_t total_air_time_secs;
|
||||
uint32_t total_up_time_secs;
|
||||
uint32_t n_sent_flood, n_sent_direct;
|
||||
uint32_t n_recv_flood, n_recv_direct;
|
||||
uint16_t err_events; // was 'n_full_events'
|
||||
int16_t last_snr; // x 4
|
||||
uint16_t n_direct_dups, n_flood_dups;
|
||||
uint32_t total_rx_air_time_secs;
|
||||
};
|
||||
|
||||
struct ClientInfo {
|
||||
mesh::Identity id;
|
||||
|
|
@ -118,7 +124,7 @@ struct ClientInfo {
|
|||
#define MAX_CLIENTS 32
|
||||
#endif
|
||||
|
||||
#ifdef WITH_RS232_BRIDGE
|
||||
#ifdef WITH_BRIDGE
|
||||
AbstractBridge* bridge;
|
||||
#endif
|
||||
|
||||
|
|
@ -308,7 +314,7 @@ protected:
|
|||
}
|
||||
}
|
||||
void logTx(mesh::Packet* pkt, int len) override {
|
||||
#ifdef WITH_RS232_BRIDGE
|
||||
#ifdef WITH_BRIDGE
|
||||
bridge->onPacketTransmitted(pkt);
|
||||
#endif
|
||||
if (_logging) {
|
||||
|
|
@ -576,8 +582,14 @@ public:
|
|||
: mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables),
|
||||
_cli(board, rtc, &_prefs, this), telemetry(MAX_PACKET_PAYLOAD - 4)
|
||||
{
|
||||
#ifdef WITH_RS232_BRIDGE
|
||||
#ifdef WITH_BRIDGE
|
||||
#if defined(WITH_RS232_BRIDGE)
|
||||
bridge = new RS232Bridge(WITH_RS232_BRIDGE, _mgr, &rtc);
|
||||
#elif defined(WITH_ESPNOW_BRIDGE)
|
||||
bridge = new ESPNowBridge(_mgr, &rtc);
|
||||
#else
|
||||
#error "You must choose either RS232 or ESPNow bridge"
|
||||
#endif
|
||||
#endif
|
||||
memset(known_clients, 0, sizeof(known_clients));
|
||||
next_local_advert = next_flood_advert = 0;
|
||||
|
|
@ -779,7 +791,7 @@ public:
|
|||
}
|
||||
|
||||
void loop() {
|
||||
#ifdef WITH_RS232_BRIDGE
|
||||
#ifdef WITH_BRIDGE
|
||||
bridge->loop();
|
||||
#endif
|
||||
|
||||
|
|
@ -831,7 +843,7 @@ void setup() {
|
|||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
|
||||
#ifdef WITH_RS232_BRIDGE
|
||||
#ifdef WITH_BRIDGE
|
||||
bridge->begin();
|
||||
#endif
|
||||
|
||||
|
|
|
|||
184
src/helpers/bridges/ESPNowBridge.cpp
Normal file
184
src/helpers/bridges/ESPNowBridge.cpp
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
#include "ESPNowBridge.h"
|
||||
|
||||
#include <RTClib.h>
|
||||
#include <WiFi.h>
|
||||
#include <esp_wifi.h>
|
||||
|
||||
#ifdef WITH_ESPNOW_BRIDGE
|
||||
|
||||
// Static member to handle callbacks
|
||||
ESPNowBridge *ESPNowBridge::_instance = nullptr;
|
||||
|
||||
// Static callback wrappers
|
||||
void ESPNowBridge::recv_cb(const uint8_t *mac, const uint8_t *data, int len) {
|
||||
if (_instance) {
|
||||
_instance->onDataRecv(mac, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
void ESPNowBridge::send_cb(const uint8_t *mac, esp_now_send_status_t status) {
|
||||
if (_instance) {
|
||||
_instance->onDataSent(mac, status);
|
||||
}
|
||||
}
|
||||
|
||||
// Fletcher16 checksum calculation
|
||||
static uint16_t fletcher16(const uint8_t *data, size_t len) {
|
||||
uint16_t sum1 = 0;
|
||||
uint16_t sum2 = 0;
|
||||
|
||||
while (len--) {
|
||||
sum1 = (sum1 + *data++) % 255;
|
||||
sum2 = (sum2 + sum1) % 255;
|
||||
}
|
||||
|
||||
return (sum2 << 8) | sum1;
|
||||
}
|
||||
|
||||
ESPNowBridge::ESPNowBridge(mesh::PacketManager *mgr, mesh::RTCClock *rtc)
|
||||
: _mgr(mgr), _rtc(rtc), _rx_buffer_pos(0) {
|
||||
_instance = this;
|
||||
}
|
||||
|
||||
void ESPNowBridge::begin() {
|
||||
// Initialize WiFi in station mode
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
// Initialize ESP-NOW
|
||||
if (esp_now_init() != ESP_OK) {
|
||||
Serial.printf("%s: ESPNOW BRIDGE: Error initializing ESP-NOW\n", getLogDateTime());
|
||||
return;
|
||||
}
|
||||
|
||||
// Register callbacks
|
||||
esp_now_register_recv_cb(recv_cb);
|
||||
esp_now_register_send_cb(send_cb);
|
||||
|
||||
// Add broadcast peer
|
||||
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.encrypt = false;
|
||||
|
||||
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
|
||||
Serial.printf("%s: ESPNOW BRIDGE: Failed to add broadcast peer\n", getLogDateTime());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ESPNowBridge::loop() {
|
||||
// Nothing to do here - ESP-NOW is callback based
|
||||
}
|
||||
|
||||
void ESPNowBridge::xorCrypt(uint8_t *data, size_t len) {
|
||||
size_t keyLen = strlen(_secret);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
data[i] ^= _secret[i % keyLen];
|
||||
}
|
||||
}
|
||||
|
||||
void ESPNowBridge::onDataRecv(const uint8_t *mac, const uint8_t *data, int len) {
|
||||
// Ignore packets that are too small
|
||||
if (len < 3) {
|
||||
#if MESH_PACKET_LOGGING
|
||||
Serial.printf("%s: ESPNOW BRIDGE: RX packet too small, len=%d\n", getLogDateTime(), len);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Check packet header magic
|
||||
if (data[0] != ESPNOW_HEADER_MAGIC) {
|
||||
#if MESH_PACKET_LOGGING
|
||||
Serial.printf("%s: ESPNOW BRIDGE: RX invalid magic 0x%02X\n", getLogDateTime(), data[0]);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a copy we can decrypt
|
||||
uint8_t decrypted[MAX_ESPNOW_PACKET_SIZE];
|
||||
memcpy(decrypted, data + 1, len - 1); // Skip magic byte
|
||||
|
||||
// Try to decrypt
|
||||
xorCrypt(decrypted, len - 1);
|
||||
|
||||
// Validate checksum
|
||||
uint16_t received_checksum = (decrypted[0] << 8) | decrypted[1];
|
||||
uint16_t calculated_checksum = fletcher16(decrypted + 2, len - 3);
|
||||
|
||||
if (received_checksum != calculated_checksum) {
|
||||
// Failed to decrypt - likely from a different network
|
||||
#if MESH_PACKET_LOGGING
|
||||
Serial.printf("%s: ESPNOW BRIDGE: RX checksum mismatch, rcv=0x%04X calc=0x%04X\n", getLogDateTime(),
|
||||
received_checksum, calculated_checksum);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if MESH_PACKET_LOGGING
|
||||
Serial.printf("%s: ESPNOW BRIDGE: RX, len=%d\n", getLogDateTime(), len - 3);
|
||||
#endif
|
||||
|
||||
// Create mesh packet
|
||||
mesh::Packet *pkt = _instance->_mgr->allocNew();
|
||||
if (!pkt) return;
|
||||
|
||||
if (pkt->readFrom(decrypted + 2, len - 3)) {
|
||||
_instance->onPacketReceived(pkt);
|
||||
} else {
|
||||
_instance->_mgr->free(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
void ESPNowBridge::onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
|
||||
// Could add transmission error handling here if needed
|
||||
}
|
||||
|
||||
void ESPNowBridge::onPacketReceived(mesh::Packet *packet) {
|
||||
if (!_seen_packets.hasSeen(packet)) {
|
||||
_mgr->queueInbound(packet, 0);
|
||||
} else {
|
||||
_mgr->free(packet);
|
||||
}
|
||||
}
|
||||
|
||||
void ESPNowBridge::onPacketTransmitted(mesh::Packet *packet) {
|
||||
if (!_seen_packets.hasSeen(packet)) {
|
||||
uint8_t buffer[MAX_ESPNOW_PACKET_SIZE];
|
||||
buffer[0] = ESPNOW_HEADER_MAGIC;
|
||||
|
||||
// Write packet to buffer starting after magic byte and checksum
|
||||
uint16_t len = packet->writeTo(buffer + 3);
|
||||
|
||||
// Calculate and add checksum
|
||||
uint16_t checksum = fletcher16(buffer + 3, len);
|
||||
buffer[1] = (checksum >> 8) & 0xFF;
|
||||
buffer[2] = checksum & 0xFF;
|
||||
|
||||
// Encrypt payload (not including magic byte)
|
||||
xorCrypt(buffer + 1, len + 2);
|
||||
|
||||
// Broadcast using ESP-NOW
|
||||
uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
esp_err_t result = esp_now_send(broadcastAddress, buffer, len + 3);
|
||||
|
||||
#if MESH_PACKET_LOGGING
|
||||
if (result == ESP_OK) {
|
||||
Serial.printf("%s: ESPNOW BRIDGE: TX, len=%d\n", getLogDateTime(), len);
|
||||
} else {
|
||||
Serial.printf("%s: ESPNOW BRIDGE: TX FAILED!\n", getLogDateTime());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
const char *ESPNowBridge::getLogDateTime() {
|
||||
static char tmp[32];
|
||||
uint32_t now = _rtc->getCurrentTime();
|
||||
DateTime dt = DateTime(now);
|
||||
sprintf(tmp, "%02d:%02d:%02d - %d/%d/%d U", dt.hour(), dt.minute(), dt.second(), dt.day(), dt.month(),
|
||||
dt.year());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#endif
|
||||
170
src/helpers/bridges/ESPNowBridge.h
Normal file
170
src/helpers/bridges/ESPNowBridge.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
#pragma once
|
||||
|
||||
#include "MeshCore.h"
|
||||
#include "esp_now.h"
|
||||
#include "helpers/AbstractBridge.h"
|
||||
#include "helpers/SimpleMeshTables.h"
|
||||
|
||||
#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
|
||||
*
|
||||
* This bridge enables mesh packet transport over ESP-NOW, a connectionless communication
|
||||
* protocol provided by Espressif that allows ESP32 devices to communicate directly
|
||||
* without WiFi router infrastructure.
|
||||
*
|
||||
* Features:
|
||||
* - Broadcast-based communication (all bridges receive all packets)
|
||||
* - Network isolation using XOR encryption with shared secret
|
||||
* - Duplicate packet detection using SimpleMeshTables tracking
|
||||
* - Maximum packet size of 250 bytes (ESP-NOW limitation)
|
||||
*
|
||||
* Packet Structure:
|
||||
* [1 byte] Magic Header (0xAB) - Used to identify ESPNowBridge packets
|
||||
* [2 bytes] Fletcher-16 checksum of encrypted payload (calculated over payload only)
|
||||
* [n bytes] Encrypted payload containing the mesh packet
|
||||
*
|
||||
* The Fletcher-16 checksum is used to validate packet integrity and detect
|
||||
* corrupted or tampered packets. It's calculated over the encrypted payload
|
||||
* and provides a simple but effective way to verify packets are both
|
||||
* uncorrupted and from the same network (since the checksum is calculated
|
||||
* after encryption).
|
||||
*
|
||||
* Configuration:
|
||||
* - Define WITH_ESPNOW_BRIDGE to enable this bridge
|
||||
* - Define WITH_ESPNOW_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
|
||||
* fail the checksum validation and be discarded.
|
||||
*/
|
||||
class ESPNowBridge : public AbstractBridge {
|
||||
private:
|
||||
static ESPNowBridge *_instance;
|
||||
static void recv_cb(const uint8_t *mac, const uint8_t *data, int len);
|
||||
static void send_cb(const uint8_t *mac, esp_now_send_status_t status);
|
||||
|
||||
/** Packet manager for allocating and queuing mesh packets */
|
||||
mesh::PacketManager *_mgr;
|
||||
|
||||
/** RTC clock for timestamping debug messages */
|
||||
mesh::RTCClock *_rtc;
|
||||
|
||||
/** Tracks seen packets to prevent loops in broadcast communications */
|
||||
SimpleMeshTables _seen_packets;
|
||||
|
||||
/**
|
||||
* Maximum ESP-NOW packet size (250 bytes)
|
||||
* This is a hardware limitation of ESP-NOW protocol:
|
||||
* - ESP-NOW header: 20 bytes
|
||||
* - Max payload: 250 bytes
|
||||
* Source: ESP-NOW API documentation
|
||||
*/
|
||||
static const size_t MAX_ESPNOW_PACKET_SIZE = 250;
|
||||
|
||||
/**
|
||||
* Magic byte to identify ESPNowBridge packets (0xAB)
|
||||
*/
|
||||
static const uint8_t ESPNOW_HEADER_MAGIC = 0xAB;
|
||||
|
||||
/** Buffer for receiving ESP-NOW packets */
|
||||
uint8_t _rx_buffer[MAX_ESPNOW_PACKET_SIZE];
|
||||
|
||||
/** 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
|
||||
*
|
||||
* Uses WITH_ESPNOW_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.
|
||||
*
|
||||
* @param data Pointer to data to encrypt/decrypt
|
||||
* @param len Length of data in bytes
|
||||
*/
|
||||
void xorCrypt(uint8_t *data, size_t len);
|
||||
|
||||
/**
|
||||
* ESP-NOW receive callback
|
||||
* Called by ESP-NOW when a packet is received
|
||||
*
|
||||
* @param mac Source MAC address
|
||||
* @param data Received data
|
||||
* @param len Length of received data
|
||||
*/
|
||||
void onDataRecv(const uint8_t *mac, const uint8_t *data, int len);
|
||||
|
||||
/**
|
||||
* ESP-NOW send callback
|
||||
* Called by ESP-NOW after a transmission attempt
|
||||
*
|
||||
* @param mac_addr Destination MAC address
|
||||
* @param status Transmission status
|
||||
*/
|
||||
void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs an ESPNowBridge instance
|
||||
*
|
||||
* @param mgr PacketManager for allocating and queuing packets
|
||||
* @param rtc RTCClock for timestamping debug messages
|
||||
*/
|
||||
ESPNowBridge(mesh::PacketManager *mgr, mesh::RTCClock *rtc);
|
||||
|
||||
/**
|
||||
* Initializes the ESP-NOW bridge
|
||||
*
|
||||
* - Configures WiFi in station mode
|
||||
* - Initializes ESP-NOW protocol
|
||||
* - Registers callbacks
|
||||
* - Sets up broadcast peer
|
||||
*/
|
||||
void begin() override;
|
||||
|
||||
/**
|
||||
* Main loop handler
|
||||
* ESP-NOW is callback-based, so this is currently empty
|
||||
*/
|
||||
void loop() override;
|
||||
|
||||
/**
|
||||
* Called when a packet is received via ESP-NOW
|
||||
* Queues the packet for mesh processing if not seen before
|
||||
*
|
||||
* @param packet The received mesh packet
|
||||
*/
|
||||
void onPacketReceived(mesh::Packet *packet) override;
|
||||
|
||||
/**
|
||||
* Called when a packet needs to be transmitted via ESP-NOW
|
||||
* Encrypts and broadcasts the packet if not seen before
|
||||
*
|
||||
* @param packet The mesh packet to transmit
|
||||
*/
|
||||
void onPacketTransmitted(mesh::Packet *packet) override;
|
||||
|
||||
/**
|
||||
* Gets formatted date/time string for logging
|
||||
* Format: "HH:MM:SS - DD/MM/YYYY U"
|
||||
*
|
||||
* @return Formatted date/time string
|
||||
*/
|
||||
const char *getLogDateTime();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
#ifdef WITH_RS232_BRIDGE
|
||||
|
||||
// Fletcher-16
|
||||
// https://en.wikipedia.org/wiki/Fletcher%27s_checksum
|
||||
// Static Fletcher-16 checksum calculation
|
||||
// Based on: https://en.wikipedia.org/wiki/Fletcher%27s_checksum
|
||||
// Used to verify data integrity of received packets
|
||||
inline static uint16_t fletcher16(const uint8_t *bytes, const size_t len) {
|
||||
uint8_t sum1 = 0, sum2 = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,28 +7,87 @@
|
|||
#ifdef WITH_RS232_BRIDGE
|
||||
|
||||
/**
|
||||
* @brief A bridge implementation that uses a serial port to connect two mesh networks.
|
||||
* @brief Bridge implementation using RS232/UART protocol for packet transport
|
||||
*
|
||||
* This bridge enables mesh packet transport over serial/UART connections,
|
||||
* allowing nodes to communicate over wired serial links. It implements a simple
|
||||
* packet framing protocol with checksums for reliable transfer.
|
||||
*
|
||||
* Features:
|
||||
* - Point-to-point communication over hardware UART
|
||||
* - Fletcher-16 checksum for data integrity verification
|
||||
* - Magic header for packet synchronization
|
||||
* - Configurable RX/TX pins via build defines
|
||||
* - Baud rate fixed at 115200
|
||||
*
|
||||
* Packet Structure:
|
||||
* [2 bytes] Magic Header (0xCAFE) - Used to identify start of packet
|
||||
* [2 bytes] Fletcher-16 checksum - Data integrity check
|
||||
* [1 byte] Payload length
|
||||
* [n bytes] Packet payload
|
||||
*
|
||||
* The Fletcher-16 checksum is used to validate packet integrity and detect
|
||||
* corrupted or malformed packets. It provides error detection capabilities
|
||||
* suitable for serial communication where noise or timing issues could
|
||||
* corrupt data.
|
||||
*
|
||||
* Configuration:
|
||||
* - Define WITH_RS232_BRIDGE to enable this bridge
|
||||
* - Define WITH_RS232_BRIDGE_RX with the RX pin number
|
||||
* - Define WITH_RS232_BRIDGE_TX with the TX pin number
|
||||
*
|
||||
* Platform Support:
|
||||
* - ESP32 targets
|
||||
* - NRF52 targets
|
||||
* - RP2040 targets
|
||||
* - STM32 targets
|
||||
*/
|
||||
class RS232Bridge : public AbstractBridge {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Serial Bridge object
|
||||
*
|
||||
* @param serial The serial port to use for the bridge.
|
||||
* @param mgr A pointer to the packet manager.
|
||||
* @param rtc A pointer to the RTC clock.
|
||||
* @brief Constructs an RS232Bridge instance
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Initializes the RS232 bridge
|
||||
*
|
||||
* - Configures UART pins based on platform
|
||||
* - Sets baud rate to 115200
|
||||
*/
|
||||
void begin() override;
|
||||
|
||||
/**
|
||||
* @brief Main loop handler
|
||||
* Processes incoming serial data and builds packets
|
||||
*/
|
||||
void loop() override;
|
||||
|
||||
/**
|
||||
* @brief Called when a packet needs to be transmitted over serial
|
||||
* Formats and sends the packet with proper framing
|
||||
*
|
||||
* @param packet The mesh packet to transmit
|
||||
*/
|
||||
void onPacketTransmitted(mesh::Packet* packet) override;
|
||||
|
||||
/**
|
||||
* @brief Called when a complete packet has been received from serial
|
||||
* Queues the packet for mesh processing if checksum is valid
|
||||
*
|
||||
* @param packet The received mesh packet
|
||||
*/
|
||||
void onPacketReceived(mesh::Packet* packet) override;
|
||||
|
||||
private:
|
||||
/** Helper function to get formatted timestamp for logging */
|
||||
const char* getLogDateTime();
|
||||
/**
|
||||
* @brief The 2-byte magic word used to signify the start of a packet.
|
||||
*/
|
||||
|
||||
/** Magic number to identify start of RS232 packets (0xCAFE) */
|
||||
static constexpr uint16_t SERIAL_PKT_MAGIC = 0xCAFE;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -64,29 +64,6 @@ lib_deps =
|
|||
${LilyGo_TLora_V2_1_1_6.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:LilyGo_TLora_V2_1_1_6_repeater_bridge]
|
||||
extends = LilyGo_TLora_V2_1_1_6
|
||||
build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/bridges/RS232Bridge.cpp>
|
||||
+<../examples/simple_repeater>
|
||||
build_flags =
|
||||
${LilyGo_TLora_V2_1_1_6.build_flags}
|
||||
-D ADVERT_NAME='"TLora-V2.1-1.6 Bridge"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D MAX_NEIGHBOURS=8
|
||||
-D WITH_RS232_BRIDGE=Serial2
|
||||
-D WITH_RS232_BRIDGE_RX=34
|
||||
-D WITH_RS232_BRIDGE_TX=25
|
||||
-D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
; -D CORE_DEBUG_LEVEL=3
|
||||
lib_deps =
|
||||
${LilyGo_TLora_V2_1_1_6.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:LilyGo_TLora_V2_1_1_6_terminal_chat]
|
||||
extends = LilyGo_TLora_V2_1_1_6
|
||||
build_flags =
|
||||
|
|
@ -179,3 +156,51 @@ build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
|
|||
lib_deps =
|
||||
${LilyGo_TLora_V2_1_1_6.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
;
|
||||
; Repeater Bridges
|
||||
;
|
||||
[env:LilyGo_TLora_V2_1_1_6_bridge_rs232]
|
||||
extends = LilyGo_TLora_V2_1_1_6
|
||||
build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/bridges/RS232Bridge.cpp>
|
||||
+<../examples/simple_repeater>
|
||||
build_flags =
|
||||
${LilyGo_TLora_V2_1_1_6.build_flags}
|
||||
-D ADVERT_NAME='"RS232 Bridge"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D MAX_NEIGHBOURS=8
|
||||
-D WITH_RS232_BRIDGE=Serial2
|
||||
-D WITH_RS232_BRIDGE_RX=34
|
||||
-D WITH_RS232_BRIDGE_TX=25
|
||||
-D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
; -D CORE_DEBUG_LEVEL=3
|
||||
lib_deps =
|
||||
${LilyGo_TLora_V2_1_1_6.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:LilyGo_TLora_V2_1_1_6_bridge_espnow]
|
||||
extends = LilyGo_TLora_V2_1_1_6
|
||||
build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/bridges/ESPNowBridge.cpp>
|
||||
+<../examples/simple_repeater>
|
||||
build_flags =
|
||||
${LilyGo_TLora_V2_1_1_6.build_flags}
|
||||
-D ADVERT_NAME='"ESPNow Bridge"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D MAX_NEIGHBOURS=8
|
||||
-D WITH_ESPNOW_BRIDGE=1
|
||||
-D WITH_ESPNOW_BRIDGE_SECRET='"shared-secret"'
|
||||
-D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
; -D CORE_DEBUG_LEVEL=3
|
||||
lib_deps =
|
||||
${LilyGo_TLora_V2_1_1_6.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
Loading…
Add table
Add a link
Reference in a new issue