I have been searching for a while for an answer to my question.
so my question is:
is there a way to change the MAC address of the peer the sender is sending to?
let me explain why I want this and maybe this will clarify my question.
I have code that reads a string (in mine case a mac address) from serial monitor and copies that into EEPROM.
when the esp32 reboots retrieve this mac address from EEPROM and store it in broadcastAddress. so the esp32 could later send to that mac address. this and all works without any issue.
i use esp_now_add_peer() to add the peer when a New MAC address is received and verified.
here is the real question does the old MAC address get replaced? or is it still stored?
is there a function like: esp_now_change_peer_mac()?
Code: Select all
#include <esp_now.h>
#include <WiFi.h>
#include <EEPROM.h>
const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;
esp_now_peer_info_t peerInfo;
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//<B4:E6:2D:FB:21:31> an example Mac address for testing.
void sendData(uint8_t data);
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("Last Packet Send Status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
delay(3000); // wait for a bit
if (!EEPROM.begin(18)) {
Serial.println("failed to initialise EEPROM");
delay(1000000);
}
Serial.print("updated broadcastAddress from EEPROM: ");
EEPROM.get(0, broadcastAddress);//Update the mac address from EEPROM
for (byte cnt = 0; cnt < sizeof(broadcastAddress); cnt++)
{
Serial.print(broadcastAddress[cnt], HEX);
Serial.print(" ");
}
Serial.println();
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
} else Serial.println("Succesfully initializing ESP-NOW");
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = true;
// Add peer and test if the peer is active if so WE ARE IN BUSINESS
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
Serial.print("Sending a test... ");
sendData(random(0,255));
}
void loop() {
recvWithStartEndMarkers(); //look for when a new message is recieved
if (newData == true){
bool rv = newMacToBroadcastAddress();// is the newly received message a MAC address? if so do some tests to see if the Recieved mac is valid. if so store it in eeprom and add a new peer.
if (rv == false){
Serial.println("An error occured while processing the received MAC address");
}
else{
Serial.print("updated broadcastAddress from EEPROM: ");
EEPROM.get(0, broadcastAddress);
for (byte cnt = 0; cnt < sizeof(broadcastAddress); cnt++){
Serial.print(broadcastAddress[cnt], HEX);
Serial.print(" ");
}
Serial.println();
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
// // Add peer and test if the peer is active if so WE ARE IN BUSINESS
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");return;
} else{ Serial.println("Added a ESPNow peer"); sendData(random(0,255));}
}
}
}
void sendData(uint8_t data) {
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &data, sizeof(data));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
}
void recvWithStartEndMarkers()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
/*
function: Process received mac address and store in EEPROM
Returns: true on success else false
*/
bool newMacToBroadcastAddress()
{
// array to store received and converted MAC address before saving to EEPROM
byte eepromMac[sizeof(broadcastAddress)];
// index where to write next byte in eepromMac array
byte idx = 0;
// tokeniser and converter
char *token;
char *ptr;
const char s[2] = ":";
if (newData == true) {
newData = false;
Serial.print("I received this: '");
Serial.print(receivedChars);
Serial.println("'");
// check the length
if (strlen(receivedChars) != 17) {
Serial.println("Expected 17 characters for MAC address");
return false;
}
/* parse data */
token = strtok(receivedChars, s);
while ( token != NULL ){
Serial.print("Token: '");
Serial.print(token);
Serial.println("'");
// check if there were more MAC bytes than needed; basically redundant
if (idx >= sizeof(broadcastAddress)) {
Serial.println("Too many tokens");
return false;
}
// token should be 2 bytes
if (strlen(token) != 2) {
Serial.println("Expected 2 characters for Mac byte, are there '-' or ' ' placed? instead please use ':'");
return false;
}
// check if values in token are hexadecimal
for (byte cnt = 0; cnt < strlen(token); cnt++) {
if (isHexadecimalDigit(token[cnt]) == false) {
Serial.println("Expected a hexadecimal Mac byte");
return false;
}
}
// convert token
byte b = strtoul(token, &ptr, 16);
// the two tests below are basically redundant but demonstrate how ptr can be used to check the result of the conversion
if (ptr == token) {
Serial.println("Expected a hexadecimal Mac byte");
return false;
}
if (*ptr != '\0') {
Serial.println("Still characters available");
return false;
}
eepromMac[idx] = b;
Serial.print(idx); Serial.print(" > ");
Serial.println(b, HEX);
idx++;
token = strtok(NULL, s);
}
Serial.println("writing to EEPROM ");
EEPROM.put(0, eepromMac);
EEPROM.commit();
delay(100);
}
return true;
}