Newer
Older
#include "ESPNow.hpp"
static const char *TAG = "ESPNOW";
uint8_t BROADCAST_MAC[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
esp_now_peer_info_t hostInfo;
Preferences preferences;
bool msg_recv = false;
bool was_msg_received() {
if (msg_recv) {
msg_recv = false;
return true;
}
return false;
void get_host_mac(uint8_t *destination) {
RtcMemory::getInstance().get_host_mac(destination);
esp_err_t add_host_to_peers(response received) {
esp_now_peer_info_t host;
memset(&host, 0, sizeof(host));
memcpy(host.peer_addr, received.mac, sizeof(received.mac));
host.encrypt = false;
host.channel = 0;
return esp_now_add_peer(&host);
void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) {
ESP_LOGE(TAG, "Message sent to %02X:%02X:%02X:%02X:%02X:%02X", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
mac_addr[4], mac_addr[5]);
void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) {
// is msg host -> yes -> set bool
// assume host change not happening, rare event
// => on host change, broadcast
// ESP_LOGD(TAG, "Message received");
// time this
auto start = millis();
response received_msg;
memcpy(&received_msg, incomingData,
sizeof(received_msg)); // TODO: check for valid mac
// all the esp32 macs so far use the same first 3(?) bytes so maybe use that
// First three bytes of MACs are always vendor specific. But vendors have a range of them.
// all Espressif registered MAC starting bytes: https://maclookup.app/vendors/espressif-inc
// you can also set your own MAC https://randomnerdtutorials.com/get-change-esp32-esp8266-mac-address-arduino/
switch (received_msg.type) {
case hostChange: {
ESP_LOGI(TAG, "hostChange received");
Time::getInstance().setTime(received_msg.time);
// delete old host
preferences.begin("config", false);
if (preferences.isKey("host")) {
ESP_LOGI(TAG, "removing old host");
uint8_t old[6];
preferences.end();
get_host_mac(old); // maybe problem here, re-opening preferences
esp_now_del_peer(old);
}
// add new host
preferences.begin("config", false);
if (preferences.putBytes("host", received_msg.mac, sizeof(received_msg.mac)) > 0) {
ESP_LOGI(TAG, "Host MAC address saved to flash %02X:%02X:%02X:%02X:%02X:%02X", received_msg.mac[0],
received_msg.mac[1], received_msg.mac[2], received_msg.mac[3], received_msg.mac[4],
received_msg.mac[5]);
} else {
ESP_LOGI(TAG, "Couldn't save Host Mac to flash");
}
preferences.end();
add_host_to_peers(received_msg);
}
case dataAck: {
// ESP_LOGI(TAG, "dataAck received.");
Time::getInstance().setTime(
received_msg.time); // see https://www.esp32.com/viewtopic.php?t=9965, maybe this needs an offset
// ESP_LOGI(TAG, "Timestamp received: %ld", Time::getInstance().getEpochSeconds());
preferences.begin("config", false);
if (!preferences.isKey("host")) {
if (preferences.putBytes("host", received_msg.mac, sizeof(received_msg.mac)) > 0) {
// ESP_LOGI(TAG, "host MAC address saved to flash %02X:%02X:%02X:%02X:%02X:%02X",
// received_msg.host[0],
// received_msg.host[1],received_msg.host[2],received_msg.host[3],received_msg.host[4],received_msg.host[5]);
// }
// add host to peers
add_host_to_peers(received_msg);
}
}
preferences.end();
// delay(50);
msg_recv = true;
}
default: {
break;
}
auto end = millis();
esp_err_t espnow_setup() {
esp_err_t result;
WiFi.mode(WIFI_STA);
result = esp_now_init();
if (result != ESP_OK) {
// initialization failed
ESP_LOGE(TAG, "ESPNow setup failed");
return result;
}
get_host_mac(hostInfo.peer_addr); // check if there is a host saved in flash mem, broadcast otherwise
hostInfo.channel = 0;
// TODO: PMK is used to encrypt LMK with the AES-128 algorithm. Call esp_now_set_pmk() to set PMK. If PMK is not
// set, a default PMK will be used.
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html
hostInfo.encrypt = false;
esp_now_add_peer(&hostInfo);
esp_now_register_recv_cb(on_data_recv);
esp_now_register_send_cb(on_data_sent);
ESP_LOGI(TAG, "ESPNow started. MAC: %s", WiFi.macAddress().c_str());
return ESP_OK;