#pragma once #include #include #include "Protocol.h" struct ReceivedPacket { uint8_t mac[6]; ProtocolPacket packet; }; class Radio { public: bool begin(); void end(); bool sendBroadcast(ProtocolPacket packet); bool sendTo(const uint8_t mac[6], ProtocolPacket packet); bool receive(ReceivedPacket &received); bool setWindowedReceive(bool enabled); void flush(); uint32_t lastReceiveMs() const { return __atomic_load_n(&lastValidRxMs_, __ATOMIC_RELAXED); } static void macText(const uint8_t mac[6], char *out, size_t size); private: static void onReceive(const esp_now_recv_info_t *info, const uint8_t *data, int length); static void heartbeatTaskEntry(void *context); void heartbeatTaskLoop(); bool ensurePeer(const uint8_t mac[6]); void maintainChannel(); static Radio *instance_; QueueHandle_t queue_ = nullptr; QueueHandle_t heartbeatQueue_ = nullptr; TaskHandle_t heartbeatTask_ = nullptr; volatile bool active_ = false; volatile uint32_t lastValidRxMs_ = 0; uint32_t lastChannelCheckMs_ = 0; bool windowedReceive_ = false; };