robust handshake for SSID List, next check the confirmations
This commit is contained in:
BIN
Documentation/SSID List Communication Flow.png
Normal file
BIN
Documentation/SSID List Communication Flow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 304 KiB |
160
include/BLE.cpp
160
include/BLE.cpp
@@ -3,9 +3,14 @@
|
|||||||
#include "WiFi.hpp"
|
#include "WiFi.hpp"
|
||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include <mutex>
|
||||||
|
#include "bmHTTP.hpp"
|
||||||
|
|
||||||
std::atomic<bool> flag_scan_requested{false};
|
std::atomic<bool> flag_scan_requested{false};
|
||||||
std::atomic<bool> credsGiven{false};
|
std::atomic<bool> credsGiven{false};
|
||||||
|
std::atomic<bool> tokenGiven{false};
|
||||||
|
std::atomic<bool> isBLEClientConnected{false};
|
||||||
|
std::atomic<bool> scanBlock{false};
|
||||||
std::mutex dataMutex;
|
std::mutex dataMutex;
|
||||||
|
|
||||||
wifi_auth_mode_t auth;
|
wifi_auth_mode_t auth;
|
||||||
@@ -17,6 +22,10 @@ static std::string UNAME = "";
|
|||||||
// Global pointers to characteristics for notification support
|
// Global pointers to characteristics for notification support
|
||||||
NimBLECharacteristic* ssidListChar = nullptr;
|
NimBLECharacteristic* ssidListChar = nullptr;
|
||||||
NimBLECharacteristic* connectConfirmChar = nullptr;
|
NimBLECharacteristic* connectConfirmChar = nullptr;
|
||||||
|
NimBLECharacteristic* authConfirmChar = nullptr;
|
||||||
|
NimBLECharacteristic* credsChar = nullptr;
|
||||||
|
NimBLECharacteristic* tokenChar = nullptr;
|
||||||
|
NimBLECharacteristic* ssidRefreshChar = nullptr;
|
||||||
|
|
||||||
NimBLEAdvertising* initBLE() {
|
NimBLEAdvertising* initBLE() {
|
||||||
NimBLEDevice::init("BlindMaster-C6");
|
NimBLEDevice::init("BlindMaster-C6");
|
||||||
@@ -40,23 +49,37 @@ NimBLEAdvertising* initBLE() {
|
|||||||
// 0x0000 - SSID List (READ + NOTIFY)
|
// 0x0000 - SSID List (READ + NOTIFY)
|
||||||
ssidListChar = pService->createCharacteristic(
|
ssidListChar = pService->createCharacteristic(
|
||||||
"0000",
|
"0000",
|
||||||
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY
|
NIMBLE_PROPERTY::READ
|
||||||
);
|
);
|
||||||
ssidListChar->createDescriptor("2902"); // Add BLE2902 descriptor for notifications
|
ssidListChar->createDescriptor("2902"); // Add BLE2902 descriptor for notifications
|
||||||
|
|
||||||
// 0x0001 - Credentials JSON (WRITE) - Replaces separate SSID/Password/Token
|
// 0x0001 - Credentials JSON (WRITE) - Replaces separate SSID/Password/Uname
|
||||||
// Expected JSON format: {"ssid":"network","password":"pass","token":"optional"}
|
// Expected JSON format: {"ssid":"network","password":"pass"}
|
||||||
NimBLECharacteristic *credsChar = pService->createCharacteristic(
|
credsChar = pService->createCharacteristic(
|
||||||
"0001",
|
"0001",
|
||||||
NIMBLE_PROPERTY::WRITE
|
NIMBLE_PROPERTY::WRITE
|
||||||
);
|
);
|
||||||
credsChar->setCallbacks(charCallbacks);
|
credsChar->setCallbacks(charCallbacks);
|
||||||
|
|
||||||
// 0x0004 - SSID Refresh (WRITE)
|
// 0x0002 - Token (WRITE)
|
||||||
NimBLECharacteristic *ssidRefreshChar = pService->createCharacteristic(
|
tokenChar = pService->createCharacteristic(
|
||||||
"0004",
|
"0002",
|
||||||
NIMBLE_PROPERTY::WRITE
|
NIMBLE_PROPERTY::WRITE
|
||||||
);
|
);
|
||||||
|
tokenChar->setCallbacks(charCallbacks);
|
||||||
|
|
||||||
|
// 0x0003 - Auth Confirmation (READ + NOTIFY)
|
||||||
|
authConfirmChar = pService->createCharacteristic(
|
||||||
|
"0003",
|
||||||
|
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY
|
||||||
|
);
|
||||||
|
authConfirmChar->createDescriptor("2902"); // Add BLE2902 descriptor for notifications
|
||||||
|
|
||||||
|
// 0x0004 - SSID Refresh (WRITE)
|
||||||
|
ssidRefreshChar = pService->createCharacteristic(
|
||||||
|
"0004",
|
||||||
|
NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY
|
||||||
|
);
|
||||||
ssidRefreshChar->setCallbacks(charCallbacks);
|
ssidRefreshChar->setCallbacks(charCallbacks);
|
||||||
|
|
||||||
// 0x0005 - Connect Confirmation (READ + NOTIFY)
|
// 0x0005 - Connect Confirmation (READ + NOTIFY)
|
||||||
@@ -82,14 +105,28 @@ NimBLEAdvertising* initBLE() {
|
|||||||
return pAdvertising;
|
return pAdvertising;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notifyConnectionStatus(bool success) {
|
||||||
|
connectConfirmChar->setValue(success ? "Connected" : "Error");
|
||||||
|
connectConfirmChar->notify();
|
||||||
|
connectConfirmChar->setValue(""); // Clear value after notify
|
||||||
|
}
|
||||||
|
void notifyAuthStatus(bool success) {
|
||||||
|
authConfirmChar->setValue(success ? "Authenticated" : "Error");
|
||||||
|
authConfirmChar->notify();
|
||||||
|
authConfirmChar->setValue(""); // Clear value after notify
|
||||||
|
}
|
||||||
|
|
||||||
bool BLEtick(NimBLEAdvertising* pAdvertising) {
|
bool BLEtick(NimBLEAdvertising* pAdvertising) {
|
||||||
if(flag_scan_requested) {
|
if(flag_scan_requested) {
|
||||||
flag_scan_requested = false;
|
flag_scan_requested = false;
|
||||||
|
if (!scanBlock) {
|
||||||
|
scanBlock = true;
|
||||||
printf("Scanning WiFi...\n");
|
printf("Scanning WiFi...\n");
|
||||||
scanAndUpdateSSIDList();
|
scanAndUpdateSSIDList();
|
||||||
}
|
}
|
||||||
|
else printf("Duplicate scan request\n");
|
||||||
|
}
|
||||||
else if (credsGiven) {
|
else if (credsGiven) {
|
||||||
credsGiven = false;
|
|
||||||
std::string tmpSSID;
|
std::string tmpSSID;
|
||||||
std::string tmpUNAME;
|
std::string tmpUNAME;
|
||||||
std::string tmpPASS;
|
std::string tmpPASS;
|
||||||
@@ -100,18 +137,25 @@ bool BLEtick(NimBLEAdvertising* pAdvertising) {
|
|||||||
tmpUNAME = UNAME;
|
tmpUNAME = UNAME;
|
||||||
tmpPASS = PASS;
|
tmpPASS = PASS;
|
||||||
tmpAUTH = auth;
|
tmpAUTH = auth;
|
||||||
|
credsGiven = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wifiConnect;
|
bool wifiConnect;
|
||||||
if (tmpAUTH == WIFI_AUTH_WPA2_ENTERPRISE || tmpAUTH == WIFI_AUTH_WPA3_ENTERPRISE)
|
if (tmpAUTH == WIFI_AUTH_WPA2_ENTERPRISE || tmpAUTH == WIFI_AUTH_WPA3_ENTERPRISE)
|
||||||
wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpUNAME.c_str(), tmpPASS.c_str(), tmpAUTH);
|
wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpUNAME.c_str(), tmpPASS.c_str(), tmpAUTH);
|
||||||
else wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpPASS.c_str(), tmpAUTH);
|
else wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpPASS.c_str(), tmpAUTH);
|
||||||
if (!wifiConnect) return false;
|
if (!wifiConnect) {
|
||||||
|
// notify errored
|
||||||
|
notifyConnectionStatus(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
nvs_handle_t WiFiHandle;
|
nvs_handle_t WiFiHandle;
|
||||||
esp_err_t err = nvs_open(nvsWiFi, NVS_READWRITE, &WiFiHandle);
|
esp_err_t err = nvs_open(nvsWiFi, NVS_READWRITE, &WiFiHandle);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
printf("ERROR Saving Credentials\n");
|
printf("ERROR Saving Credentials\n");
|
||||||
|
// notify errored
|
||||||
|
notifyConnectionStatus(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -122,12 +166,85 @@ bool BLEtick(NimBLEAdvertising* pAdvertising) {
|
|||||||
if (err == ESP_OK) nvs_commit(WiFiHandle);
|
if (err == ESP_OK) nvs_commit(WiFiHandle);
|
||||||
nvs_close(WiFiHandle);
|
nvs_close(WiFiHandle);
|
||||||
}
|
}
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
// notify connected
|
||||||
|
notifyConnectionStatus(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// notify connected
|
||||||
|
notifyConnectionStatus(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tokenGiven) {
|
||||||
|
tokenGiven = false;
|
||||||
|
if (!bmWiFi.isConnected()) {
|
||||||
|
printf("ERROR: token given without WiFi connection\n");
|
||||||
|
notifyAuthStatus(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Authenticate with server here
|
// HTTP request to verify device with token
|
||||||
|
std::string tmpTOKEN;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(dataMutex);
|
||||||
|
tmpTOKEN = TOKEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON *responseRoot;
|
||||||
|
bool success = httpGET("verify_device", tmpTOKEN, responseRoot);
|
||||||
|
if (!success) return false;
|
||||||
|
success = false;
|
||||||
|
|
||||||
|
if (responseRoot != NULL) {
|
||||||
|
cJSON *tokenItem = cJSON_GetObjectItem(responseRoot, "token");
|
||||||
|
if (cJSON_IsString(tokenItem) && tokenItem->valuestring != NULL) {
|
||||||
|
printf("New token received: %s\n", tokenItem->valuestring);
|
||||||
|
|
||||||
|
// Save token to NVS
|
||||||
|
nvs_handle_t AuthHandle;
|
||||||
|
esp_err_t nvs_err = nvs_open(nvsAuth, NVS_READWRITE, &AuthHandle);
|
||||||
|
if (nvs_err == ESP_OK) {
|
||||||
|
nvs_err = nvs_set_str(AuthHandle, tokenTag, tokenItem->valuestring);
|
||||||
|
if (nvs_err == ESP_OK) {
|
||||||
|
nvs_commit(AuthHandle);
|
||||||
|
success = true;
|
||||||
|
webToken = tokenItem->valuestring;
|
||||||
|
}
|
||||||
|
else printf("ERROR: could not save webToken to NVS\n");
|
||||||
|
nvs_close(AuthHandle);
|
||||||
|
}
|
||||||
|
else printf("ERROR: Couldn't open NVS for auth token\n");
|
||||||
|
}
|
||||||
|
cJSON_Delete(responseRoot);
|
||||||
|
}
|
||||||
|
else printf("Failed to parse JSON response\n");
|
||||||
|
|
||||||
|
notifyAuthStatus(success);
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
esp_wifi_scan_stop();
|
||||||
|
scanBlock = false;
|
||||||
|
flag_scan_requested = false;
|
||||||
|
credsGiven = false;
|
||||||
|
tokenGiven = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) {
|
||||||
|
isBLEClientConnected = true;
|
||||||
|
printf("Client connected\n");
|
||||||
|
reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
void MyServerCallbacks::onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) {
|
||||||
|
isBLEClientConnected = false;
|
||||||
|
printf("Client disconnected - reason: %d\n", reason);
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo) {
|
void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo) {
|
||||||
std::string val = pChar->getValue();
|
std::string val = pChar->getValue();
|
||||||
std::string uuidStr = pChar->getUUID().toString();
|
std::string uuidStr = pChar->getUUID().toString();
|
||||||
@@ -135,7 +252,7 @@ void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connI
|
|||||||
printf("onWrite called! UUID: %s, Value length: %d\n", uuidStr.c_str(), val.length());
|
printf("onWrite called! UUID: %s, Value length: %d\n", uuidStr.c_str(), val.length());
|
||||||
|
|
||||||
// Check which characteristic was written to
|
// Check which characteristic was written to
|
||||||
if (uuidStr.find("0001") != std::string::npos) {
|
if (pChar == credsChar) {
|
||||||
// Credentials JSON characteristic
|
// Credentials JSON characteristic
|
||||||
if (val.length() > 0) {
|
if (val.length() > 0) {
|
||||||
printf("Received JSON: %s\n", val.c_str());
|
printf("Received JSON: %s\n", val.c_str());
|
||||||
@@ -145,7 +262,6 @@ void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connI
|
|||||||
if (root != NULL) {
|
if (root != NULL) {
|
||||||
cJSON *ssid = cJSON_GetObjectItem(root, "ssid");
|
cJSON *ssid = cJSON_GetObjectItem(root, "ssid");
|
||||||
cJSON *password = cJSON_GetObjectItem(root, "password");
|
cJSON *password = cJSON_GetObjectItem(root, "password");
|
||||||
cJSON *token = cJSON_GetObjectItem(root, "token");
|
|
||||||
cJSON *authType = cJSON_GetObjectItem(root, "auth");
|
cJSON *authType = cJSON_GetObjectItem(root, "auth");
|
||||||
cJSON *uname = cJSON_GetObjectItem(root, "uname");
|
cJSON *uname = cJSON_GetObjectItem(root, "uname");
|
||||||
|
|
||||||
@@ -169,8 +285,7 @@ void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connI
|
|||||||
bool ssidPresent = cJSON_IsString(ssid) && ssid->valuestring != NULL;
|
bool ssidPresent = cJSON_IsString(ssid) && ssid->valuestring != NULL;
|
||||||
bool passPresent = cJSON_IsString(password) && password->valuestring != NULL;
|
bool passPresent = cJSON_IsString(password) && password->valuestring != NULL;
|
||||||
bool unamePresent = cJSON_IsString(uname) && uname->valuestring != NULL;
|
bool unamePresent = cJSON_IsString(uname) && uname->valuestring != NULL;
|
||||||
bool tokenPresent = cJSON_IsString(token) && token->valuestring != NULL;
|
bool tempCredsGiven = ssidPresent && (passPresent || open) &&
|
||||||
bool tempCredsGiven = tokenPresent && ssidPresent && (passPresent || open) &&
|
|
||||||
(unamePresent || !enterprise);
|
(unamePresent || !enterprise);
|
||||||
|
|
||||||
if (tempCredsGiven) {
|
if (tempCredsGiven) {
|
||||||
@@ -179,7 +294,6 @@ void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connI
|
|||||||
|
|
||||||
auth = (wifi_auth_mode_t)(authType->valueint);
|
auth = (wifi_auth_mode_t)(authType->valueint);
|
||||||
SSID = ssid->valuestring;
|
SSID = ssid->valuestring;
|
||||||
TOKEN = token->valuestring;
|
|
||||||
PASS = passPresent ? password->valuestring : "";
|
PASS = passPresent ? password->valuestring : "";
|
||||||
UNAME = unamePresent ? uname->valuestring : "";
|
UNAME = unamePresent ? uname->valuestring : "";
|
||||||
credsGiven = tempCredsGiven; // update the global flag.
|
credsGiven = tempCredsGiven; // update the global flag.
|
||||||
@@ -192,10 +306,24 @@ void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (uuidStr.find("0004") != std::string::npos) {
|
else if (pChar == tokenChar) {
|
||||||
|
if (val.length() > 0) {
|
||||||
|
printf("Received Token: %s\n", val.c_str());
|
||||||
|
std::lock_guard<std::mutex> lock(dataMutex);
|
||||||
|
TOKEN = val;
|
||||||
|
tokenGiven = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pChar == ssidRefreshChar) {
|
||||||
|
if (val == "Start") {
|
||||||
// Refresh characteristic
|
// Refresh characteristic
|
||||||
printf("Refresh Requested\n");
|
printf("Refresh Requested\n");
|
||||||
flag_scan_requested = true;
|
flag_scan_requested = true;
|
||||||
}
|
}
|
||||||
|
else if (val == "Done") {
|
||||||
|
printf("Data read complete\n");
|
||||||
|
scanBlock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else printf("Unknown UUID: %s\n", uuidStr.c_str());
|
else printf("Unknown UUID: %s\n", uuidStr.c_str());
|
||||||
}
|
}
|
||||||
@@ -4,26 +4,21 @@
|
|||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "esp_wifi_types.h"
|
#include "esp_wifi_types.h"
|
||||||
|
|
||||||
// Global pointers to characteristics for notification support
|
// Global pointers to characteristics for notification support
|
||||||
extern NimBLECharacteristic* ssidListChar;
|
extern NimBLECharacteristic* ssidListChar;
|
||||||
extern NimBLECharacteristic* connectConfirmChar;
|
extern NimBLECharacteristic* ssidRefreshChar;
|
||||||
|
extern std::atomic<bool> isBLEClientConnected{false};
|
||||||
|
|
||||||
class MyServerCallbacks : public NimBLEServerCallbacks {
|
class MyServerCallbacks : public NimBLEServerCallbacks {
|
||||||
void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) {
|
void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo);
|
||||||
printf("Client connected\n");
|
void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason);
|
||||||
};
|
|
||||||
|
|
||||||
void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) {
|
|
||||||
printf("Client disconnected - reason: %d\n", reason);
|
|
||||||
// Advertising will restart automatically
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MyCharCallbacks : public NimBLECharacteristicCallbacks {
|
class MyCharCallbacks : public NimBLECharacteristicCallbacks {
|
||||||
|
void onRead(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo);
|
||||||
void onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo);
|
void onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "cJSON.h" // Native replacement for ArduinoJson
|
#include "cJSON.h" // Native replacement for ArduinoJson
|
||||||
#include "BLE.hpp"
|
#include "BLE.hpp"
|
||||||
|
|
||||||
bool WiFi::authFailed = false;
|
std::atomic<bool> WiFi::authFailed{false};
|
||||||
EventGroupHandle_t WiFi::s_wifi_event_group = NULL;
|
EventGroupHandle_t WiFi::s_wifi_event_group = NULL;
|
||||||
esp_netif_t* WiFi::netif = NULL;
|
esp_netif_t* WiFi::netif = NULL;
|
||||||
esp_event_handler_instance_t WiFi::instance_any_id = NULL;
|
esp_event_handler_instance_t WiFi::instance_any_id = NULL;
|
||||||
@@ -49,6 +49,13 @@ void WiFi::event_handler(void* arg, esp_event_base_t event_base,
|
|||||||
}
|
}
|
||||||
xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||||
}
|
}
|
||||||
|
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) {
|
||||||
|
// This is triggered when the scan finishes!
|
||||||
|
printf("Scan complete, processing results...\n");
|
||||||
|
|
||||||
|
// Call a function to process results and notify BLE
|
||||||
|
processScanResults();
|
||||||
|
}
|
||||||
// 3. We got an IP Address -> Success!
|
// 3. We got an IP Address -> Success!
|
||||||
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||||
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
|
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
|
||||||
@@ -62,7 +69,7 @@ void WiFi::init() {
|
|||||||
// 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());
|
||||||
esp_netif_create_default_wifi_sta();
|
netif = esp_netif_create_default_wifi_sta();
|
||||||
|
|
||||||
// 2. Init WiFi Driver
|
// 2. Init WiFi Driver
|
||||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
@@ -155,6 +162,11 @@ bool WiFi::awaitConnected() {
|
|||||||
|
|
||||||
uint8_t attempts = 0;
|
uint8_t attempts = 0;
|
||||||
while (!isConnected() && attempts < 20) {
|
while (!isConnected() && attempts < 20) {
|
||||||
|
if (!isBLEClientConnected) {
|
||||||
|
printf("BLE Disconnected: Aborting WiFi connection attempt.\n");
|
||||||
|
esp_wifi_disconnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (authFailed) {
|
if (authFailed) {
|
||||||
printf("SSID/Password was wrong! Aborting connection attempt.\n");
|
printf("SSID/Password was wrong! Aborting connection attempt.\n");
|
||||||
return false;
|
return false;
|
||||||
@@ -167,24 +179,29 @@ bool WiFi::awaitConnected() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------- non-class --------------
|
// ------------- non-class --------------
|
||||||
void scanAndUpdateSSIDList() {
|
void WiFi::scanAndUpdateSSIDList() {
|
||||||
printf("Starting WiFi Scan...\n");
|
printf("Starting WiFi Scan...\n");
|
||||||
|
|
||||||
// 1. Start Scan (Blocking Mode = true)
|
// 1. Start Scan (Blocking Mode = true)
|
||||||
// In blocking mode, this function waits here until scan is done (~2 seconds)
|
// In blocking mode, this function waits here until scan is done (~2 seconds)
|
||||||
|
esp_wifi_sta_enterprise_disable();
|
||||||
|
esp_wifi_disconnect();
|
||||||
|
|
||||||
wifi_scan_config_t scan_config = {
|
wifi_scan_config_t scan_config = {
|
||||||
.ssid = NULL,
|
.ssid = NULL,
|
||||||
.bssid = NULL,
|
.bssid = NULL,
|
||||||
.channel = 0,
|
.channel = 0,
|
||||||
.show_hidden = false
|
.show_hidden = false
|
||||||
};
|
};
|
||||||
esp_err_t err = esp_wifi_scan_start(&scan_config, true);
|
esp_err_t err = esp_wifi_scan_start(&scan_config, false);
|
||||||
|
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
printf("Scan failed!\n");
|
printf("Scan failed!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFi::processScanResults() {
|
||||||
// 2. Get the results
|
// 2. Get the results
|
||||||
uint16_t ap_count = 0;
|
uint16_t ap_count = 0;
|
||||||
esp_wifi_scan_get_ap_num(&ap_count);
|
esp_wifi_scan_get_ap_num(&ap_count);
|
||||||
@@ -215,11 +232,12 @@ void scanAndUpdateSSIDList() {
|
|||||||
|
|
||||||
// 5. Update BLE
|
// 5. Update BLE
|
||||||
if (ssidListChar != nullptr) {
|
if (ssidListChar != nullptr) {
|
||||||
ssidListChar->setValue(std::string(json_string));
|
ssidListChar->setValue(json_string);
|
||||||
ssidListChar->notify();
|
ssidRefreshChar->setValue("Ready");
|
||||||
|
ssidRefreshChar->notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Cleanup Memory (CRITICAL in C++)
|
// 6. Cleanup Memory
|
||||||
free(ap_list);
|
free(ap_list);
|
||||||
cJSON_Delete(root); // This deletes all children (items) too
|
cJSON_Delete(root); // This deletes all children (items) too
|
||||||
free(json_string); // cJSON_Print allocates memory, you must free it
|
free(json_string); // cJSON_Print allocates memory, you must free it
|
||||||
|
|||||||
@@ -11,8 +11,11 @@ class WiFi {
|
|||||||
const wifi_auth_mode_t authMode);
|
const wifi_auth_mode_t authMode);
|
||||||
static bool attemptConnect(const std::string ssid, const std::string uname,
|
static bool attemptConnect(const std::string ssid, const std::string uname,
|
||||||
const std::string password, const wifi_auth_mode_t authMode);
|
const std::string password, const wifi_auth_mode_t authMode);
|
||||||
|
static bool isConnected();
|
||||||
|
static void scanAndUpdateSSIDList();
|
||||||
private:
|
private:
|
||||||
static bool authFailed;
|
static void processScanResults();
|
||||||
|
static std::atomic<bool> authFailed;
|
||||||
static bool awaitConnected();
|
static bool awaitConnected();
|
||||||
static esp_event_handler_instance_t instance_any_id;
|
static esp_event_handler_instance_t instance_any_id;
|
||||||
static esp_event_handler_instance_t instance_got_ip;
|
static esp_event_handler_instance_t instance_got_ip;
|
||||||
@@ -20,7 +23,6 @@ class WiFi {
|
|||||||
static esp_netif_t* netif;
|
static esp_netif_t* netif;
|
||||||
static void event_handler(void* arg, esp_event_base_t event_base,
|
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||||
int32_t event_id, void* event_data);
|
int32_t event_id, void* event_data);
|
||||||
static bool isConnected();
|
|
||||||
static std::string getIP();
|
static std::string getIP();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
47
include/bmHTTP.cpp
Normal file
47
include/bmHTTP.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "bmHTTP.hpp"
|
||||||
|
#include "esp_http_client.h"
|
||||||
|
#define httpSrv "http://192.168.1.190:3000/"
|
||||||
|
|
||||||
|
std::string webToken;
|
||||||
|
|
||||||
|
bool httpGET(std::string endpoint, std::string token, cJSON* &JSONresponse) {
|
||||||
|
std::string url = std::string(httpSrv) + endpoint;
|
||||||
|
|
||||||
|
esp_http_client_config_t config = {};
|
||||||
|
config.url = url.c_str();
|
||||||
|
config.method = HTTP_METHOD_GET;
|
||||||
|
|
||||||
|
esp_http_client_handle_t client = esp_http_client_init(&config);
|
||||||
|
|
||||||
|
// Add authorization header
|
||||||
|
std::string authHeader = "Bearer " + token;
|
||||||
|
esp_http_client_set_header(client, "Authorization", authHeader.c_str());
|
||||||
|
|
||||||
|
esp_err_t err = esp_http_client_perform(client);
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
int status_code = esp_http_client_get_status_code(client);
|
||||||
|
int content_length = esp_http_client_get_content_length(client);
|
||||||
|
|
||||||
|
printf("HTTP Status = %d, content_length = %d\n", status_code, content_length);
|
||||||
|
|
||||||
|
if (status_code == 200) {
|
||||||
|
std::string responseData = "";
|
||||||
|
char buffer[512]; // Read in 512-byte blocks
|
||||||
|
int read_len;
|
||||||
|
|
||||||
|
// Read until the server stops sending (read_len <= 0)
|
||||||
|
while ((read_len = esp_http_client_read(client, buffer, sizeof(buffer))) > 0)
|
||||||
|
responseData.append(buffer, read_len);
|
||||||
|
|
||||||
|
if (!responseData.empty()) {
|
||||||
|
JSONresponse = cJSON_Parse(responseData.c_str());
|
||||||
|
success = (JSONresponse != NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else printf("HTTP request failed: %s\n", esp_err_to_name(err));
|
||||||
|
|
||||||
|
esp_http_client_cleanup(client);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
10
include/bmHTTP.hpp
Normal file
10
include/bmHTTP.hpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef BMHTTP
|
||||||
|
#define BMHTTP
|
||||||
|
#include <string>
|
||||||
|
#include "cJSON.h"
|
||||||
|
|
||||||
|
extern std::string webToken;
|
||||||
|
|
||||||
|
bool httpGET(std::string endpoint, std::string token, cJSON* &JSONresponse);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -12,6 +12,8 @@
|
|||||||
#define passTag "PW"
|
#define passTag "PW"
|
||||||
#define authTag "AuthMode"
|
#define authTag "AuthMode"
|
||||||
#define unameTag "UNAME"
|
#define unameTag "UNAME"
|
||||||
|
#define nvsAuth "AUTH"
|
||||||
|
#define tokenTag "TOKEN"
|
||||||
|
|
||||||
#define getMovingCW(port) ((movingCW & (1 << port)) >> port)
|
#define getMovingCW(port) ((movingCW & (1 << port)) >> port)
|
||||||
#define setMovingCW(port) (movingCW |= (1 << port))
|
#define setMovingCW(port) (movingCW |= (1 << port))
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
void initialSetup() {
|
void initialSetup() {
|
||||||
NimBLEAdvertising* pAdv = initBLE();
|
NimBLEAdvertising* pAdv = initBLE();
|
||||||
|
|
||||||
while (1) { // try to connect to wifi too.
|
while (!BLEtick(pAdv)) {
|
||||||
BLEtick(pAdv);
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user