Add encryption via ESP-NOW
This commit is contained in:
+86
-35
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user