5 #include "AudioTools/CoreAudio/BaseStream.h"
6 #include "AudioTools/CoreAudio/AudioBasic/StrView.h"
7 #include "AudioTools/CoreAudio/Buffers.h"
15 ESPNowStream *ESPNowStreamSelf =
nullptr;
26 _lock_acquire(p_lock);
28 ~
Lock() { _lock_release(p_lock); }
31 _lock_t *p_lock =
nullptr;
42 wifi_mode_t wifi_mode = WIFI_STA;
43 const char *mac_address =
nullptr;
45 const char *ssid =
nullptr;
46 const char *password =
nullptr;
47 bool use_send_ack =
true;
48 uint16_t delay_after_write_ms = 2;
49 uint16_t delay_after_failed_write_ms = 2000;
50 uint16_t buffer_size = ESP_NOW_MAX_DATA_LEN;
51 uint16_t buffer_count = 400;
52 int write_retry_count = -1;
53 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
54 void (*recveive_cb)(
const esp_now_recv_info *info,
const uint8_t *data,
55 int data_len) =
nullptr;
57 void (*recveive_cb)(
const uint8_t *mac_addr,
const uint8_t *data,
58 int data_len) =
nullptr;
62 const char *local_master_key =
nullptr;
64 wifi_phy_rate_t
rate = WIFI_PHY_RATE_2M_S;
78 if (p_buffer !=
nullptr)
delete p_buffer;
88 static const char* result = WiFi.macAddress().c_str();
105 WiFi.mode(cfg.wifi_mode);
107 if (cfg.mac_address !=
nullptr) {
108 LOGI(
"setting mac %s", cfg.mac_address);
109 byte mac[ESP_NOW_KEY_LEN];
110 str2mac(cfg.mac_address, mac);
111 if (esp_wifi_set_mac((wifi_interface_t)getInterface(), mac) != ESP_OK) {
112 LOGE(
"Could not set mac address");
118 if (strcmp(addr, cfg.mac_address) != 0) {
119 LOGE(
"Wrong mac address: %s", addr);
124 if (WiFi.status() != WL_CONNECTED && cfg.ssid !=
nullptr &&
125 cfg.password !=
nullptr) {
126 WiFi.begin(cfg.ssid, cfg.password);
127 while (WiFi.status() != WL_CONNECTED) {
133 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
134 LOGI(
"Setting ESP-NEW rate");
135 if (esp_wifi_config_espnow_rate(getInterface(), cfg.
rate) !=
137 LOGW(
"Could not set rate");
142 Serial.print(
"mac: ");
143 Serial.println(WiFi.macAddress());
149 if (esp_now_deinit() != ESP_OK) {
150 LOGE(
"esp_now_deinit");
158 LOGE(
"addPeer before begin");
161 esp_err_t result = esp_now_add_peer(&peer);
162 if (result == ESP_OK) {
163 LOGI(
"addPeer: %s", mac2str(peer.peer_addr));
165 LOGE(
"addPeer: %d", result);
167 return result == ESP_OK;
171 template <
size_t size>
174 for (
int j = 0; j < size; j++) {
175 const char *peer = array[j];
176 if (peer !=
nullptr) {
187 esp_now_peer_info_t peer;
188 peer.channel = cfg.channel;
189 peer.ifidx = getInterface();
190 peer.encrypt =
false;
192 if (
StrView(address).equals(cfg.mac_address)){
193 LOGW(
"Did not add own address as peer");
199 strncpy((
char *)peer.lmk, cfg.local_master_key, 16);
202 if (!str2mac(address, peer.peer_addr)) {
203 LOGE(
"addPeer - Invalid address: %s", address);
210 size_t write(
const uint8_t *data,
size_t len)
override {
215 if (available_to_write > 0) {
216 resetAvailableToWrite();
217 size_t send_len = min(open, ESP_NOW_MAX_DATA_LEN);
218 esp_err_t rc = esp_now_send(
nullptr, data + result, send_len);
220 if (cfg.use_send_ack) {
221 while (available_to_write == 0) {
228 if (rc == ESP_OK && is_write_ok) {
232 LOGW(
"Write failed - retrying again");
234 if (cfg.write_retry_count>0 && retry_count>=cfg.write_retry_count){
235 LOGE(
"Write error after %d retries", cfg.write_retry_count);
242 delay(cfg.delay_after_write_ms);
247 delay(cfg.delay_after_failed_write_ms);
255 if (p_buffer ==
nullptr)
return 0;
256 Lock lock(write_lock);
260 int available()
override {
261 return p_buffer ==
nullptr ? 0 : p_buffer->
available();
264 int availableForWrite()
override {
265 return cfg.use_send_ack ? available_to_write : cfg.buffer_size;
269 ESPNowStreamConfig cfg;
270 BaseBuffer<uint8_t> *p_buffer =
nullptr;
271 esp_now_recv_cb_t receive = default_recv_cb;
272 esp_now_send_cb_t send = default_send_cb;
273 volatile size_t available_to_write;
274 bool is_init =
false;
275 bool is_write_ok =
false;
278 inline void setupReceiveBuffer(){
280 if (p_buffer ==
nullptr && cfg.buffer_count > 0) {
282 p_buffer =
new RingBuffer<uint8_t>(cfg.buffer_size * cfg.buffer_count);
286 inline void resetAvailableToWrite() {
287 if (cfg.use_send_ack) {
288 available_to_write = 0;
293 return cfg.primary_master_key !=
nullptr && cfg.local_master_key !=
nullptr;
296 wifi_interface_t getInterface() {
298 wifi_interface_t result;
299 switch (cfg.wifi_mode) {
301 result = (wifi_interface_t)ESP_IF_WIFI_STA;
304 result = (wifi_interface_t)ESP_IF_WIFI_AP;
307 result = (wifi_interface_t)0;
315 esp_err_t result = esp_now_init();
316 if (result == ESP_OK) {
319 LOGE(
"esp_now_init: %d", result);
324 esp_now_set_pmk((uint8_t *)cfg.primary_master_key);
327 if (cfg.recveive_cb !=
nullptr) {
328 esp_now_register_recv_cb(cfg.recveive_cb);
330 esp_now_register_recv_cb(receive);
332 if (cfg.use_send_ack) {
333 esp_now_register_send_cb(send);
335 available_to_write = cfg.buffer_size;
336 is_init = result == ESP_OK;
340 bool str2mac(
const char *mac, uint8_t *values) {
341 sscanf(mac,
"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &values[0], &values[1],
342 &values[2], &values[3], &values[4], &values[5]);
343 return strlen(mac) == 17;
346 const char *mac2str(
const uint8_t *array) {
347 static char macStr[18];
348 memset(macStr, 0, 18);
349 snprintf(macStr, 18,
"%02x:%02x:%02x:%02x:%02x:%02x", array[0], array[1],
350 array[2], array[3], array[4], array[5]);
351 return (
const char *)macStr;
354 static int bufferAvailableForWrite() {
355 Lock lock(ESPNowStreamSelf->write_lock);
359 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
360 static void default_recv_cb(
const esp_now_recv_info *info,
const uint8_t *data,
int data_len)
362 static void default_recv_cb(
const uint8_t *mac_addr,
const uint8_t *data,
int data_len)
365 LOGD(
"rec_cb: %d", data_len);
367 ESPNowStreamSelf->setupReceiveBuffer();
369 while (bufferAvailableForWrite() < data_len) {
372 Lock lock(ESPNowStreamSelf->write_lock);
373 size_t result = ESPNowStreamSelf->p_buffer->
writeArray(data, data_len);
374 if (result!=data_len){
375 LOGE(
"writeArray %d -> %d", data_len, result);
379 static void default_send_cb(
const uint8_t *mac_addr,
380 esp_now_send_status_t status) {
381 static uint8_t first_mac[ESP_NOW_KEY_LEN] = {0};
384 if (first_mac[0] == 0) {
385 strncpy((
char *)first_mac, (
char *)mac_addr, ESP_NOW_KEY_LEN);
387 LOGD(
"default_send_cb - %s -> %s", ESPNowStreamSelf->mac2str(mac_addr),
388 status == ESP_NOW_SEND_SUCCESS ?
"+" :
"-");
391 if (strncmp((
char *)mac_addr, (
char *)first_mac, ESP_NOW_KEY_LEN) == 0) {
392 ESPNowStreamSelf->available_to_write = ESPNowStreamSelf->cfg.buffer_size;
393 if (status == ESP_NOW_SEND_SUCCESS) {
394 ESPNowStreamSelf->is_write_ok =
true;
396 ESPNowStreamSelf->is_write_ok =
false;