Skip to content

Commit 505e9c3

Browse files
committed
feat(espnow): Add PHY configuration for ESP-NOW packets
1 parent 9b3364c commit 505e9c3

File tree

2 files changed

+99
-7
lines changed

2 files changed

+99
-7
lines changed

libraries/ESP_NOW/src/ESP32_NOW.cpp

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ static void *new_arg = nullptr; // * tx_arg = nullptr, * rx_arg = nullptr,
1818
static bool _esp_now_has_begun = false;
1919
static ESP_NOW_Peer *_esp_now_peers[ESP_NOW_MAX_TOTAL_PEER_NUM];
2020

21-
static esp_err_t _esp_now_add_peer(const uint8_t *mac_addr, uint8_t channel, wifi_interface_t iface, const uint8_t *lmk, ESP_NOW_Peer *_peer = nullptr) {
22-
log_v(MACSTR, MAC2STR(mac_addr));
21+
static esp_err_t _esp_now_add_peer(const uint8_t *mac_addr, uint8_t channel, wifi_interface_t iface, const uint8_t *lmk, esp_now_rate_config_t *rate_config, ESP_NOW_Peer *_peer = nullptr) {
22+
log_i("Adding peer " MACSTR, MAC2STR(mac_addr));
2323
if (esp_now_is_peer_exist(mac_addr)) {
2424
log_e("Peer Already Exists");
2525
return ESP_ERR_ESPNOW_EXIST;
@@ -41,17 +41,25 @@ static esp_err_t _esp_now_add_peer(const uint8_t *mac_addr, uint8_t channel, wif
4141
for (uint8_t i = 0; i < ESP_NOW_MAX_TOTAL_PEER_NUM; i++) {
4242
if (_esp_now_peers[i] == nullptr) {
4343
_esp_now_peers[i] = _peer;
44+
if (_esp_now_has_begun && rate_config != nullptr) {
45+
log_i("ESP-NOW already running. Setting PHY rate for peer " MACSTR, MAC2STR(_peer->addr()));
46+
result = esp_now_set_peer_rate_config(_peer->addr(), rate_config);
47+
if (result != ESP_OK) {
48+
log_w("Could not set the ESP-NOW PHY rate for peer " MACSTR, MAC2STR(_peer->addr()));
49+
}
50+
}
4451
return ESP_OK;
4552
}
4653
}
54+
log_e("Library Peer list full");
4755
return ESP_FAIL;
4856
}
4957
} else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
5058
log_e("ESPNOW Not Init");
5159
} else if (result == ESP_ERR_ESPNOW_ARG) {
5260
log_e("Invalid Argument");
5361
} else if (result == ESP_ERR_ESPNOW_FULL) {
54-
log_e("Peer list full");
62+
log_e("ESP-NOW Peer list full");
5563
} else if (result == ESP_ERR_ESPNOW_NO_MEM) {
5664
log_e("Out of memory");
5765
} else if (result == ESP_ERR_ESPNOW_EXIST) {
@@ -149,6 +157,21 @@ static void _esp_now_tx_cb(const uint8_t *mac_addr, esp_now_send_status_t status
149157
}
150158
}
151159

160+
esp_err_t _esp_now_set_all_peers_rate() {
161+
for (uint8_t i = 0; i < ESP_NOW_MAX_TOTAL_PEER_NUM; i++) {
162+
if (_esp_now_peers[i] != nullptr) {
163+
log_v("Setting PHY rate for peer " MACSTR, MAC2STR(_esp_now_peers[i]->addr()));
164+
esp_now_rate_config_t rate = _esp_now_peers[i]->getRate();
165+
esp_err_t err = esp_now_set_peer_rate_config(_esp_now_peers[i]->addr(), &rate);
166+
if (err != ESP_OK) {
167+
log_e("Failed to set rate for peer " MACSTR, MAC2STR(_esp_now_peers[i]->addr()));
168+
return err;
169+
}
170+
}
171+
}
172+
return ESP_OK;
173+
}
174+
152175
ESP_NOW_Class::ESP_NOW_Class() {
153176
max_data_len = 0;
154177
version = 0;
@@ -195,6 +218,14 @@ bool ESP_NOW_Class::begin(const uint8_t *pmk) {
195218
return false;
196219
}
197220

221+
// Set the peers PHY rate after initializing ESP-NOW.
222+
err = _esp_now_set_all_peers_rate();
223+
if (err != ESP_OK) {
224+
log_e("Failed to set PHY rate for peers! 0x%x", err);
225+
_esp_now_has_begun = false;
226+
return false;
227+
}
228+
198229
if (pmk) {
199230
err = esp_now_set_pmk(pmk);
200231
if (err != ESP_OK) {
@@ -243,6 +274,7 @@ bool ESP_NOW_Class::end() {
243274

244275
int ESP_NOW_Class::getTotalPeerCount() const {
245276
if (!_esp_now_has_begun) {
277+
log_e("ESP-NOW not initialized");
246278
return -1;
247279
}
248280
esp_now_peer_num_t num;
@@ -256,6 +288,7 @@ int ESP_NOW_Class::getTotalPeerCount() const {
256288

257289
int ESP_NOW_Class::getEncryptedPeerCount() const {
258290
if (!_esp_now_has_begun) {
291+
log_e("ESP-NOW not initialized");
259292
return -1;
260293
}
261294
esp_now_peer_num_t num;
@@ -295,6 +328,7 @@ int ESP_NOW_Class::availableForWrite() {
295328

296329
size_t ESP_NOW_Class::write(const uint8_t *data, size_t len) {
297330
if (!_esp_now_has_begun) {
331+
log_e("ESP-NOW not initialized. Please call begin() first to send data.");
298332
return 0;
299333
}
300334
if (len > max_data_len) {
@@ -336,7 +370,7 @@ ESP_NOW_Class ESP_NOW;
336370
*
337371
*/
338372

339-
ESP_NOW_Peer::ESP_NOW_Peer(const uint8_t *mac_addr, uint8_t channel, wifi_interface_t iface, const uint8_t *lmk) {
373+
ESP_NOW_Peer::ESP_NOW_Peer(const uint8_t *mac_addr, uint8_t channel, wifi_interface_t iface, const uint8_t *lmk, esp_now_rate_config_t *rate_config) {
340374
added = false;
341375
if (mac_addr) {
342376
memcpy(mac, mac_addr, 6);
@@ -347,6 +381,11 @@ ESP_NOW_Peer::ESP_NOW_Peer(const uint8_t *mac_addr, uint8_t channel, wifi_interf
347381
if (encrypt) {
348382
memcpy(key, lmk, 16);
349383
}
384+
if (rate_config) {
385+
rate = *rate_config;
386+
} else {
387+
rate = DEFAULT_ESPNOW_RATE_CONFIG;
388+
}
350389
}
351390

352391
bool ESP_NOW_Peer::add() {
@@ -356,7 +395,8 @@ bool ESP_NOW_Peer::add() {
356395
if (added) {
357396
return true;
358397
}
359-
if (_esp_now_add_peer(mac, chan, ifc, encrypt ? key : nullptr, this) != ESP_OK) {
398+
if (_esp_now_add_peer(mac, chan, ifc, encrypt ? key : nullptr, &rate, this) != ESP_OK) {
399+
log_e("Failed to add peer " MACSTR, MAC2STR(mac));
360400
return false;
361401
}
362402
log_v("Peer added - " MACSTR, MAC2STR(mac));
@@ -371,12 +411,15 @@ bool ESP_NOW_Peer::remove() {
371411
if (!added) {
372412
return true;
373413
}
374-
log_v("Peer removed - " MACSTR, MAC2STR(mac));
414+
log_i("Removing peer - " MACSTR, MAC2STR(mac));
375415
esp_err_t err = _esp_now_del_peer(mac);
376416
if (err == ESP_OK) {
377417
added = false;
418+
log_i("Peer removed - " MACSTR, MAC2STR(mac));
378419
return true;
379420
}
421+
422+
log_e("Failed to remove peer " MACSTR, MAC2STR(mac));
380423
return false;
381424
}
382425

@@ -389,6 +432,8 @@ bool ESP_NOW_Peer::addr(const uint8_t *mac_addr) {
389432
memcpy(mac, mac_addr, 6);
390433
return true;
391434
}
435+
log_e("Peer already added and ESP-NOW is already running. Cannot change the MAC address.");
436+
log_e("Please call addr() before adding the peer or before starting ESP-NOW.");
392437
return false;
393438
}
394439

@@ -416,6 +461,38 @@ bool ESP_NOW_Peer::setInterface(wifi_interface_t iface) {
416461
return _esp_now_modify_peer(mac, chan, ifc, encrypt ? key : nullptr) == ESP_OK;
417462
}
418463

464+
/**
465+
* @brief Set the rate configuration for the peer.
466+
*
467+
* @param rate_config Pointer to the rate configuration to set. Nullptr to reset to default rate configuration.
468+
* @return true if the rate configuration was set successfully, false otherwise.
469+
*/
470+
bool ESP_NOW_Peer::setRate(const esp_now_rate_config_t *rate_config) {
471+
if (added && _esp_now_has_begun) {
472+
log_e("Peer already added and ESP-NOW is already running. Cannot set rate configuration.");
473+
log_e("Please call setRate() before adding the peer or before starting ESP-NOW.");
474+
return false;
475+
}
476+
477+
if (rate_config == nullptr) {
478+
log_i("Resetting rate configuration to default.");
479+
rate = DEFAULT_ESPNOW_RATE_CONFIG;
480+
} else {
481+
rate = *rate_config;
482+
}
483+
484+
return true;
485+
}
486+
487+
/**
488+
* @brief Get the rate configuration for the peer.
489+
*
490+
* @return esp_now_rate_config_t The rate configuration for the peer.
491+
*/
492+
esp_now_rate_config_t ESP_NOW_Peer::getRate() const {
493+
return rate;
494+
}
495+
419496
bool ESP_NOW_Peer::isEncrypted() const {
420497
return encrypt;
421498
}

libraries/ESP_NOW/src/ESP32_NOW.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@
1111
#include "esp32-hal-log.h"
1212
#include "esp_mac.h"
1313

14+
// clang-format off
15+
#define DEFAULT_ESPNOW_RATE_CONFIG { \
16+
.phymode = WIFI_PHY_MODE_11G, \
17+
.rate = WIFI_PHY_RATE_1M_L, \
18+
.ersu = false, \
19+
.dcm = false \
20+
}
21+
// clang-format on
22+
1423
class ESP_NOW_Peer; //forward declaration for friend function
1524

1625
class ESP_NOW_Class : public Print {
@@ -29,6 +38,8 @@ class ESP_NOW_Class : public Print {
2938
int getVersion() const;
3039

3140
int availableForWrite();
41+
42+
// You can directly send data to all peers without broadcasting using ESP_NOW.write(data, len)
3243
size_t write(const uint8_t *data, size_t len);
3344
size_t write(uint8_t data) {
3445
return write(&data, 1);
@@ -47,6 +58,7 @@ class ESP_NOW_Peer {
4758
uint8_t mac[6];
4859
uint8_t chan;
4960
wifi_interface_t ifc;
61+
esp_now_rate_config_t rate;
5062
bool encrypt;
5163
uint8_t key[16];
5264

@@ -56,7 +68,7 @@ class ESP_NOW_Peer {
5668
bool remove();
5769
size_t send(const uint8_t *data, int len);
5870

59-
ESP_NOW_Peer(const uint8_t *mac_addr, uint8_t channel = 0, wifi_interface_t iface = WIFI_IF_AP, const uint8_t *lmk = nullptr);
71+
ESP_NOW_Peer(const uint8_t *mac_addr, uint8_t channel = 0, wifi_interface_t iface = WIFI_IF_AP, const uint8_t *lmk = nullptr, esp_now_rate_config_t *rate_config = nullptr);
6072

6173
public:
6274
virtual ~ESP_NOW_Peer() {}
@@ -70,6 +82,9 @@ class ESP_NOW_Peer {
7082
wifi_interface_t getInterface() const;
7183
bool setInterface(wifi_interface_t iface);
7284

85+
bool setRate(const esp_now_rate_config_t *rate_config);
86+
esp_now_rate_config_t getRate() const;
87+
7388
bool isEncrypted() const;
7489
bool setKey(const uint8_t *lmk);
7590

0 commit comments

Comments
 (0)