Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 85 additions & 6 deletions libraries/ESP_NOW/src/ESP32_NOW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ static void *new_arg = nullptr; // * tx_arg = nullptr, * rx_arg = nullptr,
static bool _esp_now_has_begun = false;
static ESP_NOW_Peer *_esp_now_peers[ESP_NOW_MAX_TOTAL_PEER_NUM];

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) {
log_v(MACSTR, MAC2STR(mac_addr));
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
) {
log_i("Adding peer " MACSTR, MAC2STR(mac_addr));
if (esp_now_is_peer_exist(mac_addr)) {
log_e("Peer Already Exists");
return ESP_ERR_ESPNOW_EXIST;
Expand All @@ -41,17 +43,25 @@ static esp_err_t _esp_now_add_peer(const uint8_t *mac_addr, uint8_t channel, wif
for (uint8_t i = 0; i < ESP_NOW_MAX_TOTAL_PEER_NUM; i++) {
if (_esp_now_peers[i] == nullptr) {
_esp_now_peers[i] = _peer;
if (_esp_now_has_begun && rate_config != nullptr) {
log_i("ESP-NOW already running. Setting PHY rate for peer " MACSTR, MAC2STR(_peer->addr()));
result = esp_now_set_peer_rate_config(_peer->addr(), rate_config);
if (result != ESP_OK) {
log_w("Could not set the ESP-NOW PHY rate for peer " MACSTR, MAC2STR(_peer->addr()));
}
}
return ESP_OK;
}
}
log_e("Library Peer list full");
return ESP_FAIL;
}
} else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
log_e("ESPNOW Not Init");
} else if (result == ESP_ERR_ESPNOW_ARG) {
log_e("Invalid Argument");
} else if (result == ESP_ERR_ESPNOW_FULL) {
log_e("Peer list full");
log_e("ESP-NOW Peer list full");
} else if (result == ESP_ERR_ESPNOW_NO_MEM) {
log_e("Out of memory");
} else if (result == ESP_ERR_ESPNOW_EXIST) {
Expand Down Expand Up @@ -149,6 +159,21 @@ static void _esp_now_tx_cb(const uint8_t *mac_addr, esp_now_send_status_t status
}
}

esp_err_t _esp_now_set_all_peers_rate() {
for (uint8_t i = 0; i < ESP_NOW_MAX_TOTAL_PEER_NUM; i++) {
if (_esp_now_peers[i] != nullptr) {
log_v("Setting PHY rate for peer " MACSTR, MAC2STR(_esp_now_peers[i]->addr()));
esp_now_rate_config_t rate = _esp_now_peers[i]->getRate();
esp_err_t err = esp_now_set_peer_rate_config(_esp_now_peers[i]->addr(), &rate);
if (err != ESP_OK) {
log_e("Failed to set rate for peer " MACSTR, MAC2STR(_esp_now_peers[i]->addr()));
return err;
}
}
}
return ESP_OK;
}

ESP_NOW_Class::ESP_NOW_Class() {
max_data_len = 0;
version = 0;
Expand Down Expand Up @@ -195,6 +220,14 @@ bool ESP_NOW_Class::begin(const uint8_t *pmk) {
return false;
}

// Set the peers PHY rate after initializing ESP-NOW.
err = _esp_now_set_all_peers_rate();
if (err != ESP_OK) {
log_e("Failed to set PHY rate for peers! 0x%x", err);
_esp_now_has_begun = false;
return false;
}

if (pmk) {
err = esp_now_set_pmk(pmk);
if (err != ESP_OK) {
Expand Down Expand Up @@ -243,6 +276,7 @@ bool ESP_NOW_Class::end() {

int ESP_NOW_Class::getTotalPeerCount() const {
if (!_esp_now_has_begun) {
log_e("ESP-NOW not initialized");
return -1;
}
esp_now_peer_num_t num;
Expand All @@ -256,6 +290,7 @@ int ESP_NOW_Class::getTotalPeerCount() const {

int ESP_NOW_Class::getEncryptedPeerCount() const {
if (!_esp_now_has_begun) {
log_e("ESP-NOW not initialized");
return -1;
}
esp_now_peer_num_t num;
Expand Down Expand Up @@ -295,6 +330,7 @@ int ESP_NOW_Class::availableForWrite() {

size_t ESP_NOW_Class::write(const uint8_t *data, size_t len) {
if (!_esp_now_has_begun) {
log_e("ESP-NOW not initialized. Please call begin() first to send data.");
return 0;
}
if (len > max_data_len) {
Expand Down Expand Up @@ -336,7 +372,7 @@ ESP_NOW_Class ESP_NOW;
*
*/

ESP_NOW_Peer::ESP_NOW_Peer(const uint8_t *mac_addr, uint8_t channel, wifi_interface_t iface, const uint8_t *lmk) {
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) {
added = false;
if (mac_addr) {
memcpy(mac, mac_addr, 6);
Expand All @@ -347,6 +383,11 @@ ESP_NOW_Peer::ESP_NOW_Peer(const uint8_t *mac_addr, uint8_t channel, wifi_interf
if (encrypt) {
memcpy(key, lmk, 16);
}
if (rate_config) {
rate = *rate_config;
} else {
rate = DEFAULT_ESPNOW_RATE_CONFIG;
}
}

bool ESP_NOW_Peer::add() {
Expand All @@ -356,7 +397,8 @@ bool ESP_NOW_Peer::add() {
if (added) {
return true;
}
if (_esp_now_add_peer(mac, chan, ifc, encrypt ? key : nullptr, this) != ESP_OK) {
if (_esp_now_add_peer(mac, chan, ifc, encrypt ? key : nullptr, &rate, this) != ESP_OK) {
log_e("Failed to add peer " MACSTR, MAC2STR(mac));
return false;
}
log_v("Peer added - " MACSTR, MAC2STR(mac));
Expand All @@ -371,12 +413,15 @@ bool ESP_NOW_Peer::remove() {
if (!added) {
return true;
}
log_v("Peer removed - " MACSTR, MAC2STR(mac));
log_i("Removing peer - " MACSTR, MAC2STR(mac));
esp_err_t err = _esp_now_del_peer(mac);
if (err == ESP_OK) {
added = false;
log_i("Peer removed - " MACSTR, MAC2STR(mac));
return true;
}

log_e("Failed to remove peer " MACSTR, MAC2STR(mac));
return false;
}

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

Expand Down Expand Up @@ -416,6 +463,38 @@ bool ESP_NOW_Peer::setInterface(wifi_interface_t iface) {
return _esp_now_modify_peer(mac, chan, ifc, encrypt ? key : nullptr) == ESP_OK;
}

/**
* @brief Set the rate configuration for the peer.
*
* @param rate_config Pointer to the rate configuration to set. Nullptr to reset to default rate configuration.
* @return true if the rate configuration was set successfully, false otherwise.
*/
bool ESP_NOW_Peer::setRate(const esp_now_rate_config_t *rate_config) {
if (added && _esp_now_has_begun) {
log_e("Peer already added and ESP-NOW is already running. Cannot set rate configuration.");
log_e("Please call setRate() before adding the peer or before starting ESP-NOW.");
return false;
}

if (rate_config == nullptr) {
log_i("Resetting rate configuration to default.");
rate = DEFAULT_ESPNOW_RATE_CONFIG;
} else {
rate = *rate_config;
}

return true;
}

/**
* @brief Get the rate configuration for the peer.
*
* @return esp_now_rate_config_t The rate configuration for the peer.
*/
esp_now_rate_config_t ESP_NOW_Peer::getRate() const {
return rate;
}

bool ESP_NOW_Peer::isEncrypted() const {
return encrypt;
}
Expand Down
20 changes: 19 additions & 1 deletion libraries/ESP_NOW/src/ESP32_NOW.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
#include "esp32-hal-log.h"
#include "esp_mac.h"

// clang-format off
#define DEFAULT_ESPNOW_RATE_CONFIG { \
.phymode = WIFI_PHY_MODE_11G, \
.rate = WIFI_PHY_RATE_1M_L, \
.ersu = false, \
.dcm = false \
}
// clang-format on

class ESP_NOW_Peer; //forward declaration for friend function

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

int availableForWrite();

// You can directly send data to all peers without broadcasting using ESP_NOW.write(data, len)
size_t write(const uint8_t *data, size_t len);
size_t write(uint8_t data) {
return write(&data, 1);
Expand All @@ -47,6 +58,7 @@ class ESP_NOW_Peer {
uint8_t mac[6];
uint8_t chan;
wifi_interface_t ifc;
esp_now_rate_config_t rate;
bool encrypt;
uint8_t key[16];

Expand All @@ -56,7 +68,10 @@ class ESP_NOW_Peer {
bool remove();
size_t send(const uint8_t *data, int len);

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_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
);

public:
virtual ~ESP_NOW_Peer() {}
Expand All @@ -70,6 +85,9 @@ class ESP_NOW_Peer {
wifi_interface_t getInterface() const;
bool setInterface(wifi_interface_t iface);

bool setRate(const esp_now_rate_config_t *rate_config);
esp_now_rate_config_t getRate() const;

bool isEncrypted() const;
bool setKey(const uint8_t *lmk);

Expand Down
Loading