Delete/add_device cycle works smoothly now. All cases tested, next up is using position and calibration data to move motors and use encoders etc.
This commit is contained in:
@@ -12,6 +12,7 @@ std::atomic<bool> credsGiven{false};
|
||||
std::atomic<bool> tokenGiven{false};
|
||||
std::atomic<bool> isBLEClientConnected{false};
|
||||
std::atomic<bool> scanBlock{false};
|
||||
std::atomic<bool> finalAuth{false};
|
||||
std::mutex dataMutex;
|
||||
|
||||
wifi_auth_mode_t auth;
|
||||
@@ -29,6 +30,8 @@ std::atomic<NimBLECharacteristic*> tokenChar = nullptr;
|
||||
std::atomic<NimBLECharacteristic*> ssidRefreshChar = nullptr;
|
||||
|
||||
NimBLEAdvertising* initBLE() {
|
||||
finalAuth = false;
|
||||
|
||||
NimBLEDevice::init("BlindMaster-C6");
|
||||
|
||||
// Optional: Boost power for better range (ESP32-C6 supports up to +20dBm)
|
||||
@@ -101,7 +104,6 @@ NimBLEAdvertising* initBLE() {
|
||||
pAdvertising->start();
|
||||
|
||||
printf("BLE Started. Waiting...\n");
|
||||
flag_scan_requested = true;
|
||||
|
||||
return pAdvertising;
|
||||
}
|
||||
@@ -223,7 +225,9 @@ bool BLEtick(NimBLEAdvertising* pAdvertising) {
|
||||
}
|
||||
else printf("Failed to parse JSON response\n");
|
||||
|
||||
finalAuth = true;
|
||||
notifyAuthStatus(success);
|
||||
if (success) NimBLEDevice::deinit(true); // deinitialize BLE
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
@@ -231,7 +235,7 @@ bool BLEtick(NimBLEAdvertising* pAdvertising) {
|
||||
|
||||
void reset() {
|
||||
esp_wifi_scan_stop();
|
||||
if (!connected) esp_wifi_disconnect();
|
||||
if (!finalAuth) esp_wifi_disconnect();
|
||||
scanBlock = false;
|
||||
flag_scan_requested = false;
|
||||
credsGiven = false;
|
||||
@@ -260,8 +264,13 @@ void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connI
|
||||
|
||||
printf("onWrite called! UUID: %s, Value length: %d\n", uuidStr.c_str(), val.length());
|
||||
|
||||
// Load atomic pointers for comparison
|
||||
NimBLECharacteristic* currentCredsChar = credsChar.load();
|
||||
NimBLECharacteristic* currentTokenChar = tokenChar.load();
|
||||
NimBLECharacteristic* currentRefreshChar = ssidRefreshChar.load();
|
||||
|
||||
// Check which characteristic was written to
|
||||
if (pChar == credsChar) {
|
||||
if (pChar == currentCredsChar) {
|
||||
// Credentials JSON characteristic
|
||||
if (val.length() > 0) {
|
||||
printf("Received JSON: %s\n", val.c_str());
|
||||
@@ -315,7 +324,7 @@ void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connI
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pChar == tokenChar) {
|
||||
else if (pChar == currentTokenChar) {
|
||||
if (val.length() > 0) {
|
||||
printf("Received Token: %s\n", val.c_str());
|
||||
std::lock_guard<std::mutex> lock(dataMutex);
|
||||
@@ -323,7 +332,7 @@ void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connI
|
||||
tokenGiven = true;
|
||||
}
|
||||
}
|
||||
else if (pChar == ssidRefreshChar) {
|
||||
else if (pChar == currentRefreshChar) {
|
||||
if (val == "Start") {
|
||||
// Refresh characteristic
|
||||
printf("Refresh Requested\n");
|
||||
|
||||
@@ -29,6 +29,4 @@ class WiFi {
|
||||
|
||||
extern WiFi bmWiFi;
|
||||
|
||||
void scanAndUpdateSSIDList();
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,10 @@
|
||||
#include "setup.hpp"
|
||||
#include "BLE.hpp"
|
||||
#include "WiFi.hpp"
|
||||
#include "nvs_flash.h"
|
||||
#include "defines.h"
|
||||
#include "bmHTTP.hpp"
|
||||
#include "socketIO.hpp"
|
||||
|
||||
void initialSetup() {
|
||||
printf("Entered Setup\n");
|
||||
@@ -10,3 +14,94 @@ void initialSetup() {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
}
|
||||
|
||||
void setupLoop() {
|
||||
bool initSuccess = false;
|
||||
while(!initSuccess) {
|
||||
nvs_handle_t WiFiHandle;
|
||||
if (nvs_open(nvsWiFi, NVS_READONLY, &WiFiHandle) == ESP_OK) {
|
||||
size_t ssidSize;
|
||||
esp_err_t WiFiPrefsError = nvs_get_str(WiFiHandle, ssidTag, NULL, &ssidSize);
|
||||
size_t pwSize;
|
||||
WiFiPrefsError |= nvs_get_str(WiFiHandle, passTag, NULL, &pwSize);
|
||||
uint8_t authMode;
|
||||
WiFiPrefsError |= nvs_get_u8(WiFiHandle, authTag, &authMode);
|
||||
printf("World\n");
|
||||
if (WiFiPrefsError == ESP_ERR_NVS_NOT_FOUND) {
|
||||
printf("Didn't find creds\n");
|
||||
// Make the RGB LED a certain color (Blue?)
|
||||
nvs_close(WiFiHandle);
|
||||
initialSetup();
|
||||
} else if (WiFiPrefsError == ESP_OK) {
|
||||
char ssid[ssidSize];
|
||||
nvs_get_str(WiFiHandle, ssidTag, ssid, &ssidSize);
|
||||
char pw[pwSize];
|
||||
nvs_get_str(WiFiHandle, passTag, pw, &pwSize);
|
||||
nvs_close(WiFiHandle);
|
||||
if (!bmWiFi.attemptConnect(ssid, pw, (wifi_auth_mode_t)authMode)) {
|
||||
// Make RGB LED certain color (Blue?)
|
||||
printf("Found credentials, failed to connect.\n");
|
||||
initialSetup();
|
||||
}
|
||||
else {
|
||||
printf("Connected to WiFi from NVS credentials\n");
|
||||
nvs_handle_t authHandle;
|
||||
if (nvs_open(nvsAuth, NVS_READONLY, &authHandle) == ESP_OK) {
|
||||
size_t tokenSize;
|
||||
if (nvs_get_str(authHandle, tokenTag, NULL, &tokenSize) == ESP_OK) {
|
||||
char token[tokenSize];
|
||||
nvs_get_str(authHandle, tokenTag, token, &tokenSize);
|
||||
nvs_close(authHandle);
|
||||
|
||||
// Use permanent device token to connect to Socket.IO
|
||||
// The server will verify the token during connection handshake
|
||||
webToken = std::string(token);
|
||||
printf("Connecting to Socket.IO server with saved token...\n");
|
||||
statusResolved = false;
|
||||
initSocketIO();
|
||||
|
||||
// Wait for device_init message from server with timeout
|
||||
int timeout_count = 0;
|
||||
const int MAX_TIMEOUT = 60; // 10 seconds (20 * 500ms)
|
||||
while (!statusResolved && timeout_count < MAX_TIMEOUT) {
|
||||
printf("Waiting for device_init message... (%d/%d)\n", timeout_count, MAX_TIMEOUT);
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
timeout_count++;
|
||||
}
|
||||
|
||||
if (timeout_count >= MAX_TIMEOUT) {
|
||||
printf("Timeout waiting for device_init - connection failed\n");
|
||||
stopSocketIO();
|
||||
initSuccess = false;
|
||||
initialSetup();
|
||||
} else {
|
||||
initSuccess = connected;
|
||||
if (!initSuccess) {
|
||||
printf("Device authentication failed - entering setup\n");
|
||||
initialSetup();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Token read unsuccessful, entering setup.\n");
|
||||
initialSetup();
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Auth NVS segment doesn't exist, entering setup.\n");
|
||||
initialSetup();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Make RGB LED certain color (Blue?)
|
||||
nvs_close(WiFiHandle);
|
||||
printf("Program error in Wifi Connection\n");
|
||||
initialSetup();
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("WiFi NVS segment doesn't exist, entering setup.\n");
|
||||
initialSetup();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,6 @@
|
||||
#define SETUP_H
|
||||
|
||||
void initialSetup();
|
||||
void setupLoop();
|
||||
|
||||
#endif
|
||||
@@ -8,7 +8,7 @@
|
||||
static esp_socketio_client_handle_t io_client;
|
||||
static esp_socketio_packet_handle_t tx_packet = NULL;
|
||||
|
||||
std::atomic<bool> statusResolved{false};
|
||||
std::atomic<bool> statusResolved{true};
|
||||
std::atomic<bool> connected{false};
|
||||
|
||||
// Event handler for Socket.IO events
|
||||
@@ -29,10 +29,9 @@ static void socketio_event_handler(void *handler_args, esp_event_base_t base,
|
||||
// Check if connected to default namespace
|
||||
char *nsp = esp_socketio_packet_get_nsp(packet);
|
||||
if (strcmp(nsp, "/") == 0) {
|
||||
printf("Connected to default namespace\n");
|
||||
printf("Connected to default namespace - waiting for device_init...\n");
|
||||
}
|
||||
connected = true;
|
||||
statusResolved = true;
|
||||
// Don't set connected yet - wait for device_init message from server
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -43,6 +42,82 @@ static void socketio_event_handler(void *handler_args, esp_event_base_t base,
|
||||
if (json) {
|
||||
char *json_str = cJSON_Print(json);
|
||||
printf("Data: %s\n", json_str);
|
||||
|
||||
// Check if this is an array event
|
||||
if (cJSON_IsArray(json) && cJSON_GetArraySize(json) >= 2) {
|
||||
cJSON *eventName = cJSON_GetArrayItem(json, 0);
|
||||
|
||||
if (cJSON_IsString(eventName)) {
|
||||
// Handle error event
|
||||
if (strcmp(eventName->valuestring, "error") == 0) {
|
||||
printf("Received error message from server\n");
|
||||
cJSON *data = cJSON_GetArrayItem(json, 1);
|
||||
|
||||
if (data) {
|
||||
cJSON *message = cJSON_GetObjectItem(data, "message");
|
||||
if (message && cJSON_IsString(message)) {
|
||||
printf("Server error: %s\n", message->valuestring);
|
||||
}
|
||||
}
|
||||
|
||||
// Mark connection as failed
|
||||
connected = false;
|
||||
statusResolved = true;
|
||||
}
|
||||
// Handle device_init event
|
||||
else if (strcmp(eventName->valuestring, "device_init") == 0) {
|
||||
printf("Received device_init message\n");
|
||||
cJSON *data = cJSON_GetArrayItem(json, 1);
|
||||
|
||||
if (data) {
|
||||
cJSON *type = cJSON_GetObjectItem(data, "type");
|
||||
if (type && strcmp(type->valuestring, "success") == 0) {
|
||||
printf("Device authenticated successfully\n");
|
||||
|
||||
// Parse device state
|
||||
cJSON *deviceState = cJSON_GetObjectItem(data, "deviceState");
|
||||
if (cJSON_IsArray(deviceState)) {
|
||||
int stateCount = cJSON_GetArraySize(deviceState);
|
||||
printf("Device has %d peripheral(s):\n", stateCount);
|
||||
|
||||
for (int i = 0; i < stateCount; i++) {
|
||||
cJSON *periph = cJSON_GetArrayItem(deviceState, i);
|
||||
int port = cJSON_GetObjectItem(periph, "port")->valueint;
|
||||
int lastPos = cJSON_GetObjectItem(periph, "lastPos")->valueint;
|
||||
bool awaitCalib = cJSON_IsTrue(cJSON_GetObjectItem(periph, "awaitCalib"));
|
||||
bool calibrated = cJSON_IsTrue(cJSON_GetObjectItem(periph, "calibrated"));
|
||||
// TODO: UPDATE MOTOR/ENCODER STATES BASED ON THIS, as well as the successive websocket updates.
|
||||
printf(" Port %d: pos=%d, calibrated=%d, awaitCalib=%d\n",
|
||||
port, lastPos, calibrated, awaitCalib);
|
||||
}
|
||||
}
|
||||
|
||||
// Now mark as connected
|
||||
connected = true;
|
||||
statusResolved = true;
|
||||
} else {
|
||||
printf("Device authentication failed\n");
|
||||
connected = false;
|
||||
statusResolved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle device_deleted event
|
||||
else if (strcmp(eventName->valuestring, "device_deleted") == 0) {
|
||||
printf("Device has been deleted from account - disconnecting\n");
|
||||
cJSON *data = cJSON_GetArrayItem(json, 1);
|
||||
if (data) {
|
||||
cJSON *message = cJSON_GetObjectItem(data, "message");
|
||||
if (message && cJSON_IsString(message)) {
|
||||
printf("Server message: %s\n", message->valuestring);
|
||||
}
|
||||
}
|
||||
connected = false;
|
||||
statusResolved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(json_str);
|
||||
}
|
||||
break;
|
||||
@@ -61,17 +136,19 @@ static void socketio_event_handler(void *handler_args, esp_event_base_t base,
|
||||
}
|
||||
}
|
||||
|
||||
// Disconnect and enter setup mode
|
||||
printf("Disconnecting and entering setup mode...\n");
|
||||
esp_socketio_client_close(io_client, pdMS_TO_TICKS(1000));
|
||||
|
||||
esp_socketio_client_destroy(io_client);
|
||||
initialSetup();
|
||||
// Set flags to indicate connection failure
|
||||
connected = false;
|
||||
statusResolved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle WebSocket-level disconnections
|
||||
if (data->websocket_event_id == WEBSOCKET_EVENT_DISCONNECTED) {
|
||||
printf("WebSocket disconnected\n");
|
||||
connected = false;
|
||||
statusResolved = true;
|
||||
}
|
||||
}
|
||||
|
||||
void initSocketIO() {
|
||||
@@ -92,6 +169,18 @@ void initSocketIO() {
|
||||
esp_socketio_client_start(io_client);
|
||||
}
|
||||
|
||||
void stopSocketIO() {
|
||||
if (io_client != NULL) {
|
||||
printf("Stopping Socket.IO client...\n");
|
||||
esp_socketio_client_close(io_client, pdMS_TO_TICKS(1000));
|
||||
esp_socketio_client_destroy(io_client);
|
||||
io_client = NULL;
|
||||
tx_packet = NULL;
|
||||
connected = false;
|
||||
statusResolved = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to emit 'calib_done' as expected by your server
|
||||
void emitCalibDone(int port) {
|
||||
// Set packet header: EIO MESSAGE type, SIO EVENT type, default namespace "/"
|
||||
|
||||
@@ -8,6 +8,9 @@ extern std::atomic<bool> connected;
|
||||
// Initialize Socket.IO client and connect to server
|
||||
void initSocketIO();
|
||||
|
||||
// Stop and destroy Socket.IO client
|
||||
void stopSocketIO();
|
||||
|
||||
// Emit calibration done event to server
|
||||
void emitCalibDone(int port);
|
||||
|
||||
|
||||
84
src/main.cpp
84
src/main.cpp
@@ -3,12 +3,9 @@
|
||||
#include "defines.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "NimBLEDevice.h"
|
||||
#include "BLE.hpp"
|
||||
#include "WiFi.hpp"
|
||||
#include "setup.hpp"
|
||||
#include "bmHTTP.hpp"
|
||||
#include "socketIO.hpp"
|
||||
#include "cJSON.h"
|
||||
|
||||
extern "C" void app_main() {
|
||||
printf("Hello ");
|
||||
@@ -22,80 +19,23 @@ extern "C" void app_main() {
|
||||
|
||||
bmWiFi.init();
|
||||
|
||||
bool initSuccess = false;
|
||||
|
||||
while(!initSuccess) {
|
||||
nvs_handle_t WiFiHandle;
|
||||
if (nvs_open(nvsWiFi, NVS_READONLY, &WiFiHandle) == ESP_OK) {
|
||||
size_t ssidSize;
|
||||
esp_err_t WiFiPrefsError = nvs_get_str(WiFiHandle, ssidTag, NULL, &ssidSize);
|
||||
size_t pwSize;
|
||||
WiFiPrefsError |= nvs_get_str(WiFiHandle, passTag, NULL, &pwSize);
|
||||
uint8_t authMode;
|
||||
WiFiPrefsError |= nvs_get_u8(WiFiHandle, authTag, &authMode);
|
||||
printf("World\n");
|
||||
if (WiFiPrefsError == ESP_ERR_NVS_NOT_FOUND) {
|
||||
printf("Didn't find creds\n");
|
||||
// Make the RGB LED a certain color (Blue?)
|
||||
nvs_close(WiFiHandle);
|
||||
initialSetup();
|
||||
} else if (WiFiPrefsError == ESP_OK) {
|
||||
char ssid[ssidSize];
|
||||
nvs_get_str(WiFiHandle, ssidTag, ssid, &ssidSize);
|
||||
char pw[pwSize];
|
||||
nvs_get_str(WiFiHandle, passTag, pw, &pwSize);
|
||||
nvs_close(WiFiHandle);
|
||||
if (!bmWiFi.attemptConnect(ssid, pw, (wifi_auth_mode_t)authMode)) {
|
||||
// Make RGB LED certain color (Blue?)
|
||||
printf("Found credentials, failed to connect.\n");
|
||||
initialSetup();
|
||||
}
|
||||
else {
|
||||
printf("Connected to WiFi from NVS credentials\n");
|
||||
nvs_handle_t authHandle;
|
||||
if (nvs_open(nvsAuth, NVS_READONLY, &authHandle) == ESP_OK) {
|
||||
size_t tokenSize;
|
||||
if (nvs_get_str(authHandle, tokenTag, NULL, &tokenSize) == ESP_OK) {
|
||||
char token[tokenSize];
|
||||
nvs_get_str(authHandle, tokenTag, token, &tokenSize);
|
||||
nvs_close(authHandle);
|
||||
|
||||
// Use permanent device token to connect to Socket.IO
|
||||
// The server will verify the token during connection handshake
|
||||
webToken = std::string(token);
|
||||
printf("Connecting to Socket.IO server with saved token...\n");
|
||||
initSocketIO();
|
||||
while (!statusResolved) vTaskDelay(pdMS_TO_TICKS(100));
|
||||
initSuccess = connected;
|
||||
}
|
||||
else {
|
||||
printf("Token read unsuccessful, entering setup.\n");
|
||||
initialSetup();
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Auth NVS segment doesn't exist, entering setup.\n");
|
||||
initialSetup();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Make RGB LED certain color (Blue?)
|
||||
nvs_close(WiFiHandle);
|
||||
printf("Program error in Wifi Connection\n");
|
||||
initialSetup();
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("WiFi NVS segment doesn't exist, entering setup.\n");
|
||||
initialSetup();
|
||||
}
|
||||
}
|
||||
setupLoop();
|
||||
|
||||
statusResolved = false;
|
||||
|
||||
// Main loop
|
||||
while (1) {
|
||||
if (statusResolved) {
|
||||
if (!connected) {
|
||||
printf("Disconnected! Beginning setup loop.\n");
|
||||
stopSocketIO();
|
||||
setupLoop();
|
||||
}
|
||||
else printf("Reconnected!\n");
|
||||
statusResolved = false;
|
||||
}
|
||||
// Your main application logic here
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
printf("Main Loop\n");
|
||||
printf("loop\n");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user