6#include "AudioTools/CoreAudio/AudioBasic/StrView.h"
7#include "AudioTools/CoreAudio/BaseStream.h"
8#include "AudioTools/Concurrency/RTOS.h"
14static ESPNowStream *ESPNowStreamSelf =
nullptr;
22 wifi_mode_t wifi_mode = WIFI_STA;
23 const char *mac_address =
nullptr;
25 const char *ssid =
nullptr;
26 const char *password =
nullptr;
27 bool use_send_ack =
true;
28 uint16_t delay_after_failed_write_ms = 2000;
29 uint16_t buffer_size = ESP_NOW_MAX_DATA_LEN;
30 uint16_t buffer_count = 400;
31 int write_retry_count = -1;
32#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
33 void (*recveive_cb)(
const esp_now_recv_info *info,
const uint8_t *data,
34 int data_len) =
nullptr;
36 void (*recveive_cb)(
const uint8_t *mac_addr,
const uint8_t *data,
37 int data_len) =
nullptr;
41 const char *local_master_key =
nullptr;
43 wifi_phy_rate_t
rate = WIFI_PHY_RATE_2M_S;
57 if (xSemaphore !=
nullptr) vSemaphoreDelete(xSemaphore);
67 static const char *result = WiFi.macAddress().c_str();
84 WiFi.mode(cfg.wifi_mode);
86 if (cfg.mac_address !=
nullptr) {
87 LOGI(
"setting mac %s", cfg.mac_address);
88 byte mac[ESP_NOW_KEY_LEN];
89 str2mac(cfg.mac_address, mac);
90 if (esp_wifi_set_mac((wifi_interface_t)getInterface(), mac) != ESP_OK) {
91 LOGE(
"Could not set mac address");
98 if (strcmp(addr, cfg.mac_address) != 0) {
99 LOGE(
"Wrong mac address: %s", addr);
104 if (WiFi.status() != WL_CONNECTED && cfg.ssid !=
nullptr &&
105 cfg.password !=
nullptr) {
106 WiFi.begin(cfg.ssid, cfg.password);
107 while (WiFi.status() != WL_CONNECTED) {
113#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
114 LOGI(
"Setting ESP-NEW rate");
115 if (esp_wifi_config_espnow_rate(getInterface(), cfg.
rate) != ESP_OK) {
116 LOGW(
"Could not set rate");
121 Serial.print(
"mac: ");
122 Serial.println(WiFi.macAddress());
129 if (esp_now_deinit() != ESP_OK) {
130 LOGE(
"esp_now_deinit");
132 if (buffer.size()>0) buffer.
resize(0);
140 LOGE(
"addPeer before begin");
143 esp_err_t result = esp_now_add_peer(&peer);
144 if (result == ESP_OK) {
145 LOGI(
"addPeer: %s", mac2str(peer.peer_addr));
147 LOGE(
"addPeer: %d", result);
149 return result == ESP_OK;
153 template <
size_t size>
156 for (
int j = 0; j < size; j++) {
157 const char *peer = array[j];
158 if (peer !=
nullptr) {
169 esp_now_peer_info_t peer;
170 peer.channel = cfg.channel;
171 peer.ifidx = getInterface();
172 peer.encrypt =
false;
174 if (
StrView(address).equals(cfg.mac_address)) {
175 LOGW(
"Did not add own address as peer");
181 strncpy((
char *)peer.lmk, cfg.local_master_key, 16);
184 if (!str2mac(address, peer.peer_addr)) {
185 LOGE(
"addPeer - Invalid address: %s", address);
192 size_t write(
const uint8_t *data,
size_t len)
override {
196 int retry_count = cfg.write_retry_count;
198 resetAvailableToWrite();
200 if (cfg.use_send_ack) {
201 xSemaphoreTake(xSemaphore, portMAX_DELAY);
203 size_t send_len = min(open, ESP_NOW_MAX_DATA_LEN);
204 esp_err_t rc = esp_now_send(
nullptr, data + result, send_len);
211 LOGW(
"Write failed - retrying again");
213 if (retry_count-- < 0 ) {
214 LOGE(
"Write error after %d retries", cfg.write_retry_count);
218 delay(cfg.delay_after_failed_write_ms);
192 size_t write(
const uint8_t *data,
size_t len)
override {
…}
226 if (buffer.size()==0)
return 0;
230 int available()
override {
231 if (!buffer)
return 0;
232 return buffer.size() == 0? 0 : buffer.
available();
235 int availableForWrite()
override {
236 if (!buffer)
return 0;
237 return cfg.use_send_ack ? available_to_write : cfg.buffer_size;
242 int size = buffer.size();
244 if (size==0)
return 0.0;
246 return 100.0 * buffer.
available() / size;
252 esp_now_recv_cb_t receive = default_recv_cb;
253 esp_now_send_cb_t send = default_send_cb;
254 volatile size_t available_to_write = 0;
255 bool is_init =
false;
256 SemaphoreHandle_t xSemaphore =
nullptr;
258 inline void setupSemaphore() {
260 if (cfg.use_send_ack && xSemaphore==
nullptr) {
261 xSemaphore = xSemaphoreCreateBinary();
262 xSemaphoreGive(xSemaphore);
266 inline void setupReceiveBuffer() {
269 LOGI(
"setupReceiveBuffer: %d", cfg.buffer_size * cfg.buffer_count);
270 buffer.
resize(cfg.buffer_size * cfg.buffer_count);
274 inline void resetAvailableToWrite() {
275 if (cfg.use_send_ack) {
276 available_to_write = 0;
284 wifi_interface_t getInterface() {
286 wifi_interface_t result;
287 switch (cfg.wifi_mode) {
289 result = (wifi_interface_t)ESP_IF_WIFI_STA;
292 result = (wifi_interface_t)ESP_IF_WIFI_AP;
295 result = (wifi_interface_t)0;
303 esp_err_t result = esp_now_init();
304 if (result == ESP_OK) {
307 LOGE(
"esp_now_init: %d", result);
315 if (cfg.recveive_cb !=
nullptr) {
316 esp_now_register_recv_cb(cfg.recveive_cb);
318 esp_now_register_recv_cb(receive);
320 if (cfg.use_send_ack) {
321 esp_now_register_send_cb(send);
323 available_to_write = cfg.buffer_size;
324 is_init = result == ESP_OK;
328 bool str2mac(
const char *mac, uint8_t *values) {
329 sscanf(mac,
"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &values[0], &values[1],
330 &values[2], &values[3], &values[4], &values[5]);
331 return strlen(mac) == 17;
334 const char *mac2str(
const uint8_t *array) {
335 static char macStr[18];
336 memset(macStr, 0, 18);
337 snprintf(macStr, 18,
"%02x:%02x:%02x:%02x:%02x:%02x", array[0], array[1],
338 array[2], array[3], array[4], array[5]);
339 return (
const char *)macStr;
342 static int bufferAvailableForWrite() {
346#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
347 static void default_recv_cb(
const esp_now_recv_info *info,
348 const uint8_t *data,
int data_len)
350 static void default_recv_cb(
const uint8_t *mac_addr,
const uint8_t *data,
354 LOGD(
"rec_cb: %d", data_len);
357 ESPNowStreamSelf->setupReceiveBuffer();
359 size_t result = ESPNowStreamSelf->buffer.
writeArray(data, data_len);
360 if (result != data_len) {
361 LOGE(
"writeArray %d -> %d", data_len, result);
365 static void default_send_cb(
const uint8_t *mac_addr,
366 esp_now_send_status_t status) {
367 static uint8_t first_mac[ESP_NOW_KEY_LEN] = {0};
370 if (first_mac[0] == 0) {
371 strncpy((
char *)first_mac, (
char *)mac_addr, ESP_NOW_KEY_LEN);
373 LOGD(
"default_send_cb - %s -> %s", ESPNowStreamSelf->mac2str(mac_addr),
374 status == ESP_NOW_SEND_SUCCESS ?
"+" :
"-");
377 if (strncmp((
char *)mac_addr, (
char *)first_mac, ESP_NOW_KEY_LEN) == 0) {
378 ESPNowStreamSelf->available_to_write = ESPNowStreamSelf->cfg.buffer_size;
379 if (status == ESP_NOW_SEND_SUCCESS) {
380 xSemaphoreGive(ESPNowStreamSelf->xSemaphore);