ESPHome 2025.9.0-dev
Loading...
Searching...
No Matches
espnow_packet.h
Go to the documentation of this file.
1#pragma once
2
3#ifdef USE_ESP32
4
5#include "espnow_err.h"
6
7#include <cstdint>
8#include <cstring>
9#include <functional>
10#include <memory>
11#include <vector>
12
13#include <esp_err.h>
14#include <esp_idf_version.h>
15#include <esp_now.h>
16
17namespace esphome::espnow {
18
19static const uint8_t ESPNOW_BROADCAST_ADDR[ESP_NOW_ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
20static const uint8_t ESPNOW_MULTICAST_ADDR[ESP_NOW_ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE};
21
23 int8_t rssi; // Received Signal Strength Indicator (RSSI) of packet, unit: dBm
24 uint32_t timestamp; // Timestamp in microseconds when the packet was received, precise only if modem sleep or
25 // light sleep is not enabled
26};
27
29 uint8_t src_addr[ESP_NOW_ETH_ALEN];
30 uint8_t des_addr[ESP_NOW_ETH_ALEN];
31 wifi_pkt_rx_ctrl_t *rx_ctrl;
32};
33
34using send_callback_t = std::function<void(esp_err_t)>;
35
37 public:
38 // NOLINTNEXTLINE(readability-identifier-naming)
39 enum esp_now_packet_type_t : uint8_t {
42 };
43
44 // Constructor for received data
45 ESPNowPacket(const esp_now_recv_info_t *info, const uint8_t *data, int size) {
46 this->init_received_data_(info, data, size);
47 };
48
49#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
50 // Constructor for sent data
51 ESPNowPacket(const esp_now_send_info_t *info, esp_now_send_status_t status) {
52 this->init_sent_data_(info->src_addr, status);
53 }
54#else
55 // Constructor for sent data
56 ESPNowPacket(const uint8_t *mac_addr, esp_now_send_status_t status) { this->init_sent_data_(mac_addr, status); }
57#endif
58
59 // Default constructor for pre-allocation in pool
61
62 void release() {}
63
64 void load_received_data(const esp_now_recv_info_t *info, const uint8_t *data, int size) {
65 this->type_ = RECEIVED;
66 this->init_received_data_(info, data, size);
67 }
68
69 void load_sent_data(const uint8_t *mac_addr, esp_now_send_status_t status) {
70 this->type_ = SENT;
71 this->init_sent_data_(mac_addr, status);
72 }
73
74 // Disable copy to prevent double-delete
75 ESPNowPacket(const ESPNowPacket &) = delete;
77
78 union {
79 // NOLINTNEXTLINE(readability-identifier-naming)
80 struct received_data {
81 ESPNowRecvInfo info; // Information about the received packet
82 uint8_t data[ESP_NOW_MAX_DATA_LEN]; // Data received in the packet
83 uint8_t size; // Size of the received data
84 WifiPacketRxControl rx_ctrl; // Status of the received packet
86
87 // NOLINTNEXTLINE(readability-identifier-naming)
88 struct sent_data {
89 uint8_t address[ESP_NOW_ETH_ALEN];
90 esp_now_send_status_t status;
93
95
96 esp_now_packet_type_t type() const { return this->type_; }
97 const ESPNowRecvInfo &get_receive_info() const { return this->packet_.receive.info; }
98
99 private:
100 void init_received_data_(const esp_now_recv_info_t *info, const uint8_t *data, int size) {
101 memcpy(this->packet_.receive.info.src_addr, info->src_addr, ESP_NOW_ETH_ALEN);
102 memcpy(this->packet_.receive.info.des_addr, info->des_addr, ESP_NOW_ETH_ALEN);
103 memcpy(this->packet_.receive.data, data, size);
104 this->packet_.receive.size = size;
105
106 this->packet_.receive.rx_ctrl.rssi = info->rx_ctrl->rssi;
107 this->packet_.receive.rx_ctrl.timestamp = info->rx_ctrl->timestamp;
108
109 this->packet_.receive.info.rx_ctrl = reinterpret_cast<wifi_pkt_rx_ctrl_t *>(&this->packet_.receive.rx_ctrl);
110 }
111
112 void init_sent_data_(const uint8_t *mac_addr, esp_now_send_status_t status) {
113 memcpy(this->packet_.sent.address, mac_addr, ESP_NOW_ETH_ALEN);
114 this->packet_.sent.status = status;
115 }
116};
117
119 public:
120 ESPNowSendPacket(const uint8_t *peer_address, const uint8_t *payload, size_t size, const send_callback_t &&callback)
121 : callback_(callback) {
122 this->init_data_(peer_address, payload, size);
123 }
124 ESPNowSendPacket(const uint8_t *peer_address, const uint8_t *payload, size_t size) {
125 this->init_data_(peer_address, payload, size);
126 }
127
128 // Default constructor for pre-allocation in pool
130
131 void release() {}
132
133 // Disable copy to prevent double-delete
136
137 void load_data(const uint8_t *peer_address, const uint8_t *payload, size_t size, const send_callback_t &callback) {
138 this->init_data_(peer_address, payload, size);
139 this->callback_ = callback;
140 }
141
142 void load_data(const uint8_t *peer_address, const uint8_t *payload, size_t size) {
143 this->init_data_(peer_address, payload, size);
144 this->callback_ = nullptr; // Reset callback
145 }
146
147 uint8_t address_[ESP_NOW_ETH_ALEN]{0}; // MAC address of the peer to send the packet to
148 uint8_t data_[ESP_NOW_MAX_DATA_LEN]{0}; // Data to send
149 uint8_t size_{0}; // Size of the data to send, must be <= ESP_NOW_MAX_DATA_LEN
150 send_callback_t callback_{nullptr}; // Callback to call when the send operation is complete
151
152 private:
153 void init_data_(const uint8_t *peer_address, const uint8_t *payload, size_t size) {
154 memcpy(this->address_, peer_address, ESP_NOW_ETH_ALEN);
155 if (size > ESP_NOW_MAX_DATA_LEN) {
156 this->size_ = 0;
157 return;
158 }
159 this->size_ = size;
160 memcpy(this->data_, payload, this->size_);
161 }
162};
163
164} // namespace esphome::espnow
165
166#endif // USE_ESP32
uint8_t address
Definition bl0906.h:4
ESPNowPacket(const ESPNowPacket &)=delete
esp_now_send_status_t status
void load_sent_data(const uint8_t *mac_addr, esp_now_send_status_t status)
ESPNowPacket & operator=(const ESPNowPacket &)=delete
union esphome::espnow::ESPNowPacket::@82 packet_
void load_received_data(const esp_now_recv_info_t *info, const uint8_t *data, int size)
esp_now_packet_type_t type_
esp_now_packet_type_t type() const
const ESPNowRecvInfo & get_receive_info() const
ESPNowPacket(const uint8_t *mac_addr, esp_now_send_status_t status)
struct esphome::espnow::ESPNowPacket::@82::received_data receive
WifiPacketRxControl rx_ctrl
struct esphome::espnow::ESPNowPacket::@82::sent_data sent
ESPNowPacket(const esp_now_send_info_t *info, esp_now_send_status_t status)
ESPNowPacket(const esp_now_recv_info_t *info, const uint8_t *data, int size)
uint8_t data[ESP_NOW_MAX_DATA_LEN]
void load_data(const uint8_t *peer_address, const uint8_t *payload, size_t size, const send_callback_t &callback)
ESPNowSendPacket & operator=(const ESPNowSendPacket &)=delete
void load_data(const uint8_t *peer_address, const uint8_t *payload, size_t size)
ESPNowSendPacket(const ESPNowSendPacket &)=delete
uint8_t address_[ESP_NOW_ETH_ALEN]
uint8_t data_[ESP_NOW_MAX_DATA_LEN]
ESPNowSendPacket(const uint8_t *peer_address, const uint8_t *payload, size_t size, const send_callback_t &&callback)
ESPNowSendPacket(const uint8_t *peer_address, const uint8_t *payload, size_t size)
std::function< void(esp_err_t)> send_callback_t
wifi_pkt_rx_ctrl_t * rx_ctrl
Rx control info of ESPNOW packet.
uint8_t des_addr[ESP_NOW_ETH_ALEN]
Destination address of ESPNOW packet.
uint8_t src_addr[ESP_NOW_ETH_ALEN]
Source address of ESPNOW packet.