espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.02k stars 7.3k forks source link

ESP-NOW cannot clear old peers from peerlist. #7503

Open kapyaar opened 1 year ago

kapyaar commented 1 year ago

Board

ESP32 Dev Module

Device Description

ESP32 Dev Module.

Hardware Configuration

2 Dev boards AS-IS. One configured as Master, and the other as Slave. Master is waiting to hear from any slaves. When it does, it will send a response packet. MAC address of master is hard coded in slave code.

Version

v2.0.5

IDE Name

Arduino IDE 2.0.1 - nightly-20221014

Operating System

Windows 11

Flash frequency

80M

PSRAM enabled

no

Upload speed

921600

Description

Trying to clear a peer from peerlist, but does not seem to clear it. Here is what I am doing. I have a master that is waiting for slave to send some data. When it gets the data, it responds with something similar, and the slave gets that data. This part is working fine. See Serial output on the slave.

Cheeky Bastard Found:  
Sending: {"Srl":"9994588758","tm0":65,"hu0":45.85}, Length: 656 to C8:2B:96:A3:6D:C8
Send Status: Success

Last Packet Send Status:    Delivery Success

Recieved {'dvc':9,'tm0':167.36} //This piece of data is coming from the Master board.

Now, I want to clear this Master's info from the slave so that it does not send data to this master any more. What I have tried so far:

  1. Use an invalid MAC address for the master. Serial says it is picking the dummy MAC as Master. but the master gets the data regardless, sends response, and slave gets the response from Master as well.
peerCount: 1
Sending: {"Srl":"9994588758","tm0":65,"hu0":45.85}, Length: 656 to AB:AB:AB:AB:AB:AB
Send Status: Success

Last Packet Send Status:    Delivery Success

Recieved {'dvc':9,'tm0':167.36}
  1. I tried deIniting espnow. As per doc, it should clear all pear info. This will stop the sending for sure. Then try send data. See Serial info.
De-initialized ESP-NOW
E (99958) ESPNOW: esp now not init!
peerCount: 1
E (99959) ESPNOW: esp now not init!
Sending: {"Srl":"9994588758","tm0":65,"hu0":45.85}, Length: 656 to AB:AB:AB:AB:AB:AB
E (99969) ESPNOW: esp now not init!
Send Status: ESPNOW not Init.

So far, so good.

  1. Now, If I re-enable espnow, IT does say no peer found. This is correct because I have only enabled espnow, not added any peers.
initialized ESP-NOW 
peerCount: 0
Sending: {"Srl":"9994588758","tm0":65,"hu0":45.85}, Length: 656 to AB:AB:AB:AB:AB:AB
Send Status: Peer not found.

So far, so good.

  1. Alright, Now, IF I repower the board, there should be nothing in the peerlist, except for the dummy MAC that I add in setup(). But....
peerCount: 1
Sending: {"Srl":"9994588758","tm0":65,"hu0":45.85}, Length: 656 to AB:AB:AB:AB:AB:AB
Send Status: Success

Last Packet Send Status:    Delivery Success
Recieved {'dvc':9,'tm0':167.36}  //Data went all the way to Master, and master responded with this. 

Sketch

/*
  ESP-NOW Demo - Transmit
  esp-now-demo-xmit.ino
  Sends data to Responder

*/

// Include Libraries
#include <esp_now.h>
#include <esp_wifi.h>
#include <WiFi.h>
#include <ArduinoJson.h>

// MAC Address of responder - edit as required
uint8_t validBroadcastAddress[] = { 0xC8, 0x2B, 0x96, 0xA3, 0x6D, 0xC8 };    // I have a working esp-now device by this MAC.
uint8_t invalidBroadcastAddress[] = { 0xab, 0xab, 0xab, 0xab, 0xab, 0xab };  //dummy.
#define CONFIG_ESPNOW_CHANNEL 11

// Peer info
esp_now_peer_info_t peerDevice;

// Callback function called when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("\r\nLast Packet Send Status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

//recieved data will process here
void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len) {
  int pairingSuccess = 0;
  char *buff = (char *)incomingData;    //char buffer
  String recv_jsondata = String(buff);  //converting into STRING
  Serial.print("Recieved ");
  Serial.print(recv_jsondata);  //Complete JSON data will be printed here

  DynamicJsonDocument doc(1024);  // for data > 1KB
  DeserializationError error = deserializeJson(doc, recv_jsondata);

  if (!error) {
  }

  else {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }
}

void sendData() {

  StaticJsonDocument<256> doc;

  String jsondata = "";  //clearing String after data is being sent
  doc["Srl"] = "9994588758";
  doc["tm0"] = 65;
  doc["hu0"] = 45.85;

  serializeJson(doc, jsondata);  //Serilizing JSON

  //Checking to see how many peers exist.
  esp_now_peer_num_t num;
  esp_now_get_peer_num(&num);
  Serial.print("peerCount: ");
  Serial.println(num.total_num);

  if (esp_now_is_peer_exist(validBroadcastAddress)) Serial.println("Cheeky Bastard Found: ");
  for (int i = 0; i < 1; i++) {
    const uint8_t *peer_addr = peerDevice.peer_addr;
    if (i == 0) {  // send only for first slave
      Serial.print("Sending: ");
      Serial.print(jsondata);
      Serial.print(", Length: ");
      Serial.print(sizeof(jsondata) * jsondata.length());
      Serial.print(" to ");
      for (int j = 0; j < 6; j++) {
        Serial.print(peer_addr[j], HEX);
        if (j < 5) Serial.print(":");
      }
    }
    esp_err_t result = esp_now_send(peer_addr, (uint8_t *)jsondata.c_str(), jsondata.length());  //Sending "jsondata"
    Serial.print("Send Status: ");
    if (result == ESP_OK) {
      Serial.println("Success");
    } else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
      // How did we get so far!!
      Serial.println("ESPNOW not Init.");
    } else if (result == ESP_ERR_ESPNOW_ARG) {
      Serial.println("Invalid Argument");
    } else if (result == ESP_ERR_ESPNOW_INTERNAL) {
      Serial.println("Internal Error");
    } else if (result == ESP_ERR_ESPNOW_NO_MEM) {
      Serial.println("ESP_ERR_ESPNOW_NO_MEM");
    } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
      Serial.println("Peer not found.");
    } else {
      Serial.println("Not sure what happened");
    }
    delay(100);
  }  

  delay(100);
}
void enableESPNOW(){

  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
  }
  Serial.println("initialized ESP-NOW ");
}

void disableESPNOW(){

  // Sending Done. Don't need this peer any more. Remove it. 
  if (esp_now_del_peer(validBroadcastAddress) != ESP_OK) {
    Serial.println("Failed to remove peer");    
  }

  /* Going one step further. DeInitilize ESP-NOW. As per documentation on 
  https://docs.espressif.com/projects/esp-idf/en/release-v3.3/api-reference/network/esp_now.html

  When esp_now_deinit() is called, all of the information of paired devices will be deleted.

  Not only does this seem to be NOT the case, but after calling a deinit, If I initiate a sendData() without further esp_now_init(), 
  the send seems to be working. 
  */
  if (esp_now_deinit() != ESP_OK) {
    Serial.println("Error De-initializing ESP-NOW");
  }
  Serial.println("De-initialized ESP-NOW");
}

void setup() {

  // Set up Serial Monitor
  Serial.begin(115200);

  // Set ESP32 as a Wi-Fi Station
  WiFi.mode(WIFI_AP_STA);
  //Without the following three lines, slave does not transmit on channel 11. Gives the following error line.
  //E (20199) ESPNOW: Peer channel is not equal to the home channel, send fail

  esp_wifi_set_promiscuous(true);
  esp_wifi_set_channel(CONFIG_ESPNOW_CHANNEL, WIFI_SECOND_CHAN_NONE);
  esp_wifi_set_promiscuous(false);

  WiFi.printDiag(Serial);

  // Initilize ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  // Register send callback function
  esp_now_register_send_cb(OnDataSent);
  // Register receive callback function
  esp_now_register_recv_cb(OnDataRecv);

  // First, Register Valid peer
  /*
  memcpy(peerDevice.peer_addr, ValidbroadcastAddress, 6);
  peerDevice.channel = CONFIG_ESPNOW_CHANNEL;
  peerDevice.encrypt = false;

  deletePeer();
  */
  // Register peer
  memcpy(peerDevice.peer_addr, invalidBroadcastAddress, 6);
  peerDevice.channel = CONFIG_ESPNOW_CHANNEL;
  peerDevice.encrypt = false;

  // Add peer

  if (esp_now_add_peer(&peerDevice) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }
}

void loop() {

  while (Serial.available()) {
    char in=Serial.read();
    if(in=='d') disableESPNOW();
    else if(in=='e') enableESPNOW();
    else sendData();
  }
}

Debug Message

Included in description.

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

VojtechBartoska commented 1 year ago

Please help with triage @me-no-dev, thanks!