Add encryption via ESP-NOW

This commit is contained in:
Riyyi
2025-09-12 22:27:55 +02:00
parent 8f4823586f
commit 224f22f23d
10 changed files with 310 additions and 157 deletions
+86 -35
View File
@@ -1,67 +1,118 @@
#include <cstdint>
#include <Arduino.h>
#include <IPAddress.h>
#include <WiFi.h>
#include <esp_now.h>
#include <esp_wifi.h>
#include "connect.h"
#include "esp32-hal.h"
#include "secrets.h"
uint64_t start;
uint8_t client_mac[6] = CLIENT_MAC;
uint8_t server_mac[6] = SERVER_MAC;
uint64_t connect = 0;
uint64_t is_connecting = 0;
IPAddress host;
void timerStart()
{
start = millis();
}
uint64_t timerElapsed()
{
auto now = millis();
uint64_t elapsed = now - start;
return elapsed;
}
uint64_t ack = 0;
uint8_t ack_speed = 50;
// -----------------------------------------
void wifiSetupEncryption();
void timerStart(uint64_t* timer)
{
*timer = millis();
}
uint64_t timerElapsed(uint64_t* timer)
{
auto now = millis();
uint64_t elapsed = now - *timer;
return elapsed;
}
void wifiSetup()
{
WiFi.mode(WIFI_STA);
WiFi.setAutoReconnect(false);
WiFi.disconnect();
delay(100);
esp_wifi_set_channel(static_cast<uint8_t>(CHANNEL), WIFI_SECOND_CHAN_NONE);
wifiSetupEncryption();
}
void wifiConnect()
// -----------------------------------------
void onDataSent(const uint8_t* mac_addr, esp_now_send_status_t status)
{
if (WiFi.status() == WL_CONNECTED) {
if (is_connecting > 0) {
host = WiFi.gatewayIP();
Serial.println("Connected to AP!");
}
is_connecting = 0;
if (status != ESP_NOW_SEND_SUCCESS) {
return;
}
if (is_connecting == 0 || timerElapsed() > is_connecting * 1000) {
if (is_connecting == 0) {
is_connecting = 10; // start with a 10 second delay
}
else {
is_connecting *= 2; // exponential backoff
}
Serial.println("Receive ACK");
timerStart();
Serial.println("Connecting");
WiFi.begin(SSID, PASSWORD);
// Flash PWR LED while still receiving acknowledgments
if (timerElapsed(&ack) > ack_speed * 2) {
timerStart(&ack);
digitalWrite(POWER_LED_PIN, HIGH);
delay(ack_speed);
digitalWrite(POWER_LED_PIN, LOW);
}
}
IPAddress wifiHost()
void onDataRecv(const uint8_t* mac_addr, const uint8_t* data, int data_len)
{
return host;
Serial.print("Received: ");
Serial.write(data, data_len);
Serial.println();
auto msg = String((const char*)data, data_len);
if (msg == "power_released_ack") {
need_power_ack = false;
wait_power_ack = false;
}
if (msg == "reset_released_ack") {
need_reset_ack = false;
wait_reset_ack = false;
}
}
void wifiSetupEncryption()
{
esp_now_deinit();
if (esp_now_init() != ESP_OK) {
Serial.println("Failed to init ESP-NOW");
return;
}
if (esp_now_set_pmk((const uint8_t*)PMK) != ESP_OK) {
Serial.println("Failed to set PMK");
return;
}
auto peerInfo = esp_now_peer_info_t {
.channel = static_cast<uint8_t>(CHANNEL),
.encrypt = true,
};
memcpy(peerInfo.peer_addr, server_mac, 6);
memcpy(peerInfo.lmk, LMK, 16);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
esp_now_register_send_cb(onDataSent);
esp_now_register_recv_cb(onDataRecv);
Serial.println("Configured encryption!");
}
// https://docs.espressif.com/projects/arduino-esp32/en/latest/api/wifi.html
+15 -3
View File
@@ -1,5 +1,17 @@
#include "IPAddress.h"
#include <cstdint>
#define CHANNEL 11
#define POWER_LED_PIN 3
#define RESET_LED_PIN 1
extern bool need_power_ack;
extern bool need_reset_ack;
extern bool wait_power_ack;
extern bool wait_reset_ack;
extern uint8_t client_mac[6];
extern uint8_t server_mac[6];
void wifiSetup();
void wifiConnect();
IPAddress wifiHost();
+28 -50
View File
@@ -1,21 +1,19 @@
#include <Arduino.h>
#include <WiFiClient.h>
#include <esp_now.h>
#include "connect.h"
#define PORT 1234
#define POWER_BUTTON_PIN 10
#define RESET_BUTTON_PIN 2
#define POWER_LED_PIN 3
#define RESET_LED_PIN 1
WiFiClient client;
int previousPowerButtonState = HIGH;
int previousResetButtonState = HIGH;
void ack();
bool need_power_ack = false;
bool need_reset_ack = false;
bool wait_power_ack = false;
bool wait_reset_ack = false;
void setup()
{
@@ -28,19 +26,17 @@ void setup()
pinMode(POWER_LED_PIN, OUTPUT);
pinMode(RESET_LED_PIN, OUTPUT);
wifiSetup();
delay(3000);
Serial.println("Client booted!");
wifiSetup();
}
void loop()
{
delay(20); // used for button debounce
wifiConnect();
digitalWrite(POWER_LED_PIN, LOW);
// digitalWrite(POWER_LED_PIN, LOW);
digitalWrite(RESET_LED_PIN, LOW);
int powerButtonState = digitalRead(POWER_BUTTON_PIN);
@@ -50,9 +46,6 @@ void loop()
if (powerButtonState == LOW && resetButtonState == LOW) {
previousPowerButtonState = HIGH;
previousResetButtonState = HIGH;
if (client.connected()) {
client.stop();
}
return;
}
@@ -68,46 +61,31 @@ void loop()
Serial.println("Pressed " + button + " button!");
if (!client.connected() && !client.connect(wifiHost(), PORT)) {
Serial.println("Connection failed");
return;
}
client.print(button + "_pressed\n");
String msg = button + "_pressed";
esp_now_send(server_mac, (const uint8_t*)msg.c_str(), msg.length());
Serial.println("Sent " + button + " button press");
ack();
}
else {
if (!client.connected()) {
return;
}
need_power_ack = true;
need_reset_ack = true;
client.print("power_released\n");
wait_power_ack = false;
wait_reset_ack = false;
return;
}
if (need_power_ack && !wait_power_ack) {
String msg = "power_released";
esp_now_send(server_mac, (const uint8_t*)msg.c_str(), msg.length());
Serial.println("Sent power button release");
ack();
client.print("reset_released\n");
wait_power_ack = true;
}
if (need_reset_ack && !wait_reset_ack) {
String msg = "reset_released";
esp_now_send(server_mac, (const uint8_t*)msg.c_str(), msg.length());
Serial.println("Sent reset button release");
ack();
client.stop();
}
}
// -----------------------------------------
void ack()
{
while (client.connected()) {
if (client.available()) {
// Wait for acknowledgment from the receiver
String response = client.readStringUntil('\n');
if (response == "ACK") {
digitalWrite(POWER_LED_PIN, HIGH);
Serial.println("Received ACK");
return;
}
}
wait_reset_ack = true;
}
}
+5 -2
View File
@@ -1,4 +1,7 @@
#pragma once
#define SSID "EXAMPLE"
#define PASSWORD "12345678"
#define CLIENT_MAC { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
#define SERVER_MAC { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
#define PMK "MASTERKEY1234567" // ESP_NOW_KEY_LEN = 16
#define LMK "1234567890ABCDEF" // ESP_NOW_KEY_LEN = 16