#include <esp_now.h>
#include <WiFi.h>

// 1. Set the PMK and LMK keys to "match" the sender's side by every byte.
const uint8_t PMK_KEY[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
const uint8_t LMK_KEY[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};

// 2. Enter the MAC address of the "sender" side so that the system accepts unicast decoding.
uint8_t senderMacAddress[] = {0x00, 0x70, 0x07, 0xa3, 0x78, 0x78}; 

//Data receiving structure (must match the data structure of the sending side)
typedef struct struct_message {
    char a[32];
    int b;
} struct_message;

struct_message myData;
//esp_now_peer_info_t peerInfo;

// A callback function that automatically executes when data is received.
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  // Copy the received data and place it into our structure variable.
 memcpy(&myData, incomingData, sizeof(myData));
  
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("Char: ");
  Serial.println(myData.a);
  Serial.print("Int: ");
  Serial.println(myData.b);
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);

  // Print your MAC address to the Serial Monitor (to be used in the transmitting code).
  Serial.print("Receiver MAC Address: ");
  Serial.println(WiFi.macAddress());

  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }



 
  // Set up PMK primary Master key.
  esp_now_set_pmk(PMK_KEY);

  // The sender registers as a peer to receive encrypted data.
  esp_now_peer_info_t peerInfo;
   memset(&peerInfo, 0, sizeof(peerInfo)); // <--- Clean up junk data.
  memcpy(peerInfo.peer_addr, senderMacAddress, 6);
  peerInfo.channel = 0; 
  
  // Enter the LMK (local Master key) and set the encryption system to true, the same as the sending side.
  memcpy(peerInfo.lmk, LMK_KEY, 16);
  peerInfo.encrypt = true; 

  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add sender as peer");
    return;
  }

 // Register the function so it's ready to execute when it receives data.
  esp_now_register_recv_cb((esp_now_recv_cb_t)OnDataRecv);
}

void loop() {
 // The receiving side can leave the loop empty. The callback system will activate automatically when a message arrives.
}
