MeshCore/src/helpers/bridges/BridgeBase.h

120 lines
3.9 KiB
C++

#pragma once
#include "helpers/AbstractBridge.h"
#include "helpers/CommonCLI.h"
#include "helpers/SimpleMeshTables.h"
#include <RTClib.h>
/**
* @brief Base class implementing common bridge functionality
*
* This class provides common functionality used by different bridge implementations
* like packet tracking, checksum calculation, timestamping, and duplicate detection.
*
* Features:
* - Fletcher-16 checksum calculation for data integrity
* - Packet duplicate detection using SimpleMeshTables
* - Common timestamp formatting for debug logging
* - Shared packet management and queuing logic
*/
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
*
* This magic number is placed at the beginning of bridge packets to identify
* them as mesh bridge packets and provide frame synchronization.
*/
static constexpr uint16_t BRIDGE_PACKET_MAGIC = 0xC03E;
/**
* @brief Common field sizes used by bridge implementations
*
* These constants define the size of common packet fields used across bridges.
* BRIDGE_MAGIC_SIZE is used by all bridges for packet identification.
* BRIDGE_LENGTH_SIZE is used by bridges that need explicit length fields (like RS232).
* BRIDGE_CHECKSUM_SIZE is used by all bridges for Fletcher-16 checksums.
*/
static constexpr uint16_t BRIDGE_MAGIC_SIZE = sizeof(BRIDGE_PACKET_MAGIC);
static constexpr uint16_t BRIDGE_LENGTH_SIZE = sizeof(uint16_t);
static constexpr uint16_t BRIDGE_CHECKSUM_SIZE = sizeof(uint16_t);
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(NodePrefs *prefs, mesh::PacketManager *mgr, mesh::RTCClock *rtc)
: _prefs(prefs), _mgr(mgr), _rtc(rtc) {}
/**
* @brief Gets formatted date/time string for logging
*
* Format: "HH:MM:SS - DD/MM/YYYY U"
*
* @return Formatted date/time string
*/
const char *getLogDateTime();
/**
* @brief Calculate Fletcher-16 checksum
*
* Based on: https://en.wikipedia.org/wiki/Fletcher%27s_checksum
* Used to verify data integrity of received packets
*
* @param data Pointer to data to calculate checksum for
* @param len Length of data in bytes
* @return Calculated Fletcher-16 checksum
*/
static uint16_t fletcher16(const uint8_t *data, size_t len);
/**
* @brief Validate received checksum against calculated checksum
*
* @param data Pointer to data to validate
* @param len Length of data in bytes
* @param received_checksum Checksum received with data
* @return true if checksum is valid, false otherwise
*/
bool validateChecksum(const uint8_t *data, size_t len, uint16_t received_checksum);
/**
* @brief Common packet handling for received packets
*
* Implements the standard pattern used by all bridges:
* - Check if packet was seen before using _seen_packets.hasSeen()
* - Queue packet for mesh processing if not seen before
* - Free packet if already seen to prevent duplicates
*
* @param packet The received mesh packet
*/
void handleReceivedPacket(mesh::Packet *packet);
};