532 lines
19 KiB
C++
532 lines
19 KiB
C++
#include "QuickEspNow.h"
|
|
|
|
#ifdef ESP32
|
|
|
|
QuickEspNow quickEspNow;
|
|
|
|
constexpr auto PEERLIST_TAG = "PEERLIST";
|
|
|
|
|
|
bool QuickEspNow::begin (uint8_t channel, uint32_t wifi_interface, bool synchronousSend) {
|
|
|
|
wifi_second_chan_t ch2 = WIFI_SECOND_CHAN_NONE;
|
|
this->synchronousSend = synchronousSend;
|
|
|
|
DEBUG_DBG (QESPNOW_TAG, "Channel: %d, Interface: %d", channel, wifi_interface);
|
|
// Set the wifi interface
|
|
switch (wifi_interface) {
|
|
case WIFI_IF_STA:
|
|
wifi_if = WIFI_IF_STA;
|
|
break;
|
|
case WIFI_IF_AP:
|
|
wifi_if = WIFI_IF_AP;
|
|
break;
|
|
default:
|
|
DEBUG_ERROR (QESPNOW_TAG, "Unknown wifi interface");
|
|
return false;
|
|
break;
|
|
}
|
|
|
|
// check channel
|
|
if (channel != CURRENT_WIFI_CHANNEL && (channel < MIN_WIFI_CHANNEL || channel > MAX_WIFI_CHANNEL)) {
|
|
DEBUG_ERROR (QESPNOW_TAG, "Invalid wifi channel %d", channel);
|
|
return false;
|
|
}
|
|
|
|
// use current channel
|
|
if (channel == CURRENT_WIFI_CHANNEL) {
|
|
uint8_t ch;
|
|
esp_wifi_get_channel (&ch, &ch2);
|
|
channel = ch;
|
|
DEBUG_DBG (QESPNOW_TAG, "Current channel: %d : %d", channel, ch2);
|
|
followWiFiChannel = true;
|
|
}
|
|
setChannel (channel, ch2);
|
|
|
|
DEBUG_INFO (QESPNOW_TAG, ARDUHAL_LOG_COLOR (ARDUHAL_LOG_COLOR_RED) "Starting ESP-NOW in in channel %u interface %s", channel, wifi_if == WIFI_IF_STA ? "STA" : "AP");
|
|
|
|
this->channel = channel;
|
|
|
|
return initComms ();
|
|
}
|
|
|
|
void QuickEspNow::stop () {
|
|
DEBUG_INFO (QESPNOW_TAG, "-------------> ESP-NOW STOP");
|
|
if (espnowTxTask) {
|
|
vTaskDelete (espnowTxTask);
|
|
espnowTxTask = nullptr;
|
|
}
|
|
if (espnowRxTask) {
|
|
vTaskDelete (espnowRxTask);
|
|
espnowRxTask = nullptr;
|
|
}
|
|
esp_now_unregister_recv_cb ();
|
|
esp_now_unregister_send_cb ();
|
|
esp_now_deinit ();
|
|
followWiFiChannel = false;
|
|
}
|
|
|
|
bool QuickEspNow::readyToSendData () {
|
|
return uxQueueMessagesWaiting (tx_queue) < queueSize;
|
|
}
|
|
|
|
bool QuickEspNow::setChannel (uint8_t channel, wifi_second_chan_t ch2) {
|
|
|
|
if (followWiFiChannel) {
|
|
DEBUG_WARN(QESPNOW_TAG, "Cannot set channel while following WiFi channel");
|
|
return false;
|
|
}
|
|
|
|
esp_err_t err_ok;
|
|
if ((err_ok = esp_wifi_set_promiscuous (true))) {
|
|
DEBUG_ERROR (QESPNOW_TAG, "Error setting promiscuous mode: %s", esp_err_to_name (err_ok));
|
|
return false;
|
|
}
|
|
if ((err_ok = esp_wifi_set_channel (channel, ch2))) { // This is needed even in STA mode. If not done and using IDF > 4.0, the ESP-NOW will not work.
|
|
DEBUG_DBG (QESPNOW_TAG, "Error setting wifi channel: %d - %s", err_ok, esp_err_to_name (err_ok));
|
|
return false;
|
|
}
|
|
if ((err_ok = esp_wifi_set_promiscuous (false))) {
|
|
DEBUG_ERROR (QESPNOW_TAG, "Error setting promiscuous mode off: %s", esp_err_to_name (err_ok));
|
|
return false;
|
|
}
|
|
|
|
this->channel = channel;
|
|
|
|
return true;
|
|
}
|
|
|
|
comms_send_error_t QuickEspNow::send (const uint8_t* dstAddress, const uint8_t* payload, size_t payload_len) {
|
|
comms_tx_queue_item_t message;
|
|
|
|
if (!dstAddress || !payload || !payload_len) {
|
|
DEBUG_WARN (QESPNOW_TAG, "Parameters error");
|
|
return COMMS_SEND_PAYLOAD_LENGTH_ERROR;
|
|
}
|
|
|
|
if (payload_len > ESP_NOW_MAX_DATA_LEN) {
|
|
DEBUG_WARN (QESPNOW_TAG, "Length error. %d", payload_len);
|
|
return COMMS_SEND_PAYLOAD_LENGTH_ERROR;
|
|
}
|
|
|
|
if (uxQueueMessagesWaiting (tx_queue) >= queueSize) {
|
|
// comms_tx_queue_item_t tempBuffer;
|
|
// xQueueReceive (tx_queue, &tempBuffer, 0);
|
|
#ifdef MEAS_TPUT
|
|
//txDataDropped += tempBuffer.payload_len;
|
|
#endif // MEAS_TPUT
|
|
//DEBUG_DBG (QESPNOW_TAG, "Message dropped");
|
|
return COMMS_SEND_QUEUE_FULL_ERROR;
|
|
}
|
|
memcpy (message.dstAddress, dstAddress, ESP_NOW_ETH_ALEN);
|
|
message.payload_len = payload_len;
|
|
memcpy (message.payload, payload, payload_len);
|
|
|
|
if (xQueueSend (tx_queue, &message, pdMS_TO_TICKS (10))) {
|
|
#ifdef MEAS_TPUT
|
|
txDataSent += message.payload_len;
|
|
#endif // MEAS_TPUT
|
|
DEBUG_DBG (QESPNOW_TAG, "--------- %d Comms messages queued. Len: %d", uxQueueMessagesWaiting (tx_queue), payload_len);
|
|
DEBUG_VERBOSE (QESPNOW_TAG, "--------- Ready to send is %s", readyToSend ? "true" : "false");
|
|
DEBUG_VERBOSE (QESPNOW_TAG, "--------- SyncronousSend is %s", synchronousSend ? "true" : "false");
|
|
if (synchronousSend) {
|
|
waitingForConfirmation = true;
|
|
DEBUG_INFO (QESPNOW_TAG, "--------- Waiting for send confirmation");
|
|
while (waitingForConfirmation) {
|
|
taskYIELD ();
|
|
}
|
|
DEBUG_INFO (QESPNOW_TAG, "--------- Confirmation is %s", sentStatus == ESP_NOW_SEND_SUCCESS ? "true" : "false");
|
|
return (sentStatus == ESP_NOW_SEND_SUCCESS) ? COMMS_SEND_OK : COMMS_SEND_CONFIRM_ERROR;
|
|
}
|
|
return COMMS_SEND_OK;
|
|
} else {
|
|
DEBUG_WARN (QESPNOW_TAG, "Error queuing Comms message to " MACSTR, MAC2STR (dstAddress));
|
|
return COMMS_SEND_MSG_ENQUEUE_ERROR;
|
|
}
|
|
}
|
|
|
|
void QuickEspNow::onDataRcvd (comms_hal_rcvd_data dataRcvd) {
|
|
this->dataRcvd = dataRcvd;
|
|
}
|
|
|
|
#ifdef MEAS_TPUT
|
|
void QuickEspNow::calculateDataTP () {
|
|
time_t measTime = (millis () - lastDataTPMeas);
|
|
lastDataTPMeas = millis ();
|
|
|
|
if (txDataSent > 0) {
|
|
txDataTP = txDataSent * 1000 / measTime;
|
|
//DEBUG_WARN("Meas time: %d, Data sent: %d, Data TP: %f", measTime, txDataSent, txDataTP);
|
|
txDroppedDataRatio = (float)txDataDropped / (float)txDataSent;
|
|
//DEBUG_WARN("Data dropped: %d, Drop ratio: %f", txDataDropped, txDroppedDataRatio);
|
|
txDataSent = 0;
|
|
} else {
|
|
txDataTP = 0;
|
|
txDroppedDataRatio = 0;
|
|
}
|
|
if (rxDataReceived > 0) {
|
|
rxDataTP = rxDataReceived * 1000 / measTime;
|
|
//DEBUG_WARN("Meas time: %d, Data received: %d, Data TP: %f", measTime, rxDataReceived, rxDataTP);
|
|
rxDataReceived = 0;
|
|
} else {
|
|
rxDataTP = 0;
|
|
}
|
|
txDataDropped = 0;
|
|
}
|
|
|
|
void QuickEspNow::tp_timer_cb (void* param) {
|
|
quickEspNow.calculateDataTP ();
|
|
DEBUG_WARN (QESPNOW_TAG, "TxData TP: %.3f kbps, Drop Ratio: %.2f %%, RxDataTP: %.3f kbps",
|
|
quickEspNow.txDataTP * 8 / 1000,
|
|
quickEspNow.txDroppedDataRatio * 100,
|
|
quickEspNow.rxDataTP * 8 / 1000);
|
|
}
|
|
|
|
#endif // MEAS_TPUT
|
|
|
|
void QuickEspNow::onDataSent (comms_hal_sent_data sentResult) {
|
|
this->sentResult = sentResult;
|
|
}
|
|
|
|
int32_t QuickEspNow::sendEspNowMessage (comms_tx_queue_item_t* message) {
|
|
int32_t error;
|
|
|
|
if (!message) {
|
|
DEBUG_WARN (QESPNOW_TAG, "Message is null");
|
|
return -1;
|
|
}
|
|
if (!(message->payload_len) || (message->payload_len > ESP_NOW_MAX_DATA_LEN)) {
|
|
DEBUG_WARN (QESPNOW_TAG, "Message length error");
|
|
return -1;
|
|
}
|
|
|
|
DEBUG_VERBOSE (QESPNOW_TAG, "ESP-NOW message to " MACSTR, MAC2STR (message->dstAddress));
|
|
|
|
|
|
addPeer (message->dstAddress);
|
|
DEBUG_DBG (QESPNOW_TAG, "Peer added " MACSTR, MAC2STR (message->dstAddress));
|
|
readyToSend = false;
|
|
DEBUG_VERBOSE (QESPNOW_TAG, "-------------- Ready to send: false");
|
|
|
|
error = esp_now_send (message->dstAddress, message->payload, message->payload_len);
|
|
DEBUG_DBG (QESPNOW_TAG, "esp now send result = %s", esp_err_to_name (error));
|
|
if (error != ESP_OK) {
|
|
DEBUG_WARN (QESPNOW_TAG, "Error sending message: %s", esp_err_to_name (error));
|
|
}
|
|
// if (error == ESP_OK) {
|
|
// txDataSent += message->payload_len;
|
|
// }
|
|
if (error == ESP_ERR_ESPNOW_NO_MEM) {
|
|
delay (2);
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
void QuickEspNow::espnowTxHandle () {
|
|
if (readyToSend) {
|
|
//DEBUG_WARN ("Process queue: Elements: %d", tx_queue.size ());
|
|
comms_tx_queue_item_t message;
|
|
while (xQueueReceive (tx_queue, &message, pdMS_TO_TICKS (1000))) {
|
|
DEBUG_DBG (QESPNOW_TAG, "Comms message got from queue. %d left", uxQueueMessagesWaiting (tx_queue));
|
|
while (!readyToSend && !synchronousSend) {
|
|
delay (0);
|
|
}
|
|
if (!sendEspNowMessage (&message)) {
|
|
DEBUG_DBG (QESPNOW_TAG, "Message to " MACSTR " sent. Len: %u", MAC2STR (message.dstAddress), message.payload_len);
|
|
} else {
|
|
DEBUG_WARN (QESPNOW_TAG, "Error sending message to " MACSTR ". Len: %u", MAC2STR (message.dstAddress), message.payload_len);
|
|
}
|
|
//message.payload_len = 0;
|
|
DEBUG_DBG (QESPNOW_TAG, "Comms message pop. Queue size %d", uxQueueMessagesWaiting (tx_queue));
|
|
}
|
|
|
|
} else {
|
|
DEBUG_DBG (QESPNOW_TAG, "Not ready to send");
|
|
}
|
|
}
|
|
|
|
void QuickEspNow::enableTransmit (bool enable) {
|
|
DEBUG_DBG (QESPNOW_TAG, "Send esp-now task %s", enable ? "enabled" : "disabled");
|
|
if (enable) {
|
|
if (espnowTxTask_cb) {
|
|
vTaskResume (espnowTxTask);
|
|
vTaskResume (espnowRxTask);
|
|
}
|
|
} else {
|
|
if (espnowTxTask_cb) {
|
|
vTaskSuspend (espnowTxTask);
|
|
vTaskSuspend (espnowRxTask);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool QuickEspNow::addPeer (const uint8_t* peer_addr) {
|
|
esp_now_peer_info_t peer;
|
|
esp_err_t error = ESP_OK;
|
|
|
|
if (peer_list.get_peer_number () >= ESP_NOW_MAX_TOTAL_PEER_NUM) {
|
|
DEBUG_VERBOSE (QESPNOW_TAG, "Peer list full. Deleting older");
|
|
if (uint8_t* deleted_mac = peer_list.delete_peer ()) {
|
|
esp_now_del_peer (deleted_mac);
|
|
} else {
|
|
DEBUG_ERROR (QESPNOW_TAG, "Error deleting peer");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (peer_list.peer_exists (peer_addr)) {
|
|
DEBUG_VERBOSE (QESPNOW_TAG, "Peer already exists");
|
|
ESP_ERROR_CHECK (esp_now_get_peer (peer_addr, &peer));
|
|
|
|
uint8_t currentChannel = peer.channel;
|
|
DEBUG_DBG (QESPNOW_TAG, "Peer " MACSTR " is using channel %d", MAC2STR (peer_addr), currentChannel);
|
|
if (currentChannel != this->channel) {
|
|
DEBUG_DBG (QESPNOW_TAG, "Peer channel has to change from %d to %d", currentChannel, this->channel);
|
|
ESP_ERROR_CHECK_WITHOUT_ABORT (esp_now_get_peer (peer_addr, &peer));
|
|
peer.channel = this->channel;
|
|
ESP_ERROR_CHECK_WITHOUT_ABORT (esp_now_mod_peer (&peer));
|
|
DEBUG_ERROR (QESPNOW_TAG, "Peer channel changed to %d", this->channel);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
memcpy (peer.peer_addr, peer_addr, ESP_NOW_ETH_ALEN);
|
|
uint8_t ch;
|
|
wifi_second_chan_t secondCh;
|
|
esp_wifi_get_channel (&ch, &secondCh);
|
|
peer.channel = ch;
|
|
peer.ifidx = wifi_if;
|
|
peer.encrypt = false;
|
|
error = esp_now_add_peer (&peer);
|
|
if (!error) {
|
|
DEBUG_DBG (QESPNOW_TAG, "Peer added");
|
|
peer_list.add_peer (peer_addr);
|
|
} else {
|
|
DEBUG_ERROR (QESPNOW_TAG, "Error adding peer: %s", esp_err_to_name (error));
|
|
return false;
|
|
}
|
|
DEBUG_DBG (QESPNOW_TAG, "Peer " MACSTR " added on channel %u. Result 0x%X %s", MAC2STR (peer_addr), ch, error, esp_err_to_name (error));
|
|
return error == ESP_OK;
|
|
}
|
|
|
|
bool QuickEspNow::initComms () {
|
|
if (esp_now_init ()) {
|
|
DEBUG_ERROR (QESPNOW_TAG, "Failed to init ESP-NOW");
|
|
// ESP.restart ();
|
|
// delay (1);
|
|
return false;
|
|
}
|
|
|
|
esp_now_register_recv_cb (rx_cb);
|
|
esp_now_register_send_cb (reinterpret_cast<esp_now_send_cb_t>(tx_cb));
|
|
|
|
int txQueueSize = queueSize;
|
|
if (synchronousSend) {
|
|
txQueueSize = 1;
|
|
}
|
|
|
|
tx_queue = xQueueCreate (txQueueSize, sizeof (comms_tx_queue_item_t));
|
|
xTaskCreateUniversal (espnowTxTask_cb, "espnow_loop", 8 * 1024, NULL, 1, &espnowTxTask, CONFIG_ARDUINO_RUNNING_CORE);
|
|
|
|
rx_queue = xQueueCreate (queueSize, sizeof (comms_rx_queue_item_t));
|
|
xTaskCreateUniversal (espnowRxTask_cb, "receive_handle", 4 * 1024, NULL, 1, &espnowRxTask, CONFIG_ARDUINO_RUNNING_CORE);
|
|
|
|
#ifdef MEAS_TPUT
|
|
dataTPTimer = xTimerCreate ("espnow_tp_timer", pdMS_TO_TICKS (MEAS_TP_EVERY_MS), pdTRUE, NULL, tp_timer_cb);
|
|
xTimerStart (dataTPTimer, 0);
|
|
#endif // MEAS_TPUT
|
|
|
|
return true;
|
|
}
|
|
|
|
void QuickEspNow::espnowTxTask_cb (void* param) {
|
|
for (;;) {
|
|
quickEspNow.espnowTxHandle ();
|
|
}
|
|
|
|
}
|
|
|
|
void QuickEspNow::espnowRxHandle () {
|
|
comms_rx_queue_item_t rxMessage;
|
|
|
|
if (xQueueReceive (rx_queue, &rxMessage, portMAX_DELAY)) {
|
|
DEBUG_DBG (QESPNOW_TAG, "Comms message got from queue. %d left", uxQueueMessagesWaiting (rx_queue));
|
|
DEBUG_VERBOSE (QESPNOW_TAG, "Received message from " MACSTR " Len: %u", MAC2STR (rxMessage.srcAddress), rxMessage.payload_len);
|
|
DEBUG_VERBOSE (QESPNOW_TAG, "Message: %.*s", rxMessage.payload_len, rxMessage.payload);
|
|
|
|
if (quickEspNow.dataRcvd) {
|
|
bool broadcast = !memcmp (rxMessage.dstAddress, ESPNOW_BROADCAST_ADDRESS, ESP_NOW_ETH_ALEN);
|
|
quickEspNow.dataRcvd (rxMessage.srcAddress, rxMessage.payload, rxMessage.payload_len, rxMessage.rssi, broadcast); // rssi should be in dBm but it has added almost 100 dB. Do not know why
|
|
}
|
|
} else {
|
|
DEBUG_DBG (QESPNOW_TAG, "No message in queue");
|
|
}
|
|
|
|
}
|
|
|
|
void QuickEspNow::espnowRxTask_cb (void* param) {
|
|
for (;;) {
|
|
quickEspNow.espnowRxHandle ();
|
|
}
|
|
}
|
|
|
|
void QuickEspNow::rx_cb(const esp_now_recv_info_t* esp_now_info, const uint8_t* data, int len) {
|
|
espnow_frame_format_t* espnow_data = (espnow_frame_format_t*)(data - sizeof(espnow_frame_format_t));
|
|
wifi_promiscuous_pkt_t* promiscuous_pkt = (wifi_promiscuous_pkt_t*)(data - sizeof(wifi_pkt_rx_ctrl_t) - sizeof(espnow_frame_format_t));
|
|
wifi_pkt_rx_ctrl_t* rx_ctrl = &promiscuous_pkt->rx_ctrl;
|
|
const uint8_t* mac_addr = esp_now_info->src_addr;
|
|
comms_rx_queue_item_t message;
|
|
|
|
DEBUG_DBG(QESPNOW_TAG, "Received message with RSSI %d from " MACSTR " Len: %u", rx_ctrl->rssi, MAC2STR(esp_now_info->src_addr), len);
|
|
|
|
memcpy(message.srcAddress, mac_addr, ESP_NOW_ETH_ALEN);
|
|
memcpy(message.payload, data, len);
|
|
message.payload_len = len;
|
|
message.rssi = rx_ctrl->rssi;
|
|
memcpy(message.dstAddress, espnow_data->destination_address, ESP_NOW_ETH_ALEN);
|
|
|
|
if (uxQueueMessagesWaiting(quickEspNow.rx_queue) >= quickEspNow.queueSize) {
|
|
comms_rx_queue_item_t tempBuffer;
|
|
xQueueReceive(quickEspNow.rx_queue, &tempBuffer, 0);
|
|
DEBUG_DBG(QESPNOW_TAG, "Rx Message dropped");
|
|
}
|
|
#ifdef MEAS_TPUT
|
|
quickEspNow.rxDataReceived += len;
|
|
#endif // MEAS_TPUT
|
|
|
|
if (!xQueueSend(quickEspNow.rx_queue, &message, pdMS_TO_TICKS(100))) {
|
|
DEBUG_WARN(QESPNOW_TAG, "Error sending message to queue");
|
|
}
|
|
}
|
|
|
|
void QuickEspNow::tx_cb (uint8_t* mac_addr, uint8_t status) {
|
|
quickEspNow.readyToSend = true;
|
|
quickEspNow.sentStatus = status;
|
|
quickEspNow.waitingForConfirmation = false;
|
|
DEBUG_DBG (QESPNOW_TAG, "-------------- Ready to send: true. Status: %d", status);
|
|
if (quickEspNow.sentResult) {
|
|
quickEspNow.sentResult (mac_addr, status);
|
|
}
|
|
}
|
|
|
|
uint8_t PeerListClass::get_peer_number () {
|
|
return peer_list.peer_number;
|
|
}
|
|
|
|
bool PeerListClass::peer_exists (const uint8_t* mac) {
|
|
for (uint8_t i = 0; i < ESP_NOW_MAX_TOTAL_PEER_NUM; i++) {
|
|
if (memcmp (peer_list.peer[i].mac, mac, ESP_NOW_ETH_ALEN) == 0) {
|
|
if (peer_list.peer[i].active) {
|
|
peer_list.peer[i].last_msg = millis ();
|
|
DEBUG_VERBOSE (PEERLIST_TAG, "Peer " MACSTR " found. Updated last_msg", MAC2STR (mac));
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
peer_t* PeerListClass::get_peer (const uint8_t* mac) {
|
|
for (uint8_t i = 0; i < ESP_NOW_MAX_TOTAL_PEER_NUM; i++) {
|
|
if (memcmp (peer_list.peer[i].mac, mac, ESP_NOW_ETH_ALEN) == 0) {
|
|
if (peer_list.peer[i].active) {
|
|
DEBUG_VERBOSE (PEERLIST_TAG, "Peer " MACSTR " found", MAC2STR (mac));
|
|
return &(peer_list.peer[i]);
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
bool PeerListClass::update_peer_use (const uint8_t* mac) {
|
|
peer_t* peer = get_peer (mac);
|
|
if (peer) {
|
|
peer->last_msg = millis ();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool PeerListClass::add_peer (const uint8_t* mac) {
|
|
if (int i = peer_exists (mac)) {
|
|
DEBUG_VERBOSE (PEERLIST_TAG, "Peer " MACSTR " already exists", MAC2STR (mac));
|
|
return false;
|
|
}
|
|
if (peer_list.peer_number >= ESP_NOW_MAX_TOTAL_PEER_NUM) {
|
|
//DEBUG_VERBOSE (PEERLIST_TAG, "Peer list full. Deleting older");
|
|
#ifndef UNIT_TEST
|
|
DEBUG_ERROR (PEERLIST_TAG, "Should never happen");
|
|
#endif
|
|
return false;
|
|
// delete_peer (); // Delete should happen in higher level
|
|
}
|
|
|
|
for (uint8_t i = 0; i < ESP_NOW_MAX_TOTAL_PEER_NUM; i++) {
|
|
if (!peer_list.peer[i].active) {
|
|
memcpy (peer_list.peer[i].mac, mac, ESP_NOW_ETH_ALEN);
|
|
peer_list.peer[i].active = true;
|
|
peer_list.peer[i].last_msg = millis ();
|
|
peer_list.peer_number++;
|
|
DEBUG_VERBOSE (PEERLIST_TAG, "Peer " MACSTR " added. Total peers = %d", MAC2STR (mac), peer_list.peer_number);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool PeerListClass::delete_peer (const uint8_t* mac) {
|
|
peer_t* peer = get_peer (mac);
|
|
if (peer) {
|
|
peer->active = false;
|
|
peer_list.peer_number--;
|
|
DEBUG_VERBOSE (PEERLIST_TAG, "Peer " MACSTR " deleted. Total peers = %d", MAC2STR (mac), peer_list.peer_number);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Delete peer with older message
|
|
uint8_t* PeerListClass::delete_peer () {
|
|
uint32_t oldest_msg = 0;
|
|
int oldest_index = -1;
|
|
uint8_t* mac = NULL;
|
|
for (int i = 0; i < ESP_NOW_MAX_TOTAL_PEER_NUM; i++) {
|
|
if (peer_list.peer[i].active) {
|
|
if (peer_list.peer[i].last_msg < oldest_msg || oldest_msg == 0) {
|
|
oldest_msg = peer_list.peer[i].last_msg;
|
|
oldest_index = i;
|
|
DEBUG_VERBOSE (PEERLIST_TAG, "Peer " MACSTR " is %d ms old. Deleting", MAC2STR (peer_list.peer[i].mac), oldest_msg);
|
|
}
|
|
}
|
|
}
|
|
if (oldest_index != -1) {
|
|
peer_list.peer[oldest_index].active = false;
|
|
peer_list.peer_number--;
|
|
mac = peer_list.peer[oldest_index].mac;
|
|
DEBUG_VERBOSE (PEERLIST_TAG, "Peer " MACSTR " deleted. Last message %d ms ago. Total peers = %d", MAC2STR (mac), millis () - peer_list.peer[oldest_index].last_msg, peer_list.peer_number);
|
|
}
|
|
return mac;
|
|
}
|
|
|
|
bool QuickEspNow::setWiFiBandwidth (wifi_interface_t iface, wifi_bandwidth_t bw) {
|
|
esp_err_t err_ok;
|
|
if ((err_ok = esp_wifi_set_bandwidth (iface, bw))) {
|
|
DEBUG_ERROR (QESPNOW_TAG, "Error setting wifi bandwidth: %s", esp_err_to_name (err_ok));
|
|
}
|
|
return !err_ok;
|
|
}
|
|
|
|
#ifdef UNIT_TEST
|
|
void PeerListClass::dump_peer_list () {
|
|
Serial.printf ("Number of peers %d\n", peer_list.peer_number);
|
|
for (int i = 0; i < ESP_NOW_MAX_TOTAL_PEER_NUM; i++) {
|
|
if (peer_list.peer[i].active) {
|
|
Serial.printf ("Peer " MACSTR " is %d ms old\n", MAC2STR (peer_list.peer[i].mac), millis () - peer_list.peer[i].last_msg);
|
|
}
|
|
}
|
|
}
|
|
#endif // UNIT_TEST
|
|
#endif // ESP32
|