5 #include "AudioTools/BaseStream.h"
6 #include "AudioBasic/Str.h"
7 #include "AudioTools/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");
117 if (strcmp(addr, cfg.mac_address) != 0) {
118 LOGE(
"Wrong mac address: %s", addr);
123 if (WiFi.status() != WL_CONNECTED && cfg.ssid !=
nullptr &&
124 cfg.password !=
nullptr) {
125 WiFi.begin(cfg.ssid, cfg.password);
126 while (WiFi.status() != WL_CONNECTED) {
132 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
133 LOGI(
"Setting ESP-NEW rate");
134 if (esp_wifi_config_espnow_rate(getInterface(), cfg.
rate) !=
136 LOGW(
"Could not set rate");
141 Serial.print(
"mac: ");
142 Serial.println(WiFi.macAddress());
148 if (esp_now_deinit() != ESP_OK) {
149 LOGE(
"esp_now_deinit");
157 LOGE(
"addPeer before begin");
160 esp_err_t result = esp_now_add_peer(&peer);
161 if (result == ESP_OK) {
162 LOGI(
"addPeer: %s", mac2str(peer.peer_addr));
164 LOGE(
"addPeer: %d", result);
166 return result == ESP_OK;
170 template <
size_t size>
173 for (
int j = 0; j < size; j++) {
174 const char *peer = array[j];
175 if (peer !=
nullptr) {
186 esp_now_peer_info_t peer;
187 peer.channel = cfg.channel;
188 peer.ifidx = getInterface();
189 peer.encrypt =
false;
191 if (
Str(address).equals(cfg.mac_address)){
192 LOGW(
"Did not add own address as peer");
198 strncpy((
char *)peer.lmk, cfg.local_master_key, 16);
201 if (!str2mac(address, peer.peer_addr)) {
202 LOGE(
"addPeer - Invalid address: %s", address);
209 size_t write(
const uint8_t *data,
size_t len)
override {
214 if (available_to_write > 0) {
215 resetAvailableToWrite();
216 size_t send_len = min(open, ESP_NOW_MAX_DATA_LEN);
217 esp_err_t rc = esp_now_send(
nullptr, data + result, send_len);
219 if (cfg.use_send_ack) {
220 while (available_to_write == 0) {
227 if (rc == ESP_OK && is_write_ok) {
231 LOGW(
"Write failed - retrying again");
233 if (cfg.write_retry_count>0 && retry_count>=cfg.write_retry_count){
234 LOGE(
"Write error after %d retries", cfg.write_retry_count);
241 delay(cfg.delay_after_write_ms);
246 delay(cfg.delay_after_failed_write_ms);
254 if (p_buffer ==
nullptr)
return 0;
255 Lock lock(write_lock);
259 int available()
override {
260 return p_buffer ==
nullptr ? 0 : p_buffer->
available();
263 int availableForWrite()
override {
264 return cfg.use_send_ack ? available_to_write : cfg.buffer_size;
268 ESPNowStreamConfig cfg;
269 BaseBuffer<uint8_t> *p_buffer =
nullptr;
270 esp_now_recv_cb_t receive = default_recv_cb;
271 esp_now_send_cb_t send = default_send_cb;
272 volatile size_t available_to_write;
273 bool is_init =
false;
274 bool is_write_ok =
false;
277 inline void setupReceiveBuffer(){
279 if (p_buffer ==
nullptr && cfg.buffer_count > 0) {
281 p_buffer =
new RingBuffer<uint8_t>(cfg.buffer_size * cfg.buffer_count);
285 inline void resetAvailableToWrite() {
286 if (cfg.use_send_ack) {
287 available_to_write = 0;
292 return cfg.primary_master_key !=
nullptr && cfg.local_master_key !=
nullptr;
295 wifi_interface_t getInterface() {
297 wifi_interface_t result;
298 switch (cfg.wifi_mode) {
300 result = (wifi_interface_t)ESP_IF_WIFI_STA;
303 result = (wifi_interface_t)ESP_IF_WIFI_AP;
306 result = (wifi_interface_t)0;
314 esp_err_t result = esp_now_init();
315 if (result == ESP_OK) {
318 LOGE(
"esp_now_init: %d", result);
323 esp_now_set_pmk((uint8_t *)cfg.primary_master_key);
326 if (cfg.recveive_cb !=
nullptr) {
327 esp_now_register_recv_cb(cfg.recveive_cb);
329 esp_now_register_recv_cb(receive);
331 if (cfg.use_send_ack) {
332 esp_now_register_send_cb(send);
334 available_to_write = cfg.buffer_size;
335 is_init = result == ESP_OK;
339 bool str2mac(
const char *mac, uint8_t *values) {
340 sscanf(mac,
"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &values[0], &values[1],
341 &values[2], &values[3], &values[4], &values[5]);
342 return strlen(mac) == 17;
345 const char *mac2str(
const uint8_t *array) {
346 static char macStr[18];
347 memset(macStr, 0, 18);
348 snprintf(macStr, 18,
"%02x:%02x:%02x:%02x:%02x:%02x", array[0], array[1],
349 array[2], array[3], array[4], array[5]);
350 return (
const char *)macStr;
353 static int bufferAvailableForWrite() {
354 Lock lock(ESPNowStreamSelf->write_lock);
358 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
359 static void default_recv_cb(
const esp_now_recv_info *info,
const uint8_t *data,
int data_len)
361 static void default_recv_cb(
const uint8_t *mac_addr,
const uint8_t *data,
int data_len)
364 LOGD(
"rec_cb: %d", data_len);
366 ESPNowStreamSelf->setupReceiveBuffer();
368 while (bufferAvailableForWrite() < data_len) {
371 Lock lock(ESPNowStreamSelf->write_lock);
372 size_t result = ESPNowStreamSelf->p_buffer->
writeArray(data, data_len);
373 if (result!=data_len){
374 LOGE(
"writeArray %d -> %d", data_len, result);
378 static void default_send_cb(
const uint8_t *mac_addr,
379 esp_now_send_status_t status) {
380 static uint8_t first_mac[ESP_NOW_KEY_LEN] = {0};
383 if (first_mac[0] == 0) {
384 strncpy((
char *)first_mac, (
char *)mac_addr, ESP_NOW_KEY_LEN);
386 LOGD(
"default_send_cb - %s -> %s", ESPNowStreamSelf->mac2str(mac_addr),
387 status == ESP_NOW_SEND_SUCCESS ?
"+" :
"-");
390 if (strncmp((
char *)mac_addr, (
char *)first_mac, ESP_NOW_KEY_LEN) == 0) {
391 ESPNowStreamSelf->available_to_write = ESPNowStreamSelf->cfg.buffer_size;
392 if (status == ESP_NOW_SEND_SUCCESS) {
393 ESPNowStreamSelf->is_write_ok =
true;
395 ESPNowStreamSelf->is_write_ok =
false;