Ready for NVS and Auth
This commit is contained in:
135
include/BLE.cpp
135
include/BLE.cpp
@@ -2,15 +2,15 @@
|
|||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
#include "WiFi.hpp"
|
#include "WiFi.hpp"
|
||||||
|
|
||||||
bool flag_scan_requested = false;
|
std::atomic<bool> flag_scan_requested{false};
|
||||||
|
std::atomic<bool> credsGiven{false};
|
||||||
|
std::mutex dataMutex;
|
||||||
|
|
||||||
std::string tempSSID = "";
|
wifi_auth_mode_t auth;
|
||||||
std::string tempPassword = "";
|
static std::string SSID = "";
|
||||||
bool SSIDGiven = false;
|
static std::string TOKEN = "";
|
||||||
bool passGiven = false;
|
static std::string PASS = "";
|
||||||
|
static std::string UNAME = "";
|
||||||
std::string token = "";
|
|
||||||
bool tokenGiven = false;
|
|
||||||
|
|
||||||
// Global pointers to characteristics for notification support
|
// Global pointers to characteristics for notification support
|
||||||
NimBLECharacteristic* ssidListChar = nullptr;
|
NimBLECharacteristic* ssidListChar = nullptr;
|
||||||
@@ -42,26 +42,13 @@ NimBLEAdvertising* initBLE() {
|
|||||||
);
|
);
|
||||||
ssidListChar->createDescriptor("2902"); // Add BLE2902 descriptor for notifications
|
ssidListChar->createDescriptor("2902"); // Add BLE2902 descriptor for notifications
|
||||||
|
|
||||||
// 0x0001 - SSID (WRITE)
|
// 0x0001 - Credentials JSON (WRITE) - Replaces separate SSID/Password/Token
|
||||||
NimBLECharacteristic *ssidChar = pService->createCharacteristic(
|
// Expected JSON format: {"ssid":"network","password":"pass","token":"optional"}
|
||||||
|
NimBLECharacteristic *credsChar = pService->createCharacteristic(
|
||||||
"0001",
|
"0001",
|
||||||
NIMBLE_PROPERTY::WRITE
|
NIMBLE_PROPERTY::WRITE
|
||||||
);
|
);
|
||||||
ssidChar->setCallbacks(charCallbacks);
|
credsChar->setCallbacks(charCallbacks);
|
||||||
|
|
||||||
// 0x0002 - Password (WRITE)
|
|
||||||
NimBLECharacteristic *passChar = pService->createCharacteristic(
|
|
||||||
"0002",
|
|
||||||
NIMBLE_PROPERTY::WRITE
|
|
||||||
);
|
|
||||||
passChar->setCallbacks(charCallbacks);
|
|
||||||
|
|
||||||
// 0x0003 - Token (WRITE)
|
|
||||||
NimBLECharacteristic *tokenChar = pService->createCharacteristic(
|
|
||||||
"0003",
|
|
||||||
NIMBLE_PROPERTY::WRITE
|
|
||||||
);
|
|
||||||
tokenChar->setCallbacks(charCallbacks);
|
|
||||||
|
|
||||||
// 0x0004 - SSID Refresh (WRITE)
|
// 0x0004 - SSID Refresh (WRITE)
|
||||||
NimBLECharacteristic *ssidRefreshChar = pService->createCharacteristic(
|
NimBLECharacteristic *ssidRefreshChar = pService->createCharacteristic(
|
||||||
@@ -93,10 +80,106 @@ NimBLEAdvertising* initBLE() {
|
|||||||
return pAdvertising;
|
return pAdvertising;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BLEtick(NimBLEAdvertising* pAdvertising) {
|
bool BLEtick(NimBLEAdvertising* pAdvertising) {
|
||||||
if(flag_scan_requested) {
|
if(flag_scan_requested) {
|
||||||
flag_scan_requested = false;
|
flag_scan_requested = false;
|
||||||
printf("Scanning WiFi...\n");
|
printf("Scanning WiFi...\n");
|
||||||
scanAndUpdateSSIDList();
|
scanAndUpdateSSIDList();
|
||||||
}
|
}
|
||||||
|
else if (credsGiven) {
|
||||||
|
credsGiven = false;
|
||||||
|
std::string tmpSSID;
|
||||||
|
std::string tmpUNAME;
|
||||||
|
std::string tmpPASS;
|
||||||
|
wifi_auth_mode_t tmpAUTH;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(dataMutex);
|
||||||
|
tmpSSID = SSID;
|
||||||
|
tmpUNAME = UNAME;
|
||||||
|
tmpPASS = PASS;
|
||||||
|
tmpAUTH = auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wifiConnect;
|
||||||
|
if (tmpAUTH == WIFI_AUTH_WPA2_ENTERPRISE || tmpAUTH == WIFI_AUTH_WPA3_ENTERPRISE)
|
||||||
|
wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpUNAME.c_str(), tmpPASS.c_str(), tmpAUTH);
|
||||||
|
else wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpPASS.c_str(), tmpAUTH);
|
||||||
|
if (!wifiConnect) return false;
|
||||||
|
|
||||||
|
// save wifi credentials here
|
||||||
|
// Authenticate with server here
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo) {
|
||||||
|
std::string val = pChar->getValue();
|
||||||
|
std::string uuidStr = pChar->getUUID().toString();
|
||||||
|
|
||||||
|
printf("onWrite called! UUID: %s, Value length: %d\n", uuidStr.c_str(), val.length());
|
||||||
|
|
||||||
|
// Check which characteristic was written to
|
||||||
|
if (uuidStr.find("0001") != std::string::npos) {
|
||||||
|
// Credentials JSON characteristic
|
||||||
|
if (val.length() > 0) {
|
||||||
|
printf("Received JSON: %s\n", val.c_str());
|
||||||
|
|
||||||
|
// Parse JSON using cJSON
|
||||||
|
cJSON *root = cJSON_Parse(val.c_str());
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON *ssid = cJSON_GetObjectItem(root, "ssid");
|
||||||
|
cJSON *password = cJSON_GetObjectItem(root, "password");
|
||||||
|
cJSON *token = cJSON_GetObjectItem(root, "token");
|
||||||
|
cJSON *authType = cJSON_GetObjectItem(root, "auth");
|
||||||
|
cJSON *uname = cJSON_GetObjectItem(root, "uname");
|
||||||
|
|
||||||
|
bool enterprise = false;
|
||||||
|
bool open = false;
|
||||||
|
bool error = false;
|
||||||
|
if (cJSON_IsNumber(authType)) {
|
||||||
|
enterprise = authType->valueint == WIFI_AUTH_WPA2_ENTERPRISE ||
|
||||||
|
authType->valueint == WIFI_AUTH_WPA3_ENTERPRISE;
|
||||||
|
open = authType->valueint == WIFI_AUTH_OPEN;
|
||||||
|
error = authType->valueint < 0 || authType->valueint >= WIFI_AUTH_MAX;
|
||||||
|
}
|
||||||
|
else error = true;
|
||||||
|
if (error) {
|
||||||
|
printf("ERROR: Invalid Auth mode passed in with JSON.\n");
|
||||||
|
credsGiven = false;
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ssidPresent = cJSON_IsString(ssid) && ssid->valuestring != NULL;
|
||||||
|
bool passPresent = cJSON_IsString(password) && password->valuestring != NULL;
|
||||||
|
bool unamePresent = cJSON_IsString(uname) && uname->valuestring != NULL;
|
||||||
|
bool tokenPresent = cJSON_IsString(token) && token->valuestring != NULL;
|
||||||
|
bool tempCredsGiven = tokenPresent && ssidPresent && (passPresent || open) &&
|
||||||
|
(unamePresent || !enterprise);
|
||||||
|
|
||||||
|
if (tempCredsGiven) {
|
||||||
|
printf("Received credentials, will attempt connection\n");
|
||||||
|
std::lock_guard<std::mutex> lock(dataMutex);
|
||||||
|
|
||||||
|
auth = (wifi_auth_mode_t)(authType->valueint);
|
||||||
|
SSID = ssid->valuestring;
|
||||||
|
TOKEN = token->valuestring;
|
||||||
|
PASS = passPresent ? password->valuestring : "";
|
||||||
|
UNAME = unamePresent ? uname->valuestring : "";
|
||||||
|
credsGiven = tempCredsGiven; // update the global flag.
|
||||||
|
}
|
||||||
|
else printf("ERROR: Did not receive necessary credentials.\n");
|
||||||
|
cJSON_Delete(root);
|
||||||
|
} else {
|
||||||
|
printf("Failed to parse JSON\n");
|
||||||
|
credsGiven = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (uuidStr.find("0004") != std::string::npos) {
|
||||||
|
// Refresh characteristic
|
||||||
|
printf("Refresh Requested\n");
|
||||||
|
flag_scan_requested = true;
|
||||||
|
}
|
||||||
|
else printf("Unknown UUID: %s\n", uuidStr.c_str());
|
||||||
|
}
|
||||||
@@ -2,16 +2,11 @@
|
|||||||
#define BLE_H
|
#define BLE_H
|
||||||
|
|
||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
|
#include "cJSON.h"
|
||||||
extern bool flag_scan_requested;
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
extern std::string tempSSID;
|
#include <string>
|
||||||
extern std::string tempPassword;
|
#include "esp_wifi_types.h"
|
||||||
extern bool SSIDGiven;
|
|
||||||
extern bool passGiven;
|
|
||||||
|
|
||||||
extern std::string token;
|
|
||||||
extern bool tokenGiven;
|
|
||||||
|
|
||||||
// Global pointers to characteristics for notification support
|
// Global pointers to characteristics for notification support
|
||||||
extern NimBLECharacteristic* ssidListChar;
|
extern NimBLECharacteristic* ssidListChar;
|
||||||
@@ -29,49 +24,10 @@ class MyServerCallbacks : public NimBLEServerCallbacks {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class MyCharCallbacks : public NimBLECharacteristicCallbacks {
|
class MyCharCallbacks : public NimBLECharacteristicCallbacks {
|
||||||
void onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo) {
|
void onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo);
|
||||||
std::string val = pChar->getValue();
|
|
||||||
std::string uuidStr = pChar->getUUID().toString();
|
|
||||||
|
|
||||||
printf("onWrite called! UUID: %s, Value length: %d\n", uuidStr.c_str(), val.length());
|
|
||||||
|
|
||||||
// Check which characteristic was written to
|
|
||||||
if (uuidStr.find("0001") != std::string::npos) {
|
|
||||||
// SSID characteristic
|
|
||||||
if (val.length() > 0) {
|
|
||||||
printf("Received SSID: %s\n", val.c_str());
|
|
||||||
tempSSID = val;
|
|
||||||
SSIDGiven = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (uuidStr.find("0002") != std::string::npos) {
|
|
||||||
// Password characteristic
|
|
||||||
if (val.length() > 0) {
|
|
||||||
printf("Received Password: %s\n", val.c_str());
|
|
||||||
passGiven = true;
|
|
||||||
tempPassword = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (uuidStr.find("0003") != std::string::npos) {
|
|
||||||
// Token characteristic
|
|
||||||
if (val.length() > 0) {
|
|
||||||
printf("Received Token: %s\n", val.c_str());
|
|
||||||
tokenGiven = true;
|
|
||||||
token = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (uuidStr.find("0004") != std::string::npos) {
|
|
||||||
// Refresh characteristic
|
|
||||||
printf("Refresh Requested\n");
|
|
||||||
flag_scan_requested = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("Unknown UUID: %s\n", uuidStr.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NimBLEAdvertising* initBLE();
|
NimBLEAdvertising* initBLE();
|
||||||
void BLEtick(NimBLEAdvertising* pAdvertising);
|
bool BLEtick(NimBLEAdvertising* pAdvertising);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -58,6 +58,7 @@ void WiFi::event_handler(void* arg, esp_event_base_t event_base,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WiFi::init() {
|
void WiFi::init() {
|
||||||
|
s_wifi_event_group = xEventGroupCreate();
|
||||||
// 1. Init Network Interface
|
// 1. Init Network Interface
|
||||||
ESP_ERROR_CHECK(esp_netif_init());
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
@@ -105,53 +106,46 @@ std::string WiFi::getIP() {
|
|||||||
return std::string(buf);
|
return std::string(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFi::attemptConnect(char *SSID, char *PW, wifi_auth_mode_t authMode) {
|
bool WiFi::attemptConnect(const std::string ssid, const std::string password,
|
||||||
|
const wifi_auth_mode_t authMode) {
|
||||||
|
esp_wifi_sta_enterprise_disable();
|
||||||
|
esp_wifi_disconnect();
|
||||||
|
|
||||||
wifi_config_t wifi_config = {};
|
wifi_config_t wifi_config = {};
|
||||||
strncpy((char*)wifi_config.sta.ssid, SSID, sizeof(wifi_config.sta.ssid));
|
snprintf((char*)wifi_config.sta.ssid, sizeof(wifi_config.sta.ssid), "%s", ssid.c_str());
|
||||||
strncpy((char*)wifi_config.sta.password, PW, sizeof(wifi_config.sta.password));
|
snprintf((char*)wifi_config.sta.password, sizeof(wifi_config.sta.password), "%s", password.c_str());
|
||||||
|
|
||||||
wifi_config.sta.threshold.authmode = authMode;
|
wifi_config.sta.threshold.authmode = authMode;
|
||||||
wifi_config.sta.pmf_cfg.capable = true;
|
wifi_config.sta.pmf_cfg.capable = true;
|
||||||
wifi_config.sta.pmf_cfg.required = false;
|
wifi_config.sta.pmf_cfg.required = false;
|
||||||
|
|
||||||
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
|
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
|
||||||
|
|
||||||
return awaitConnected();
|
return awaitConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFi::attemptConnect(char *SSID, char *username, char *PW, wifi_auth_mode_t authMode) {
|
bool WiFi::attemptConnect(const std::string ssid, const std::string uname,
|
||||||
std::string ssid = SSID;
|
const std::string password, const wifi_auth_mode_t authMode) {
|
||||||
std::string uname = username;
|
esp_wifi_disconnect();
|
||||||
std::string password = PW;
|
|
||||||
// 1. Auto-generate the Identity
|
// 1. Auto-generate the Identity
|
||||||
std::string identity = "anonymous";
|
std::string identity = "anonymous";
|
||||||
|
|
||||||
// Check if the username is an email (contains '@')
|
|
||||||
size_t atPos = uname.find('@');
|
size_t atPos = uname.find('@');
|
||||||
if (atPos != std::string::npos) {
|
if (atPos != std::string::npos) identity += uname.substr(atPos);
|
||||||
// Append the domain from the real username
|
|
||||||
// Example: "user@gmail.com" -> "anonymous@gmail.com"
|
|
||||||
identity += uname.substr(atPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Real User: %s\n", uname.c_str());
|
printf("Real User: %s\n", uname.c_str());
|
||||||
printf("Outer ID : %s (Privacy Safe)\n", identity.c_str());
|
printf("Outer ID : %s (Privacy Safe)\n", identity.c_str());
|
||||||
|
|
||||||
// 2. Clear & Config
|
|
||||||
esp_wifi_disconnect();
|
|
||||||
|
|
||||||
wifi_config_t wifi_config = {};
|
wifi_config_t wifi_config = {};
|
||||||
strncpy((char*)wifi_config.sta.ssid, ssid.c_str(), sizeof(wifi_config.sta.ssid));
|
snprintf((char*)wifi_config.sta.ssid, sizeof(wifi_config.sta.ssid), "%s", ssid.c_str());
|
||||||
wifi_config.sta.threshold.authmode = authMode;
|
wifi_config.sta.threshold.authmode = authMode;
|
||||||
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||||
|
|
||||||
// 3. Set the calculated identity (using new ESP-IDF v5.x API)
|
// 3. Set the calculated identity (using new ESP-IDF v5.x API)
|
||||||
|
esp_wifi_sta_enterprise_enable();
|
||||||
esp_eap_client_set_identity((uint8_t *)identity.c_str(), identity.length());
|
esp_eap_client_set_identity((uint8_t *)identity.c_str(), identity.length());
|
||||||
esp_eap_client_set_username((uint8_t *)uname.c_str(), uname.length());
|
esp_eap_client_set_username((uint8_t *)uname.c_str(), uname.length());
|
||||||
esp_eap_client_set_password((uint8_t *)password.c_str(), password.length());
|
esp_eap_client_set_password((uint8_t *)password.c_str(), password.length());
|
||||||
|
|
||||||
esp_wifi_sta_enterprise_enable();
|
|
||||||
|
|
||||||
return awaitConnected();
|
return awaitConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,13 @@
|
|||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
extern WiFi bmWiFi;
|
|
||||||
|
|
||||||
class WiFi {
|
class WiFi {
|
||||||
public:
|
public:
|
||||||
static void init();
|
static void init();
|
||||||
static bool attemptConnect(char *SSID, char *PW, wifi_auth_mode_t authMode);
|
static bool attemptConnect(const std::string ssid, const std::string password,
|
||||||
static bool attemptConnect(char *SSID, char *username, char *PW,
|
const wifi_auth_mode_t authMode);
|
||||||
wifi_auth_mode_t authMode);
|
static bool attemptConnect(const std::string ssid, const std::string uname,
|
||||||
|
const std::string password, const wifi_auth_mode_t authMode);
|
||||||
private:
|
private:
|
||||||
static bool authFailed;
|
static bool authFailed;
|
||||||
static bool awaitConnected();
|
static bool awaitConnected();
|
||||||
@@ -25,6 +24,8 @@ class WiFi {
|
|||||||
static std::string getIP();
|
static std::string getIP();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern WiFi bmWiFi;
|
||||||
|
|
||||||
void scanAndUpdateSSIDList();
|
void scanAndUpdateSSIDList();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user