From 3a7057722377b88474876335f445693fb73857ce Mon Sep 17 00:00:00 2001 From: Summer <71572746+SummerSigh@users.noreply.github.com> Date: Wed, 11 Jun 2025 04:55:38 -0700 Subject: [PATCH 1/7] upload mutimodal --- .../CameraManager/CameraManager.cpp | 8 +- components/CommandManager/CMakeLists.txt | 3 +- .../CommandManager/CommandManager.cpp | 45 +- .../CommandManager/CommandManager.hpp | 8 + .../CommandManager/CommandResult.hpp | 35 +- .../CommandManager/CommandSchema.hpp | 5 + .../CommandManager/DependencyRegistry.hpp | 3 +- .../commands/device_commands.cpp | 67 +- .../commands/device_commands.hpp | 8 +- .../CommandManager/commands/scan_commands.cpp | 38 + .../CommandManager/commands/scan_commands.hpp | 10 + .../commands/simple_commands.cpp | 19 + .../commands/simple_commands.hpp | 2 + .../CommandManager/commands/wifi_commands.cpp | 77 ++ .../CommandManager/commands/wifi_commands.hpp | 5 + components/Helpers/CMakeLists.txt | 4 +- components/Helpers/Helpers/main_globals.cpp | 40 + components/Helpers/Helpers/main_globals.hpp | 28 + .../ProjectConfig/ProjectConfig/Models.hpp | 12 +- .../ProjectConfig/ProjectConfig.cpp | 15 +- .../ProjectConfig/ProjectConfig.hpp | 3 +- components/SerialManager/CMakeLists.txt | 2 +- .../SerialManager/SerialManager.cpp | 64 +- .../SerialManager/SerialManager.hpp | 7 +- .../StreamServer/StreamServer.cpp | 23 +- components/UVCStream/UVCStream/UVCStream.cpp | 7 + components/UVCStream/UVCStream/UVCStream.hpp | 1 + components/wifiManager/CMakeLists.txt | 2 +- .../wifiManager/wifiManager/WiFiScanner.cpp | 205 +++++ .../wifiManager/wifiManager/WiFiScanner.hpp | 29 + .../wifiManager/wifiManager/wifiManager.cpp | 227 ++++- .../wifiManager/wifiManager/wifiManager.hpp | 11 +- dependencies.lock | 2 +- main/openiris_main.cpp | 224 ++++- sdkconfig | 526 ++++++++++- sdkconfig.old | 254 +++++- tools/openiris_setup.py | 816 ++++++++++++++++++ tools/requirements.txt | 1 + tools/setup.bat | 7 + tools/setup.sh | 6 + tools/wifi_scanner.py | 177 ++++ 41 files changed, 2883 insertions(+), 143 deletions(-) create mode 100644 components/CommandManager/CommandManager/commands/scan_commands.cpp create mode 100644 components/CommandManager/CommandManager/commands/scan_commands.hpp create mode 100644 components/Helpers/Helpers/main_globals.cpp create mode 100644 components/Helpers/Helpers/main_globals.hpp create mode 100644 components/wifiManager/wifiManager/WiFiScanner.cpp create mode 100644 components/wifiManager/wifiManager/WiFiScanner.hpp create mode 100644 tools/openiris_setup.py create mode 100644 tools/requirements.txt create mode 100644 tools/setup.bat create mode 100644 tools/setup.sh create mode 100644 tools/wifi_scanner.py diff --git a/components/CameraManager/CameraManager/CameraManager.cpp b/components/CameraManager/CameraManager/CameraManager.cpp index 511a48d..1774395 100644 --- a/components/CameraManager/CameraManager/CameraManager.cpp +++ b/components/CameraManager/CameraManager/CameraManager.cpp @@ -80,10 +80,10 @@ void CameraManager::setupCameraPinout() .pixel_format = PIXFORMAT_JPEG, // YUV422,GRAYSCALE,RGB565,JPEG .frame_size = FRAMESIZE_240X240, // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates. - .jpeg_quality = 7, // 0-63, for OV series camera sensors, lower number means higher quality - .fb_count = 2, // 3 // When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode. - .fb_location = CAMERA_FB_IN_PSRAM, // maybe it cannot put them fully in psram? - .grab_mode = CAMERA_GRAB_WHEN_EMPTY, // CAMERA_GRAB_LATEST + .jpeg_quality = 10, // 0-63, for OV series camera sensors, lower number means higher quality + .fb_count = 2, // Use 2 for streaming to balance memory and performance + .fb_location = CAMERA_FB_IN_PSRAM, // Use PSRAM for frame buffers + .grab_mode = CAMERA_GRAB_LATEST, // Always grab the latest frame for streaming }; } diff --git a/components/CommandManager/CMakeLists.txt b/components/CommandManager/CMakeLists.txt index 30a6234..16e8afc 100644 --- a/components/CommandManager/CMakeLists.txt +++ b/components/CommandManager/CMakeLists.txt @@ -7,8 +7,9 @@ idf_component_register( "CommandManager/commands/config_commands.cpp" "CommandManager/commands/mdns_commands.cpp" "CommandManager/commands/device_commands.cpp" + "CommandManager/commands/scan_commands.cpp" INCLUDE_DIRS "CommandManager" "CommandManager/commands" - REQUIRES ProjectConfig cJSON CameraManager OpenIrisTasks + REQUIRES ProjectConfig cJSON CameraManager OpenIrisTasks wifiManager Helpers ) \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index 9d981f1..64cba54 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -1,7 +1,9 @@ #include "CommandManager.hpp" +#include std::unordered_map commandTypeMap = { {"ping", CommandType::PING}, + {"pause", CommandType::PAUSE}, {"set_wifi", CommandType::SET_WIFI}, {"update_wifi", CommandType::UPDATE_WIFI}, {"set_streaming_mode", CommandType::SET_STREAMING_MODE}, @@ -15,6 +17,12 @@ std::unordered_map commandTypeMap = { {"get_config", CommandType::GET_CONFIG}, {"reset_config", CommandType::RESET_CONFIG}, {"restart_device", CommandType::RESTART_DEVICE}, + {"scan_networks", CommandType::SCAN_NETWORKS}, + {"start_streaming", CommandType::START_STREAMING}, + {"get_wifi_status", CommandType::GET_WIFI_STATUS}, + {"connect_wifi", CommandType::CONNECT_WIFI}, + {"switch_mode", CommandType::SWITCH_MODE}, + {"get_device_mode", CommandType::GET_DEVICE_MODE}, }; std::function CommandManager::createCommand(const CommandType type, std::string_view json) const { @@ -22,6 +30,23 @@ std::function CommandManager::createCommand(const CommandType t { case CommandType::PING: return { PingCommand }; + case CommandType::PAUSE: + return [json] { + PausePayload payload; + cJSON* root = cJSON_Parse(std::string(json).c_str()); + if (root) { + cJSON* pauseItem = cJSON_GetObjectItem(root, "pause"); + if (pauseItem && cJSON_IsBool(pauseItem)) { + payload.pause = cJSON_IsTrue(pauseItem); + } else { + payload.pause = true; // Default to pause if not specified + } + cJSON_Delete(root); + } else { + payload.pause = true; // Default to pause if parsing fails + } + return PauseCommand(payload); + }; case CommandType::SET_STREAMING_MODE: return [this, json] {return setDeviceModeCommand(this->registry, json); }; case CommandType::UPDATE_OTA_CREDENTIALS: @@ -48,6 +73,18 @@ std::function CommandManager::createCommand(const CommandType t return [this, json] { return resetConfigCommand(this->registry, json); }; case CommandType::RESTART_DEVICE: return restartDeviceCommand; + case CommandType::SCAN_NETWORKS: + return [this] { return scanNetworksCommand(this->registry); }; + case CommandType::START_STREAMING: + return startStreamingCommand; + case CommandType::GET_WIFI_STATUS: + return [this] { return getWiFiStatusCommand(this->registry); }; + case CommandType::CONNECT_WIFI: + return [this] { return connectWiFiCommand(this->registry); }; + case CommandType::SWITCH_MODE: + return [this, json] { return switchModeCommand(this->registry, json); }; + case CommandType::GET_DEVICE_MODE: + return [this] { return getDeviceModeCommand(this->registry); }; default: return nullptr; } @@ -98,11 +135,15 @@ CommandResult CommandManager::executeFromJson(const std::string_view json) const cJSON_AddItemToArray(responses, response); } - const auto jsonString = cJSON_Print(responseDocument); + char* jsonString = cJSON_Print(responseDocument); cJSON_Delete(responseDocument); cJSON_Delete(parsedJson); - return CommandResult::getSuccessResult(jsonString); + // Return the JSON response directly without wrapping it + // The responseDocument already contains the proper format: {"results": [...]} + CommandResult result = CommandResult::getRawJsonResult(jsonString); + free(jsonString); + return result; } CommandResult CommandManager::executeFromType(const CommandType type, const std::string_view json) const diff --git a/components/CommandManager/CommandManager/CommandManager.hpp b/components/CommandManager/CommandManager/CommandManager.hpp index eea0477..02231e3 100644 --- a/components/CommandManager/CommandManager/CommandManager.hpp +++ b/components/CommandManager/CommandManager/CommandManager.hpp @@ -17,12 +17,14 @@ #include "commands/mdns_commands.hpp" #include "commands/wifi_commands.hpp" #include "commands/device_commands.hpp" +#include "commands/scan_commands.hpp" #include enum class CommandType { None, PING, + PAUSE, SET_WIFI, UPDATE_OTA_CREDENTIALS, SET_STREAMING_MODE, @@ -36,6 +38,12 @@ enum class CommandType GET_CONFIG, RESET_CONFIG, RESTART_DEVICE, + SCAN_NETWORKS, + START_STREAMING, + GET_WIFI_STATUS, + CONNECT_WIFI, + SWITCH_MODE, + GET_DEVICE_MODE, }; class CommandManager diff --git a/components/CommandManager/CommandManager/CommandResult.hpp b/components/CommandManager/CommandManager/CommandResult.hpp index f033954..b73fc8a 100644 --- a/components/CommandManager/CommandManager/CommandResult.hpp +++ b/components/CommandManager/CommandManager/CommandResult.hpp @@ -3,34 +3,52 @@ #include #include +#include class CommandResult { -private: +public: enum class Status { SUCCESS, FAILURE, }; +private: Status status; std::string message; +public: CommandResult(std::string message, const Status status) { this->status = status; + + // Escape quotes and backslashes in the message for JSON + std::string escapedMessage = message; + size_t pos = 0; + // First escape backslashes + while ((pos = escapedMessage.find('\\', pos)) != std::string::npos) { + escapedMessage.replace(pos, 1, "\\\\"); + pos += 2; + } + // Then escape quotes + pos = 0; + while ((pos = escapedMessage.find('"', pos)) != std::string::npos) { + escapedMessage.replace(pos, 1, "\\\""); + pos += 2; + } + if (status == Status::SUCCESS) { // we gotta do it this way, because if we define it as { "result": " {} " } it crashes the compiler, lol - this->message = std::format("{}\"result\":\" {} \"{}", "{", message, "}"); + this->message = std::format("{}\"result\":\"{}\"{}", "{", escapedMessage, "}"); } else { - this->message = std::format("{}\"error\":\" {} \"{}", "{", message, "}"); + this->message = std::format("{}\"error\":\"{}\"{}", "{", escapedMessage, "}"); } } -public: bool isSuccess() const { return status == Status::SUCCESS; } static CommandResult getSuccessResult(const std::string &message) @@ -42,8 +60,17 @@ public: { return CommandResult(message, Status::FAILURE); } + + // Create a result that returns raw JSON without wrapper + static CommandResult getRawJsonResult(const std::string &jsonMessage) + { + CommandResult result("", Status::SUCCESS); + result.message = jsonMessage; + return result; + } std::string getResult() const { return this->message; } + }; #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandSchema.hpp b/components/CommandManager/CommandManager/CommandSchema.hpp index 991b928..72e5440 100644 --- a/components/CommandManager/CommandManager/CommandSchema.hpp +++ b/components/CommandManager/CommandManager/CommandSchema.hpp @@ -57,4 +57,9 @@ struct RestartCameraPayload : BasePayload { bool mode; }; + +struct PausePayload : BasePayload +{ + bool pause; +}; #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/DependencyRegistry.hpp b/components/CommandManager/CommandManager/DependencyRegistry.hpp index 2a5e378..48b6ee8 100644 --- a/components/CommandManager/CommandManager/DependencyRegistry.hpp +++ b/components/CommandManager/CommandManager/DependencyRegistry.hpp @@ -7,7 +7,8 @@ enum class DependencyType { project_config, - camera_manager + camera_manager, + wifi_manager }; class DependencyRegistry diff --git a/components/CommandManager/CommandManager/commands/device_commands.cpp b/components/CommandManager/CommandManager/commands/device_commands.cpp index 0a3fe92..fa5d390 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.cpp +++ b/components/CommandManager/CommandManager/commands/device_commands.cpp @@ -2,6 +2,8 @@ #include #include +#include "esp_timer.h" +#include // Implementation inspired by SummerSigh work, initial PR opened in openiris repo, adapted to this rewrite CommandResult setDeviceModeCommand(std::shared_ptr registry, std::string_view jsonPayload) { @@ -46,7 +48,7 @@ CommandResult updateOTACredentialsCommand(std::shared_ptr re } } - if (const auto OTAPasswordObject = cJSON_GetObjectItem(parsedJson, s"password"); OTAPasswordObject != nullptr) { + if (const auto OTAPasswordObject = cJSON_GetObjectItem(parsedJson, "password"); OTAPasswordObject != nullptr) { OTAPassword = OTAPasswordObject->valuestring; } @@ -64,3 +66,66 @@ CommandResult restartDeviceCommand() { OpenIrisTasks::ScheduleRestart(2000); return CommandResult::getSuccessResult("Device restarted"); } + +CommandResult startStreamingCommand() { + activateStreaming(false); // Don't disable setup interfaces by default + return CommandResult::getSuccessResult("Streaming started"); +} + +CommandResult switchModeCommand(std::shared_ptr registry, std::string_view jsonPayload) { + const auto parsedJson = cJSON_Parse(jsonPayload.data()); + if (parsedJson == nullptr) { + return CommandResult::getErrorResult("Invalid payload"); + } + + const auto modeObject = cJSON_GetObjectItem(parsedJson, "mode"); + if (modeObject == nullptr) { + return CommandResult::getErrorResult("Invalid payload - missing mode"); + } + + const char* modeStr = modeObject->valuestring; + StreamingMode newMode; + + ESP_LOGI("[DEVICE_COMMANDS]", "Switch mode command received with mode: %s", modeStr); + + if (strcmp(modeStr, "uvc") == 0 || strcmp(modeStr, "UVC") == 0) { + newMode = StreamingMode::UVC; + } else if (strcmp(modeStr, "wifi") == 0 || strcmp(modeStr, "WiFi") == 0 || strcmp(modeStr, "WIFI") == 0) { + newMode = StreamingMode::WIFI; + } else if (strcmp(modeStr, "auto") == 0 || strcmp(modeStr, "AUTO") == 0) { + newMode = StreamingMode::AUTO; + } else { + return CommandResult::getErrorResult("Invalid mode - use 'uvc', 'wifi', or 'auto'"); + } + + const auto projectConfig = registry->resolve(DependencyType::project_config); + ESP_LOGI("[DEVICE_COMMANDS]", "Setting device mode to: %d", (int)newMode); + projectConfig->setDeviceMode(newMode); + + cJSON_Delete(parsedJson); + + return CommandResult::getSuccessResult("Device mode switched, restart to apply"); +} + +CommandResult getDeviceModeCommand(std::shared_ptr registry) { + const auto projectConfig = registry->resolve(DependencyType::project_config); + StreamingMode currentMode = projectConfig->getDeviceMode(); + + const char* modeStr = "unknown"; + switch (currentMode) { + case StreamingMode::UVC: + modeStr = "UVC"; + break; + case StreamingMode::WIFI: + modeStr = "WiFi"; + break; + case StreamingMode::AUTO: + modeStr = "Auto"; + break; + } + + char result[100]; + sprintf(result, "{\"mode\":\"%s\",\"value\":%d}", modeStr, (int)currentMode); + + return CommandResult::getSuccessResult(result); +} diff --git a/components/CommandManager/CommandManager/commands/device_commands.hpp b/components/CommandManager/CommandManager/commands/device_commands.hpp index 2532624..5685f13 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.hpp +++ b/components/CommandManager/CommandManager/commands/device_commands.hpp @@ -6,4 +6,10 @@ CommandResult setDeviceModeCommand(std::shared_ptr registry, CommandResult updateOTACredentialsCommand(std::shared_ptr registry, std::string_view jsonPayload); -CommandResult restartDeviceCommand(); \ No newline at end of file +CommandResult restartDeviceCommand(); + +CommandResult startStreamingCommand(); + +CommandResult switchModeCommand(std::shared_ptr registry, std::string_view jsonPayload); + +CommandResult getDeviceModeCommand(std::shared_ptr registry); \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/scan_commands.cpp b/components/CommandManager/CommandManager/commands/scan_commands.cpp new file mode 100644 index 0000000..054a621 --- /dev/null +++ b/components/CommandManager/CommandManager/commands/scan_commands.cpp @@ -0,0 +1,38 @@ +#include "scan_commands.hpp" +#include "cJSON.h" +#include "esp_log.h" +#include + +CommandResult scanNetworksCommand(std::shared_ptr registry) { + auto wifiManager = registry->resolve(DependencyType::wifi_manager); + if (!wifiManager) { + return CommandResult::getErrorResult("WiFiManager not available"); + } + + auto networks = wifiManager->ScanNetworks(); + + cJSON *root = cJSON_CreateObject(); + cJSON *networksArray = cJSON_CreateArray(); + cJSON_AddItemToObject(root, "networks", networksArray); + + for (const auto& network : networks) { + cJSON *networkObject = cJSON_CreateObject(); + cJSON_AddStringToObject(networkObject, "ssid", network.ssid.c_str()); + cJSON_AddNumberToObject(networkObject, "channel", network.channel); + cJSON_AddNumberToObject(networkObject, "rssi", network.rssi); + char mac_str[18]; + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", + network.mac[0], network.mac[1], network.mac[2], + network.mac[3], network.mac[4], network.mac[5]); + cJSON_AddStringToObject(networkObject, "mac_address", mac_str); + cJSON_AddNumberToObject(networkObject, "auth_mode", network.auth_mode); + cJSON_AddItemToArray(networksArray, networkObject); + } + + char *json_string = cJSON_PrintUnformatted(root); + printf("%s\n", json_string); + cJSON_Delete(root); + free(json_string); + + return CommandResult::getSuccessResult("Networks scanned"); +} \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/scan_commands.hpp b/components/CommandManager/CommandManager/commands/scan_commands.hpp new file mode 100644 index 0000000..7e7df86 --- /dev/null +++ b/components/CommandManager/CommandManager/commands/scan_commands.hpp @@ -0,0 +1,10 @@ +#ifndef SCAN_COMMANDS_HPP +#define SCAN_COMMANDS_HPP + +#include "../CommandResult.hpp" +#include "../DependencyRegistry.hpp" +#include + +CommandResult scanNetworksCommand(std::shared_ptr registry); + +#endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/simple_commands.cpp b/components/CommandManager/CommandManager/commands/simple_commands.cpp index b1fc7b9..909568a 100644 --- a/components/CommandManager/CommandManager/commands/simple_commands.cpp +++ b/components/CommandManager/CommandManager/commands/simple_commands.cpp @@ -1,6 +1,25 @@ #include "simple_commands.hpp" +#include "main_globals.hpp" +#include "esp_log.h" + +static const char* TAG = "SimpleCommands"; CommandResult PingCommand() { return CommandResult::getSuccessResult("pong"); }; + +CommandResult PauseCommand(const PausePayload& payload) +{ + ESP_LOGI(TAG, "Pause command received: %s", payload.pause ? "true" : "false"); + + startupPaused = payload.pause; + + if (payload.pause) { + ESP_LOGI(TAG, "Startup paused - device will remain in configuration mode"); + return CommandResult::getSuccessResult("Startup paused"); + } else { + ESP_LOGI(TAG, "Startup resumed"); + return CommandResult::getSuccessResult("Startup resumed"); + } +}; diff --git a/components/CommandManager/CommandManager/commands/simple_commands.hpp b/components/CommandManager/CommandManager/commands/simple_commands.hpp index 0883da9..9db7ea9 100644 --- a/components/CommandManager/CommandManager/commands/simple_commands.hpp +++ b/components/CommandManager/CommandManager/commands/simple_commands.hpp @@ -3,7 +3,9 @@ #include #include "CommandResult.hpp" +#include "CommandSchema.hpp" CommandResult PingCommand(); +CommandResult PauseCommand(const PausePayload& payload); #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/wifi_commands.cpp b/components/CommandManager/CommandManager/commands/wifi_commands.cpp index 5f671f9..8ca0fcf 100644 --- a/components/CommandManager/CommandManager/commands/wifi_commands.cpp +++ b/components/CommandManager/CommandManager/commands/wifi_commands.cpp @@ -1,4 +1,5 @@ #include "wifi_commands.hpp" +#include "esp_netif.h" std::optional parseSetWiFiCommandPayload(std::string_view jsonPayload) { @@ -223,3 +224,79 @@ CommandResult updateAPWiFiCommand(std::shared_ptr registry, return CommandResult::getSuccessResult("Config updated"); } + +CommandResult getWiFiStatusCommand(std::shared_ptr registry) { + auto wifiManager = registry->resolve(DependencyType::wifi_manager); + auto projectConfig = registry->resolve(DependencyType::project_config); + + // Get current WiFi state + auto wifiState = wifiManager->GetCurrentWiFiState(); + auto networks = projectConfig->getWifiConfigs(); + + cJSON* statusJson = cJSON_CreateObject(); + + // Add WiFi state + const char* stateStr = "unknown"; + switch(wifiState) { + case WiFiState_e::WiFiState_NotInitialized: + stateStr = "not_initialized"; + break; + case WiFiState_e::WiFiState_Initialized: + stateStr = "initialized"; + break; + case WiFiState_e::WiFiState_ReadyToConnect: + stateStr = "ready"; + break; + case WiFiState_e::WiFiState_Connecting: + stateStr = "connecting"; + break; + case WiFiState_e::WiFiState_WaitingForIp: + stateStr = "waiting_for_ip"; + break; + case WiFiState_e::WiFiState_Connected: + stateStr = "connected"; + break; + case WiFiState_e::WiFiState_Disconnected: + stateStr = "disconnected"; + break; + case WiFiState_e::WiFiState_Error: + stateStr = "error"; + break; + } + cJSON_AddStringToObject(statusJson, "status", stateStr); + cJSON_AddNumberToObject(statusJson, "networks_configured", networks.size()); + + // Add IP info if connected + if (wifiState == WiFiState_e::WiFiState_Connected) { + // Get IP address from ESP32 + esp_netif_ip_info_t ip_info; + esp_netif_t* netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + if (netif && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK) { + char ip_str[16]; + sprintf(ip_str, IPSTR, IP2STR(&ip_info.ip)); + cJSON_AddStringToObject(statusJson, "ip_address", ip_str); + } + } + + char* statusString = cJSON_PrintUnformatted(statusJson); + std::string result(statusString); + free(statusString); + cJSON_Delete(statusJson); + + return CommandResult::getSuccessResult(result); +} + +CommandResult connectWiFiCommand(std::shared_ptr registry) { + auto wifiManager = registry->resolve(DependencyType::wifi_manager); + auto projectConfig = registry->resolve(DependencyType::project_config); + + auto networks = projectConfig->getWifiConfigs(); + if (networks.empty()) { + return CommandResult::getErrorResult("No WiFi networks configured"); + } + + // Trigger WiFi connection attempt + wifiManager->TryConnectToStoredNetworks(); + + return CommandResult::getSuccessResult("WiFi connection attempt started"); +} diff --git a/components/CommandManager/CommandManager/commands/wifi_commands.hpp b/components/CommandManager/CommandManager/commands/wifi_commands.hpp index e344427..f98245d 100644 --- a/components/CommandManager/CommandManager/commands/wifi_commands.hpp +++ b/components/CommandManager/CommandManager/commands/wifi_commands.hpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -18,3 +20,6 @@ CommandResult updateWiFiCommand(std::shared_ptr registry, st std::optional parseUpdateAPWiFiCommandPayload(std::string_view jsonPayload); CommandResult updateAPWiFiCommand(std::shared_ptr registry, std::string_view jsonPayload); + +CommandResult getWiFiStatusCommand(std::shared_ptr registry); +CommandResult connectWiFiCommand(std::shared_ptr registry); diff --git a/components/Helpers/CMakeLists.txt b/components/Helpers/CMakeLists.txt index 80ffdf3..5d592c6 100644 --- a/components/Helpers/CMakeLists.txt +++ b/components/Helpers/CMakeLists.txt @@ -1,4 +1,4 @@ -idf_component_register(SRCS "Helpers/helpers.cpp" - INCLUDE_DIRS "helpers" +idf_component_register(SRCS "Helpers/helpers.cpp" "Helpers/main_globals.cpp" + INCLUDE_DIRS "Helpers" REQUIRES esp_timer ) \ No newline at end of file diff --git a/components/Helpers/Helpers/main_globals.cpp b/components/Helpers/Helpers/main_globals.cpp new file mode 100644 index 0000000..8ed665d --- /dev/null +++ b/components/Helpers/Helpers/main_globals.cpp @@ -0,0 +1,40 @@ +#include "main_globals.hpp" +#include "esp_log.h" + +// Forward declarations +extern void start_video_streaming(void *arg); + +// Global variables to be set by main +static esp_timer_handle_t* g_streaming_timer_handle = nullptr; +static TaskHandle_t* g_serial_manager_handle = nullptr; + +// Functions for main to set the global handles +void setStreamingTimerHandle(esp_timer_handle_t* handle) { + g_streaming_timer_handle = handle; +} + +void setSerialManagerHandle(TaskHandle_t* handle) { + g_serial_manager_handle = handle; +} + +// Functions for components to access the handles +esp_timer_handle_t* getStreamingTimerHandle() { + return g_streaming_timer_handle; +} + +TaskHandle_t* getSerialManagerHandle() { + return g_serial_manager_handle; +} + +// Global pause state +bool startupPaused = false; + +// Function to manually activate streaming +void activateStreaming(bool disableSetup) { + ESP_LOGI("[MAIN_GLOBALS]", "Manually activating streaming, disableSetup=%s", disableSetup ? "true" : "false"); + + TaskHandle_t* serialHandle = disableSetup ? g_serial_manager_handle : nullptr; + void* serialTaskHandle = (serialHandle && *serialHandle) ? *serialHandle : nullptr; + + start_video_streaming(serialTaskHandle); +} \ No newline at end of file diff --git a/components/Helpers/Helpers/main_globals.hpp b/components/Helpers/Helpers/main_globals.hpp new file mode 100644 index 0000000..d13f7fc --- /dev/null +++ b/components/Helpers/Helpers/main_globals.hpp @@ -0,0 +1,28 @@ +#pragma once +#ifndef MAIN_GLOBALS_HPP +#define MAIN_GLOBALS_HPP + +#include "esp_timer.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +// Functions for main to set global handles +void setStreamingTimerHandle(esp_timer_handle_t* handle); +void setSerialManagerHandle(TaskHandle_t* handle); + +// Functions to access global handles from components +esp_timer_handle_t* getStreamingTimerHandle(); +TaskHandle_t* getSerialManagerHandle(); + +// Function to manually activate streaming +void activateStreaming(bool disableSetup = false); + +// Function to notify that a command was received during startup +extern void notify_startup_command_received(); + +// Global variables for startup state +extern bool startupCommandReceived; +extern esp_timer_handle_t startupTimerHandle; +extern bool startupPaused; + +#endif \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/Models.hpp b/components/ProjectConfig/ProjectConfig/Models.hpp index f931775..d2a01c1 100644 --- a/components/ProjectConfig/ProjectConfig/Models.hpp +++ b/components/ProjectConfig/ProjectConfig/Models.hpp @@ -8,6 +8,7 @@ #include #include "sdkconfig.h" #include +#include "esp_log.h" struct BaseConfigModel { @@ -31,11 +32,14 @@ struct DeviceMode_t : BaseConfigModel { explicit DeviceMode_t( Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::AUTO){} void load() { - this->mode = static_cast(this->pref->getInt("mode", 0)); + int stored_mode = this->pref->getInt("mode", 0); + this->mode = static_cast(stored_mode); + ESP_LOGI("DeviceMode", "Loaded device mode: %d", stored_mode); } void save() const { this->pref->putInt("mode", static_cast(this->mode)); + ESP_LOGI("DeviceMode", "Saved device mode: %d", static_cast(this->mode)); } }; @@ -182,6 +186,9 @@ struct WiFiConfig_t : BaseConfigModel this->password = this->pref->getString(("password" + iter_str).c_str(), ""); this->channel = this->pref->getUInt(("channel" + iter_str).c_str()); this->power = this->pref->getUInt(("power" + iter_str).c_str()); + + ESP_LOGI("WiFiConfig", "Loaded network %d: name=%s, ssid=%s, channel=%d", + index, this->name.c_str(), this->ssid.c_str(), this->channel); }; void save() const { @@ -193,6 +200,9 @@ struct WiFiConfig_t : BaseConfigModel this->pref->putString(("password" + iter_str).c_str(), this->password.c_str()); this->pref->putUInt(("channel" + iter_str).c_str(), this->channel); this->pref->putUInt(("power" + iter_str).c_str(), this->power); + + ESP_LOGI("WiFiConfig", "Saved network %d: name=%s, ssid=%s, channel=%d", + this->index, this->name.c_str(), this->ssid.c_str(), this->channel); }; std::string toRepresentation() diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp index eb42bdc..ae7b189 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp @@ -147,6 +147,8 @@ void ProjectConfig::setWifiConfig(const std::string &networkName, it->password = password; it->channel = channel; it->power = power; + // Save the updated network immediately + it->save(); return; } @@ -155,6 +157,9 @@ void ProjectConfig::setWifiConfig(const std::string &networkName, ESP_LOGI(CONFIGURATION_TAG, "No networks, We're adding a new network"); this->config.networks.emplace_back(this->pref, static_cast(0), networkName, ssid, password, channel, power); + // Save the new network immediately + this->config.networks.back().save(); + saveNetworkCount(this->pref, 1); return; } @@ -168,6 +173,9 @@ void ProjectConfig::setWifiConfig(const std::string &networkName, uint8_t last_index = getNetworkCount(this->pref); this->config.networks.emplace_back(this->pref, last_index, networkName, ssid, password, channel, power); + // Save the new network immediately + this->config.networks.back().save(); + saveNetworkCount(this->pref, static_cast(this->config.networks.size())); } else { @@ -212,6 +220,7 @@ void ProjectConfig::setAPWifiConfig(const std::string &ssid, void ProjectConfig::setDeviceMode(const StreamingMode deviceMode) { this->config.device_mode.mode = deviceMode; + this->config.device_mode.save(); // Save immediately } //********************************************************************************************************************** @@ -249,6 +258,10 @@ TrackerConfig_t &ProjectConfig::getTrackerConfig() return this->config; } -DeviceMode_t &ProjectConfig::getDeviceMode() { +DeviceMode_t &ProjectConfig::getDeviceModeConfig() { return this->config.device_mode; +} + +StreamingMode ProjectConfig::getDeviceMode() { + return this->config.device_mode.mode; } \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp index da59033..b256c22 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp @@ -31,7 +31,7 @@ public: bool reset(); DeviceConfig_t &getDeviceConfig(); - DeviceMode_t &getDeviceMode(); + DeviceMode_t &getDeviceModeConfig(); CameraConfig_t &getCameraConfig(); std::vector &getWifiConfigs(); AP_WiFiConfig_t &getAPWifiConfig(); @@ -61,6 +61,7 @@ public: uint8_t channel); void setWiFiTxPower(uint8_t power); void setDeviceMode(StreamingMode deviceMode); + StreamingMode getDeviceMode(); private: Preferences *pref; diff --git a/components/SerialManager/CMakeLists.txt b/components/SerialManager/CMakeLists.txt index 0cd7215..aaaa174 100644 --- a/components/SerialManager/CMakeLists.txt +++ b/components/SerialManager/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "SerialManager/SerialManager.cpp" INCLUDE_DIRS "SerialManager" - REQUIRES esp_driver_uart CommandManager + REQUIRES esp_driver_uart CommandManager ProjectConfig ) \ No newline at end of file diff --git a/components/SerialManager/SerialManager/SerialManager.cpp b/components/SerialManager/SerialManager/SerialManager.cpp index 93d6a3e..d1c60c9 100644 --- a/components/SerialManager/SerialManager/SerialManager.cpp +++ b/components/SerialManager/SerialManager/SerialManager.cpp @@ -1,8 +1,11 @@ #include "SerialManager.hpp" +#include "esp_log.h" +#include "main_globals.hpp" #define BUF_SIZE (1024) -SerialManager::SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle) : commandManager(commandManager), timerHandle(timerHandle) { +SerialManager::SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle, std::shared_ptr deviceConfig) + : commandManager(commandManager), timerHandle(timerHandle), deviceConfig(deviceConfig) { this->data = static_cast(malloc(BUF_SIZE)); this->temp_data = static_cast(malloc(256)); } @@ -20,9 +23,6 @@ void SerialManager::try_receive() int current_position = 0; int len = usb_serial_jtag_read_bytes(this->temp_data, 256, 1000 / 20); - if (len) { - esp_timer_stop(*timerHandle); - } // since we've got something on the serial port // we gotta keep reading until we've got the whole message while (len) @@ -38,19 +38,73 @@ void SerialManager::try_receive() data[current_position] = '\0'; current_position = 0; + // Notify main that a command was received during startup + notify_startup_command_received(); + const auto result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast(this->data))); const auto resultMessage = result.getResult(); usb_serial_jtag_write_bytes(resultMessage.c_str(), resultMessage.length(), 1000 / 20); - esp_timer_start_once(*timerHandle, 30000000); // 30s } } +void SerialManager::send_heartbeat() +{ + // Get the MAC address as unique identifier + uint8_t mac[6]; + esp_read_mac(mac, ESP_MAC_WIFI_STA); + + // Format as serial number string + char serial_number[18]; + sprintf(serial_number, "%02X%02X%02X%02X%02X%02X", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + // Create heartbeat JSON with serial number + char heartbeat[128]; + sprintf(heartbeat, "{\"heartbeat\":\"openiris_setup_mode\",\"serial\":\"%s\"}\n", serial_number); + + usb_serial_jtag_write_bytes(heartbeat, strlen(heartbeat), 1000 / 20); +} + +bool SerialManager::should_send_heartbeat() +{ + // Always send heartbeat during startup delay or if no WiFi configured + extern bool startupCommandReceived; + extern esp_timer_handle_t startupTimerHandle; + + // If startup timer is still running, always send heartbeat + if (startupTimerHandle != nullptr) { + return true; + } + + // If in heartbeat mode after startup, continue sending + if (startupCommandReceived) { + return true; + } + + // Otherwise, only send if no WiFi credentials configured + const auto wifiConfigs = deviceConfig->getWifiConfigs(); + return wifiConfigs.empty(); +} + void HandleSerialManagerTask(void *pvParameters) { auto const serialManager = static_cast(pvParameters); + TickType_t lastHeartbeat = xTaskGetTickCount(); + const TickType_t heartbeatInterval = pdMS_TO_TICKS(2000); // 2 second heartbeat while (true) { serialManager->try_receive(); + + // Send heartbeat every 2 seconds, but only if no WiFi credentials are set + TickType_t currentTime = xTaskGetTickCount(); + if ((currentTime - lastHeartbeat) >= heartbeatInterval) { + if (serialManager->should_send_heartbeat()) { + serialManager->send_heartbeat(); + } + lastHeartbeat = currentTime; + } + + vTaskDelay(pdMS_TO_TICKS(50)); // Small delay to prevent busy waiting } } \ No newline at end of file diff --git a/components/SerialManager/SerialManager/SerialManager.hpp b/components/SerialManager/SerialManager/SerialManager.hpp index e3fca9a..a8c92c9 100644 --- a/components/SerialManager/SerialManager/SerialManager.hpp +++ b/components/SerialManager/SerialManager/SerialManager.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" @@ -15,17 +16,21 @@ #include "driver/usb_serial_jtag.h" #include "esp_vfs_usb_serial_jtag.h" #include "esp_vfs_dev.h" +#include "esp_mac.h" class SerialManager { public: - explicit SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle); + explicit SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle, std::shared_ptr deviceConfig); void setup(); void try_receive(); + void send_heartbeat(); + bool should_send_heartbeat(); private: std::shared_ptr commandManager; esp_timer_handle_t *timerHandle; + std::shared_ptr deviceConfig; uint8_t *data; uint8_t *temp_data; }; diff --git a/components/StreamServer/StreamServer/StreamServer.cpp b/components/StreamServer/StreamServer/StreamServer.cpp index cf666f6..c40f5cc 100644 --- a/components/StreamServer/StreamServer/StreamServer.cpp +++ b/components/StreamServer/StreamServer/StreamServer.cpp @@ -38,8 +38,11 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) if (!fb) { - ESP_LOGE(STREAM_SERVER_TAG, "Camera capture failed with resposne %s", esp_err_to_name(response)); + ESP_LOGE(STREAM_SERVER_TAG, "Camera capture failed"); response = ESP_FAIL; + // Don't break immediately, try to recover + vTaskDelay(pdMS_TO_TICKS(10)); + continue; } else { @@ -70,10 +73,15 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) } if (response != ESP_OK) break; - long request_end = Helpers::getTimeInMillis(); - long latency = (request_end - last_request_time); - last_request_time = request_end; - ESP_LOGI(STREAM_SERVER_TAG, "Size: %uKB, Time: %lims (%lifps)\n", _jpg_buf_len / 1024, latency, 1000 / latency); + + // Only log every 100 frames to reduce overhead + static int frame_count = 0; + if (++frame_count % 100 == 0) { + long request_end = Helpers::getTimeInMillis(); + long latency = (request_end - last_request_time); + last_request_time = request_end; + ESP_LOGI(STREAM_SERVER_TAG, "Size: %uKB, Time: %lims (%lifps)", _jpg_buf_len / 1024, latency, 1000 / latency); + } } last_frame = 0; return response; @@ -93,8 +101,9 @@ esp_err_t StreamServer::startStreamServer() config.max_uri_handlers = 10; config.server_port = STREAM_SERVER_PORT; config.ctrl_port = STREAM_SERVER_PORT; - config.recv_wait_timeout = 100; - config.send_wait_timeout = 100; + config.recv_wait_timeout = 5; // 5 seconds for receiving + config.send_wait_timeout = 5; // 5 seconds for sending + config.lru_purge_enable = true; // Enable LRU purge for better connection handling httpd_uri_t stream_page = { .uri = "/", diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index ffc370c..2de5c82 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -119,5 +119,12 @@ esp_err_t UVCStreamManager::setup() } ESP_LOGI(UVC_STREAM_TAG, "Initialized UVC Device"); + return ESP_OK; +} + +esp_err_t UVCStreamManager::start() +{ + ESP_LOGI(UVC_STREAM_TAG, "Starting UVC streaming"); + // UVC device is already initialized in setup(), just log that we're starting return ESP_OK; } \ No newline at end of file diff --git a/components/UVCStream/UVCStream/UVCStream.hpp b/components/UVCStream/UVCStream/UVCStream.hpp index 34a4d92..084cf18 100644 --- a/components/UVCStream/UVCStream/UVCStream.hpp +++ b/components/UVCStream/UVCStream/UVCStream.hpp @@ -41,6 +41,7 @@ class UVCStreamManager public: esp_err_t setup(); + esp_err_t start(); }; #endif // UVCSTREAM_HPP diff --git a/components/wifiManager/CMakeLists.txt b/components/wifiManager/CMakeLists.txt index 37fcbe2..bb241da 100644 --- a/components/wifiManager/CMakeLists.txt +++ b/components/wifiManager/CMakeLists.txt @@ -1,4 +1,4 @@ -idf_component_register(SRCS "wifiManager/wifiManager.cpp" +idf_component_register(SRCS "wifiManager/wifiManager.cpp" "wifiManager/WiFiScanner.cpp" INCLUDE_DIRS "wifiManager" REQUIRES esp_wifi nvs_flash esp_event esp_netif lwip StateManager ProjectConfig ) \ No newline at end of file diff --git a/components/wifiManager/wifiManager/WiFiScanner.cpp b/components/wifiManager/wifiManager/WiFiScanner.cpp new file mode 100644 index 0000000..8e7f171 --- /dev/null +++ b/components/wifiManager/wifiManager/WiFiScanner.cpp @@ -0,0 +1,205 @@ +#include "WiFiScanner.hpp" +#include + +WiFiScanner::WiFiScanner() {} + +void WiFiScanner::scanResultCallback(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { + auto* scanner = static_cast(arg); + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { + uint16_t ap_count = 0; + esp_wifi_scan_get_ap_num(&ap_count); + + if (ap_count == 0) { + ESP_LOGI(TAG, "No access points found"); + return; + } + + wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count]; + ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, ap_records)); + + scanner->networks.clear(); + for (uint16_t i = 0; i < ap_count; i++) { + WiFiNetwork network; + network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); + network.channel = ap_records[i].primary; + network.rssi = ap_records[i].rssi; + memcpy(network.mac, ap_records[i].bssid, 6); + network.auth_mode = ap_records[i].authmode; + + scanner->networks.push_back(network); + } + + delete[] ap_records; + ESP_LOGI(TAG, "Found %d access points", ap_count); + } +} + +std::vector WiFiScanner::scanNetworks() { + std::vector scan_results; + + // Check if WiFi is initialized + wifi_mode_t mode; + esp_err_t err = esp_wifi_get_mode(&mode); + if (err == ESP_ERR_WIFI_NOT_INIT) { + ESP_LOGE(TAG, "WiFi not initialized"); + return scan_results; + } + + + // Give WiFi more time to be ready + vTaskDelay(pdMS_TO_TICKS(500)); + + // Stop any ongoing scan + esp_wifi_scan_stop(); + + // Try sequential channel scanning as a workaround + bool try_sequential_scan = true; // Enable sequential scan + + if (!try_sequential_scan) { + // Normal all-channel scan + wifi_scan_config_t scan_config = { + .ssid = nullptr, + .bssid = nullptr, + .channel = 0, // 0 means scan all channels + .show_hidden = true, + .scan_type = WIFI_SCAN_TYPE_ACTIVE, // Active scan + .scan_time = { + .active = { + .min = 120, // Min per channel + .max = 300 // Max per channel + }, + .passive = 360 + }, + .home_chan_dwell_time = 0, // 0 for default + .channel_bitmap = 0 // 0 for all channels + }; + + err = esp_wifi_scan_start(&scan_config, false); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to start scan: %s", esp_err_to_name(err)); + return scan_results; + } + } else { + // Sequential channel scan - scan each channel individually + std::vector all_records; + + for (uint8_t ch = 1; ch <= 13; ch++) { + wifi_scan_config_t scan_config = { + .ssid = nullptr, + .bssid = nullptr, + .channel = ch, // Specific channel + .show_hidden = true, + .scan_type = WIFI_SCAN_TYPE_ACTIVE, + .scan_time = { + .active = { + .min = 100, + .max = 200 + }, + .passive = 300 + }, + .home_chan_dwell_time = 0, + .channel_bitmap = 0 + }; + + err = esp_wifi_scan_start(&scan_config, true); // Blocking scan + if (err == ESP_OK) { + uint16_t ch_count = 0; + esp_wifi_scan_get_ap_num(&ch_count); + if (ch_count > 0) { + wifi_ap_record_t* ch_records = new wifi_ap_record_t[ch_count]; + if (esp_wifi_scan_get_ap_records(&ch_count, ch_records) == ESP_OK) { + for (uint16_t i = 0; i < ch_count; i++) { + all_records.push_back(ch_records[i]); + } + } + delete[] ch_records; + } + } + vTaskDelay(pdMS_TO_TICKS(50)); + } + + // Process all collected records + for (const auto& record : all_records) { + WiFiNetwork network; + network.ssid = std::string(reinterpret_cast(record.ssid)); + network.channel = record.primary; + network.rssi = record.rssi; + memcpy(network.mac, record.bssid, 6); + network.auth_mode = record.authmode; + scan_results.push_back(network); + } + + // Skip the normal result processing + return scan_results; + } + + // Wait for scan completion with timeout + int timeout_ms = 15000; // 15 second timeout + int elapsed_ms = 0; + + while (elapsed_ms < timeout_ms) { + uint16_t temp_count = 0; + esp_err_t count_err = esp_wifi_scan_get_ap_num(&temp_count); + + if (count_err == ESP_OK) { + // Wait a bit longer after finding networks to ensure scan is complete + if (temp_count > 0 && elapsed_ms > 5000) { + break; + } + } + + vTaskDelay(pdMS_TO_TICKS(200)); + elapsed_ms += 200; + } + + if (elapsed_ms >= timeout_ms) { + ESP_LOGE(TAG, "Scan timeout after %d ms", timeout_ms); + esp_wifi_scan_stop(); + return scan_results; + } + + // Get scan results + uint16_t ap_count = 0; + esp_wifi_scan_get_ap_num(&ap_count); + + if (ap_count == 0) { + ESP_LOGI(TAG, "No access points found"); + return scan_results; + } + + wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count]; + err = esp_wifi_scan_get_ap_records(&ap_count, ap_records); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to get scan records: %s", esp_err_to_name(err)); + delete[] ap_records; + return scan_results; + } + + // Build the results vector and track channels found + bool channels_found[15] = {false}; // Track channels 0-14 + + for (uint16_t i = 0; i < ap_count; i++) { + WiFiNetwork network; + network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); + network.channel = ap_records[i].primary; + network.rssi = ap_records[i].rssi; + memcpy(network.mac, ap_records[i].bssid, 6); + network.auth_mode = ap_records[i].authmode; + + if (network.channel <= 14) { + channels_found[network.channel] = true; + } + + scan_results.push_back(network); + } + + + delete[] ap_records; + ESP_LOGI(TAG, "Found %d access points", ap_count); + + // Also update the member variable for compatibility + networks = scan_results; + + return scan_results; +} \ No newline at end of file diff --git a/components/wifiManager/wifiManager/WiFiScanner.hpp b/components/wifiManager/wifiManager/WiFiScanner.hpp new file mode 100644 index 0000000..acb4d6e --- /dev/null +++ b/components/wifiManager/wifiManager/WiFiScanner.hpp @@ -0,0 +1,29 @@ +#pragma once +#ifndef WIFI_SCANNER_HPP +#define WIFI_SCANNER_HPP + +#include +#include +#include "esp_wifi.h" +#include "esp_log.h" + +struct WiFiNetwork { + std::string ssid; + uint8_t channel; + int8_t rssi; + uint8_t mac[6]; + wifi_auth_mode_t auth_mode; +}; + +class WiFiScanner { +public: + WiFiScanner(); + std::vector scanNetworks(); + static void scanResultCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); + +private: + static constexpr char const* TAG = "WiFiScanner"; + std::vector networks; +}; + +#endif \ No newline at end of file diff --git a/components/wifiManager/wifiManager/wifiManager.cpp b/components/wifiManager/wifiManager/wifiManager.cpp index 616b383..ffbae5c 100644 --- a/components/wifiManager/wifiManager/wifiManager.cpp +++ b/components/wifiManager/wifiManager/wifiManager.cpp @@ -2,6 +2,10 @@ static auto WIFI_MANAGER_TAG = "[WIFI_MANAGER]"; +// Define the global variables declared as extern in the header +int s_retry_num = 0; +EventGroupHandle_t s_wifi_event_group; + void WiFiManagerHelpers::event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { @@ -15,6 +19,9 @@ void WiFiManagerHelpers::event_handler(void *arg, esp_event_base_t event_base, } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; + ESP_LOGI(WIFI_MANAGER_TAG, "Disconnect reason: %d", disconnected->reason); + if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { esp_wifi_connect(); @@ -37,19 +44,70 @@ void WiFiManagerHelpers::event_handler(void *arg, esp_event_base_t event_base, } } -WiFiManager::WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager *stateManager) : deviceConfig(deviceConfig), eventQueue(eventQueue), stateManager(stateManager) {} +WiFiManager::WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager *stateManager) + : deviceConfig(deviceConfig), eventQueue(eventQueue), stateManager(stateManager), wifiScanner(std::make_unique()) {} void WiFiManager::SetCredentials(const char *ssid, const char *password) { - memcpy(_wifi_cfg.sta.ssid, ssid, std::min(strlen(ssid), sizeof(_wifi_cfg.sta.ssid))); - - memcpy(_wifi_cfg.sta.password, password, std::min(strlen(password), sizeof(_wifi_cfg.sta.password))); + // Clear the config first + memset(&_wifi_cfg, 0, sizeof(_wifi_cfg)); + + // Copy SSID with null termination + size_t ssid_len = std::min(strlen(ssid), sizeof(_wifi_cfg.sta.ssid) - 1); + memcpy(_wifi_cfg.sta.ssid, ssid, ssid_len); + _wifi_cfg.sta.ssid[ssid_len] = '\0'; + + // Copy password with null termination + size_t pass_len = std::min(strlen(password), sizeof(_wifi_cfg.sta.password) - 1); + memcpy(_wifi_cfg.sta.password, password, pass_len); + _wifi_cfg.sta.password[pass_len] = '\0'; + + // Set other required fields + // Use open auth if no password, otherwise allow any WPA variant + if (strlen(password) == 0) { + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; + } else { + // IMPORTANT: Set threshold to WEP to accept ANY security mode >= WEP + // This allows WPA, WPA2, WPA3, etc. The driver will negotiate the highest common mode + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WEP; + } + + // CRITICAL: Disable PMF completely - this often causes handshake timeouts + _wifi_cfg.sta.pmf_cfg.capable = false; + _wifi_cfg.sta.pmf_cfg.required = false; + + // IMPORTANT: Set scan method to ALL channels + _wifi_cfg.sta.scan_method = WIFI_ALL_CHANNEL_SCAN; + _wifi_cfg.sta.bssid_set = 0; // Don't use specific BSSID + _wifi_cfg.sta.channel = 0; // Scan all channels + + // Additional settings that might help with compatibility + _wifi_cfg.sta.listen_interval = 0; // Default listen interval + _wifi_cfg.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; // Connect to strongest signal + + // IMPORTANT: For WPA/WPA2 Personal networks + _wifi_cfg.sta.threshold.rssi = -127; // Accept any signal strength + _wifi_cfg.sta.sae_pwe_h2e = WPA3_SAE_PWE_UNSPECIFIED; // Let driver decide SAE mode + + // Log what we're trying to connect to with detailed debugging + ESP_LOGI(WIFI_MANAGER_TAG, "Setting credentials for SSID: '%s' (length: %d)", ssid, (int)strlen(ssid)); + ESP_LOGI(WIFI_MANAGER_TAG, "Password: '%s' (length: %d)", password, (int)strlen(password)); + ESP_LOGI(WIFI_MANAGER_TAG, "Auth mode: %d, PMF capable: %d", + _wifi_cfg.sta.threshold.authmode, _wifi_cfg.sta.pmf_cfg.capable); + + // Print hex dump of SSID to catch any hidden characters + ESP_LOG_BUFFER_HEX_LEVEL(WIFI_MANAGER_TAG, _wifi_cfg.sta.ssid, strlen((char*)_wifi_cfg.sta.ssid), ESP_LOG_INFO); + + // Print hex dump of password to catch any hidden characters + ESP_LOG_BUFFER_HEX_LEVEL(WIFI_MANAGER_TAG, _wifi_cfg.sta.password, strlen((char*)_wifi_cfg.sta.password), ESP_LOG_INFO); } void WiFiManager::ConnectWithHardcodedCredentials() { SystemEvent event = {EventSource::WIFI, WiFiState_e::WiFiState_ReadyToConnect}; this->SetCredentials(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD); + esp_wifi_stop(); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &_wifi_cfg)); xQueueSend(this->eventQueue, &event, 10); @@ -103,16 +161,38 @@ void WiFiManager::ConnectWithStoredCredentials() return; } + // Stop WiFi once before the loop + esp_wifi_stop(); + vTaskDelay(pdMS_TO_TICKS(100)); + + // Ensure we're in STA mode + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + for (const auto& network : networks) { - xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT); + // Reset retry counter for each network attempt + s_retry_num = 0; + xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); this->SetCredentials(network.ssid.c_str(), network.password.c_str()); - // we need to update the config after every credential change + // Update config without stopping WiFi again + ESP_LOGI(WIFI_MANAGER_TAG, "Attempting to connect to SSID: '%s'", network.ssid.c_str()); + + // Double-check the actual config being sent to WiFi driver + ESP_LOGI(WIFI_MANAGER_TAG, "Final SSID in config: '%s' (len: %d)", + (char*)_wifi_cfg.sta.ssid, (int)strlen((char*)_wifi_cfg.sta.ssid)); + ESP_LOGI(WIFI_MANAGER_TAG, "Final password in config: '%s' (len: %d)", + (char*)_wifi_cfg.sta.password, (int)strlen((char*)_wifi_cfg.sta.password)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &_wifi_cfg)); xQueueSend(this->eventQueue, &event, 10); - esp_wifi_start(); + // Start WiFi if not already started + esp_err_t start_err = esp_wifi_start(); + if (start_err != ESP_OK && start_err != ESP_ERR_WIFI_STATE) { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to start WiFi: %s", esp_err_to_name(start_err)); + continue; + } event.value = WiFiState_e::WiFiState_Connecting; xQueueSend(this->eventQueue, &event, 10); @@ -121,19 +201,23 @@ void WiFiManager::ConnectWithStoredCredentials() WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, - portMAX_DELAY); + pdMS_TO_TICKS(30000)); // 30 second timeout instead of portMAX_DELAY if (bits & WIFI_CONNECTED_BIT) { - ESP_LOGI(WIFI_MANAGER_TAG, "connected to ap SSID:%p password:%p", - _wifi_cfg.sta.ssid, _wifi_cfg.sta.password); + ESP_LOGI(WIFI_MANAGER_TAG, "connected to ap SSID:%s", + network.ssid.c_str()); event.value = WiFiState_e::WiFiState_Connected; xQueueSend(this->eventQueue, &event, 10); return; } - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to SSID:%p, password:%p, trying next stored network", - _wifi_cfg.sta.ssid, _wifi_cfg.sta.password); + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to SSID:%s, trying next stored network", + network.ssid.c_str()); + + // Disconnect before trying next network + esp_wifi_disconnect(); + vTaskDelay(pdMS_TO_TICKS(100)); } event.value = WiFiState_e::WiFiState_Error; @@ -165,6 +249,109 @@ void WiFiManager::SetupAccessPoint() ESP_LOGI(WIFI_MANAGER_TAG, "AP started."); } +std::vector WiFiManager::ScanNetworks() { + wifi_mode_t current_mode; + esp_err_t err = esp_wifi_get_mode(¤t_mode); + + if (err == ESP_ERR_WIFI_NOT_INIT) { + ESP_LOGE(WIFI_MANAGER_TAG, "WiFi not initialized for scanning"); + return std::vector(); + } + + // If we're in AP-only mode, we need STA interface for scanning + if (current_mode == WIFI_MODE_AP) { + ESP_LOGI(WIFI_MANAGER_TAG, "AP mode detected, checking for STA interface"); + + // Check if STA netif already exists + esp_netif_t* sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + bool sta_netif_exists = (sta_netif != nullptr); + + if (!sta_netif_exists) { + ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface for scanning"); + sta_netif = esp_netif_create_default_wifi_sta(); + } + + ESP_LOGI(WIFI_MANAGER_TAG, "Switching to APSTA mode for scanning"); + err = esp_wifi_set_mode(WIFI_MODE_APSTA); + if (err != ESP_OK) { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to set APSTA mode: %s", esp_err_to_name(err)); + if (!sta_netif_exists && sta_netif) { + esp_netif_destroy(sta_netif); + } + return std::vector(); + } + + // Configure STA with empty config to prevent auto-connect + wifi_config_t empty_config = {}; + esp_wifi_set_config(WIFI_IF_STA, &empty_config); + + // Ensure STA is disconnected and not trying to connect + esp_wifi_disconnect(); + vTaskDelay(pdMS_TO_TICKS(500)); + + // Longer delay for mode to stabilize and enable all channels + vTaskDelay(pdMS_TO_TICKS(1500)); + + // Perform scan + auto networks = wifiScanner->scanNetworks(); + + // Restore AP-only mode + ESP_LOGI(WIFI_MANAGER_TAG, "Restoring AP-only mode"); + esp_wifi_set_mode(WIFI_MODE_AP); + + // Clean up STA interface if we created it + if (!sta_netif_exists && sta_netif) { + esp_netif_destroy(sta_netif); + } + + return networks; + } + + // If already in STA or APSTA mode, scan directly + return wifiScanner->scanNetworks(); +} + +WiFiState_e WiFiManager::GetCurrentWiFiState() { + return this->stateManager->GetWifiState(); +} + +void WiFiManager::TryConnectToStoredNetworks() { + ESP_LOGI(WIFI_MANAGER_TAG, "Manual WiFi connection attempt requested"); + + // Check current WiFi mode + wifi_mode_t current_mode; + esp_err_t err = esp_wifi_get_mode(¤t_mode); + if (err != ESP_OK) { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to get WiFi mode: %s", esp_err_to_name(err)); + return; + } + + // If in AP mode, we need to properly transition to STA mode + if (current_mode == WIFI_MODE_AP || current_mode == WIFI_MODE_APSTA) { + ESP_LOGI(WIFI_MANAGER_TAG, "Currently in AP mode, transitioning to STA mode"); + + // Stop WiFi first + esp_wifi_stop(); + vTaskDelay(pdMS_TO_TICKS(100)); + + // Check if STA interface exists, create if needed + esp_netif_t* sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + if (sta_netif == nullptr) { + ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface"); + sta_netif = esp_netif_create_default_wifi_sta(); + } + + // Set to STA mode + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + // Reset retry counter and clear all event bits + s_retry_num = 0; + xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); + this->ConnectWithStoredCredentials(); +} + void WiFiManager::Begin() { s_wifi_event_group = xEventGroupCreate(); @@ -176,6 +363,18 @@ void WiFiManager::Begin() wifi_init_config_t esp_wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&esp_wifi_init_config)); + // Set WiFi country to enable all channels (1-14) + wifi_country_t country_config = { + .cc = "JP", // Japan allows channels 1-14 (most permissive) + .schan = 1, + .nchan = 14, + .max_tx_power = 20, + .policy = WIFI_COUNTRY_POLICY_AUTO + }; + ESP_ERROR_CHECK(esp_wifi_set_country(&country_config)); + + + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &WiFiManagerHelpers::event_handler, @@ -188,8 +387,8 @@ void WiFiManager::Begin() &instance_got_ip)); _wifi_cfg = {}; - _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WEP; - _wifi_cfg.sta.pmf_cfg.capable = true; + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; // Start with open, will be set properly by SetCredentials + _wifi_cfg.sta.pmf_cfg.capable = false; // Disable PMF by default _wifi_cfg.sta.pmf_cfg.required = false; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); diff --git a/components/wifiManager/wifiManager/wifiManager.hpp b/components/wifiManager/wifiManager/wifiManager.hpp index b96e8fa..8a78826 100644 --- a/components/wifiManager/wifiManager/wifiManager.hpp +++ b/components/wifiManager/wifiManager/wifiManager.hpp @@ -7,17 +7,20 @@ #include #include #include +#include "WiFiScanner.hpp" #include "esp_event.h" #include "esp_wifi.h" #include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #define EXAMPLE_ESP_MAXIMUM_RETRY 3 #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 -static int s_retry_num = 0; -static EventGroupHandle_t s_wifi_event_group; +extern int s_retry_num; +extern EventGroupHandle_t s_wifi_event_group; namespace WiFiManagerHelpers { @@ -34,6 +37,7 @@ private: StateManager *stateManager; wifi_init_config_t _wifi_init_cfg = WIFI_INIT_CONFIG_DEFAULT(); wifi_config_t _wifi_cfg = {}; + std::unique_ptr wifiScanner; esp_event_handler_instance_t instance_any_id; esp_event_handler_instance_t instance_got_ip; @@ -48,6 +52,9 @@ private: public: WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager *stateManager); void Begin(); + std::vector ScanNetworks(); + WiFiState_e GetCurrentWiFiState(); + void TryConnectToStoredNetworks(); }; #endif \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock index 77a7abe..0530828 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -77,7 +77,7 @@ dependencies: idf: source: type: idf - version: 5.3.2 + version: 5.3.3 direct_dependencies: - espressif/esp32-camera - espressif/led_strip diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index e2d1498..d97ec8d 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef CONFIG_WIRED_MODE #include @@ -29,8 +30,10 @@ #define CONFIG_LED_C_PIN_GPIO (gpio_num_t) CONFIG_LED_C_PIN esp_timer_handle_t timerHandle; +esp_timer_handle_t startupTimerHandle; QueueHandle_t eventQueue = xQueueCreate(10, sizeof(SystemEvent)); QueueHandle_t ledStateQueue = xQueueCreate(10, sizeof(uint32_t)); +bool startupCommandReceived = false; auto *stateManager = new StateManager(eventQueue, ledStateQueue); auto dependencyRegistry = std::make_shared(); @@ -40,7 +43,7 @@ WebSocketLogger webSocketLogger; Preferences preferences; auto deviceConfig = std::make_shared(&preferences); -WiFiManager wifiManager(deviceConfig, eventQueue, stateManager); +auto wifiManager = std::make_shared(deviceConfig, eventQueue, stateManager); MDNSManager mdnsManager(deviceConfig, eventQueue); std::shared_ptr cameraHandler = std::make_shared(deviceConfig, eventQueue); @@ -53,7 +56,7 @@ UVCStreamManager uvcStream; #endif auto *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue); -auto *serialManager = new SerialManager(commandManager, &timerHandle); +auto *serialManager = new SerialManager(commandManager, &timerHandle, deviceConfig); static void initNVSStorage() { @@ -77,54 +80,152 @@ void disable_serial_manager_task(TaskHandle_t serialManagerHandle) vTaskDelete(serialManagerHandle); } -// the idea here is pretty simple. -// After setting everything up, we start a 30s timer with this as a callback -// if we get anything on the serial, we stop the timer and reset it after the commands are done -// this is done to ensure the user has enough time to configure the board if need be -// -// todo: check the initial PR by Summer and port the device mode from that, should be useful -// but we'll have to rethink it +// New setup flow: +// 1. Device starts in setup mode (AP + Serial active) +// 2. User configures WiFi via serial commands +// 3. Device attempts WiFi connection while maintaining setup interfaces +// 4. Device reports connection status via serial +// 5. User explicitly starts streaming after verifying connectivity void start_video_streaming(void *arg) { - if (!deviceConfig->getWifiConfigs().empty() || strcmp(CONFIG_WIFI_SSID, "") != 0) { - // make sure the server runs on a separate core - ESP_LOGI("[MAIN]", "WiFi setup detected, starting WiFi streaming."); - streamServer.startStreamServer(); - } else { + // Get the stored device mode + StreamingMode deviceMode = deviceConfig->getDeviceMode(); + + // Check if WiFi is actually connected, not just configured + bool hasWifiCredentials = !deviceConfig->getWifiConfigs().empty() || strcmp(CONFIG_WIFI_SSID, "") != 0; + bool wifiConnected = (wifiManager->GetCurrentWiFiState() == WiFiState_e::WiFiState_Connected); + + if (deviceMode == StreamingMode::UVC) { #ifdef CONFIG_WIRED_MODE - ESP_LOGI("[MAIN]", "UVC setup detected, starting UVC streaming."); - uvcStream.setup(); + ESP_LOGI("[MAIN]", "Starting UVC streaming mode."); + // Initialize UVC if not already done + static bool uvcInitialized = false; + if (!uvcInitialized) { + ESP_LOGI("[MAIN]", "Initializing UVC hardware..."); + esp_err_t ret = uvcStream.setup(); + if (ret != ESP_OK) { + ESP_LOGE("[MAIN]", "Failed to initialize UVC: %s", esp_err_to_name(ret)); + return; + } + uvcInitialized = true; + } + uvcStream.start(); #else - ESP_LOGE("[MAIN]", "The board does not support UVC, please, setup WiFi connection."); + ESP_LOGE("[MAIN]", "UVC mode selected but CONFIG_WIRED_MODE not enabled in build!"); + ESP_LOGI("[MAIN]", "Falling back to WiFi mode if credentials available"); + deviceMode = StreamingMode::WIFI; #endif } - - ESP_LOGI("[MAIN]", "Setup window expired, started streaming services, quitting serial manager."); - const auto serialTaskHandle = static_cast(arg); - disable_serial_manager_task(serialTaskHandle); -} - -esp_timer_handle_t createStartVideoStreamingTimer(void *pvParameter) -{ - esp_timer_handle_t handle; - const esp_timer_create_args_t args = { - .callback = &start_video_streaming, - .arg = pvParameter, - .name = "startVideoStreaming"}; - - if (const auto result = esp_timer_create(&args, &handle); result != ESP_OK) - { - ESP_LOGE("[MAIN]", "Failed to create timer: %s", esp_err_to_name(result)); + + if ((deviceMode == StreamingMode::WIFI || deviceMode == StreamingMode::AUTO) && hasWifiCredentials && wifiConnected) { + ESP_LOGI("[MAIN]", "Starting WiFi streaming mode."); + streamServer.startStreamServer(); + } else { + if (hasWifiCredentials && !wifiConnected) { + ESP_LOGE("[MAIN]", "WiFi credentials configured but not connected. Try connecting first."); + } else { + ESP_LOGE("[MAIN]", "No streaming mode available. Please configure WiFi."); + } + return; } - return handle; + ESP_LOGI("[MAIN]", "Streaming started successfully."); + + // Optionally disable serial manager after explicit streaming start + if (arg != nullptr) { + ESP_LOGI("[MAIN]", "Disabling setup interfaces after streaming start."); + const auto serialTaskHandle = static_cast(arg); + disable_serial_manager_task(serialTaskHandle); + } +} + +// Manual streaming activation - no timer needed +void activate_streaming(TaskHandle_t serialTaskHandle = nullptr) +{ + start_video_streaming(serialTaskHandle); +} + +// Callback for automatic startup after delay +void startup_timer_callback(void* arg) +{ + ESP_LOGI("[MAIN]", "Startup timer fired, startupCommandReceived=%s, startupPaused=%s", + startupCommandReceived ? "true" : "false", + startupPaused ? "true" : "false"); + + if (!startupCommandReceived && !startupPaused) { + ESP_LOGI("[MAIN]", "No command received during startup delay, proceeding with automatic mode startup"); + + // Get the stored device mode + StreamingMode deviceMode = deviceConfig->getDeviceMode(); + ESP_LOGI("[MAIN]", "Stored device mode: %d", (int)deviceMode); + + // Get the serial manager handle to disable it after streaming starts + TaskHandle_t* serialHandle = getSerialManagerHandle(); + TaskHandle_t serialTaskHandle = (serialHandle && *serialHandle) ? *serialHandle : nullptr; + + if (deviceMode == StreamingMode::WIFI || deviceMode == StreamingMode::AUTO) { + // For WiFi mode, check if we have credentials and are connected + bool hasWifiCredentials = !deviceConfig->getWifiConfigs().empty() || strcmp(CONFIG_WIFI_SSID, "") != 0; + bool wifiConnected = (wifiManager->GetCurrentWiFiState() == WiFiState_e::WiFiState_Connected); + + ESP_LOGI("[MAIN]", "WiFi check - hasCredentials: %s, connected: %s", + hasWifiCredentials ? "true" : "false", + wifiConnected ? "true" : "false"); + + if (hasWifiCredentials && wifiConnected) { + ESP_LOGI("[MAIN]", "Starting WiFi streaming automatically"); + activate_streaming(serialTaskHandle); + } else if (hasWifiCredentials && !wifiConnected) { + ESP_LOGI("[MAIN]", "WiFi credentials exist but not connected, waiting..."); + // Could retry connection here + } else { + ESP_LOGI("[MAIN]", "No WiFi credentials, staying in setup mode"); + } + } + else if (deviceMode == StreamingMode::UVC) { +#ifdef CONFIG_WIRED_MODE + ESP_LOGI("[MAIN]", "Starting UVC streaming automatically"); + activate_streaming(serialTaskHandle); +#else + ESP_LOGE("[MAIN]", "UVC mode selected but CONFIG_WIRED_MODE not enabled in build!"); + ESP_LOGI("[MAIN]", "Device will stay in setup mode. Enable CONFIG_WIRED_MODE and rebuild."); +#endif + } + else { + ESP_LOGI("[MAIN]", "Unknown device mode: %d", (int)deviceMode); + } + } else { + if (startupPaused) { + ESP_LOGI("[MAIN]", "Startup paused, staying in heartbeat mode"); + } else { + ESP_LOGI("[MAIN]", "Command received during startup, staying in heartbeat mode"); + } + } + + // Delete the timer after it fires + esp_timer_delete(startupTimerHandle); + startupTimerHandle = nullptr; +} + +// Function to notify that a command was received during startup +void notify_startup_command_received() +{ + startupCommandReceived = true; + + // Cancel the startup timer if it's still running + if (startupTimerHandle != nullptr) { + esp_timer_stop(startupTimerHandle); + esp_timer_delete(startupTimerHandle); + startupTimerHandle = nullptr; + ESP_LOGI("[MAIN]", "Startup timer cancelled, staying in heartbeat mode"); + } } extern "C" void app_main(void) { - TaskHandle_t *serialManagerHandle = nullptr; dependencyRegistry->registerService(DependencyType::project_config, deviceConfig); dependencyRegistry->registerService(DependencyType::camera_manager, cameraHandler); + dependencyRegistry->registerService(DependencyType::wifi_manager, wifiManager); // uvc plan // cleanup the logs - done // prepare the camera to be initialized with UVC - done? @@ -197,19 +298,23 @@ extern "C" void app_main(void) deviceConfig->load(); serialManager->setup(); + static TaskHandle_t serialManagerHandle = nullptr; xTaskCreate( HandleSerialManagerTask, "HandleSerialManagerTask", 1024 * 6, serialManager, 1, // we only rely on the serial manager during provisioning, we can run it slower - serialManagerHandle); + &serialManagerHandle); - wifiManager.Begin(); + wifiManager->Begin(); mdnsManager.start(); restAPI->begin(); cameraHandler->setupCamera(); + // Don't initialize UVC here - wait for the timer to decide + // UVC will be initialized when streaming actually starts + xTaskCreate( HandleRestAPIPollTask, "HandleRestAPIPollTask", @@ -218,9 +323,44 @@ extern "C" void app_main(void) 1, // it's the rest API, we only serve commands over it so we don't really need a higher priority nullptr); - timerHandle = createStartVideoStreamingTimer(serialManagerHandle); - if (timerHandle != nullptr) - { - esp_timer_start_once(timerHandle, 30000000); // 30s + // New flow: Device starts with a 20-second delay before automatic mode startup + ESP_LOGI("[MAIN]", "====================================="); + ESP_LOGI("[MAIN]", "STARTUP: 20-SECOND DELAY MODE ACTIVE"); + ESP_LOGI("[MAIN]", "====================================="); + ESP_LOGI("[MAIN]", "Device will wait 20 seconds for commands..."); + + // Get the stored device mode + StreamingMode deviceMode = deviceConfig->getDeviceMode(); + ESP_LOGI("[MAIN]", "Stored device mode: %s (value: %d)", + deviceMode == StreamingMode::UVC ? "UVC" : + deviceMode == StreamingMode::WIFI ? "WiFi" : + "Auto", (int)deviceMode); + + // If WiFi credentials exist, attempt connection but stay in setup mode + if (!deviceConfig->getWifiConfigs().empty()) { + ESP_LOGI("[MAIN]", "WiFi credentials found, attempting connection in background"); + // WiFi connection happens in wifiManager->Begin() above } + + // Reset startup state + startupCommandReceived = false; + + // Create a one-shot timer for 20 seconds + const esp_timer_create_args_t startup_timer_args = { + .callback = &startup_timer_callback, + .arg = nullptr, + .dispatch_method = ESP_TIMER_TASK, + .name = "startup_timer", + .skip_unhandled_events = false + }; + + ESP_ERROR_CHECK(esp_timer_create(&startup_timer_args, &startupTimerHandle)); + ESP_ERROR_CHECK(esp_timer_start_once(startupTimerHandle, 20000000)); // 20 seconds in microseconds + + ESP_LOGI("[MAIN]", "Started 20-second startup timer"); + ESP_LOGI("[MAIN]", "Send any command within 20 seconds to enter heartbeat mode"); + + // Set global handles for component access + setStreamingTimerHandle(&timerHandle); + setSerialManagerHandle(&serialManagerHandle); } diff --git a/sdkconfig b/sdkconfig index fdb88a9..89fd862 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1,6 +1,7 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.3.3 Project Configuration +# CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 CONFIG_SOC_ADC_SUPPORTED=y @@ -63,6 +64,7 @@ CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_SIMD_INSTRUCTION_SUPPORTED=y CONFIG_SOC_XTAL_SUPPORT_40M=y CONFIG_SOC_APPCPU_HAS_CLOCK_GATING_BUG=y CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y @@ -100,6 +102,7 @@ CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_SIMD_PREFERRED_DATA_ALIGNMENT=16 CONFIG_SOC_DS_SIGNATURE_MAX_BIT_LEN=4096 CONFIG_SOC_DS_KEY_PARAM_MD_IV_LENGTH=16 CONFIG_SOC_DS_KEY_CHECK_MAX_WAIT_US=1100 @@ -202,6 +205,7 @@ CONFIG_SOC_RTCIO_PIN_COUNT=22 CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_LP_IO_CLOCK_IS_INDEPENDENT=y CONFIG_SOC_SDM_GROUPS=y CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 CONFIG_SOC_SDM_CLK_SUPPORT_APB=y @@ -242,6 +246,8 @@ CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=54 CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 CONFIG_SOC_TOUCH_SENSOR_VERSION=2 CONFIG_SOC_TOUCH_SENSOR_NUM=15 CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y @@ -365,11 +371,13 @@ CONFIG_IDF_TOOLCHAIN="gcc" CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_INIT_VERSION="5.3.2" +CONFIG_IDF_INIT_VERSION="5.3.3" CONFIG_IDF_TARGET_ESP32S3=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 +# # Build type +# CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y # CONFIG_APP_BUILD_TYPE_RAM is not set CONFIG_APP_BUILD_GENERATE_BINARIES=y @@ -378,11 +386,18 @@ CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y # CONFIG_APP_REPRODUCIBLE_BUILD is not set # CONFIG_APP_NO_BLOBS is not set # end of Build type + +# # Bootloader config +# + +# # Bootloader manager +# CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y CONFIG_BOOTLOADER_PROJECT_VER=1 # end of Bootloader manager + CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0 CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set @@ -395,10 +410,14 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y # CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# # Serial Flash Configurations +# # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # end of Serial Flash Configurations + CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y # CONFIG_BOOTLOADER_FACTORY_RESET is not set # CONFIG_BOOTLOADER_APP_TEST is not set @@ -413,7 +432,10 @@ CONFIG_BOOTLOADER_WDT_TIME_MS=9000 CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set # end of Bootloader config + +# # Security features +# CONFIG_SECURE_BOOT_V2_RSA_SUPPORTED=y CONFIG_SECURE_BOOT_V2_PREFERRED=y # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set @@ -421,13 +443,17 @@ CONFIG_SECURE_BOOT_V2_PREFERRED=y # CONFIG_SECURE_FLASH_ENC_ENABLED is not set CONFIG_SECURE_ROM_DL_MODE_ENABLED=y # end of Security features + +# # Application manager +# CONFIG_APP_COMPILE_TIME_DATE=y # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9 # end of Application manager + CONFIG_ESP_ROM_HAS_CRC_LE=y CONFIG_ESP_ROM_HAS_CRC_BE=y CONFIG_ESP_ROM_HAS_MZ_CRC32=y @@ -455,13 +481,19 @@ CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG=y CONFIG_ESP_ROM_HAS_SW_FLOAT=y CONFIG_ESP_ROM_HAS_VERSION=y CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y + +# # Boot ROM Behavior +# CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y # CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set # CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set # CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set # end of Boot ROM Behavior + +# # Serial flasher config +# # CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_OCT_FLASH is not set CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=y @@ -495,7 +527,10 @@ CONFIG_ESPTOOLPY_AFTER_RESET=y CONFIG_ESPTOOLPY_AFTER="hard_reset" CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # end of Serial flasher config + +# # Partition Table +# # CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set @@ -505,12 +540,17 @@ CONFIG_PARTITION_TABLE_FILENAME="min_spiffs.csv" CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table + +# # OpenIris basic configuration +# CONFIG_ENV_GPIO_RANGE_MIN=0 CONFIG_ENV_GPIO_RANGE_MAX=48 CONFIG_ENV_GPIO_IN_RANGE_MAX=48 CONFIG_ENV_GPIO_OUT_RANGE_MAX=48 CONFIG_BLINK_GPIO=38 +CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL=y +CONFIG_LED_C_PIN=1 CONFIG_BLINK_PERIOD=1000 CONFIG_WIRED_MODE=y CONFIG_MDNS_HOSTNAME="openiristracker" @@ -518,10 +558,11 @@ CONFIG_WIFI_SSID="" CONFIG_WIFI_PASSWORD="" CONFIG_AP_WIFI_SSID="EyeTrackVR" CONFIG_AP_WIFI_PASSWORD="12345678" -# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set -CONFIG_LED_C_PIN=1 # end of OpenIris basic configuration + +# # Camera sensor pinout configuration +# CONFIG_CAMERA_MODULE_NAME="SWROOM_BABBLE_S3" CONFIG_PWDN_GPIO_NUM=-1 CONFIG_RESET_GPIO_NUM=-1 @@ -540,7 +581,10 @@ CONFIG_VSYNC_GPIO_NUM=21 CONFIG_HREF_GPIO_NUM=14 CONFIG_PCLK_GPIO_NUM=7 # end of Camera sensor pinout configuration + +# # Compiler options +# # CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_COMPILER_OPTIMIZATION_SIZE is not set CONFIG_COMPILER_OPTIMIZATION_PERF=y @@ -567,8 +611,14 @@ CONFIG_COMPILER_RT_LIB_NAME="gcc" # CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y # end of Compiler options + +# # Component config +# + +# # Application Level Tracing +# # CONFIG_APPTRACE_DEST_JTAG is not set CONFIG_APPTRACE_DEST_NONE=y # CONFIG_APPTRACE_DEST_UART1 is not set @@ -578,52 +628,110 @@ CONFIG_APPTRACE_DEST_UART_NONE=y CONFIG_APPTRACE_UART_TASK_PRIO=1 CONFIG_APPTRACE_LOCK_ENABLE=y # end of Application Level Tracing + +# # Bluetooth +# # CONFIG_BT_ENABLED is not set -CONFIG_BT_ALARM_MAX_NUM=50 + +# +# Common Options +# +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# end of Common Options # end of Bluetooth + +# # Console Library +# # CONFIG_CONSOLE_SORTED_HELP is not set # end of Console Library + +# # Driver Configurations +# + +# # TWAI Configuration +# # CONFIG_TWAI_ISR_IN_IRAM is not set CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # end of TWAI Configuration + +# # Legacy ADC Driver Configuration +# # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set + +# # Legacy ADC Calibration Configuration +# # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set # end of Legacy ADC Calibration Configuration # end of Legacy ADC Driver Configuration + +# # Legacy MCPWM Driver Configurations +# # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations + +# # Legacy Timer Group Driver Configurations +# # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations + +# # Legacy RMT Driver Configurations +# # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations + +# # Legacy I2S Driver Configurations +# # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations + +# # Legacy PCNT Driver Configurations +# # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations + +# # Legacy SDM Driver Configurations +# # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations + +# # Legacy Temperature Sensor Driver Configurations +# # CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_TEMP_SENSOR_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Temperature Sensor Driver Configurations # end of Driver Configurations + +# # eFuse Bit Manager +# # CONFIG_EFUSE_CUSTOM_TABLE is not set # CONFIG_EFUSE_VIRTUAL is not set CONFIG_EFUSE_MAX_BLK_LEN=256 # end of eFuse Bit Manager + +# # ESP-TLS +# CONFIG_ESP_TLS_USING_MBEDTLS=y CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set @@ -633,80 +741,135 @@ CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y # CONFIG_ESP_TLS_PSK_VERIFICATION is not set # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS + +# # ADC and ADC Calibration +# # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set # CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 is not set # CONFIG_ADC_ENABLE_DEBUG_LOG is not set # end of ADC and ADC Calibration + +# # Wireless Coexistence +# CONFIG_ESP_COEX_ENABLED=y # CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set # CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence + +# # Common ESP-related +# CONFIG_ESP_ERR_TO_NAME_LOOKUP=y # end of Common ESP-related + +# # ESP-Driver:GPIO Configurations +# # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:GPIO Configurations + +# # ESP-Driver:GPTimer Configurations +# CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations + +# # ESP-Driver:I2C Configurations +# # CONFIG_I2C_ISR_IRAM_SAFE is not set # CONFIG_I2C_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2C Configurations + +# # ESP-Driver:I2S Configurations +# # CONFIG_I2S_ISR_IRAM_SAFE is not set # CONFIG_I2S_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:I2S Configurations + +# # ESP-Driver:LEDC Configurations +# # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set # end of ESP-Driver:LEDC Configurations + +# # ESP-Driver:MCPWM Configurations +# # CONFIG_MCPWM_ISR_IRAM_SAFE is not set # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:MCPWM Configurations + +# # ESP-Driver:PCNT Configurations +# # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set # CONFIG_PCNT_ISR_IRAM_SAFE is not set # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:PCNT Configurations + +# # ESP-Driver:RMT Configurations +# # CONFIG_RMT_ISR_IRAM_SAFE is not set # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set # CONFIG_RMT_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:RMT Configurations + +# # ESP-Driver:Sigma Delta Modulator Configurations +# # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set # CONFIG_SDM_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Sigma Delta Modulator Configurations + +# # ESP-Driver:SPI Configurations +# # CONFIG_SPI_MASTER_IN_IRAM is not set CONFIG_SPI_MASTER_ISR_IN_IRAM=y # CONFIG_SPI_SLAVE_IN_IRAM is not set CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # end of ESP-Driver:SPI Configurations + +# # ESP-Driver:Touch Sensor Configurations +# # CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set # CONFIG_TOUCH_ISR_IRAM_SAFE is not set # CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Touch Sensor Configurations + +# # ESP-Driver:Temperature Sensor Configurations +# # CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:Temperature Sensor Configurations + +# # ESP-Driver:UART Configurations +# # CONFIG_UART_ISR_IN_IRAM is not set # end of ESP-Driver:UART Configurations + +# # ESP-Driver:USB Serial/JTAG Configuration +# CONFIG_USJ_ENABLE_USB_SERIAL_JTAG=y # end of ESP-Driver:USB Serial/JTAG Configuration + +# # Ethernet +# CONFIG_ETH_ENABLED=y CONFIG_ETH_USE_SPI_ETHERNET=y # CONFIG_ETH_SPI_ETHERNET_DM9051 is not set @@ -715,24 +878,43 @@ CONFIG_ETH_USE_SPI_ETHERNET=y # CONFIG_ETH_USE_OPENETH is not set # CONFIG_ETH_TRANSMIT_MUTEX is not set # end of Ethernet + +# # Event Loop Library +# # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y # end of Event Loop Library + +# # GDB Stub +# CONFIG_ESP_GDBSTUB_ENABLED=y # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 # end of GDB Stub + +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + +# # ESP HTTP client +# CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set # end of ESP HTTP client + +# # HTTP Server +# CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y @@ -741,28 +923,49 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 CONFIG_HTTPD_WS_SUPPORT=y # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set # end of HTTP Server + +# # ESP HTTPS OTA +# # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set # end of ESP HTTPS OTA + +# # ESP HTTPS server +# # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set # end of ESP HTTPS server + +# # Hardware Settings +# + +# # Chip revision +# CONFIG_ESP32S3_REV_MIN_0=y # CONFIG_ESP32S3_REV_MIN_1 is not set # CONFIG_ESP32S3_REV_MIN_2 is not set CONFIG_ESP32S3_REV_MIN_FULL=0 CONFIG_ESP_REV_MIN_FULL=0 + +# # Maximum Supported ESP32-S3 Revision (Rev v0.99) +# CONFIG_ESP32S3_REV_MAX_FULL=99 CONFIG_ESP_REV_MAX_FULL=99 CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=199 + +# # Maximum Supported ESP32-S3 eFuse Block Revision (eFuse Block Rev v1.99) +# # end of Chip revision + +# # MAC Config +# CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y @@ -774,7 +977,10 @@ CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set # end of MAC Config + +# # Sleep Config +# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND=y CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y @@ -785,36 +991,61 @@ CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y # end of Sleep Config + +# # RTC Clock Config +# CONFIG_RTC_CLK_SRC_INT_RC=y # CONFIG_RTC_CLK_SRC_EXT_CRYS is not set # CONFIG_RTC_CLK_SRC_EXT_OSC is not set # CONFIG_RTC_CLK_SRC_INT_8MD256 is not set CONFIG_RTC_CLK_CAL_CYCLES=1024 # end of RTC Clock Config + +# # Peripheral Control +# CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y # end of Peripheral Control + +# # GDMA Configurations +# CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y # CONFIG_GDMA_ISR_IRAM_SAFE is not set # CONFIG_GDMA_ENABLE_DEBUG_LOG is not set # end of GDMA Configurations + +# # Main XTAL Config +# CONFIG_XTAL_FREQ_40=y CONFIG_XTAL_FREQ=40 # end of Main XTAL Config + CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # end of Hardware Settings + +# # LCD and Touch Panel +# + +# # LCD Touch Drivers are maintained in the IDF Component Registry +# + +# # LCD Peripheral Configuration +# # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set # CONFIG_LCD_RGB_RESTART_IN_VSYNC is not set # end of LCD Peripheral Configuration # end of LCD and Touch Panel + +# # ESP NETIF Adapter +# CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set @@ -824,9 +1055,15 @@ CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y # CONFIG_ESP_NETIF_BRIDGE_EN is not set # CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set # end of ESP NETIF Adapter + +# # Partition API Configuration +# # end of Partition API Configuration + +# # PHY +# CONFIG_ESP_PHY_ENABLED=y CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set @@ -840,16 +1077,26 @@ CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY + +# # Power Management +# # CONFIG_PM_ENABLE is not set # CONFIG_PM_SLP_IRAM_OPT is not set CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP=y # end of Power Management + +# # ESP PSRAM +# CONFIG_SPIRAM=y + +# # SPI RAM config +# CONFIG_SPIRAM_MODE_QUAD=y # CONFIG_SPIRAM_MODE_OCT is not set CONFIG_SPIRAM_TYPE_AUTO=y @@ -879,15 +1126,24 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set # end of SPI RAM config # end of ESP PSRAM + +# # ESP Ringbuf +# # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf + +# # ESP System Settings +# # CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set # CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 + +# # Cache config +# CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB=y # CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB is not set CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE=0x4000 @@ -909,14 +1165,21 @@ CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y # CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 # end of Cache config + +# # Memory +# # CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set # CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set # end of Memory + +# # Trace memory +# # CONFIG_ESP32S3_TRAX is not set CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 # end of Trace memory + # CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set @@ -924,10 +1187,14 @@ CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# # Memory protection +# CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y # end of Memory protection + CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 @@ -961,7 +1228,10 @@ CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# # Brownout Detector +# CONFIG_ESP_BROWNOUT_DET=y CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set @@ -972,15 +1242,22 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set CONFIG_ESP_BROWNOUT_DET_LVL=7 # end of Brownout Detector + CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y CONFIG_ESP_SYSTEM_BBPLL_RECALIB=y # end of ESP System Settings + +# # IPC (Inter-Processor Call) +# CONFIG_ESP_IPC_TASK_STACK_SIZE=1280 CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y CONFIG_ESP_IPC_ISR_ENABLE=y # end of IPC (Inter-Processor Call) + +# # ESP Timer (High Resolution Timer) +# # CONFIG_ESP_TIMER_PROFILING is not set CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y @@ -993,14 +1270,17 @@ CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set CONFIG_ESP_TIMER_IMPL_SYSTIMER=y # end of ESP Timer (High Resolution Timer) + +# # Wi-Fi +# CONFIG_ESP_WIFI_ENABLED=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 @@ -1010,7 +1290,6 @@ CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP_WIFI_RX_BA_WIN=6 -# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP_WIFI_NVS_ENABLED=y CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set @@ -1043,21 +1322,31 @@ CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y # CONFIG_ESP_WIFI_DPP_SUPPORT is not set # CONFIG_ESP_WIFI_11R_SUPPORT is not set # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# # WPS Configuration Options +# # CONFIG_ESP_WIFI_WPS_STRICT is not set # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set # end of WPS Configuration Options + # CONFIG_ESP_WIFI_DEBUG_PRINT is not set # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set # end of Wi-Fi + +# # Core dump +# # CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set # CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y # end of Core dump + +# # FAT Filesystem support +# CONFIG_FATFS_VOLUME_COUNT=2 CONFIG_FATFS_LFN_NONE=y # CONFIG_FATFS_LFN_HEAP is not set @@ -1097,8 +1386,14 @@ CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y # end of FAT Filesystem support + +# # FreeRTOS +# + +# # Kernel +# # CONFIG_FREERTOS_SMP is not set # CONFIG_FREERTOS_UNICORE is not set CONFIG_FREERTOS_HZ=1000 @@ -1126,7 +1421,10 @@ CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel + +# # Port +# # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set @@ -1141,6 +1439,7 @@ CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port + CONFIG_FREERTOS_PORT=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y @@ -1149,7 +1448,10 @@ CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y CONFIG_FREERTOS_NUMBER_OF_CORES=2 # end of FreeRTOS + +# # Hardware Abstraction Layer (HAL) and Low Level (LL) +# CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y # CONFIG_HAL_ASSERTION_DISABLE is not set # CONFIG_HAL_ASSERTION_SILENT is not set @@ -1158,9 +1460,11 @@ CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 CONFIG_HAL_WDT_USE_ROM_IMPL=y CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set # end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# # Heap memory debugging +# CONFIG_HEAP_POISONING_DISABLED=y # CONFIG_HEAP_POISONING_LIGHT is not set # CONFIG_HEAP_POISONING_COMPREHENSIVE is not set @@ -1172,7 +1476,10 @@ CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set # end of Heap memory debugging + +# # Log output +# # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set # CONFIG_LOG_DEFAULT_LEVEL_WARN is not set @@ -1189,7 +1496,10 @@ CONFIG_LOG_COLORS=y CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set # end of Log output + +# # LWIP +# CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" # CONFIG_LWIP_NETIF_API is not set @@ -1230,12 +1540,16 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y CONFIG_LWIP_DHCP_OPTIONS_LEN=68 CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# # DHCP server +# CONFIG_LWIP_DHCPS=y CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y # end of DHCP server + # CONFIG_LWIP_AUTOIP is not set CONFIG_LWIP_IPV4=y CONFIG_LWIP_IPV6=y @@ -1245,7 +1559,10 @@ CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# # TCP +# CONFIG_LWIP_MAX_ACTIVE_TCP=16 CONFIG_LWIP_MAX_LISTENING_TCP=16 CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y @@ -1268,15 +1585,22 @@ CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set CONFIG_LWIP_TCP_RTO_TIME=1500 # end of TCP + +# # UDP +# CONFIG_LWIP_MAX_UDP_PCBS=16 CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 # end of UDP + +# # Checksums +# # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums + CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set @@ -1289,30 +1613,46 @@ CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # CONFIG_LWIP_SLIP_SUPPORT is not set + +# # ICMP +# CONFIG_LWIP_ICMP=y # CONFIG_LWIP_MULTICAST_PING is not set # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP + +# # LWIP RAW API +# CONFIG_LWIP_MAX_RAW_PCBS=16 # end of LWIP RAW API + +# # SNTP +# CONFIG_LWIP_SNTP_MAX_SERVERS=1 # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 CONFIG_LWIP_SNTP_STARTUP_DELAY=y CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 # end of SNTP + +# # DNS +# CONFIG_LWIP_DNS_MAX_HOST_IP=1 CONFIG_LWIP_DNS_MAX_SERVERS=3 # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set # CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set # end of DNS + CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# # Hooks +# # CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y # CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set @@ -1334,9 +1674,13 @@ CONFIG_LWIP_HOOK_IP6_INPUT_NONE=y # CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT is not set # CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set # end of Hooks + # CONFIG_LWIP_DEBUG is not set # end of LWIP + +# # mbedTLS +# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y # CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set # CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set @@ -1346,7 +1690,10 @@ CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set # CONFIG_MBEDTLS_DEBUG is not set + +# # mbedTLS v3.x related +# # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set @@ -1354,7 +1701,10 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y CONFIG_MBEDTLS_PKCS7_C=y # end of mbedTLS v3.x related + +# # Certificate Bundle +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set @@ -1363,6 +1713,7 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle + # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y @@ -1390,7 +1741,10 @@ CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y CONFIG_MBEDTLS_TLS_SERVER=y CONFIG_MBEDTLS_TLS_CLIENT=y CONFIG_MBEDTLS_TLS_ENABLED=y + +# # TLS Key Exchange Methods +# # CONFIG_MBEDTLS_PSK_MODES is not set CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y @@ -1399,6 +1753,7 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y # end of TLS Key Exchange Methods + CONFIG_MBEDTLS_SSL_RENEGOTIATION=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set @@ -1406,7 +1761,10 @@ CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# # Symmetric Ciphers +# CONFIG_MBEDTLS_AES_C=y # CONFIG_MBEDTLS_CAMELLIA_C is not set # CONFIG_MBEDTLS_DES_C is not set @@ -1416,13 +1774,18 @@ CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y # CONFIG_MBEDTLS_NIST_KW_C is not set # end of Symmetric Ciphers + # CONFIG_MBEDTLS_RIPEMD160_C is not set + +# # Certificates +# CONFIG_MBEDTLS_PEM_PARSE_C=y CONFIG_MBEDTLS_PEM_WRITE_C=y CONFIG_MBEDTLS_X509_CRL_PARSE_C=y CONFIG_MBEDTLS_X509_CSR_PARSE_C=y # end of Certificates + CONFIG_MBEDTLS_ECP_C=y # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y @@ -1449,7 +1812,10 @@ CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y # end of mbedTLS + +# # ESP-MQTT Configurations +# CONFIG_MQTT_PROTOCOL_311=y # CONFIG_MQTT_PROTOCOL_5 is not set CONFIG_MQTT_TRANSPORT_SSL=y @@ -1462,7 +1828,10 @@ CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set # CONFIG_MQTT_CUSTOM_OUTBOX is not set # end of ESP-MQTT Configurations + +# # Newlib +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set # CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set @@ -1475,35 +1844,41 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y # CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set # CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set # end of Newlib + CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y + +# # NVS +# # CONFIG_NVS_ENCRYPTION is not set # CONFIG_NVS_ASSERT_ERROR_CHECK is not set # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set # end of NVS + +# # OpenThread +# # CONFIG_OPENTHREAD_ENABLED is not set -# Thread Operational Dataset -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" -CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" -CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 -CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" -CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" -CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" -# end of Thread Operational Dataset -CONFIG_OPENTHREAD_XTAL_ACCURACY=130 + +# +# OpenThread Spinel +# # CONFIG_OPENTHREAD_SPINEL_ONLY is not set -CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y -# Thread Address Query Config -# end of Thread Address Query Config +# end of OpenThread Spinel # end of OpenThread + +# # Protocomm +# CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y # end of Protocomm + +# # PThreads +# CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 CONFIG_PTHREAD_STACK_MIN=768 @@ -1513,18 +1888,33 @@ CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" # end of PThreads + +# # MMU Config +# CONFIG_MMU_PAGE_SIZE_64KB=y CONFIG_MMU_PAGE_MODE="64KB" CONFIG_MMU_PAGE_SIZE=0x10000 # end of MMU Config + +# # Main Flash configuration +# + +# # SPI Flash behavior when brownout +# CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y CONFIG_SPI_FLASH_BROWNOUT_RESET=y # end of SPI Flash behavior when brownout + +# # Optional and Experimental Features (READ DOCS FIRST) +# + +# # Features here require specific hardware (READ DOCS FIRST!) +# # CONFIG_SPI_FLASH_HPM_ENA is not set CONFIG_SPI_FLASH_HPM_AUTO=y # CONFIG_SPI_FLASH_HPM_DIS is not set @@ -1537,7 +1927,10 @@ CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration + +# # SPI Flash driver +# # CONFIG_SPI_FLASH_VERIFY_WRITE is not set # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y @@ -1553,7 +1946,10 @@ CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# # Auto-detect flash chips +# CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y @@ -1569,15 +1965,23 @@ CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP=y # end of Auto-detect flash chips + CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y # end of SPI Flash driver + +# # SPIFFS Configuration +# CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# # SPIFFS Cache Configuration +# CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y # CONFIG_SPIFFS_CACHE_STATS is not set # end of SPIFFS Cache Configuration + CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set @@ -1588,7 +1992,10 @@ CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y CONFIG_SPIFFS_META_LENGTH=4 CONFIG_SPIFFS_USE_MTIME=y + +# # Debug Configuration +# # CONFIG_SPIFFS_DBG is not set # CONFIG_SPIFFS_API_DBG is not set # CONFIG_SPIFFS_GC_DBG is not set @@ -1597,19 +2004,34 @@ CONFIG_SPIFFS_USE_MTIME=y # CONFIG_SPIFFS_TEST_VISUALISATION is not set # end of Debug Configuration # end of SPIFFS Configuration + +# # TCP Transport +# + +# # Websocket +# CONFIG_WS_TRANSPORT=y CONFIG_WS_BUFFER_SIZE=1024 # CONFIG_WS_DYNAMIC_BUFFER is not set # end of Websocket # end of TCP Transport + +# # Ultra Low Power (ULP) Co-processor +# # CONFIG_ULP_COPROC_ENABLED is not set + +# # ULP Debugging Options +# # end of ULP Debugging Options # end of Ultra Low Power (ULP) Co-processor + +# # Unity unit testing library +# CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y # CONFIG_UNITY_ENABLE_64BIT is not set @@ -1618,24 +2040,38 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y # CONFIG_UNITY_ENABLE_FIXTURE is not set # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set # end of Unity unit testing library + +# # USB-OTG +# CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y # CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set # CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set + +# # Hub Driver Configuration +# + +# # Root Port configuration +# CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 CONFIG_USB_HOST_RESET_HOLD_MS=30 CONFIG_USB_HOST_RESET_RECOVERY_MS=30 CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 # end of Root Port configuration + # CONFIG_USB_HOST_HUBS_SUPPORTED is not set # end of Hub Driver Configuration + # CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK is not set CONFIG_USB_OTG_SUPPORTED=y # end of USB-OTG + +# # Virtual file system +# CONFIG_VFS_SUPPORT_IO=y CONFIG_VFS_SUPPORT_DIR=y CONFIG_VFS_SUPPORT_SELECT=y @@ -1643,22 +2079,34 @@ CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y # CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y CONFIG_VFS_MAX_COUNT=8 + +# # Host File System I/O (Semihosting) +# CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # end of Host File System I/O (Semihosting) # end of Virtual file system + +# # Wear Levelling +# # CONFIG_WL_SECTOR_SIZE_512 is not set CONFIG_WL_SECTOR_SIZE_4096=y CONFIG_WL_SECTOR_SIZE=4096 # end of Wear Levelling + +# # Wi-Fi Provisioning Manager +# CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager + +# # CMake Utilities +# # CONFIG_CU_RELINKER_ENABLE is not set # CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y @@ -1666,7 +2114,10 @@ CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y # CONFIG_CU_GCC_LTO_ENABLE is not set # CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set # end of CMake Utilities + +# # Camera configuration +# # CONFIG_OV7670_SUPPORT is not set # CONFIG_OV7725_SUPPORT is not set # CONFIG_NT99141_SUPPORT is not set @@ -1694,7 +2145,10 @@ CONFIG_CAMERA_JPEG_MODE_FRAME_SIZE_AUTO=y # CONFIG_CAMERA_CONVERTER_ENABLED is not set # CONFIG_LCD_CAM_ISR_IRAM_SAFE is not set # end of Camera configuration + +# # mDNS +# CONFIG_MDNS_MAX_INTERFACES=3 CONFIG_MDNS_MAX_SERVICES=10 CONFIG_MDNS_TASK_PRIORITY=1 @@ -1712,20 +2166,29 @@ CONFIG_MDNS_TIMER_PERIOD_MS=100 CONFIG_MDNS_ENABLE_CONSOLE_CLI=y # CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# # MDNS Predefined interfaces +# CONFIG_MDNS_PREDEF_NETIF_STA=y CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_MDNS_PREDEF_NETIF_ETH=y # end of MDNS Predefined interfaces # end of mDNS + +# # USB Device UVC +# CONFIG_TUSB_VID=0x303A CONFIG_TUSB_PID=0x8000 CONFIG_TUSB_MANUFACTURER="ETVR" CONFIG_TUSB_PRODUCT="OpenIris Camera" CONFIG_TUSB_SERIAL_NUM="12345678" # CONFIG_UVC_SUPPORT_TWO_CAM is not set + +# # USB Cam1 Config +# CONFIG_FORMAT_MJPEG_CAM1=y # CONFIG_FORMAT_H264_CAM1 is not set # CONFIG_FORMAT_UNCOMPR_CAM1 is not set @@ -1742,24 +2205,39 @@ CONFIG_UVC_CAM1_FRAMESIZE_WIDTH=240 CONFIG_UVC_CAM1_FRAMESIZE_HEIGT=240 CONFIG_UVC_CAM1_MULTI_FRAMESIZE=y # end of USB Cam1 Config + +# # UVC_MULTI_FRAME_CONFIG +# + +# # FRAME_SIZE_1 +# CONFIG_UVC_MULTI_FRAME_WIDTH_1=240 CONFIG_UVC_MULTI_FRAME_HEIGHT_1=240 CONFIG_UVC_MULTI_FRAME_FPS_1=60 # end of FRAME_SIZE_1 + +# # FRAME_SIZE_2 +# CONFIG_UVC_MULTI_FRAME_WIDTH_2=240 CONFIG_UVC_MULTI_FRAME_HEIGHT_2=240 CONFIG_UVC_MULTI_FRAME_FPS_2=60 # end of FRAME_SIZE_2 + +# # FRAME_SIZE_3 +# CONFIG_UVC_MULTI_FRAME_WIDTH_3=240 CONFIG_UVC_MULTI_FRAME_HEIGHT_3=240 CONFIG_UVC_MULTI_FRAME_FPS_3=60 # end of FRAME_SIZE_3 # end of UVC_MULTI_FRAME_CONFIG + +# # UVC Task Config +# CONFIG_UVC_TINYUSB_TASK_PRIORITY=4 CONFIG_UVC_TINYUSB_TASK_CORE=-1 CONFIG_UVC_CAM1_TASK_PRIORITY=3 @@ -1767,7 +2245,9 @@ CONFIG_UVC_CAM1_TASK_CORE=-1 # end of UVC Task Config # end of USB Device UVC # end of Component config + # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + # Deprecated options for backward compatibility # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set # CONFIG_NO_BLOBS is not set @@ -1879,15 +2359,14 @@ CONFIG_ESP32_WIFI_ENABLED=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP32_WIFI_RX_BA_WIN=6 -# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP32_WIFI_NVS_ENABLED=y CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set @@ -1960,4 +2439,3 @@ CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # End of deprecated options -CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL=y diff --git a/sdkconfig.old b/sdkconfig.old index 2259232..125ee3c 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.3.3 Project Configuration # CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 @@ -64,6 +64,7 @@ CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_SIMD_INSTRUCTION_SUPPORTED=y CONFIG_SOC_XTAL_SUPPORT_40M=y CONFIG_SOC_APPCPU_HAS_CLOCK_GATING_BUG=y CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y @@ -101,6 +102,7 @@ CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_SIMD_PREFERRED_DATA_ALIGNMENT=16 CONFIG_SOC_DS_SIGNATURE_MAX_BIT_LEN=4096 CONFIG_SOC_DS_KEY_PARAM_MD_IV_LENGTH=16 CONFIG_SOC_DS_KEY_CHECK_MAX_WAIT_US=1100 @@ -203,6 +205,7 @@ CONFIG_SOC_RTCIO_PIN_COUNT=22 CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_LP_IO_CLOCK_IS_INDEPENDENT=y CONFIG_SOC_SDM_GROUPS=y CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 CONFIG_SOC_SDM_CLK_SUPPORT_APB=y @@ -243,6 +246,8 @@ CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=54 CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 CONFIG_SOC_TOUCH_SENSOR_VERSION=2 CONFIG_SOC_TOUCH_SENSOR_NUM=15 CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y @@ -366,7 +371,7 @@ CONFIG_IDF_TOOLCHAIN="gcc" CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_INIT_VERSION="5.3.2" +CONFIG_IDF_INIT_VERSION="5.3.3" CONFIG_IDF_TARGET_ESP32S3=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 @@ -544,11 +549,10 @@ CONFIG_ENV_GPIO_RANGE_MAX=48 CONFIG_ENV_GPIO_IN_RANGE_MAX=48 CONFIG_ENV_GPIO_OUT_RANGE_MAX=48 CONFIG_BLINK_GPIO=38 -# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set +CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL=y CONFIG_LED_C_PIN=1 CONFIG_BLINK_PERIOD=1000 -CONFIG_ILLUMINATOR_PIN=1 -CONFIG_WIRED_MODE=y +# CONFIG_WIRED_MODE is not set CONFIG_MDNS_HOSTNAME="openiristracker" CONFIG_WIFI_SSID="" CONFIG_WIFI_PASSWORD="" @@ -629,7 +633,12 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # # CONFIG_BT_ENABLED is not set -CONFIG_BT_ALARM_MAX_NUM=50 + +# +# Common Options +# +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# end of Common Options # end of Bluetooth # @@ -653,6 +662,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # # Legacy ADC Calibration Configuration @@ -665,42 +675,49 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy MCPWM Driver Configurations # # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # # Legacy Temperature Sensor Driver Configurations # # CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_TEMP_SENSOR_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Temperature Sensor Driver Configurations # end of Driver Configurations @@ -760,6 +777,7 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations @@ -878,6 +896,13 @@ CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 # end of GDB Stub +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + # # ESP HTTP client # @@ -1052,6 +1077,7 @@ CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # @@ -1252,9 +1278,9 @@ CONFIG_ESP_WIFI_ENABLED=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 @@ -1264,7 +1290,6 @@ CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP_WIFI_RX_BA_WIN=6 -# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP_WIFI_NVS_ENABLED=y CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set @@ -1435,7 +1460,6 @@ CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 CONFIG_HAL_WDT_USE_ROM_IMPL=y CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set # end of Hardware Abstraction Layer (HAL) and Low Level (LL) # @@ -1837,25 +1861,10 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y # CONFIG_OPENTHREAD_ENABLED is not set # -# Thread Operational Dataset +# OpenThread Spinel # -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" -CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" -CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 -CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" -CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" -CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" -# end of Thread Operational Dataset - -CONFIG_OPENTHREAD_XTAL_ACCURACY=130 # CONFIG_OPENTHREAD_SPINEL_ONLY is not set -CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y - -# -# Thread Address Query Config -# -# end of Thread Address Query Config +# end of OpenThread Spinel # end of OpenThread # @@ -1864,6 +1873,7 @@ CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y # end of Protocomm # @@ -2237,3 +2247,195 @@ CONFIG_UVC_CAM1_TASK_CORE=-1 # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +CONFIG_FLASHMODE_QIO=y +# CONFIG_FLASHMODE_QOUT is not set +# CONFIG_FLASHMODE_DIO is not set +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +# CONFIG_EXTERNAL_COEX_ENABLE is not set +# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_REDUCE_PHY_TX_POWER is not set +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y +CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240 +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32S3_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32S3_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_7=y +CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 +CONFIG_IPC_TASK_STACK_SIZE=1280 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 +CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_SUITE_B_192 is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_SYSTIMER=y +CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py new file mode 100644 index 0000000..e4996eb --- /dev/null +++ b/tools/openiris_setup.py @@ -0,0 +1,816 @@ +#!/usr/bin/env python3 +""" +OpenIris Setup CLI Tool + +This tool automatically discovers OpenIris devices via heartbeat, +allows WiFi configuration, and monitors the device logs. +""" + +import json +import time +import threading +import argparse +import sys +from typing import Dict, List, Optional, Tuple +import serial +import serial.tools.list_ports +from dataclasses import dataclass + + +@dataclass +class WiFiNetwork: + ssid: str + channel: int + rssi: int + mac_address: str + auth_mode: int + + @property + def security_type(self) -> str: + """Convert auth_mode to human readable string""" + auth_modes = { + 0: "Open", + 1: "WEP", + 2: "WPA PSK", + 3: "WPA2 PSK", + 4: "WPA WPA2 PSK", + 5: "WPA2 Enterprise", + 6: "WPA3 PSK", + 7: "WPA2 WPA3 PSK" + } + return auth_modes.get(self.auth_mode, f"Unknown ({self.auth_mode})") + + +class OpenIrisDevice: + def __init__(self, port: str, serial_number: str, debug: bool = False): + + self.port = port + self.serial_number = serial_number + self.connection: Optional[serial.Serial] = None + self.networks: List[WiFiNetwork] = [] + self.debug = debug + + def connect(self) -> bool: + """Connect to the device""" + try: + self.connection = serial.Serial( + port=self.port, + baudrate=115200, + timeout=1, + write_timeout=1 + ) + print(f"āœ… Connected to device {self.serial_number} on {self.port}") + + # Immediately send pause command to keep device in setup mode + print("āøļø Pausing device startup...") + # Use shorter timeout for pause command since device is just starting up + pause_response = self.send_command("pause", {"pause": True}, timeout=5) + if "error" not in pause_response and pause_response.get("results"): + print("āœ… Device paused in setup mode") + elif "error" in pause_response and pause_response["error"] == "Command timeout": + # Even if we timeout, the command likely worked (as seen in logs) + print("āœ… Device pause command sent (startup logs may have obscured response)") + else: + print(f"āš ļø Pause status uncertain: {pause_response}") + + return True + except Exception as e: + print(f"āŒ Failed to connect to {self.port}: {e}") + return False + + def disconnect(self): + """Disconnect from the device""" + if self.connection and self.connection.is_open: + # Optionally unpause the device before disconnecting + print("Resuming device startup...") + self.send_command("pause", {"pause": False}) + + self.connection.close() + print(f"šŸ”Œ Disconnected from {self.port}") + + def send_command(self, command: str, params: Dict = None, timeout: int = None) -> Dict: + """Send a command to the device and wait for response""" + if not self.connection or not self.connection.is_open: + return {"error": "Not connected"} + + cmd_obj = {"commands": [{"command": command}]} + if params: + cmd_obj["commands"][0]["data"] = params + + cmd_json = json.dumps(cmd_obj) + '\n' + + try: + # Clear any pending data + self.connection.reset_input_buffer() + + # Send command + print(f"šŸ“¤ Sending: {cmd_json.strip()}") + self.connection.write(cmd_json.encode()) + + # For scan_networks command, handle special case + if command == "scan_networks": + # Use provided timeout or default to 30 seconds for scan + scan_timeout = timeout if timeout is not None else 30 + return self._handle_scan_response(scan_timeout) + + # Wait for response (skip heartbeats and logs) + start_time = time.time() + response_buffer = "" + + # Use provided timeout or default to 15 seconds + cmd_timeout = timeout if timeout is not None else 15 + while time.time() - start_time < cmd_timeout: + try: + if self.connection.in_waiting: + data = self.connection.read(self.connection.in_waiting).decode('utf-8', errors='ignore') + response_buffer += data + + # Show raw data for debugging + if self.debug and data.strip(): + print(f"šŸ“” Raw: {repr(data)}") + print(f"šŸ“ Buffer: {repr(response_buffer[-200:])}") + + # Clean buffer and look for JSON + import re + + # Remove ANSI escape sequences + clean_buffer = re.sub(r'\x1b\[[0-9;]*m', '', response_buffer) + clean_buffer = clean_buffer.replace('\r', '') + + # Look for JSON objects - handle both single-line and multi-line + # Try to find complete JSON objects + start_idx = clean_buffer.find('{') + while start_idx >= 0: + # Count braces to find complete JSON + brace_count = 0 + end_idx = -1 + + for i in range(start_idx, len(clean_buffer)): + if clean_buffer[i] == '{': + brace_count += 1 + elif clean_buffer[i] == '}': + brace_count -= 1 + if brace_count == 0: + end_idx = i + 1 + break + + if end_idx > start_idx: + json_str = clean_buffer[start_idx:end_idx] + + # Try to parse any complete JSON object + try: + # Clean up the JSON + clean_json = json_str.replace('\t', ' ').replace('\n', ' ').replace('\r', '') + clean_json = re.sub(r'\s+', ' ', clean_json) + + response = json.loads(clean_json) + + # Return if this is a command response with results + if "results" in response: + return response + + except json.JSONDecodeError: + pass + + # Look for next JSON object + start_idx = clean_buffer.find('{', end_idx) + else: + # No complete JSON found yet + break + else: + time.sleep(0.1) + except Exception as e: + print(f"āš ļø Exception: {e}") + continue + + return {"error": "Command timeout"} + except Exception as e: + return {"error": f"Communication error: {e}"} + + def _handle_scan_response(self, timeout: int = 30) -> Dict: + """Handle scan_networks command response which outputs raw JSON first""" + start_time = time.time() + response_buffer = "" + + while time.time() - start_time < timeout: # Configurable timeout for scan + if self.connection.in_waiting: + data = self.connection.read(self.connection.in_waiting).decode('utf-8', errors='ignore') + response_buffer += data + + # Look for WiFi networks JSON directly (new format) + # The scan command now outputs JSON directly followed by command result + if '{"networks":[' in response_buffer: + import re + + # Look for the networks JSON pattern that appears first + networks_pattern = r'\{"networks":\[.*?\]\}' + matches = re.findall(networks_pattern, response_buffer, re.DOTALL) + + for match in matches: + try: + # Parse the networks JSON directly + networks_data = json.loads(match) + if "networks" in networks_data: + # Return in the expected format for compatibility + return {"results": [json.dumps({"result": match})]} + except json.JSONDecodeError: + continue + + # Also check if we have the command result indicating completion + if '{"results":' in response_buffer and '"Networks scanned"' in response_buffer: + # We've received the completion message, parse any networks found + import re + networks_pattern = r'\{"networks":\[.*?\]\}' + matches = re.findall(networks_pattern, response_buffer, re.DOTALL) + + for match in matches: + try: + networks_data = json.loads(match) + if "networks" in networks_data: + return {"results": [json.dumps({"result": match})]} + except json.JSONDecodeError: + continue + + # If we get here, scan completed but no networks found + return {"results": [json.dumps({"result": '{"networks":[]}'})]} + else: + time.sleep(0.1) + + return {"error": "Scan timeout"} + + def scan_networks(self, timeout: int = 30) -> bool: + """Scan for WiFi networks""" + print(f"šŸ” Scanning for WiFi networks (this may take up to {timeout} seconds)...") + response = self.send_command("scan_networks", timeout=timeout) + + if "error" in response: + print(f"āŒ Scan failed: {response['error']}") + return False + + try: + # Parse the nested JSON response + results = response.get("results", []) + if not results: + print("āŒ No scan results received") + return False + + # The result is JSON-encoded string inside the response + result_data = json.loads(results[0]) + networks_data = json.loads(result_data["result"]) + + self.networks = [] + channels_found = set() + + for net in networks_data.get("networks", []): + network = WiFiNetwork( + ssid=net["ssid"], + channel=net["channel"], + rssi=net["rssi"], + mac_address=net["mac_address"], + auth_mode=net["auth_mode"] + ) + self.networks.append(network) + channels_found.add(net["channel"]) + + # Sort networks by RSSI (strongest first) + self.networks.sort(key=lambda x: x.rssi, reverse=True) + + print(f"āœ… Found {len(self.networks)} networks on channels: {sorted(channels_found)}") + return True + + except Exception as e: + print(f"āŒ Failed to parse scan results: {e}") + return False + + def set_wifi(self, ssid: str, password: str) -> bool: + """Configure WiFi credentials""" + print(f"šŸ”§ Setting WiFi credentials for '{ssid}'...") + + params = { + "name": "main", + "ssid": ssid, + "password": password, + "channel": 0, + "power": 0 + } + + response = self.send_command("set_wifi", params) + + if "error" in response: + print(f"āŒ WiFi setup failed: {response['error']}") + return False + + print("āœ… WiFi credentials set successfully") + return True + + def get_wifi_status(self) -> Dict: + """Get current WiFi connection status""" + response = self.send_command("get_wifi_status") + + if "error" in response: + print(f"āŒ Failed to get WiFi status: {response['error']}") + return {} + + try: + # Parse the nested JSON response + results = response.get("results", []) + if results: + result_data = json.loads(results[0]) + # The result is a JSON-encoded string, need to decode it + status_json = result_data["result"] + + # First, unescape the JSON string properly + # Replace escaped backslashes and quotes + status_json = status_json.replace('\\\\', '\\') + status_json = status_json.replace('\\"', '"') + + # Now parse the cleaned JSON + status_data = json.loads(status_json) + return status_data + except Exception as e: + print(f"āŒ Failed to parse WiFi status: {e}") + # Try to show raw response for debugging + if "results" in response and response["results"]: + print(f"šŸ“ Raw result: {response['results'][0]}") + + return {} + + def connect_wifi(self) -> bool: + """Attempt to connect to configured WiFi""" + print("šŸ”— Attempting WiFi connection...") + response = self.send_command("connect_wifi") + + if "error" in response: + print(f"āŒ WiFi connection failed: {response['error']}") + return False + + print("āœ… WiFi connection attempt started") + return True + + def start_streaming(self) -> bool: + """Start streaming mode""" + print("šŸš€ Starting streaming mode...") + response = self.send_command("start_streaming") + + if "error" in response: + print(f"āŒ Failed to start streaming: {response['error']}") + return False + + print("āœ… Streaming mode started") + return True + + def switch_mode(self, mode: str) -> bool: + """Switch device mode between WiFi, UVC, and Auto""" + print(f"šŸ”„ Switching device mode to '{mode}'...") + + params = {"mode": mode} + response = self.send_command("switch_mode", params) + + if "error" in response: + print(f"āŒ Failed to switch mode: {response['error']}") + return False + + print(f"āœ… Device mode switched to '{mode}' successfully!") + print("šŸ”„ Please restart the device for changes to take effect") + return True + + def get_device_mode(self) -> str: + """Get current device mode""" + response = self.send_command("get_device_mode") + + if "error" in response: + print(f"āŒ Failed to get device mode: {response['error']}") + return "unknown" + + try: + results = response.get("results", []) + if results: + result_data = json.loads(results[0]) + mode_data = json.loads(result_data["result"]) + return mode_data.get("mode", "unknown") + except Exception as e: + print(f"āŒ Failed to parse mode response: {e}") + return "unknown" + + def monitor_logs(self): + """Monitor device logs until interrupted""" + print("šŸ“‹ Monitoring device logs (Press Ctrl+C to exit)...") + print("-" * 60) + + if not self.connection or not self.connection.is_open: + print("āŒ Not connected to device") + return + + try: + while True: + try: + if self.connection.in_waiting > 0: + line = self.connection.readline().decode().strip() + if line: + # Skip JSON command responses, show raw logs + if not (line.startswith('{') and line.endswith('}')): + print(line) + elif "heartbeat" not in line: + # Show non-heartbeat JSON responses + print(f"šŸ“” {line}") + else: + time.sleep(0.1) # Small delay to prevent busy waiting + except Exception: + continue + except KeyboardInterrupt: + print("\nšŸ›‘ Log monitoring stopped") + + +class OpenIrisDiscovery: + def __init__(self): + self.devices: Dict[str, OpenIrisDevice] = {} + self.discovery_active = False + + def discover_devices(self, timeout: int = 3) -> List[OpenIrisDevice]: + """Discover OpenIris devices via heartbeat - ultra-fast concurrent scanning""" + print(f"⚔ Fast-scanning for OpenIris devices...") + + # Get all serial ports + ports = list(serial.tools.list_ports.comports()) + if not ports: + print("āŒ No serial ports found") + return [] + + # Prioritize likely ESP32 USB ports for faster detection + priority_ports = [] + other_ports = [] + + for port in ports: + # Common ESP32 USB-to-serial descriptions + desc_lower = (port.description or "").lower() + # Include generic "USB Serial Device" which is common on Windows + if any(keyword in desc_lower for keyword in + ["cp210", "ch340", "ftdi", "esp32", "silicon labs", "usb-serial", "usb serial", "usb serial device"]): + priority_ports.append(port) + else: + other_ports.append(port) + + # Check priority ports first, then others + sorted_ports = priority_ports + other_ports + + if priority_ports: + print(f"šŸ“” Checking {len(sorted_ports)} ports ({len(priority_ports)} prioritized USB serial ports)...") + else: + print(f"šŸ“” Checking {len(sorted_ports)} serial ports...") + + discovered = {} + lock = threading.Lock() + threads = [] + + def check_port_fast(port_info): + """Check a single port for OpenIris heartbeat - optimized for speed""" + try: + # Initial connection timeout - 500ms + ser = serial.Serial(port_info.device, 115200, timeout=0.5) + ser.reset_input_buffer() + + # Wait up to 2 seconds for heartbeat + start_time = time.time() + while time.time() - start_time < 2.0: + try: + # Read timeout - 200ms + ser.timeout = 10 + if ser.in_waiting > 0: + line = ser.readline() + if line: + try: + data = json.loads(line.decode().strip()) + if (data.get("heartbeat") == "openiris_setup_mode" and + "serial" in data): + serial_num = data["serial"] + with lock: + if serial_num not in discovered: + device = OpenIrisDevice(port_info.device, serial_num, debug=False) + discovered[serial_num] = device + print(f"šŸ’“ Found {serial_num} on {port_info.device}") + # Return immediately to stop checking this port + ser.close() + return True + except (json.JSONDecodeError, UnicodeDecodeError): + pass + else: + time.sleep(0.05) # Very short sleep + except Exception: + pass + + ser.close() + except Exception: + # Port not available or not the right device + pass + return False + + # Start concurrent port checking + for port in sorted_ports: + thread = threading.Thread(target=check_port_fast, args=(port,)) + thread.daemon = True + thread.start() + threads.append(thread) + + # Wait for threads to complete or timeout + timeout_time = time.time() + timeout + for thread in threads: + remaining = timeout_time - time.time() + if remaining > 0: + thread.join(timeout=remaining) + + # If we found at least one device, return immediately + if discovered: + break + + devices = list(discovered.values()) + + if devices: + print(f"āœ… Found {len(devices)} OpenIris device(s)") + else: + print("āŒ No OpenIris devices found in {:.1f} seconds".format(time.time() - (timeout_time - timeout))) + print("šŸ’” Device has 20-second setup window after power on") + + return devices + + def _check_port(self, port: str, discovered: Dict, timeout: int): + """Check a single port for OpenIris heartbeat""" + try: + with serial.Serial(port, 115200, timeout=1) as ser: + start_time = time.time() + + while time.time() - start_time < timeout: + try: + line = ser.readline().decode().strip() + if line: + try: + data = json.loads(line) + if (data.get("heartbeat") == "openiris_setup_mode" and + "serial" in data): + + serial_num = data["serial"] + if serial_num not in discovered: + discovered[serial_num] = OpenIrisDevice(port, serial_num, debug=False) + print(f"šŸ’“ Found device {serial_num} on {port}") + return + except json.JSONDecodeError: + continue + except Exception: + continue + except Exception: + # Port not available or not a serial device + pass + + +def display_networks(networks: List[WiFiNetwork]): + """Display available WiFi networks in a formatted table""" + if not networks: + print("āŒ No networks available") + return + + print("\nšŸ“” Available WiFi Networks:") + print("-" * 85) + print(f"{'#':<3} {'SSID':<32} {'Channel':<8} {'Signal':<20} {'Security':<15}") + print("-" * 85) + + # Networks are already sorted by signal strength from scan_networks + for i, network in enumerate(networks, 1): + # Create signal strength visualization + signal_bars = "ā–“" * min(5, max(0, (network.rssi + 100) // 10)) + signal_str = f"{signal_bars:<5} ({network.rssi} dBm)" + + # Format SSID (show hidden networks as ) + ssid_display = network.ssid if network.ssid else "" + + print(f"{i:<3} {ssid_display:<32} {network.channel:<8} {signal_str:<20} {network.security_type:<15}") + + print("-" * 85) + + # Show channel distribution + channels = {} + for net in networks: + channels[net.channel] = channels.get(net.channel, 0) + 1 + + print(f"\nšŸ“Š Channel distribution: ", end="") + for ch in sorted(channels.keys()): + print(f"Ch{ch}: {channels[ch]} networks ", end="") + print() + + +def main(): + parser = argparse.ArgumentParser(description="OpenIris Setup CLI Tool") + parser.add_argument("--timeout", type=int, default=3, + help="Discovery timeout in seconds (default: 3)") + parser.add_argument("--port", type=str, + help="Skip discovery and connect directly to specified port") + parser.add_argument("--scan-timeout", type=int, default=30, + help="WiFi scan timeout in seconds (default: 30)") + parser.add_argument("--no-auto", action="store_true", + help="Don't auto-connect to first device found") + parser.add_argument("--debug", action="store_true", + help="Show debug output including raw serial data") + args = parser.parse_args() + + print("šŸ”§ OpenIris Setup Tool") + print("=" * 50) + + device = None + + try: + if args.port: + # Connect directly to specified port + print(f"šŸ“” Connecting directly to {args.port}...") + device = OpenIrisDevice(args.port, "direct", debug=args.debug) + if not device.connect(): + return 1 + else: + # Fast device discovery + discovery = OpenIrisDiscovery() + devices = discovery.discover_devices(args.timeout) + + if not devices: + print("\nāŒ No OpenIris devices found automatically") + print("\nšŸ’” Troubleshooting:") + print(" - Make sure device is connected via USB") + print(" - Device must be powered on within last 20 seconds") + print(" - Try specifying port manually with --port") + + # Show available ports to help user + print("\nšŸ“‹ Available serial ports:") + all_ports = list(serial.tools.list_ports.comports()) + for p in all_ports: + print(f" - {p.device}: {p.description}") + + # Offer manual port entry + manual_port = input("\nšŸ”Œ Enter serial port manually (e.g. COM15, /dev/ttyUSB0) or press Enter to exit: ").strip() + if manual_port: + device = OpenIrisDevice(manual_port, "manual", debug=args.debug) + if not device.connect(): + return 1 + else: + return 1 + else: + # Auto-connect to first device found (unless disabled) + if len(devices) == 1 or not args.no_auto: + device = devices[0] + device.debug = args.debug # Set debug mode + print(f"\nšŸŽÆ Auto-connecting to {device.serial_number}...") + if not device.connect(): + return 1 + else: + # Multiple devices found with no-auto flag + print("\nšŸ”¢ Multiple devices found. Select one:") + for i, dev in enumerate(devices, 1): + print(f" {i}. {dev.serial_number} on {dev.port}") + + while True: + try: + choice = int(input("\nEnter device number: ")) - 1 + if 0 <= choice < len(devices): + device = devices[choice] + break + else: + print("āŒ Invalid selection") + except ValueError: + print("āŒ Please enter a number") + + # Connect to selected device + device.debug = args.debug # Set debug mode + if not device.connect(): + return 1 + + # Main interaction loop + while True: + print("\nšŸ”§ Setup Options:") + print("1. šŸ” Scan for WiFi networks") + print("2. šŸ“” Show available networks") + print("3. šŸ” Configure WiFi") + print("4. šŸ“¶ Check WiFi status") + print("5. šŸ”— Connect to WiFi") + print("6. šŸš€ Start streaming mode") + print("7. šŸ”„ Switch device mode (WiFi/UVC/Auto)") + print("8. šŸ“‹ Monitor logs") + print("9. 🚪 Exit") + + choice = input("\nSelect option (1-9): ").strip() + + if choice == "1": + # Ask if user wants custom timeout + custom = input("Use custom scan timeout? (y/N): ").strip().lower() + if custom == 'y': + try: + timeout = int(input("Enter timeout in seconds (5-120): ")) + if 5 <= timeout <= 120: + device.scan_networks(timeout) + else: + print("āŒ Timeout must be between 5 and 120 seconds") + device.scan_networks(args.scan_timeout) + except ValueError: + print("āŒ Invalid timeout, using default") + device.scan_networks(args.scan_timeout) + else: + device.scan_networks(args.scan_timeout) + + elif choice == "2": + display_networks(device.networks) + + elif choice == "3": + if not device.networks: + print("āŒ No networks available. Please scan first.") + continue + + display_networks(device.networks) + + while True: + try: + net_choice = input("\nEnter network number (or 'back'): ").strip() + if net_choice.lower() == 'back': + break + + net_idx = int(net_choice) - 1 + sorted_networks = sorted(device.networks, key=lambda x: x.rssi, reverse=True) + + if 0 <= net_idx < len(sorted_networks): + selected_network = sorted_networks[net_idx] + + print(f"\nšŸ” Selected: {selected_network.ssid}") + print(f"Security: {selected_network.security_type}") + + if selected_network.auth_mode == 0: # Open network + password = "" + print("šŸ”“ Open network - no password required") + else: + password = input("Enter WiFi password: ") + + if device.set_wifi(selected_network.ssid, password): + print("āœ… WiFi configured successfully!") + print("šŸ’” Next steps:") + print(" 4. Check WiFi status") + print(" 5. Connect to WiFi (if needed)") + print(" 6. Start streaming when connected") + break + else: + print("āŒ Invalid network number") + except ValueError: + print("āŒ Please enter a number or 'back'") + + elif choice == "4": + # Check WiFi status + status = device.get_wifi_status() + if status: + print(f"šŸ“¶ WiFi Status: {status.get('status', 'unknown')}") + print(f"šŸ“” Networks configured: {status.get('networks_configured', 0)}") + if status.get('ip_address'): + print(f"🌐 IP Address: {status['ip_address']}") + else: + print("āŒ Unable to get WiFi status") + + elif choice == "5": + # Attempt WiFi connection + device.connect_wifi() + print("šŸ•°ļø Wait a few seconds then check status (option 4)") + + elif choice == "6": + device.start_streaming() + print("šŸš€ Streaming started! Use option 8 to monitor logs.") + + elif choice == "7": + # Switch device mode + current_mode = device.get_device_mode() + print(f"\nšŸ“ Current device mode: {current_mode}") + print("\nšŸ”„ Select new device mode:") + print("1. WiFi - Stream over WiFi connection") + print("2. UVC - Stream as USB webcam") + print("3. Auto - Automatic mode selection") + + mode_choice = input("\nSelect mode (1-3): ").strip() + + if mode_choice == "1": + device.switch_mode("wifi") + elif mode_choice == "2": + device.switch_mode("uvc") + elif mode_choice == "3": + device.switch_mode("auto") + else: + print("āŒ Invalid mode selection") + + elif choice == "8": + device.monitor_logs() + + elif choice == "9": + break + + else: + print("āŒ Invalid option") + + except KeyboardInterrupt: + print("\nšŸ›‘ Setup interrupted") + + finally: + if device: + device.disconnect() + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/tools/requirements.txt b/tools/requirements.txt new file mode 100644 index 0000000..29284eb --- /dev/null +++ b/tools/requirements.txt @@ -0,0 +1 @@ +pyserial>=3.5 \ No newline at end of file diff --git a/tools/setup.bat b/tools/setup.bat new file mode 100644 index 0000000..0da4843 --- /dev/null +++ b/tools/setup.bat @@ -0,0 +1,7 @@ +@echo off +echo Installing OpenIris Setup Tool dependencies... +pip install -r requirements.txt +echo. +echo Setup complete! Run the tool with: +echo python openiris_setup.py +pause \ No newline at end of file diff --git a/tools/setup.sh b/tools/setup.sh new file mode 100644 index 0000000..f70dc19 --- /dev/null +++ b/tools/setup.sh @@ -0,0 +1,6 @@ +#!/bin/bash +echo "Installing OpenIris Setup Tool dependencies..." +pip3 install -r requirements.txt +echo "" +echo "Setup complete! Run the tool with:" +echo "python3 openiris_setup.py" \ No newline at end of file diff --git a/tools/wifi_scanner.py b/tools/wifi_scanner.py new file mode 100644 index 0000000..d5397f6 --- /dev/null +++ b/tools/wifi_scanner.py @@ -0,0 +1,177 @@ +import serial +import time +import json +from typing import List, Dict + +class ESPWiFiScanner: + def __init__(self, port: str, baudrate: int = 115200): + self.port = port + self.baudrate = baudrate + self.serial = None + + def connect(self) -> bool: + try: + self.serial = serial.Serial( + port=self.port, + baudrate=self.baudrate, + timeout=1 + ) + return True + except serial.SerialException as e: + print(f"Error connecting to ESP32: {e}") + return False + + def scan_networks(self, timeout_seconds: int = 30) -> List[Dict]: + if not self.serial: + print("Not connected to ESP32") + return [] + + self.serial.reset_input_buffer() + + command = '{"commands":[{"command":"scan_networks","data":{}}]}\n' + self.serial.write(command.encode()) + + timeout_start = time.time() + response_buffer = "" + + while time.time() - timeout_start < timeout_seconds: + if self.serial.in_waiting: + data = self.serial.read(self.serial.in_waiting).decode('utf-8', errors='ignore') + response_buffer += data + + # Look for WiFi networks JSON directly (new format) + # The scan command now outputs JSON directly followed by command result + if '{"networks":[' in response_buffer: + import re + + # Look for the networks JSON pattern that appears first + networks_pattern = r'\{"networks":\[.*?\]\}' + matches = re.findall(networks_pattern, response_buffer, re.DOTALL) + + for match in matches: + try: + # Parse the networks JSON directly + networks_data = json.loads(match) + if "networks" in networks_data: + return networks_data["networks"] + except json.JSONDecodeError: + continue + + # Also check if we have the command result indicating completion + if '{"results":' in response_buffer and '"Networks scanned"' in response_buffer: + # We've received the completion message, parse any networks found + import re + networks_pattern = r'\{"networks":\[.*?\]\}' + matches = re.findall(networks_pattern, response_buffer, re.DOTALL) + + for match in matches: + try: + networks_data = json.loads(match) + if "networks" in networks_data: + return networks_data["networks"] + except json.JSONDecodeError: + continue + + # If we get here, scan completed but no networks found + return [] + else: + time.sleep(0.1) + + print("Failed to receive clean JSON response. Raw data:") + print("=" * 50) + print(response_buffer) + print("=" * 50) + return [] + + def close(self): + if self.serial: + self.serial.close() + +def main(): + import sys + import argparse + + parser = argparse.ArgumentParser(description='ESP32 WiFi Scanner') + parser.add_argument('port', nargs='?', default='COM15', help='Serial port (default: COM9)') + parser.add_argument('-t', '--timeout', type=int, default=30, + help='Scan timeout in seconds (default: 30)') + args = parser.parse_args() + + scanner = ESPWiFiScanner(args.port) + + if scanner.connect(): + print(f"Connected to ESP32 on {args.port}") + print(f"Scanning for WiFi networks (timeout: {args.timeout} seconds)...") + start_time = time.time() + networks = scanner.scan_networks(args.timeout) + scan_time = time.time() - start_time + + if networks: + # Sort by RSSI (strongest first) + networks.sort(key=lambda x: x.get('rssi', -100), reverse=True) + + print(f"\nāœ… Found {len(networks)} WiFi Networks in {scan_time:.1f} seconds:") + print("{:<32} | {:<7} | {:<15} | {:<17} | {:<9}".format( + "SSID", "Channel", "Signal", "MAC Address", "Security" + )) + print("-" * 85) + + # Track channels found + channels_found = set() + auth_modes = { + 0: "Open", + 1: "WEP", + 2: "WPA-PSK", + 3: "WPA2-PSK", + 4: "WPA/WPA2", + 5: "WPA2-Enterprise", + 6: "WPA3-PSK", + 7: "WPA2/WPA3", + 8: "WAPI-PSK" + } + + for network in networks: + ssid = network.get('ssid', '') + if not ssid: + ssid = "" + + channel = network.get('channel', 0) + channels_found.add(channel) + + # Create signal strength visualization + rssi = network.get('rssi', -100) + signal_bars = "ā–“" * min(5, max(0, (rssi + 100) // 10)) + signal_str = f"{signal_bars:<5} ({rssi} dBm)" + + auth_mode = network.get('auth_mode', 0) + security = auth_modes.get(auth_mode, f"Type {auth_mode}") + + print("{:<32} | {:<7} | {:<15} | {:<17} | {:<9}".format( + ssid[:32], # Truncate long SSIDs + channel, + signal_str, + network.get('mac_address', '?'), + security + )) + + # Show channel distribution + print(f"\nšŸ“Š Channels detected: {sorted(channels_found)}") + channel_counts = {} + for net in networks: + ch = net.get('channel', 0) + channel_counts[ch] = channel_counts.get(ch, 0) + 1 + + print("šŸ“Š Channel distribution: ", end="") + for ch in sorted(channel_counts.keys()): + print(f"Ch{ch}: {channel_counts[ch]} networks ", end="") + print() + + else: + print("āŒ No networks found or scan failed") + + scanner.close() + else: + print(f"Failed to connect to ESP32 on {args.port}") + +if __name__ == "__main__": + main() \ No newline at end of file From d9ace4bc0595d5d8e3a6fb9eef08bc6e3e8fd761 Mon Sep 17 00:00:00 2001 From: Summer <71572746+SummerSigh@users.noreply.github.com> Date: Wed, 11 Jun 2025 04:55:38 -0700 Subject: [PATCH 2/7] upload mutimodal --- .../CameraManager/CameraManager.cpp | 8 +- components/CommandManager/CMakeLists.txt | 3 +- .../CommandManager/CommandManager.cpp | 45 +- .../CommandManager/CommandManager.hpp | 8 + .../CommandManager/CommandResult.hpp | 35 +- .../CommandManager/CommandSchema.hpp | 5 + .../CommandManager/DependencyRegistry.hpp | 3 +- .../commands/device_commands.cpp | 65 ++ .../commands/device_commands.hpp | 8 +- .../CommandManager/commands/scan_commands.cpp | 38 + .../CommandManager/commands/scan_commands.hpp | 10 + .../commands/simple_commands.cpp | 19 + .../commands/simple_commands.hpp | 2 + .../CommandManager/commands/wifi_commands.cpp | 77 ++ .../CommandManager/commands/wifi_commands.hpp | 5 + components/Helpers/CMakeLists.txt | 2 +- components/Helpers/Helpers/main_globals.cpp | 40 + components/Helpers/Helpers/main_globals.hpp | 28 + .../ProjectConfig/ProjectConfig/Models.hpp | 12 +- .../ProjectConfig/ProjectConfig.cpp | 15 +- .../ProjectConfig/ProjectConfig.hpp | 3 +- components/SerialManager/CMakeLists.txt | 2 +- .../SerialManager/SerialManager.cpp | 64 +- .../SerialManager/SerialManager.hpp | 7 +- .../StreamServer/StreamServer.cpp | 23 +- components/UVCStream/UVCStream/UVCStream.cpp | 7 + components/UVCStream/UVCStream/UVCStream.hpp | 1 + components/wifiManager/CMakeLists.txt | 2 +- .../wifiManager/wifiManager/WiFiScanner.cpp | 205 +++++ .../wifiManager/wifiManager/WiFiScanner.hpp | 29 + .../wifiManager/wifiManager/wifiManager.cpp | 227 ++++- .../wifiManager/wifiManager/wifiManager.hpp | 11 +- dependencies.lock | 2 +- main/openiris_main.cpp | 230 ++++- sdkconfig | 201 ++--- sdkconfig.old | 254 +++++- tools/openiris_setup.py | 816 ++++++++++++++++++ tools/requirements.txt | 1 + tools/setup.bat | 7 + tools/setup.sh | 6 + tools/wifi_scanner.py | 177 ++++ 41 files changed, 2484 insertions(+), 219 deletions(-) create mode 100644 components/CommandManager/CommandManager/commands/scan_commands.cpp create mode 100644 components/CommandManager/CommandManager/commands/scan_commands.hpp create mode 100644 components/Helpers/Helpers/main_globals.cpp create mode 100644 components/Helpers/Helpers/main_globals.hpp create mode 100644 components/wifiManager/wifiManager/WiFiScanner.cpp create mode 100644 components/wifiManager/wifiManager/WiFiScanner.hpp create mode 100644 tools/openiris_setup.py create mode 100644 tools/requirements.txt create mode 100644 tools/setup.bat create mode 100644 tools/setup.sh create mode 100644 tools/wifi_scanner.py diff --git a/components/CameraManager/CameraManager/CameraManager.cpp b/components/CameraManager/CameraManager/CameraManager.cpp index 511a48d..1774395 100644 --- a/components/CameraManager/CameraManager/CameraManager.cpp +++ b/components/CameraManager/CameraManager/CameraManager.cpp @@ -80,10 +80,10 @@ void CameraManager::setupCameraPinout() .pixel_format = PIXFORMAT_JPEG, // YUV422,GRAYSCALE,RGB565,JPEG .frame_size = FRAMESIZE_240X240, // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates. - .jpeg_quality = 7, // 0-63, for OV series camera sensors, lower number means higher quality - .fb_count = 2, // 3 // When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode. - .fb_location = CAMERA_FB_IN_PSRAM, // maybe it cannot put them fully in psram? - .grab_mode = CAMERA_GRAB_WHEN_EMPTY, // CAMERA_GRAB_LATEST + .jpeg_quality = 10, // 0-63, for OV series camera sensors, lower number means higher quality + .fb_count = 2, // Use 2 for streaming to balance memory and performance + .fb_location = CAMERA_FB_IN_PSRAM, // Use PSRAM for frame buffers + .grab_mode = CAMERA_GRAB_LATEST, // Always grab the latest frame for streaming }; } diff --git a/components/CommandManager/CMakeLists.txt b/components/CommandManager/CMakeLists.txt index 30a6234..16e8afc 100644 --- a/components/CommandManager/CMakeLists.txt +++ b/components/CommandManager/CMakeLists.txt @@ -7,8 +7,9 @@ idf_component_register( "CommandManager/commands/config_commands.cpp" "CommandManager/commands/mdns_commands.cpp" "CommandManager/commands/device_commands.cpp" + "CommandManager/commands/scan_commands.cpp" INCLUDE_DIRS "CommandManager" "CommandManager/commands" - REQUIRES ProjectConfig cJSON CameraManager OpenIrisTasks + REQUIRES ProjectConfig cJSON CameraManager OpenIrisTasks wifiManager Helpers ) \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index 9d981f1..64cba54 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -1,7 +1,9 @@ #include "CommandManager.hpp" +#include std::unordered_map commandTypeMap = { {"ping", CommandType::PING}, + {"pause", CommandType::PAUSE}, {"set_wifi", CommandType::SET_WIFI}, {"update_wifi", CommandType::UPDATE_WIFI}, {"set_streaming_mode", CommandType::SET_STREAMING_MODE}, @@ -15,6 +17,12 @@ std::unordered_map commandTypeMap = { {"get_config", CommandType::GET_CONFIG}, {"reset_config", CommandType::RESET_CONFIG}, {"restart_device", CommandType::RESTART_DEVICE}, + {"scan_networks", CommandType::SCAN_NETWORKS}, + {"start_streaming", CommandType::START_STREAMING}, + {"get_wifi_status", CommandType::GET_WIFI_STATUS}, + {"connect_wifi", CommandType::CONNECT_WIFI}, + {"switch_mode", CommandType::SWITCH_MODE}, + {"get_device_mode", CommandType::GET_DEVICE_MODE}, }; std::function CommandManager::createCommand(const CommandType type, std::string_view json) const { @@ -22,6 +30,23 @@ std::function CommandManager::createCommand(const CommandType t { case CommandType::PING: return { PingCommand }; + case CommandType::PAUSE: + return [json] { + PausePayload payload; + cJSON* root = cJSON_Parse(std::string(json).c_str()); + if (root) { + cJSON* pauseItem = cJSON_GetObjectItem(root, "pause"); + if (pauseItem && cJSON_IsBool(pauseItem)) { + payload.pause = cJSON_IsTrue(pauseItem); + } else { + payload.pause = true; // Default to pause if not specified + } + cJSON_Delete(root); + } else { + payload.pause = true; // Default to pause if parsing fails + } + return PauseCommand(payload); + }; case CommandType::SET_STREAMING_MODE: return [this, json] {return setDeviceModeCommand(this->registry, json); }; case CommandType::UPDATE_OTA_CREDENTIALS: @@ -48,6 +73,18 @@ std::function CommandManager::createCommand(const CommandType t return [this, json] { return resetConfigCommand(this->registry, json); }; case CommandType::RESTART_DEVICE: return restartDeviceCommand; + case CommandType::SCAN_NETWORKS: + return [this] { return scanNetworksCommand(this->registry); }; + case CommandType::START_STREAMING: + return startStreamingCommand; + case CommandType::GET_WIFI_STATUS: + return [this] { return getWiFiStatusCommand(this->registry); }; + case CommandType::CONNECT_WIFI: + return [this] { return connectWiFiCommand(this->registry); }; + case CommandType::SWITCH_MODE: + return [this, json] { return switchModeCommand(this->registry, json); }; + case CommandType::GET_DEVICE_MODE: + return [this] { return getDeviceModeCommand(this->registry); }; default: return nullptr; } @@ -98,11 +135,15 @@ CommandResult CommandManager::executeFromJson(const std::string_view json) const cJSON_AddItemToArray(responses, response); } - const auto jsonString = cJSON_Print(responseDocument); + char* jsonString = cJSON_Print(responseDocument); cJSON_Delete(responseDocument); cJSON_Delete(parsedJson); - return CommandResult::getSuccessResult(jsonString); + // Return the JSON response directly without wrapping it + // The responseDocument already contains the proper format: {"results": [...]} + CommandResult result = CommandResult::getRawJsonResult(jsonString); + free(jsonString); + return result; } CommandResult CommandManager::executeFromType(const CommandType type, const std::string_view json) const diff --git a/components/CommandManager/CommandManager/CommandManager.hpp b/components/CommandManager/CommandManager/CommandManager.hpp index eea0477..02231e3 100644 --- a/components/CommandManager/CommandManager/CommandManager.hpp +++ b/components/CommandManager/CommandManager/CommandManager.hpp @@ -17,12 +17,14 @@ #include "commands/mdns_commands.hpp" #include "commands/wifi_commands.hpp" #include "commands/device_commands.hpp" +#include "commands/scan_commands.hpp" #include enum class CommandType { None, PING, + PAUSE, SET_WIFI, UPDATE_OTA_CREDENTIALS, SET_STREAMING_MODE, @@ -36,6 +38,12 @@ enum class CommandType GET_CONFIG, RESET_CONFIG, RESTART_DEVICE, + SCAN_NETWORKS, + START_STREAMING, + GET_WIFI_STATUS, + CONNECT_WIFI, + SWITCH_MODE, + GET_DEVICE_MODE, }; class CommandManager diff --git a/components/CommandManager/CommandManager/CommandResult.hpp b/components/CommandManager/CommandManager/CommandResult.hpp index f033954..b73fc8a 100644 --- a/components/CommandManager/CommandManager/CommandResult.hpp +++ b/components/CommandManager/CommandManager/CommandResult.hpp @@ -3,34 +3,52 @@ #include #include +#include class CommandResult { -private: +public: enum class Status { SUCCESS, FAILURE, }; +private: Status status; std::string message; +public: CommandResult(std::string message, const Status status) { this->status = status; + + // Escape quotes and backslashes in the message for JSON + std::string escapedMessage = message; + size_t pos = 0; + // First escape backslashes + while ((pos = escapedMessage.find('\\', pos)) != std::string::npos) { + escapedMessage.replace(pos, 1, "\\\\"); + pos += 2; + } + // Then escape quotes + pos = 0; + while ((pos = escapedMessage.find('"', pos)) != std::string::npos) { + escapedMessage.replace(pos, 1, "\\\""); + pos += 2; + } + if (status == Status::SUCCESS) { // we gotta do it this way, because if we define it as { "result": " {} " } it crashes the compiler, lol - this->message = std::format("{}\"result\":\" {} \"{}", "{", message, "}"); + this->message = std::format("{}\"result\":\"{}\"{}", "{", escapedMessage, "}"); } else { - this->message = std::format("{}\"error\":\" {} \"{}", "{", message, "}"); + this->message = std::format("{}\"error\":\"{}\"{}", "{", escapedMessage, "}"); } } -public: bool isSuccess() const { return status == Status::SUCCESS; } static CommandResult getSuccessResult(const std::string &message) @@ -42,8 +60,17 @@ public: { return CommandResult(message, Status::FAILURE); } + + // Create a result that returns raw JSON without wrapper + static CommandResult getRawJsonResult(const std::string &jsonMessage) + { + CommandResult result("", Status::SUCCESS); + result.message = jsonMessage; + return result; + } std::string getResult() const { return this->message; } + }; #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/CommandSchema.hpp b/components/CommandManager/CommandManager/CommandSchema.hpp index 991b928..72e5440 100644 --- a/components/CommandManager/CommandManager/CommandSchema.hpp +++ b/components/CommandManager/CommandManager/CommandSchema.hpp @@ -57,4 +57,9 @@ struct RestartCameraPayload : BasePayload { bool mode; }; + +struct PausePayload : BasePayload +{ + bool pause; +}; #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/DependencyRegistry.hpp b/components/CommandManager/CommandManager/DependencyRegistry.hpp index 2a5e378..48b6ee8 100644 --- a/components/CommandManager/CommandManager/DependencyRegistry.hpp +++ b/components/CommandManager/CommandManager/DependencyRegistry.hpp @@ -7,7 +7,8 @@ enum class DependencyType { project_config, - camera_manager + camera_manager, + wifi_manager }; class DependencyRegistry diff --git a/components/CommandManager/CommandManager/commands/device_commands.cpp b/components/CommandManager/CommandManager/commands/device_commands.cpp index 6f9b552..fa5d390 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.cpp +++ b/components/CommandManager/CommandManager/commands/device_commands.cpp @@ -2,6 +2,8 @@ #include #include +#include "esp_timer.h" +#include // Implementation inspired by SummerSigh work, initial PR opened in openiris repo, adapted to this rewrite CommandResult setDeviceModeCommand(std::shared_ptr registry, std::string_view jsonPayload) { @@ -64,3 +66,66 @@ CommandResult restartDeviceCommand() { OpenIrisTasks::ScheduleRestart(2000); return CommandResult::getSuccessResult("Device restarted"); } + +CommandResult startStreamingCommand() { + activateStreaming(false); // Don't disable setup interfaces by default + return CommandResult::getSuccessResult("Streaming started"); +} + +CommandResult switchModeCommand(std::shared_ptr registry, std::string_view jsonPayload) { + const auto parsedJson = cJSON_Parse(jsonPayload.data()); + if (parsedJson == nullptr) { + return CommandResult::getErrorResult("Invalid payload"); + } + + const auto modeObject = cJSON_GetObjectItem(parsedJson, "mode"); + if (modeObject == nullptr) { + return CommandResult::getErrorResult("Invalid payload - missing mode"); + } + + const char* modeStr = modeObject->valuestring; + StreamingMode newMode; + + ESP_LOGI("[DEVICE_COMMANDS]", "Switch mode command received with mode: %s", modeStr); + + if (strcmp(modeStr, "uvc") == 0 || strcmp(modeStr, "UVC") == 0) { + newMode = StreamingMode::UVC; + } else if (strcmp(modeStr, "wifi") == 0 || strcmp(modeStr, "WiFi") == 0 || strcmp(modeStr, "WIFI") == 0) { + newMode = StreamingMode::WIFI; + } else if (strcmp(modeStr, "auto") == 0 || strcmp(modeStr, "AUTO") == 0) { + newMode = StreamingMode::AUTO; + } else { + return CommandResult::getErrorResult("Invalid mode - use 'uvc', 'wifi', or 'auto'"); + } + + const auto projectConfig = registry->resolve(DependencyType::project_config); + ESP_LOGI("[DEVICE_COMMANDS]", "Setting device mode to: %d", (int)newMode); + projectConfig->setDeviceMode(newMode); + + cJSON_Delete(parsedJson); + + return CommandResult::getSuccessResult("Device mode switched, restart to apply"); +} + +CommandResult getDeviceModeCommand(std::shared_ptr registry) { + const auto projectConfig = registry->resolve(DependencyType::project_config); + StreamingMode currentMode = projectConfig->getDeviceMode(); + + const char* modeStr = "unknown"; + switch (currentMode) { + case StreamingMode::UVC: + modeStr = "UVC"; + break; + case StreamingMode::WIFI: + modeStr = "WiFi"; + break; + case StreamingMode::AUTO: + modeStr = "Auto"; + break; + } + + char result[100]; + sprintf(result, "{\"mode\":\"%s\",\"value\":%d}", modeStr, (int)currentMode); + + return CommandResult::getSuccessResult(result); +} diff --git a/components/CommandManager/CommandManager/commands/device_commands.hpp b/components/CommandManager/CommandManager/commands/device_commands.hpp index 2532624..5685f13 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.hpp +++ b/components/CommandManager/CommandManager/commands/device_commands.hpp @@ -6,4 +6,10 @@ CommandResult setDeviceModeCommand(std::shared_ptr registry, CommandResult updateOTACredentialsCommand(std::shared_ptr registry, std::string_view jsonPayload); -CommandResult restartDeviceCommand(); \ No newline at end of file +CommandResult restartDeviceCommand(); + +CommandResult startStreamingCommand(); + +CommandResult switchModeCommand(std::shared_ptr registry, std::string_view jsonPayload); + +CommandResult getDeviceModeCommand(std::shared_ptr registry); \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/scan_commands.cpp b/components/CommandManager/CommandManager/commands/scan_commands.cpp new file mode 100644 index 0000000..054a621 --- /dev/null +++ b/components/CommandManager/CommandManager/commands/scan_commands.cpp @@ -0,0 +1,38 @@ +#include "scan_commands.hpp" +#include "cJSON.h" +#include "esp_log.h" +#include + +CommandResult scanNetworksCommand(std::shared_ptr registry) { + auto wifiManager = registry->resolve(DependencyType::wifi_manager); + if (!wifiManager) { + return CommandResult::getErrorResult("WiFiManager not available"); + } + + auto networks = wifiManager->ScanNetworks(); + + cJSON *root = cJSON_CreateObject(); + cJSON *networksArray = cJSON_CreateArray(); + cJSON_AddItemToObject(root, "networks", networksArray); + + for (const auto& network : networks) { + cJSON *networkObject = cJSON_CreateObject(); + cJSON_AddStringToObject(networkObject, "ssid", network.ssid.c_str()); + cJSON_AddNumberToObject(networkObject, "channel", network.channel); + cJSON_AddNumberToObject(networkObject, "rssi", network.rssi); + char mac_str[18]; + sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", + network.mac[0], network.mac[1], network.mac[2], + network.mac[3], network.mac[4], network.mac[5]); + cJSON_AddStringToObject(networkObject, "mac_address", mac_str); + cJSON_AddNumberToObject(networkObject, "auth_mode", network.auth_mode); + cJSON_AddItemToArray(networksArray, networkObject); + } + + char *json_string = cJSON_PrintUnformatted(root); + printf("%s\n", json_string); + cJSON_Delete(root); + free(json_string); + + return CommandResult::getSuccessResult("Networks scanned"); +} \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/scan_commands.hpp b/components/CommandManager/CommandManager/commands/scan_commands.hpp new file mode 100644 index 0000000..7e7df86 --- /dev/null +++ b/components/CommandManager/CommandManager/commands/scan_commands.hpp @@ -0,0 +1,10 @@ +#ifndef SCAN_COMMANDS_HPP +#define SCAN_COMMANDS_HPP + +#include "../CommandResult.hpp" +#include "../DependencyRegistry.hpp" +#include + +CommandResult scanNetworksCommand(std::shared_ptr registry); + +#endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/simple_commands.cpp b/components/CommandManager/CommandManager/commands/simple_commands.cpp index b1fc7b9..909568a 100644 --- a/components/CommandManager/CommandManager/commands/simple_commands.cpp +++ b/components/CommandManager/CommandManager/commands/simple_commands.cpp @@ -1,6 +1,25 @@ #include "simple_commands.hpp" +#include "main_globals.hpp" +#include "esp_log.h" + +static const char* TAG = "SimpleCommands"; CommandResult PingCommand() { return CommandResult::getSuccessResult("pong"); }; + +CommandResult PauseCommand(const PausePayload& payload) +{ + ESP_LOGI(TAG, "Pause command received: %s", payload.pause ? "true" : "false"); + + startupPaused = payload.pause; + + if (payload.pause) { + ESP_LOGI(TAG, "Startup paused - device will remain in configuration mode"); + return CommandResult::getSuccessResult("Startup paused"); + } else { + ESP_LOGI(TAG, "Startup resumed"); + return CommandResult::getSuccessResult("Startup resumed"); + } +}; diff --git a/components/CommandManager/CommandManager/commands/simple_commands.hpp b/components/CommandManager/CommandManager/commands/simple_commands.hpp index 0883da9..9db7ea9 100644 --- a/components/CommandManager/CommandManager/commands/simple_commands.hpp +++ b/components/CommandManager/CommandManager/commands/simple_commands.hpp @@ -3,7 +3,9 @@ #include #include "CommandResult.hpp" +#include "CommandSchema.hpp" CommandResult PingCommand(); +CommandResult PauseCommand(const PausePayload& payload); #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/wifi_commands.cpp b/components/CommandManager/CommandManager/commands/wifi_commands.cpp index 5f671f9..8ca0fcf 100644 --- a/components/CommandManager/CommandManager/commands/wifi_commands.cpp +++ b/components/CommandManager/CommandManager/commands/wifi_commands.cpp @@ -1,4 +1,5 @@ #include "wifi_commands.hpp" +#include "esp_netif.h" std::optional parseSetWiFiCommandPayload(std::string_view jsonPayload) { @@ -223,3 +224,79 @@ CommandResult updateAPWiFiCommand(std::shared_ptr registry, return CommandResult::getSuccessResult("Config updated"); } + +CommandResult getWiFiStatusCommand(std::shared_ptr registry) { + auto wifiManager = registry->resolve(DependencyType::wifi_manager); + auto projectConfig = registry->resolve(DependencyType::project_config); + + // Get current WiFi state + auto wifiState = wifiManager->GetCurrentWiFiState(); + auto networks = projectConfig->getWifiConfigs(); + + cJSON* statusJson = cJSON_CreateObject(); + + // Add WiFi state + const char* stateStr = "unknown"; + switch(wifiState) { + case WiFiState_e::WiFiState_NotInitialized: + stateStr = "not_initialized"; + break; + case WiFiState_e::WiFiState_Initialized: + stateStr = "initialized"; + break; + case WiFiState_e::WiFiState_ReadyToConnect: + stateStr = "ready"; + break; + case WiFiState_e::WiFiState_Connecting: + stateStr = "connecting"; + break; + case WiFiState_e::WiFiState_WaitingForIp: + stateStr = "waiting_for_ip"; + break; + case WiFiState_e::WiFiState_Connected: + stateStr = "connected"; + break; + case WiFiState_e::WiFiState_Disconnected: + stateStr = "disconnected"; + break; + case WiFiState_e::WiFiState_Error: + stateStr = "error"; + break; + } + cJSON_AddStringToObject(statusJson, "status", stateStr); + cJSON_AddNumberToObject(statusJson, "networks_configured", networks.size()); + + // Add IP info if connected + if (wifiState == WiFiState_e::WiFiState_Connected) { + // Get IP address from ESP32 + esp_netif_ip_info_t ip_info; + esp_netif_t* netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + if (netif && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK) { + char ip_str[16]; + sprintf(ip_str, IPSTR, IP2STR(&ip_info.ip)); + cJSON_AddStringToObject(statusJson, "ip_address", ip_str); + } + } + + char* statusString = cJSON_PrintUnformatted(statusJson); + std::string result(statusString); + free(statusString); + cJSON_Delete(statusJson); + + return CommandResult::getSuccessResult(result); +} + +CommandResult connectWiFiCommand(std::shared_ptr registry) { + auto wifiManager = registry->resolve(DependencyType::wifi_manager); + auto projectConfig = registry->resolve(DependencyType::project_config); + + auto networks = projectConfig->getWifiConfigs(); + if (networks.empty()) { + return CommandResult::getErrorResult("No WiFi networks configured"); + } + + // Trigger WiFi connection attempt + wifiManager->TryConnectToStoredNetworks(); + + return CommandResult::getSuccessResult("WiFi connection attempt started"); +} diff --git a/components/CommandManager/CommandManager/commands/wifi_commands.hpp b/components/CommandManager/CommandManager/commands/wifi_commands.hpp index e344427..f98245d 100644 --- a/components/CommandManager/CommandManager/commands/wifi_commands.hpp +++ b/components/CommandManager/CommandManager/commands/wifi_commands.hpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -18,3 +20,6 @@ CommandResult updateWiFiCommand(std::shared_ptr registry, st std::optional parseUpdateAPWiFiCommandPayload(std::string_view jsonPayload); CommandResult updateAPWiFiCommand(std::shared_ptr registry, std::string_view jsonPayload); + +CommandResult getWiFiStatusCommand(std::shared_ptr registry); +CommandResult connectWiFiCommand(std::shared_ptr registry); diff --git a/components/Helpers/CMakeLists.txt b/components/Helpers/CMakeLists.txt index 238bb60..5d592c6 100644 --- a/components/Helpers/CMakeLists.txt +++ b/components/Helpers/CMakeLists.txt @@ -1,4 +1,4 @@ -idf_component_register(SRCS "Helpers/helpers.cpp" +idf_component_register(SRCS "Helpers/helpers.cpp" "Helpers/main_globals.cpp" INCLUDE_DIRS "Helpers" REQUIRES esp_timer ) \ No newline at end of file diff --git a/components/Helpers/Helpers/main_globals.cpp b/components/Helpers/Helpers/main_globals.cpp new file mode 100644 index 0000000..8ed665d --- /dev/null +++ b/components/Helpers/Helpers/main_globals.cpp @@ -0,0 +1,40 @@ +#include "main_globals.hpp" +#include "esp_log.h" + +// Forward declarations +extern void start_video_streaming(void *arg); + +// Global variables to be set by main +static esp_timer_handle_t* g_streaming_timer_handle = nullptr; +static TaskHandle_t* g_serial_manager_handle = nullptr; + +// Functions for main to set the global handles +void setStreamingTimerHandle(esp_timer_handle_t* handle) { + g_streaming_timer_handle = handle; +} + +void setSerialManagerHandle(TaskHandle_t* handle) { + g_serial_manager_handle = handle; +} + +// Functions for components to access the handles +esp_timer_handle_t* getStreamingTimerHandle() { + return g_streaming_timer_handle; +} + +TaskHandle_t* getSerialManagerHandle() { + return g_serial_manager_handle; +} + +// Global pause state +bool startupPaused = false; + +// Function to manually activate streaming +void activateStreaming(bool disableSetup) { + ESP_LOGI("[MAIN_GLOBALS]", "Manually activating streaming, disableSetup=%s", disableSetup ? "true" : "false"); + + TaskHandle_t* serialHandle = disableSetup ? g_serial_manager_handle : nullptr; + void* serialTaskHandle = (serialHandle && *serialHandle) ? *serialHandle : nullptr; + + start_video_streaming(serialTaskHandle); +} \ No newline at end of file diff --git a/components/Helpers/Helpers/main_globals.hpp b/components/Helpers/Helpers/main_globals.hpp new file mode 100644 index 0000000..d13f7fc --- /dev/null +++ b/components/Helpers/Helpers/main_globals.hpp @@ -0,0 +1,28 @@ +#pragma once +#ifndef MAIN_GLOBALS_HPP +#define MAIN_GLOBALS_HPP + +#include "esp_timer.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +// Functions for main to set global handles +void setStreamingTimerHandle(esp_timer_handle_t* handle); +void setSerialManagerHandle(TaskHandle_t* handle); + +// Functions to access global handles from components +esp_timer_handle_t* getStreamingTimerHandle(); +TaskHandle_t* getSerialManagerHandle(); + +// Function to manually activate streaming +void activateStreaming(bool disableSetup = false); + +// Function to notify that a command was received during startup +extern void notify_startup_command_received(); + +// Global variables for startup state +extern bool startupCommandReceived; +extern esp_timer_handle_t startupTimerHandle; +extern bool startupPaused; + +#endif \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/Models.hpp b/components/ProjectConfig/ProjectConfig/Models.hpp index f931775..d2a01c1 100644 --- a/components/ProjectConfig/ProjectConfig/Models.hpp +++ b/components/ProjectConfig/ProjectConfig/Models.hpp @@ -8,6 +8,7 @@ #include #include "sdkconfig.h" #include +#include "esp_log.h" struct BaseConfigModel { @@ -31,11 +32,14 @@ struct DeviceMode_t : BaseConfigModel { explicit DeviceMode_t( Preferences *pref) : BaseConfigModel(pref), mode(StreamingMode::AUTO){} void load() { - this->mode = static_cast(this->pref->getInt("mode", 0)); + int stored_mode = this->pref->getInt("mode", 0); + this->mode = static_cast(stored_mode); + ESP_LOGI("DeviceMode", "Loaded device mode: %d", stored_mode); } void save() const { this->pref->putInt("mode", static_cast(this->mode)); + ESP_LOGI("DeviceMode", "Saved device mode: %d", static_cast(this->mode)); } }; @@ -182,6 +186,9 @@ struct WiFiConfig_t : BaseConfigModel this->password = this->pref->getString(("password" + iter_str).c_str(), ""); this->channel = this->pref->getUInt(("channel" + iter_str).c_str()); this->power = this->pref->getUInt(("power" + iter_str).c_str()); + + ESP_LOGI("WiFiConfig", "Loaded network %d: name=%s, ssid=%s, channel=%d", + index, this->name.c_str(), this->ssid.c_str(), this->channel); }; void save() const { @@ -193,6 +200,9 @@ struct WiFiConfig_t : BaseConfigModel this->pref->putString(("password" + iter_str).c_str(), this->password.c_str()); this->pref->putUInt(("channel" + iter_str).c_str(), this->channel); this->pref->putUInt(("power" + iter_str).c_str(), this->power); + + ESP_LOGI("WiFiConfig", "Saved network %d: name=%s, ssid=%s, channel=%d", + this->index, this->name.c_str(), this->ssid.c_str(), this->channel); }; std::string toRepresentation() diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp index eb42bdc..ae7b189 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp @@ -147,6 +147,8 @@ void ProjectConfig::setWifiConfig(const std::string &networkName, it->password = password; it->channel = channel; it->power = power; + // Save the updated network immediately + it->save(); return; } @@ -155,6 +157,9 @@ void ProjectConfig::setWifiConfig(const std::string &networkName, ESP_LOGI(CONFIGURATION_TAG, "No networks, We're adding a new network"); this->config.networks.emplace_back(this->pref, static_cast(0), networkName, ssid, password, channel, power); + // Save the new network immediately + this->config.networks.back().save(); + saveNetworkCount(this->pref, 1); return; } @@ -168,6 +173,9 @@ void ProjectConfig::setWifiConfig(const std::string &networkName, uint8_t last_index = getNetworkCount(this->pref); this->config.networks.emplace_back(this->pref, last_index, networkName, ssid, password, channel, power); + // Save the new network immediately + this->config.networks.back().save(); + saveNetworkCount(this->pref, static_cast(this->config.networks.size())); } else { @@ -212,6 +220,7 @@ void ProjectConfig::setAPWifiConfig(const std::string &ssid, void ProjectConfig::setDeviceMode(const StreamingMode deviceMode) { this->config.device_mode.mode = deviceMode; + this->config.device_mode.save(); // Save immediately } //********************************************************************************************************************** @@ -249,6 +258,10 @@ TrackerConfig_t &ProjectConfig::getTrackerConfig() return this->config; } -DeviceMode_t &ProjectConfig::getDeviceMode() { +DeviceMode_t &ProjectConfig::getDeviceModeConfig() { return this->config.device_mode; +} + +StreamingMode ProjectConfig::getDeviceMode() { + return this->config.device_mode.mode; } \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp index da59033..b256c22 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp @@ -31,7 +31,7 @@ public: bool reset(); DeviceConfig_t &getDeviceConfig(); - DeviceMode_t &getDeviceMode(); + DeviceMode_t &getDeviceModeConfig(); CameraConfig_t &getCameraConfig(); std::vector &getWifiConfigs(); AP_WiFiConfig_t &getAPWifiConfig(); @@ -61,6 +61,7 @@ public: uint8_t channel); void setWiFiTxPower(uint8_t power); void setDeviceMode(StreamingMode deviceMode); + StreamingMode getDeviceMode(); private: Preferences *pref; diff --git a/components/SerialManager/CMakeLists.txt b/components/SerialManager/CMakeLists.txt index 0cd7215..aaaa174 100644 --- a/components/SerialManager/CMakeLists.txt +++ b/components/SerialManager/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "SerialManager/SerialManager.cpp" INCLUDE_DIRS "SerialManager" - REQUIRES esp_driver_uart CommandManager + REQUIRES esp_driver_uart CommandManager ProjectConfig ) \ No newline at end of file diff --git a/components/SerialManager/SerialManager/SerialManager.cpp b/components/SerialManager/SerialManager/SerialManager.cpp index 93d6a3e..d1c60c9 100644 --- a/components/SerialManager/SerialManager/SerialManager.cpp +++ b/components/SerialManager/SerialManager/SerialManager.cpp @@ -1,8 +1,11 @@ #include "SerialManager.hpp" +#include "esp_log.h" +#include "main_globals.hpp" #define BUF_SIZE (1024) -SerialManager::SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle) : commandManager(commandManager), timerHandle(timerHandle) { +SerialManager::SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle, std::shared_ptr deviceConfig) + : commandManager(commandManager), timerHandle(timerHandle), deviceConfig(deviceConfig) { this->data = static_cast(malloc(BUF_SIZE)); this->temp_data = static_cast(malloc(256)); } @@ -20,9 +23,6 @@ void SerialManager::try_receive() int current_position = 0; int len = usb_serial_jtag_read_bytes(this->temp_data, 256, 1000 / 20); - if (len) { - esp_timer_stop(*timerHandle); - } // since we've got something on the serial port // we gotta keep reading until we've got the whole message while (len) @@ -38,19 +38,73 @@ void SerialManager::try_receive() data[current_position] = '\0'; current_position = 0; + // Notify main that a command was received during startup + notify_startup_command_received(); + const auto result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast(this->data))); const auto resultMessage = result.getResult(); usb_serial_jtag_write_bytes(resultMessage.c_str(), resultMessage.length(), 1000 / 20); - esp_timer_start_once(*timerHandle, 30000000); // 30s } } +void SerialManager::send_heartbeat() +{ + // Get the MAC address as unique identifier + uint8_t mac[6]; + esp_read_mac(mac, ESP_MAC_WIFI_STA); + + // Format as serial number string + char serial_number[18]; + sprintf(serial_number, "%02X%02X%02X%02X%02X%02X", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + // Create heartbeat JSON with serial number + char heartbeat[128]; + sprintf(heartbeat, "{\"heartbeat\":\"openiris_setup_mode\",\"serial\":\"%s\"}\n", serial_number); + + usb_serial_jtag_write_bytes(heartbeat, strlen(heartbeat), 1000 / 20); +} + +bool SerialManager::should_send_heartbeat() +{ + // Always send heartbeat during startup delay or if no WiFi configured + extern bool startupCommandReceived; + extern esp_timer_handle_t startupTimerHandle; + + // If startup timer is still running, always send heartbeat + if (startupTimerHandle != nullptr) { + return true; + } + + // If in heartbeat mode after startup, continue sending + if (startupCommandReceived) { + return true; + } + + // Otherwise, only send if no WiFi credentials configured + const auto wifiConfigs = deviceConfig->getWifiConfigs(); + return wifiConfigs.empty(); +} + void HandleSerialManagerTask(void *pvParameters) { auto const serialManager = static_cast(pvParameters); + TickType_t lastHeartbeat = xTaskGetTickCount(); + const TickType_t heartbeatInterval = pdMS_TO_TICKS(2000); // 2 second heartbeat while (true) { serialManager->try_receive(); + + // Send heartbeat every 2 seconds, but only if no WiFi credentials are set + TickType_t currentTime = xTaskGetTickCount(); + if ((currentTime - lastHeartbeat) >= heartbeatInterval) { + if (serialManager->should_send_heartbeat()) { + serialManager->send_heartbeat(); + } + lastHeartbeat = currentTime; + } + + vTaskDelay(pdMS_TO_TICKS(50)); // Small delay to prevent busy waiting } } \ No newline at end of file diff --git a/components/SerialManager/SerialManager/SerialManager.hpp b/components/SerialManager/SerialManager/SerialManager.hpp index e3fca9a..a8c92c9 100644 --- a/components/SerialManager/SerialManager/SerialManager.hpp +++ b/components/SerialManager/SerialManager/SerialManager.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" @@ -15,17 +16,21 @@ #include "driver/usb_serial_jtag.h" #include "esp_vfs_usb_serial_jtag.h" #include "esp_vfs_dev.h" +#include "esp_mac.h" class SerialManager { public: - explicit SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle); + explicit SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle, std::shared_ptr deviceConfig); void setup(); void try_receive(); + void send_heartbeat(); + bool should_send_heartbeat(); private: std::shared_ptr commandManager; esp_timer_handle_t *timerHandle; + std::shared_ptr deviceConfig; uint8_t *data; uint8_t *temp_data; }; diff --git a/components/StreamServer/StreamServer/StreamServer.cpp b/components/StreamServer/StreamServer/StreamServer.cpp index cf666f6..c40f5cc 100644 --- a/components/StreamServer/StreamServer/StreamServer.cpp +++ b/components/StreamServer/StreamServer/StreamServer.cpp @@ -38,8 +38,11 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) if (!fb) { - ESP_LOGE(STREAM_SERVER_TAG, "Camera capture failed with resposne %s", esp_err_to_name(response)); + ESP_LOGE(STREAM_SERVER_TAG, "Camera capture failed"); response = ESP_FAIL; + // Don't break immediately, try to recover + vTaskDelay(pdMS_TO_TICKS(10)); + continue; } else { @@ -70,10 +73,15 @@ esp_err_t StreamHelpers::stream(httpd_req_t *req) } if (response != ESP_OK) break; - long request_end = Helpers::getTimeInMillis(); - long latency = (request_end - last_request_time); - last_request_time = request_end; - ESP_LOGI(STREAM_SERVER_TAG, "Size: %uKB, Time: %lims (%lifps)\n", _jpg_buf_len / 1024, latency, 1000 / latency); + + // Only log every 100 frames to reduce overhead + static int frame_count = 0; + if (++frame_count % 100 == 0) { + long request_end = Helpers::getTimeInMillis(); + long latency = (request_end - last_request_time); + last_request_time = request_end; + ESP_LOGI(STREAM_SERVER_TAG, "Size: %uKB, Time: %lims (%lifps)", _jpg_buf_len / 1024, latency, 1000 / latency); + } } last_frame = 0; return response; @@ -93,8 +101,9 @@ esp_err_t StreamServer::startStreamServer() config.max_uri_handlers = 10; config.server_port = STREAM_SERVER_PORT; config.ctrl_port = STREAM_SERVER_PORT; - config.recv_wait_timeout = 100; - config.send_wait_timeout = 100; + config.recv_wait_timeout = 5; // 5 seconds for receiving + config.send_wait_timeout = 5; // 5 seconds for sending + config.lru_purge_enable = true; // Enable LRU purge for better connection handling httpd_uri_t stream_page = { .uri = "/", diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index d5667d0..e4ad8a7 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -149,5 +149,12 @@ esp_err_t UVCStreamManager::setup() } ESP_LOGI(UVC_STREAM_TAG, "Initialized UVC Device"); + return ESP_OK; +} + +esp_err_t UVCStreamManager::start() +{ + ESP_LOGI(UVC_STREAM_TAG, "Starting UVC streaming"); + // UVC device is already initialized in setup(), just log that we're starting return ESP_OK; } \ No newline at end of file diff --git a/components/UVCStream/UVCStream/UVCStream.hpp b/components/UVCStream/UVCStream/UVCStream.hpp index 614972b..9048569 100644 --- a/components/UVCStream/UVCStream/UVCStream.hpp +++ b/components/UVCStream/UVCStream/UVCStream.hpp @@ -54,6 +54,7 @@ class UVCStreamManager public: esp_err_t setup(); + esp_err_t start(); }; #endif // UVCSTREAM_HPP diff --git a/components/wifiManager/CMakeLists.txt b/components/wifiManager/CMakeLists.txt index 37fcbe2..bb241da 100644 --- a/components/wifiManager/CMakeLists.txt +++ b/components/wifiManager/CMakeLists.txt @@ -1,4 +1,4 @@ -idf_component_register(SRCS "wifiManager/wifiManager.cpp" +idf_component_register(SRCS "wifiManager/wifiManager.cpp" "wifiManager/WiFiScanner.cpp" INCLUDE_DIRS "wifiManager" REQUIRES esp_wifi nvs_flash esp_event esp_netif lwip StateManager ProjectConfig ) \ No newline at end of file diff --git a/components/wifiManager/wifiManager/WiFiScanner.cpp b/components/wifiManager/wifiManager/WiFiScanner.cpp new file mode 100644 index 0000000..8e7f171 --- /dev/null +++ b/components/wifiManager/wifiManager/WiFiScanner.cpp @@ -0,0 +1,205 @@ +#include "WiFiScanner.hpp" +#include + +WiFiScanner::WiFiScanner() {} + +void WiFiScanner::scanResultCallback(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { + auto* scanner = static_cast(arg); + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { + uint16_t ap_count = 0; + esp_wifi_scan_get_ap_num(&ap_count); + + if (ap_count == 0) { + ESP_LOGI(TAG, "No access points found"); + return; + } + + wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count]; + ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, ap_records)); + + scanner->networks.clear(); + for (uint16_t i = 0; i < ap_count; i++) { + WiFiNetwork network; + network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); + network.channel = ap_records[i].primary; + network.rssi = ap_records[i].rssi; + memcpy(network.mac, ap_records[i].bssid, 6); + network.auth_mode = ap_records[i].authmode; + + scanner->networks.push_back(network); + } + + delete[] ap_records; + ESP_LOGI(TAG, "Found %d access points", ap_count); + } +} + +std::vector WiFiScanner::scanNetworks() { + std::vector scan_results; + + // Check if WiFi is initialized + wifi_mode_t mode; + esp_err_t err = esp_wifi_get_mode(&mode); + if (err == ESP_ERR_WIFI_NOT_INIT) { + ESP_LOGE(TAG, "WiFi not initialized"); + return scan_results; + } + + + // Give WiFi more time to be ready + vTaskDelay(pdMS_TO_TICKS(500)); + + // Stop any ongoing scan + esp_wifi_scan_stop(); + + // Try sequential channel scanning as a workaround + bool try_sequential_scan = true; // Enable sequential scan + + if (!try_sequential_scan) { + // Normal all-channel scan + wifi_scan_config_t scan_config = { + .ssid = nullptr, + .bssid = nullptr, + .channel = 0, // 0 means scan all channels + .show_hidden = true, + .scan_type = WIFI_SCAN_TYPE_ACTIVE, // Active scan + .scan_time = { + .active = { + .min = 120, // Min per channel + .max = 300 // Max per channel + }, + .passive = 360 + }, + .home_chan_dwell_time = 0, // 0 for default + .channel_bitmap = 0 // 0 for all channels + }; + + err = esp_wifi_scan_start(&scan_config, false); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to start scan: %s", esp_err_to_name(err)); + return scan_results; + } + } else { + // Sequential channel scan - scan each channel individually + std::vector all_records; + + for (uint8_t ch = 1; ch <= 13; ch++) { + wifi_scan_config_t scan_config = { + .ssid = nullptr, + .bssid = nullptr, + .channel = ch, // Specific channel + .show_hidden = true, + .scan_type = WIFI_SCAN_TYPE_ACTIVE, + .scan_time = { + .active = { + .min = 100, + .max = 200 + }, + .passive = 300 + }, + .home_chan_dwell_time = 0, + .channel_bitmap = 0 + }; + + err = esp_wifi_scan_start(&scan_config, true); // Blocking scan + if (err == ESP_OK) { + uint16_t ch_count = 0; + esp_wifi_scan_get_ap_num(&ch_count); + if (ch_count > 0) { + wifi_ap_record_t* ch_records = new wifi_ap_record_t[ch_count]; + if (esp_wifi_scan_get_ap_records(&ch_count, ch_records) == ESP_OK) { + for (uint16_t i = 0; i < ch_count; i++) { + all_records.push_back(ch_records[i]); + } + } + delete[] ch_records; + } + } + vTaskDelay(pdMS_TO_TICKS(50)); + } + + // Process all collected records + for (const auto& record : all_records) { + WiFiNetwork network; + network.ssid = std::string(reinterpret_cast(record.ssid)); + network.channel = record.primary; + network.rssi = record.rssi; + memcpy(network.mac, record.bssid, 6); + network.auth_mode = record.authmode; + scan_results.push_back(network); + } + + // Skip the normal result processing + return scan_results; + } + + // Wait for scan completion with timeout + int timeout_ms = 15000; // 15 second timeout + int elapsed_ms = 0; + + while (elapsed_ms < timeout_ms) { + uint16_t temp_count = 0; + esp_err_t count_err = esp_wifi_scan_get_ap_num(&temp_count); + + if (count_err == ESP_OK) { + // Wait a bit longer after finding networks to ensure scan is complete + if (temp_count > 0 && elapsed_ms > 5000) { + break; + } + } + + vTaskDelay(pdMS_TO_TICKS(200)); + elapsed_ms += 200; + } + + if (elapsed_ms >= timeout_ms) { + ESP_LOGE(TAG, "Scan timeout after %d ms", timeout_ms); + esp_wifi_scan_stop(); + return scan_results; + } + + // Get scan results + uint16_t ap_count = 0; + esp_wifi_scan_get_ap_num(&ap_count); + + if (ap_count == 0) { + ESP_LOGI(TAG, "No access points found"); + return scan_results; + } + + wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count]; + err = esp_wifi_scan_get_ap_records(&ap_count, ap_records); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to get scan records: %s", esp_err_to_name(err)); + delete[] ap_records; + return scan_results; + } + + // Build the results vector and track channels found + bool channels_found[15] = {false}; // Track channels 0-14 + + for (uint16_t i = 0; i < ap_count; i++) { + WiFiNetwork network; + network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); + network.channel = ap_records[i].primary; + network.rssi = ap_records[i].rssi; + memcpy(network.mac, ap_records[i].bssid, 6); + network.auth_mode = ap_records[i].authmode; + + if (network.channel <= 14) { + channels_found[network.channel] = true; + } + + scan_results.push_back(network); + } + + + delete[] ap_records; + ESP_LOGI(TAG, "Found %d access points", ap_count); + + // Also update the member variable for compatibility + networks = scan_results; + + return scan_results; +} \ No newline at end of file diff --git a/components/wifiManager/wifiManager/WiFiScanner.hpp b/components/wifiManager/wifiManager/WiFiScanner.hpp new file mode 100644 index 0000000..acb4d6e --- /dev/null +++ b/components/wifiManager/wifiManager/WiFiScanner.hpp @@ -0,0 +1,29 @@ +#pragma once +#ifndef WIFI_SCANNER_HPP +#define WIFI_SCANNER_HPP + +#include +#include +#include "esp_wifi.h" +#include "esp_log.h" + +struct WiFiNetwork { + std::string ssid; + uint8_t channel; + int8_t rssi; + uint8_t mac[6]; + wifi_auth_mode_t auth_mode; +}; + +class WiFiScanner { +public: + WiFiScanner(); + std::vector scanNetworks(); + static void scanResultCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); + +private: + static constexpr char const* TAG = "WiFiScanner"; + std::vector networks; +}; + +#endif \ No newline at end of file diff --git a/components/wifiManager/wifiManager/wifiManager.cpp b/components/wifiManager/wifiManager/wifiManager.cpp index 616b383..ffbae5c 100644 --- a/components/wifiManager/wifiManager/wifiManager.cpp +++ b/components/wifiManager/wifiManager/wifiManager.cpp @@ -2,6 +2,10 @@ static auto WIFI_MANAGER_TAG = "[WIFI_MANAGER]"; +// Define the global variables declared as extern in the header +int s_retry_num = 0; +EventGroupHandle_t s_wifi_event_group; + void WiFiManagerHelpers::event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { @@ -15,6 +19,9 @@ void WiFiManagerHelpers::event_handler(void *arg, esp_event_base_t event_base, } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; + ESP_LOGI(WIFI_MANAGER_TAG, "Disconnect reason: %d", disconnected->reason); + if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { esp_wifi_connect(); @@ -37,19 +44,70 @@ void WiFiManagerHelpers::event_handler(void *arg, esp_event_base_t event_base, } } -WiFiManager::WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager *stateManager) : deviceConfig(deviceConfig), eventQueue(eventQueue), stateManager(stateManager) {} +WiFiManager::WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager *stateManager) + : deviceConfig(deviceConfig), eventQueue(eventQueue), stateManager(stateManager), wifiScanner(std::make_unique()) {} void WiFiManager::SetCredentials(const char *ssid, const char *password) { - memcpy(_wifi_cfg.sta.ssid, ssid, std::min(strlen(ssid), sizeof(_wifi_cfg.sta.ssid))); - - memcpy(_wifi_cfg.sta.password, password, std::min(strlen(password), sizeof(_wifi_cfg.sta.password))); + // Clear the config first + memset(&_wifi_cfg, 0, sizeof(_wifi_cfg)); + + // Copy SSID with null termination + size_t ssid_len = std::min(strlen(ssid), sizeof(_wifi_cfg.sta.ssid) - 1); + memcpy(_wifi_cfg.sta.ssid, ssid, ssid_len); + _wifi_cfg.sta.ssid[ssid_len] = '\0'; + + // Copy password with null termination + size_t pass_len = std::min(strlen(password), sizeof(_wifi_cfg.sta.password) - 1); + memcpy(_wifi_cfg.sta.password, password, pass_len); + _wifi_cfg.sta.password[pass_len] = '\0'; + + // Set other required fields + // Use open auth if no password, otherwise allow any WPA variant + if (strlen(password) == 0) { + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; + } else { + // IMPORTANT: Set threshold to WEP to accept ANY security mode >= WEP + // This allows WPA, WPA2, WPA3, etc. The driver will negotiate the highest common mode + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WEP; + } + + // CRITICAL: Disable PMF completely - this often causes handshake timeouts + _wifi_cfg.sta.pmf_cfg.capable = false; + _wifi_cfg.sta.pmf_cfg.required = false; + + // IMPORTANT: Set scan method to ALL channels + _wifi_cfg.sta.scan_method = WIFI_ALL_CHANNEL_SCAN; + _wifi_cfg.sta.bssid_set = 0; // Don't use specific BSSID + _wifi_cfg.sta.channel = 0; // Scan all channels + + // Additional settings that might help with compatibility + _wifi_cfg.sta.listen_interval = 0; // Default listen interval + _wifi_cfg.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; // Connect to strongest signal + + // IMPORTANT: For WPA/WPA2 Personal networks + _wifi_cfg.sta.threshold.rssi = -127; // Accept any signal strength + _wifi_cfg.sta.sae_pwe_h2e = WPA3_SAE_PWE_UNSPECIFIED; // Let driver decide SAE mode + + // Log what we're trying to connect to with detailed debugging + ESP_LOGI(WIFI_MANAGER_TAG, "Setting credentials for SSID: '%s' (length: %d)", ssid, (int)strlen(ssid)); + ESP_LOGI(WIFI_MANAGER_TAG, "Password: '%s' (length: %d)", password, (int)strlen(password)); + ESP_LOGI(WIFI_MANAGER_TAG, "Auth mode: %d, PMF capable: %d", + _wifi_cfg.sta.threshold.authmode, _wifi_cfg.sta.pmf_cfg.capable); + + // Print hex dump of SSID to catch any hidden characters + ESP_LOG_BUFFER_HEX_LEVEL(WIFI_MANAGER_TAG, _wifi_cfg.sta.ssid, strlen((char*)_wifi_cfg.sta.ssid), ESP_LOG_INFO); + + // Print hex dump of password to catch any hidden characters + ESP_LOG_BUFFER_HEX_LEVEL(WIFI_MANAGER_TAG, _wifi_cfg.sta.password, strlen((char*)_wifi_cfg.sta.password), ESP_LOG_INFO); } void WiFiManager::ConnectWithHardcodedCredentials() { SystemEvent event = {EventSource::WIFI, WiFiState_e::WiFiState_ReadyToConnect}; this->SetCredentials(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD); + esp_wifi_stop(); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &_wifi_cfg)); xQueueSend(this->eventQueue, &event, 10); @@ -103,16 +161,38 @@ void WiFiManager::ConnectWithStoredCredentials() return; } + // Stop WiFi once before the loop + esp_wifi_stop(); + vTaskDelay(pdMS_TO_TICKS(100)); + + // Ensure we're in STA mode + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + for (const auto& network : networks) { - xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT); + // Reset retry counter for each network attempt + s_retry_num = 0; + xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); this->SetCredentials(network.ssid.c_str(), network.password.c_str()); - // we need to update the config after every credential change + // Update config without stopping WiFi again + ESP_LOGI(WIFI_MANAGER_TAG, "Attempting to connect to SSID: '%s'", network.ssid.c_str()); + + // Double-check the actual config being sent to WiFi driver + ESP_LOGI(WIFI_MANAGER_TAG, "Final SSID in config: '%s' (len: %d)", + (char*)_wifi_cfg.sta.ssid, (int)strlen((char*)_wifi_cfg.sta.ssid)); + ESP_LOGI(WIFI_MANAGER_TAG, "Final password in config: '%s' (len: %d)", + (char*)_wifi_cfg.sta.password, (int)strlen((char*)_wifi_cfg.sta.password)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &_wifi_cfg)); xQueueSend(this->eventQueue, &event, 10); - esp_wifi_start(); + // Start WiFi if not already started + esp_err_t start_err = esp_wifi_start(); + if (start_err != ESP_OK && start_err != ESP_ERR_WIFI_STATE) { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to start WiFi: %s", esp_err_to_name(start_err)); + continue; + } event.value = WiFiState_e::WiFiState_Connecting; xQueueSend(this->eventQueue, &event, 10); @@ -121,19 +201,23 @@ void WiFiManager::ConnectWithStoredCredentials() WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, - portMAX_DELAY); + pdMS_TO_TICKS(30000)); // 30 second timeout instead of portMAX_DELAY if (bits & WIFI_CONNECTED_BIT) { - ESP_LOGI(WIFI_MANAGER_TAG, "connected to ap SSID:%p password:%p", - _wifi_cfg.sta.ssid, _wifi_cfg.sta.password); + ESP_LOGI(WIFI_MANAGER_TAG, "connected to ap SSID:%s", + network.ssid.c_str()); event.value = WiFiState_e::WiFiState_Connected; xQueueSend(this->eventQueue, &event, 10); return; } - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to SSID:%p, password:%p, trying next stored network", - _wifi_cfg.sta.ssid, _wifi_cfg.sta.password); + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to SSID:%s, trying next stored network", + network.ssid.c_str()); + + // Disconnect before trying next network + esp_wifi_disconnect(); + vTaskDelay(pdMS_TO_TICKS(100)); } event.value = WiFiState_e::WiFiState_Error; @@ -165,6 +249,109 @@ void WiFiManager::SetupAccessPoint() ESP_LOGI(WIFI_MANAGER_TAG, "AP started."); } +std::vector WiFiManager::ScanNetworks() { + wifi_mode_t current_mode; + esp_err_t err = esp_wifi_get_mode(¤t_mode); + + if (err == ESP_ERR_WIFI_NOT_INIT) { + ESP_LOGE(WIFI_MANAGER_TAG, "WiFi not initialized for scanning"); + return std::vector(); + } + + // If we're in AP-only mode, we need STA interface for scanning + if (current_mode == WIFI_MODE_AP) { + ESP_LOGI(WIFI_MANAGER_TAG, "AP mode detected, checking for STA interface"); + + // Check if STA netif already exists + esp_netif_t* sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + bool sta_netif_exists = (sta_netif != nullptr); + + if (!sta_netif_exists) { + ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface for scanning"); + sta_netif = esp_netif_create_default_wifi_sta(); + } + + ESP_LOGI(WIFI_MANAGER_TAG, "Switching to APSTA mode for scanning"); + err = esp_wifi_set_mode(WIFI_MODE_APSTA); + if (err != ESP_OK) { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to set APSTA mode: %s", esp_err_to_name(err)); + if (!sta_netif_exists && sta_netif) { + esp_netif_destroy(sta_netif); + } + return std::vector(); + } + + // Configure STA with empty config to prevent auto-connect + wifi_config_t empty_config = {}; + esp_wifi_set_config(WIFI_IF_STA, &empty_config); + + // Ensure STA is disconnected and not trying to connect + esp_wifi_disconnect(); + vTaskDelay(pdMS_TO_TICKS(500)); + + // Longer delay for mode to stabilize and enable all channels + vTaskDelay(pdMS_TO_TICKS(1500)); + + // Perform scan + auto networks = wifiScanner->scanNetworks(); + + // Restore AP-only mode + ESP_LOGI(WIFI_MANAGER_TAG, "Restoring AP-only mode"); + esp_wifi_set_mode(WIFI_MODE_AP); + + // Clean up STA interface if we created it + if (!sta_netif_exists && sta_netif) { + esp_netif_destroy(sta_netif); + } + + return networks; + } + + // If already in STA or APSTA mode, scan directly + return wifiScanner->scanNetworks(); +} + +WiFiState_e WiFiManager::GetCurrentWiFiState() { + return this->stateManager->GetWifiState(); +} + +void WiFiManager::TryConnectToStoredNetworks() { + ESP_LOGI(WIFI_MANAGER_TAG, "Manual WiFi connection attempt requested"); + + // Check current WiFi mode + wifi_mode_t current_mode; + esp_err_t err = esp_wifi_get_mode(¤t_mode); + if (err != ESP_OK) { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to get WiFi mode: %s", esp_err_to_name(err)); + return; + } + + // If in AP mode, we need to properly transition to STA mode + if (current_mode == WIFI_MODE_AP || current_mode == WIFI_MODE_APSTA) { + ESP_LOGI(WIFI_MANAGER_TAG, "Currently in AP mode, transitioning to STA mode"); + + // Stop WiFi first + esp_wifi_stop(); + vTaskDelay(pdMS_TO_TICKS(100)); + + // Check if STA interface exists, create if needed + esp_netif_t* sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + if (sta_netif == nullptr) { + ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface"); + sta_netif = esp_netif_create_default_wifi_sta(); + } + + // Set to STA mode + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + // Reset retry counter and clear all event bits + s_retry_num = 0; + xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); + this->ConnectWithStoredCredentials(); +} + void WiFiManager::Begin() { s_wifi_event_group = xEventGroupCreate(); @@ -176,6 +363,18 @@ void WiFiManager::Begin() wifi_init_config_t esp_wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&esp_wifi_init_config)); + // Set WiFi country to enable all channels (1-14) + wifi_country_t country_config = { + .cc = "JP", // Japan allows channels 1-14 (most permissive) + .schan = 1, + .nchan = 14, + .max_tx_power = 20, + .policy = WIFI_COUNTRY_POLICY_AUTO + }; + ESP_ERROR_CHECK(esp_wifi_set_country(&country_config)); + + + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &WiFiManagerHelpers::event_handler, @@ -188,8 +387,8 @@ void WiFiManager::Begin() &instance_got_ip)); _wifi_cfg = {}; - _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WEP; - _wifi_cfg.sta.pmf_cfg.capable = true; + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; // Start with open, will be set properly by SetCredentials + _wifi_cfg.sta.pmf_cfg.capable = false; // Disable PMF by default _wifi_cfg.sta.pmf_cfg.required = false; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); diff --git a/components/wifiManager/wifiManager/wifiManager.hpp b/components/wifiManager/wifiManager/wifiManager.hpp index b96e8fa..8a78826 100644 --- a/components/wifiManager/wifiManager/wifiManager.hpp +++ b/components/wifiManager/wifiManager/wifiManager.hpp @@ -7,17 +7,20 @@ #include #include #include +#include "WiFiScanner.hpp" #include "esp_event.h" #include "esp_wifi.h" #include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #define EXAMPLE_ESP_MAXIMUM_RETRY 3 #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 -static int s_retry_num = 0; -static EventGroupHandle_t s_wifi_event_group; +extern int s_retry_num; +extern EventGroupHandle_t s_wifi_event_group; namespace WiFiManagerHelpers { @@ -34,6 +37,7 @@ private: StateManager *stateManager; wifi_init_config_t _wifi_init_cfg = WIFI_INIT_CONFIG_DEFAULT(); wifi_config_t _wifi_cfg = {}; + std::unique_ptr wifiScanner; esp_event_handler_instance_t instance_any_id; esp_event_handler_instance_t instance_got_ip; @@ -48,6 +52,9 @@ private: public: WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager *stateManager); void Begin(); + std::vector ScanNetworks(); + WiFiState_e GetCurrentWiFiState(); + void TryConnectToStoredNetworks(); }; #endif \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock index c56cb65..c7e209c 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -53,7 +53,7 @@ dependencies: idf: source: type: idf - version: 5.3.2 + version: 5.3.3 direct_dependencies: - espressif/cmake_utilities - espressif/esp32-camera diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index e5e9744..a837f63 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef CONFIG_WIRED_MODE #include @@ -29,8 +30,10 @@ #define CONFIG_LED_C_PIN_GPIO (gpio_num_t) CONFIG_LED_C_PIN esp_timer_handle_t timerHandle; +esp_timer_handle_t startupTimerHandle; QueueHandle_t eventQueue = xQueueCreate(10, sizeof(SystemEvent)); QueueHandle_t ledStateQueue = xQueueCreate(10, sizeof(uint32_t)); +bool startupCommandReceived = false; auto *stateManager = new StateManager(eventQueue, ledStateQueue); auto dependencyRegistry = std::make_shared(); @@ -39,8 +42,8 @@ auto commandManager = std::make_shared(dependencyRegistry); WebSocketLogger webSocketLogger; Preferences preferences; -std::shared_ptr deviceConfig = std::make_shared(&preferences); -WiFiManager wifiManager(deviceConfig, eventQueue, stateManager); +auto deviceConfig = std::make_shared(&preferences); +auto wifiManager = std::make_shared(deviceConfig, eventQueue, stateManager); MDNSManager mdnsManager(deviceConfig, eventQueue); std::shared_ptr cameraHandler = std::make_shared(deviceConfig, eventQueue); @@ -53,7 +56,7 @@ UVCStreamManager uvcStream; #endif auto *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue); -auto *serialManager = new SerialManager(commandManager, &timerHandle); +auto *serialManager = new SerialManager(commandManager, &timerHandle, deviceConfig); static void initNVSStorage() { esp_err_t ret = nvs_flash_init(); @@ -73,58 +76,151 @@ void disable_serial_manager_task(TaskHandle_t serialManagerHandle) { vTaskDelete(serialManagerHandle); } -// the idea here is pretty simple. -// After setting everything up, we start a 30s timer with this as a callback -// if we get anything on the serial, we stop the timer and reset it after the commands are done -// this is done to ensure the user has enough time to configure the board if need be -void start_video_streaming(void *arg) { - // if we're in auto-mode, we can decide which streaming helper to start based on the - // presence of Wi-Fi credentials - ESP_LOGI("[MAIN]", "Setup window expired, starting streaming services, quitting serial manager."); - switch (deviceConfig->getDeviceMode().mode) { - case StreamingMode::AUTO: - if (!deviceConfig->getWifiConfigs().empty() || strcmp(CONFIG_WIFI_SSID, "") != 0) { - // todo make sure the server runs on a separate core - ESP_LOGI("[MAIN]", "WiFi setup detected, starting WiFi streaming."); - streamServer.startStreamServer(); - } else { - ESP_LOGI("[MAIN]", "UVC setup detected, starting UVC streaming."); - uvcStream.setup(); +// New setup flow: +// 1. Device starts in setup mode (AP + Serial active) +// 2. User configures WiFi via serial commands +// 3. Device attempts WiFi connection while maintaining setup interfaces +// 4. Device reports connection status via serial +// 5. User explicitly starts streaming after verifying connectivity +void start_video_streaming(void *arg) +{ + // Get the stored device mode + StreamingMode deviceMode = deviceConfig->getDeviceMode(); + + // Check if WiFi is actually connected, not just configured + bool hasWifiCredentials = !deviceConfig->getWifiConfigs().empty() || strcmp(CONFIG_WIFI_SSID, "") != 0; + bool wifiConnected = (wifiManager->GetCurrentWiFiState() == WiFiState_e::WiFiState_Connected); + + if (deviceMode == StreamingMode::UVC) { +#ifdef CONFIG_WIRED_MODE + ESP_LOGI("[MAIN]", "Starting UVC streaming mode."); + // Initialize UVC if not already done + static bool uvcInitialized = false; + if (!uvcInitialized) { + ESP_LOGI("[MAIN]", "Initializing UVC hardware..."); + esp_err_t ret = uvcStream.setup(); + if (ret != ESP_OK) { + ESP_LOGE("[MAIN]", "Failed to initialize UVC: %s", esp_err_to_name(ret)); + return; } - break; - case StreamingMode::UVC: - ESP_LOGI("[MAIN]", "Device set to UVC Mode, starting UVC streaming."); - uvcStream.setup(); - break; - case StreamingMode::WIFI: - ESP_LOGI("[MAIN]", "Device set to Wi-Fi mode, starting WiFi streaming."); - streamServer.startStreamServer(); - break; + uvcInitialized = true; + } + uvcStream.start(); +#else + ESP_LOGE("[MAIN]", "UVC mode selected but CONFIG_WIRED_MODE not enabled in build!"); + ESP_LOGI("[MAIN]", "Falling back to WiFi mode if credentials available"); + deviceMode = StreamingMode::WIFI; +#endif } - const auto serialTaskHandle = static_cast(arg); - disable_serial_manager_task(serialTaskHandle); + if ((deviceMode == StreamingMode::WIFI || deviceMode == StreamingMode::AUTO) && hasWifiCredentials && wifiConnected) { + ESP_LOGI("[MAIN]", "Starting WiFi streaming mode."); + streamServer.startStreamServer(); + } else { + if (hasWifiCredentials && !wifiConnected) { + ESP_LOGE("[MAIN]", "WiFi credentials configured but not connected. Try connecting first."); + } else { + ESP_LOGE("[MAIN]", "No streaming mode available. Please configure WiFi."); + } + return; + } + + ESP_LOGI("[MAIN]", "Streaming started successfully."); + + // Optionally disable serial manager after explicit streaming start + if (arg != nullptr) { + ESP_LOGI("[MAIN]", "Disabling setup interfaces after streaming start."); + const auto serialTaskHandle = static_cast(arg); + disable_serial_manager_task(serialTaskHandle); + } } -esp_timer_handle_t createStartVideoStreamingTimer(void *pvParameter) { - esp_timer_handle_t handle; - const esp_timer_create_args_t args = { - .callback = &start_video_streaming, - .arg = pvParameter, - .name = "startVideoStreaming" - }; +// Manual streaming activation - no timer needed +void activate_streaming(TaskHandle_t serialTaskHandle = nullptr) +{ + start_video_streaming(serialTaskHandle); +} - if (const auto result = esp_timer_create(&args, &handle); result != ESP_OK) { - ESP_LOGE("[MAIN]", "Failed to create timer: %s", esp_err_to_name(result)); +// Callback for automatic startup after delay +void startup_timer_callback(void* arg) +{ + ESP_LOGI("[MAIN]", "Startup timer fired, startupCommandReceived=%s, startupPaused=%s", + startupCommandReceived ? "true" : "false", + startupPaused ? "true" : "false"); + + if (!startupCommandReceived && !startupPaused) { + ESP_LOGI("[MAIN]", "No command received during startup delay, proceeding with automatic mode startup"); + + // Get the stored device mode + StreamingMode deviceMode = deviceConfig->getDeviceMode(); + ESP_LOGI("[MAIN]", "Stored device mode: %d", (int)deviceMode); + + // Get the serial manager handle to disable it after streaming starts + TaskHandle_t* serialHandle = getSerialManagerHandle(); + TaskHandle_t serialTaskHandle = (serialHandle && *serialHandle) ? *serialHandle : nullptr; + + if (deviceMode == StreamingMode::WIFI || deviceMode == StreamingMode::AUTO) { + // For WiFi mode, check if we have credentials and are connected + bool hasWifiCredentials = !deviceConfig->getWifiConfigs().empty() || strcmp(CONFIG_WIFI_SSID, "") != 0; + bool wifiConnected = (wifiManager->GetCurrentWiFiState() == WiFiState_e::WiFiState_Connected); + + ESP_LOGI("[MAIN]", "WiFi check - hasCredentials: %s, connected: %s", + hasWifiCredentials ? "true" : "false", + wifiConnected ? "true" : "false"); + + if (hasWifiCredentials && wifiConnected) { + ESP_LOGI("[MAIN]", "Starting WiFi streaming automatically"); + activate_streaming(serialTaskHandle); + } else if (hasWifiCredentials && !wifiConnected) { + ESP_LOGI("[MAIN]", "WiFi credentials exist but not connected, waiting..."); + // Could retry connection here + } else { + ESP_LOGI("[MAIN]", "No WiFi credentials, staying in setup mode"); + } + } + else if (deviceMode == StreamingMode::UVC) { +#ifdef CONFIG_WIRED_MODE + ESP_LOGI("[MAIN]", "Starting UVC streaming automatically"); + activate_streaming(serialTaskHandle); +#else + ESP_LOGE("[MAIN]", "UVC mode selected but CONFIG_WIRED_MODE not enabled in build!"); + ESP_LOGI("[MAIN]", "Device will stay in setup mode. Enable CONFIG_WIRED_MODE and rebuild."); +#endif + } + else { + ESP_LOGI("[MAIN]", "Unknown device mode: %d", (int)deviceMode); + } + } else { + if (startupPaused) { + ESP_LOGI("[MAIN]", "Startup paused, staying in heartbeat mode"); + } else { + ESP_LOGI("[MAIN]", "Command received during startup, staying in heartbeat mode"); + } } - return handle; + // Delete the timer after it fires + esp_timer_delete(startupTimerHandle); + startupTimerHandle = nullptr; +} + +// Function to notify that a command was received during startup +void notify_startup_command_received() +{ + startupCommandReceived = true; + + // Cancel the startup timer if it's still running + if (startupTimerHandle != nullptr) { + esp_timer_stop(startupTimerHandle); + esp_timer_delete(startupTimerHandle); + startupTimerHandle = nullptr; + ESP_LOGI("[MAIN]", "Startup timer cancelled, staying in heartbeat mode"); + } } extern "C" void app_main(void) { - TaskHandle_t *serialManagerHandle = nullptr; dependencyRegistry->registerService(DependencyType::project_config, deviceConfig); dependencyRegistry->registerService(DependencyType::camera_manager, cameraHandler); + dependencyRegistry->registerService(DependencyType::wifi_manager, wifiManager); // uvc plan // cleanup the logs - done // prepare the camera to be initialized with UVC - done? @@ -197,19 +293,23 @@ extern "C" void app_main(void) { deviceConfig->load(); serialManager->setup(); + static TaskHandle_t serialManagerHandle = nullptr; xTaskCreate( HandleSerialManagerTask, "HandleSerialManagerTask", 1024 * 6, serialManager, 1, // we only rely on the serial manager during provisioning, we can run it slower - serialManagerHandle); + &serialManagerHandle); - wifiManager.Begin(); + wifiManager->Begin(); mdnsManager.start(); restAPI->begin(); cameraHandler->setupCamera(); + // Don't initialize UVC here - wait for the timer to decide + // UVC will be initialized when streaming actually starts + xTaskCreate( HandleRestAPIPollTask, "HandleRestAPIPollTask", @@ -218,8 +318,44 @@ extern "C" void app_main(void) { 1, // it's the rest API, we only serve commands over it so we don't really need a higher priority nullptr); - timerHandle = createStartVideoStreamingTimer(serialManagerHandle); - if (timerHandle != nullptr) { - esp_timer_start_once(timerHandle, 30000000); // 30s + // New flow: Device starts with a 20-second delay before automatic mode startup + ESP_LOGI("[MAIN]", "====================================="); + ESP_LOGI("[MAIN]", "STARTUP: 20-SECOND DELAY MODE ACTIVE"); + ESP_LOGI("[MAIN]", "====================================="); + ESP_LOGI("[MAIN]", "Device will wait 20 seconds for commands..."); + + // Get the stored device mode + StreamingMode deviceMode = deviceConfig->getDeviceMode(); + ESP_LOGI("[MAIN]", "Stored device mode: %s (value: %d)", + deviceMode == StreamingMode::UVC ? "UVC" : + deviceMode == StreamingMode::WIFI ? "WiFi" : + "Auto", (int)deviceMode); + + // If WiFi credentials exist, attempt connection but stay in setup mode + if (!deviceConfig->getWifiConfigs().empty()) { + ESP_LOGI("[MAIN]", "WiFi credentials found, attempting connection in background"); + // WiFi connection happens in wifiManager->Begin() above } + + // Reset startup state + startupCommandReceived = false; + + // Create a one-shot timer for 20 seconds + const esp_timer_create_args_t startup_timer_args = { + .callback = &startup_timer_callback, + .arg = nullptr, + .dispatch_method = ESP_TIMER_TASK, + .name = "startup_timer", + .skip_unhandled_events = false + }; + + ESP_ERROR_CHECK(esp_timer_create(&startup_timer_args, &startupTimerHandle)); + ESP_ERROR_CHECK(esp_timer_start_once(startupTimerHandle, 20000000)); // 20 seconds in microseconds + + ESP_LOGI("[MAIN]", "Started 20-second startup timer"); + ESP_LOGI("[MAIN]", "Send any command within 20 seconds to enter heartbeat mode"); + + // Set global handles for component access + setStreamingTimerHandle(&timerHandle); + setSerialManagerHandle(&serialManagerHandle); } diff --git a/sdkconfig b/sdkconfig index 1d2a05b..89fd862 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.3.3 Project Configuration # CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 @@ -64,6 +64,7 @@ CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_SIMD_INSTRUCTION_SUPPORTED=y CONFIG_SOC_XTAL_SUPPORT_40M=y CONFIG_SOC_APPCPU_HAS_CLOCK_GATING_BUG=y CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y @@ -101,6 +102,7 @@ CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_SIMD_PREFERRED_DATA_ALIGNMENT=16 CONFIG_SOC_DS_SIGNATURE_MAX_BIT_LEN=4096 CONFIG_SOC_DS_KEY_PARAM_MD_IV_LENGTH=16 CONFIG_SOC_DS_KEY_CHECK_MAX_WAIT_US=1100 @@ -203,6 +205,7 @@ CONFIG_SOC_RTCIO_PIN_COUNT=22 CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_LP_IO_CLOCK_IS_INDEPENDENT=y CONFIG_SOC_SDM_GROUPS=y CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 CONFIG_SOC_SDM_CLK_SUPPORT_APB=y @@ -243,6 +246,8 @@ CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=54 CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 CONFIG_SOC_TOUCH_SENSOR_VERSION=2 CONFIG_SOC_TOUCH_SENSOR_NUM=15 CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y @@ -366,7 +371,7 @@ CONFIG_IDF_TOOLCHAIN="gcc" CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_INIT_VERSION="5.3.2" +CONFIG_IDF_INIT_VERSION="5.3.3" CONFIG_IDF_TARGET_ESP32S3=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 @@ -628,7 +633,12 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # # CONFIG_BT_ENABLED is not set -CONFIG_BT_ALARM_MAX_NUM=50 + +# +# Common Options +# +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# end of Common Options # end of Bluetooth # @@ -652,6 +662,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # # Legacy ADC Calibration Configuration @@ -664,42 +675,49 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy MCPWM Driver Configurations # # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # # Legacy Temperature Sensor Driver Configurations # # CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_TEMP_SENSOR_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Temperature Sensor Driver Configurations # end of Driver Configurations @@ -759,6 +777,7 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations @@ -877,6 +896,13 @@ CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 # end of GDB Stub +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + # # ESP HTTP client # @@ -1051,6 +1077,7 @@ CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # @@ -1251,9 +1278,9 @@ CONFIG_ESP_WIFI_ENABLED=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 @@ -1263,7 +1290,6 @@ CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP_WIFI_RX_BA_WIN=6 -# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP_WIFI_NVS_ENABLED=y CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set @@ -1434,7 +1460,6 @@ CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 CONFIG_HAL_WDT_USE_ROM_IMPL=y CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set # end of Hardware Abstraction Layer (HAL) and Low Level (LL) # @@ -1836,25 +1861,10 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y # CONFIG_OPENTHREAD_ENABLED is not set # -# Thread Operational Dataset +# OpenThread Spinel # -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" -CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" -CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 -CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" -CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" -CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" -# end of Thread Operational Dataset - -CONFIG_OPENTHREAD_XTAL_ACCURACY=130 # CONFIG_OPENTHREAD_SPINEL_ONLY is not set -CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y - -# -# Thread Address Query Config -# -# end of Thread Address Query Config +# end of OpenThread Spinel # end of OpenThread # @@ -1863,6 +1873,7 @@ CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y # end of Protocomm # @@ -2093,75 +2104,6 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager -# -# USB Device UVC -# -CONFIG_TUSB_VID=0x303A -CONFIG_TUSB_PID=0x8000 -CONFIG_TUSB_MANUFACTURER="ETVR" -CONFIG_TUSB_PRODUCT="OpenIris Camera" -CONFIG_TUSB_SERIAL_NUM="12345678" -# CONFIG_UVC_SUPPORT_TWO_CAM is not set - -# -# USB Cam1 Config -# -CONFIG_FORMAT_MJPEG_CAM1=y -# CONFIG_FORMAT_H264_CAM1 is not set -# CONFIG_FORMAT_UNCOMPR_CAM1 is not set -# CONFIG_UVC_MODE_ISOC_CAM1 is not set -CONFIG_UVC_MODE_BULK_CAM1=y -CONFIG_FRAMESIZE_QVGA=y -# CONFIG_FRAMESIZE_HVGA is not set -# CONFIG_FRAMESIZE_VGA is not set -# CONFIG_FRAMESIZE_SVGA is not set -# CONFIG_FRAMESIZE_HD is not set -# CONFIG_FRAMESIZE_FHD is not set -CONFIG_UVC_CAM1_FRAMERATE=90 -CONFIG_UVC_CAM1_FRAMESIZE_WIDTH=240 -CONFIG_UVC_CAM1_FRAMESIZE_HEIGT=240 -CONFIG_UVC_CAM1_MULTI_FRAMESIZE=y -# end of USB Cam1 Config - -# -# UVC_MULTI_FRAME_CONFIG -# - -# -# FRAME_SIZE_1 -# -CONFIG_UVC_MULTI_FRAME_WIDTH_1=240 -CONFIG_UVC_MULTI_FRAME_HEIGHT_1=240 -CONFIG_UVC_MULTI_FRAME_FPS_1=90 -# end of FRAME_SIZE_1 - -# -# FRAME_SIZE_2 -# -CONFIG_UVC_MULTI_FRAME_WIDTH_2=240 -CONFIG_UVC_MULTI_FRAME_HEIGHT_2=240 -CONFIG_UVC_MULTI_FRAME_FPS_2=90 -# end of FRAME_SIZE_2 - -# -# FRAME_SIZE_3 -# -CONFIG_UVC_MULTI_FRAME_WIDTH_3=240 -CONFIG_UVC_MULTI_FRAME_HEIGHT_3=240 -CONFIG_UVC_MULTI_FRAME_FPS_3=90 -# end of FRAME_SIZE_3 -# end of UVC_MULTI_FRAME_CONFIG - -# -# UVC Task Config -# -CONFIG_UVC_TINYUSB_TASK_PRIORITY=3 -CONFIG_UVC_TINYUSB_TASK_CORE=-1 -CONFIG_UVC_CAM1_TASK_PRIORITY=2 -CONFIG_UVC_CAM1_TASK_CORE=-1 -# end of UVC Task Config -# end of USB Device UVC - # # CMake Utilities # @@ -2233,6 +2175,75 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_MDNS_PREDEF_NETIF_ETH=y # end of MDNS Predefined interfaces # end of mDNS + +# +# USB Device UVC +# +CONFIG_TUSB_VID=0x303A +CONFIG_TUSB_PID=0x8000 +CONFIG_TUSB_MANUFACTURER="ETVR" +CONFIG_TUSB_PRODUCT="OpenIris Camera" +CONFIG_TUSB_SERIAL_NUM="12345678" +# CONFIG_UVC_SUPPORT_TWO_CAM is not set + +# +# USB Cam1 Config +# +CONFIG_FORMAT_MJPEG_CAM1=y +# CONFIG_FORMAT_H264_CAM1 is not set +# CONFIG_FORMAT_UNCOMPR_CAM1 is not set +# CONFIG_UVC_MODE_ISOC_CAM1 is not set +CONFIG_UVC_MODE_BULK_CAM1=y +CONFIG_FRAMESIZE_QVGA=y +# CONFIG_FRAMESIZE_HVGA is not set +# CONFIG_FRAMESIZE_VGA is not set +# CONFIG_FRAMESIZE_SVGA is not set +# CONFIG_FRAMESIZE_HD is not set +# CONFIG_FRAMESIZE_FHD is not set +CONFIG_UVC_CAM1_FRAMERATE=90 +CONFIG_UVC_CAM1_FRAMESIZE_WIDTH=240 +CONFIG_UVC_CAM1_FRAMESIZE_HEIGT=240 +CONFIG_UVC_CAM1_MULTI_FRAMESIZE=y +# end of USB Cam1 Config + +# +# UVC_MULTI_FRAME_CONFIG +# + +# +# FRAME_SIZE_1 +# +CONFIG_UVC_MULTI_FRAME_WIDTH_1=240 +CONFIG_UVC_MULTI_FRAME_HEIGHT_1=240 +CONFIG_UVC_MULTI_FRAME_FPS_1=60 +# end of FRAME_SIZE_1 + +# +# FRAME_SIZE_2 +# +CONFIG_UVC_MULTI_FRAME_WIDTH_2=240 +CONFIG_UVC_MULTI_FRAME_HEIGHT_2=240 +CONFIG_UVC_MULTI_FRAME_FPS_2=60 +# end of FRAME_SIZE_2 + +# +# FRAME_SIZE_3 +# +CONFIG_UVC_MULTI_FRAME_WIDTH_3=240 +CONFIG_UVC_MULTI_FRAME_HEIGHT_3=240 +CONFIG_UVC_MULTI_FRAME_FPS_3=60 +# end of FRAME_SIZE_3 +# end of UVC_MULTI_FRAME_CONFIG + +# +# UVC Task Config +# +CONFIG_UVC_TINYUSB_TASK_PRIORITY=4 +CONFIG_UVC_TINYUSB_TASK_CORE=-1 +CONFIG_UVC_CAM1_TASK_PRIORITY=3 +CONFIG_UVC_CAM1_TASK_CORE=-1 +# end of UVC Task Config +# end of USB Device UVC # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -2326,7 +2337,6 @@ CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y CONFIG_ESP32S3_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y CONFIG_ESP32S3_BROWNOUT_DET=y -CONFIG_ESP32S3_BROWNOUT_DET=y CONFIG_BROWNOUT_DET_LVL_SEL_7=y CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y # CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set @@ -2349,17 +2359,14 @@ CONFIG_ESP32_WIFI_ENABLED=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP32_WIFI_NVS_ENABLED=y CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set diff --git a/sdkconfig.old b/sdkconfig.old index 2259232..125ee3c 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.3.3 Project Configuration # CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 @@ -64,6 +64,7 @@ CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_SIMD_INSTRUCTION_SUPPORTED=y CONFIG_SOC_XTAL_SUPPORT_40M=y CONFIG_SOC_APPCPU_HAS_CLOCK_GATING_BUG=y CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y @@ -101,6 +102,7 @@ CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_SIMD_PREFERRED_DATA_ALIGNMENT=16 CONFIG_SOC_DS_SIGNATURE_MAX_BIT_LEN=4096 CONFIG_SOC_DS_KEY_PARAM_MD_IV_LENGTH=16 CONFIG_SOC_DS_KEY_CHECK_MAX_WAIT_US=1100 @@ -203,6 +205,7 @@ CONFIG_SOC_RTCIO_PIN_COUNT=22 CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_LP_IO_CLOCK_IS_INDEPENDENT=y CONFIG_SOC_SDM_GROUPS=y CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 CONFIG_SOC_SDM_CLK_SUPPORT_APB=y @@ -243,6 +246,8 @@ CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=54 CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 CONFIG_SOC_TOUCH_SENSOR_VERSION=2 CONFIG_SOC_TOUCH_SENSOR_NUM=15 CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y @@ -366,7 +371,7 @@ CONFIG_IDF_TOOLCHAIN="gcc" CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_INIT_VERSION="5.3.2" +CONFIG_IDF_INIT_VERSION="5.3.3" CONFIG_IDF_TARGET_ESP32S3=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 @@ -544,11 +549,10 @@ CONFIG_ENV_GPIO_RANGE_MAX=48 CONFIG_ENV_GPIO_IN_RANGE_MAX=48 CONFIG_ENV_GPIO_OUT_RANGE_MAX=48 CONFIG_BLINK_GPIO=38 -# CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL is not set +CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL=y CONFIG_LED_C_PIN=1 CONFIG_BLINK_PERIOD=1000 -CONFIG_ILLUMINATOR_PIN=1 -CONFIG_WIRED_MODE=y +# CONFIG_WIRED_MODE is not set CONFIG_MDNS_HOSTNAME="openiristracker" CONFIG_WIFI_SSID="" CONFIG_WIFI_PASSWORD="" @@ -629,7 +633,12 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # # CONFIG_BT_ENABLED is not set -CONFIG_BT_ALARM_MAX_NUM=50 + +# +# Common Options +# +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# end of Common Options # end of Bluetooth # @@ -653,6 +662,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # # Legacy ADC Calibration Configuration @@ -665,42 +675,49 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy MCPWM Driver Configurations # # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations # # Legacy PCNT Driver Configurations # # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # # Legacy Temperature Sensor Driver Configurations # # CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_TEMP_SENSOR_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Temperature Sensor Driver Configurations # end of Driver Configurations @@ -760,6 +777,7 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations @@ -878,6 +896,13 @@ CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 # end of GDB Stub +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + # # ESP HTTP client # @@ -1052,6 +1077,7 @@ CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # @@ -1252,9 +1278,9 @@ CONFIG_ESP_WIFI_ENABLED=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 @@ -1264,7 +1290,6 @@ CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP_WIFI_RX_BA_WIN=6 -# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP_WIFI_NVS_ENABLED=y CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set @@ -1435,7 +1460,6 @@ CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 CONFIG_HAL_WDT_USE_ROM_IMPL=y CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set # end of Hardware Abstraction Layer (HAL) and Low Level (LL) # @@ -1837,25 +1861,10 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y # CONFIG_OPENTHREAD_ENABLED is not set # -# Thread Operational Dataset +# OpenThread Spinel # -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" -CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" -CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 -CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" -CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" -CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" -# end of Thread Operational Dataset - -CONFIG_OPENTHREAD_XTAL_ACCURACY=130 # CONFIG_OPENTHREAD_SPINEL_ONLY is not set -CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y - -# -# Thread Address Query Config -# -# end of Thread Address Query Config +# end of OpenThread Spinel # end of OpenThread # @@ -1864,6 +1873,7 @@ CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y # end of Protocomm # @@ -2237,3 +2247,195 @@ CONFIG_UVC_CAM1_TASK_CORE=-1 # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +CONFIG_FLASHMODE_QIO=y +# CONFIG_FLASHMODE_QOUT is not set +# CONFIG_FLASHMODE_DIO is not set +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +# CONFIG_EXTERNAL_COEX_ENABLE is not set +# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_REDUCE_PHY_TX_POWER is not set +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y +CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240 +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32S3_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32S3_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_7=y +CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 +CONFIG_IPC_TASK_STACK_SIZE=1280 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 +CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_SUITE_B_192 is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_SYSTIMER=y +CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py new file mode 100644 index 0000000..e4996eb --- /dev/null +++ b/tools/openiris_setup.py @@ -0,0 +1,816 @@ +#!/usr/bin/env python3 +""" +OpenIris Setup CLI Tool + +This tool automatically discovers OpenIris devices via heartbeat, +allows WiFi configuration, and monitors the device logs. +""" + +import json +import time +import threading +import argparse +import sys +from typing import Dict, List, Optional, Tuple +import serial +import serial.tools.list_ports +from dataclasses import dataclass + + +@dataclass +class WiFiNetwork: + ssid: str + channel: int + rssi: int + mac_address: str + auth_mode: int + + @property + def security_type(self) -> str: + """Convert auth_mode to human readable string""" + auth_modes = { + 0: "Open", + 1: "WEP", + 2: "WPA PSK", + 3: "WPA2 PSK", + 4: "WPA WPA2 PSK", + 5: "WPA2 Enterprise", + 6: "WPA3 PSK", + 7: "WPA2 WPA3 PSK" + } + return auth_modes.get(self.auth_mode, f"Unknown ({self.auth_mode})") + + +class OpenIrisDevice: + def __init__(self, port: str, serial_number: str, debug: bool = False): + + self.port = port + self.serial_number = serial_number + self.connection: Optional[serial.Serial] = None + self.networks: List[WiFiNetwork] = [] + self.debug = debug + + def connect(self) -> bool: + """Connect to the device""" + try: + self.connection = serial.Serial( + port=self.port, + baudrate=115200, + timeout=1, + write_timeout=1 + ) + print(f"āœ… Connected to device {self.serial_number} on {self.port}") + + # Immediately send pause command to keep device in setup mode + print("āøļø Pausing device startup...") + # Use shorter timeout for pause command since device is just starting up + pause_response = self.send_command("pause", {"pause": True}, timeout=5) + if "error" not in pause_response and pause_response.get("results"): + print("āœ… Device paused in setup mode") + elif "error" in pause_response and pause_response["error"] == "Command timeout": + # Even if we timeout, the command likely worked (as seen in logs) + print("āœ… Device pause command sent (startup logs may have obscured response)") + else: + print(f"āš ļø Pause status uncertain: {pause_response}") + + return True + except Exception as e: + print(f"āŒ Failed to connect to {self.port}: {e}") + return False + + def disconnect(self): + """Disconnect from the device""" + if self.connection and self.connection.is_open: + # Optionally unpause the device before disconnecting + print("Resuming device startup...") + self.send_command("pause", {"pause": False}) + + self.connection.close() + print(f"šŸ”Œ Disconnected from {self.port}") + + def send_command(self, command: str, params: Dict = None, timeout: int = None) -> Dict: + """Send a command to the device and wait for response""" + if not self.connection or not self.connection.is_open: + return {"error": "Not connected"} + + cmd_obj = {"commands": [{"command": command}]} + if params: + cmd_obj["commands"][0]["data"] = params + + cmd_json = json.dumps(cmd_obj) + '\n' + + try: + # Clear any pending data + self.connection.reset_input_buffer() + + # Send command + print(f"šŸ“¤ Sending: {cmd_json.strip()}") + self.connection.write(cmd_json.encode()) + + # For scan_networks command, handle special case + if command == "scan_networks": + # Use provided timeout or default to 30 seconds for scan + scan_timeout = timeout if timeout is not None else 30 + return self._handle_scan_response(scan_timeout) + + # Wait for response (skip heartbeats and logs) + start_time = time.time() + response_buffer = "" + + # Use provided timeout or default to 15 seconds + cmd_timeout = timeout if timeout is not None else 15 + while time.time() - start_time < cmd_timeout: + try: + if self.connection.in_waiting: + data = self.connection.read(self.connection.in_waiting).decode('utf-8', errors='ignore') + response_buffer += data + + # Show raw data for debugging + if self.debug and data.strip(): + print(f"šŸ“” Raw: {repr(data)}") + print(f"šŸ“ Buffer: {repr(response_buffer[-200:])}") + + # Clean buffer and look for JSON + import re + + # Remove ANSI escape sequences + clean_buffer = re.sub(r'\x1b\[[0-9;]*m', '', response_buffer) + clean_buffer = clean_buffer.replace('\r', '') + + # Look for JSON objects - handle both single-line and multi-line + # Try to find complete JSON objects + start_idx = clean_buffer.find('{') + while start_idx >= 0: + # Count braces to find complete JSON + brace_count = 0 + end_idx = -1 + + for i in range(start_idx, len(clean_buffer)): + if clean_buffer[i] == '{': + brace_count += 1 + elif clean_buffer[i] == '}': + brace_count -= 1 + if brace_count == 0: + end_idx = i + 1 + break + + if end_idx > start_idx: + json_str = clean_buffer[start_idx:end_idx] + + # Try to parse any complete JSON object + try: + # Clean up the JSON + clean_json = json_str.replace('\t', ' ').replace('\n', ' ').replace('\r', '') + clean_json = re.sub(r'\s+', ' ', clean_json) + + response = json.loads(clean_json) + + # Return if this is a command response with results + if "results" in response: + return response + + except json.JSONDecodeError: + pass + + # Look for next JSON object + start_idx = clean_buffer.find('{', end_idx) + else: + # No complete JSON found yet + break + else: + time.sleep(0.1) + except Exception as e: + print(f"āš ļø Exception: {e}") + continue + + return {"error": "Command timeout"} + except Exception as e: + return {"error": f"Communication error: {e}"} + + def _handle_scan_response(self, timeout: int = 30) -> Dict: + """Handle scan_networks command response which outputs raw JSON first""" + start_time = time.time() + response_buffer = "" + + while time.time() - start_time < timeout: # Configurable timeout for scan + if self.connection.in_waiting: + data = self.connection.read(self.connection.in_waiting).decode('utf-8', errors='ignore') + response_buffer += data + + # Look for WiFi networks JSON directly (new format) + # The scan command now outputs JSON directly followed by command result + if '{"networks":[' in response_buffer: + import re + + # Look for the networks JSON pattern that appears first + networks_pattern = r'\{"networks":\[.*?\]\}' + matches = re.findall(networks_pattern, response_buffer, re.DOTALL) + + for match in matches: + try: + # Parse the networks JSON directly + networks_data = json.loads(match) + if "networks" in networks_data: + # Return in the expected format for compatibility + return {"results": [json.dumps({"result": match})]} + except json.JSONDecodeError: + continue + + # Also check if we have the command result indicating completion + if '{"results":' in response_buffer and '"Networks scanned"' in response_buffer: + # We've received the completion message, parse any networks found + import re + networks_pattern = r'\{"networks":\[.*?\]\}' + matches = re.findall(networks_pattern, response_buffer, re.DOTALL) + + for match in matches: + try: + networks_data = json.loads(match) + if "networks" in networks_data: + return {"results": [json.dumps({"result": match})]} + except json.JSONDecodeError: + continue + + # If we get here, scan completed but no networks found + return {"results": [json.dumps({"result": '{"networks":[]}'})]} + else: + time.sleep(0.1) + + return {"error": "Scan timeout"} + + def scan_networks(self, timeout: int = 30) -> bool: + """Scan for WiFi networks""" + print(f"šŸ” Scanning for WiFi networks (this may take up to {timeout} seconds)...") + response = self.send_command("scan_networks", timeout=timeout) + + if "error" in response: + print(f"āŒ Scan failed: {response['error']}") + return False + + try: + # Parse the nested JSON response + results = response.get("results", []) + if not results: + print("āŒ No scan results received") + return False + + # The result is JSON-encoded string inside the response + result_data = json.loads(results[0]) + networks_data = json.loads(result_data["result"]) + + self.networks = [] + channels_found = set() + + for net in networks_data.get("networks", []): + network = WiFiNetwork( + ssid=net["ssid"], + channel=net["channel"], + rssi=net["rssi"], + mac_address=net["mac_address"], + auth_mode=net["auth_mode"] + ) + self.networks.append(network) + channels_found.add(net["channel"]) + + # Sort networks by RSSI (strongest first) + self.networks.sort(key=lambda x: x.rssi, reverse=True) + + print(f"āœ… Found {len(self.networks)} networks on channels: {sorted(channels_found)}") + return True + + except Exception as e: + print(f"āŒ Failed to parse scan results: {e}") + return False + + def set_wifi(self, ssid: str, password: str) -> bool: + """Configure WiFi credentials""" + print(f"šŸ”§ Setting WiFi credentials for '{ssid}'...") + + params = { + "name": "main", + "ssid": ssid, + "password": password, + "channel": 0, + "power": 0 + } + + response = self.send_command("set_wifi", params) + + if "error" in response: + print(f"āŒ WiFi setup failed: {response['error']}") + return False + + print("āœ… WiFi credentials set successfully") + return True + + def get_wifi_status(self) -> Dict: + """Get current WiFi connection status""" + response = self.send_command("get_wifi_status") + + if "error" in response: + print(f"āŒ Failed to get WiFi status: {response['error']}") + return {} + + try: + # Parse the nested JSON response + results = response.get("results", []) + if results: + result_data = json.loads(results[0]) + # The result is a JSON-encoded string, need to decode it + status_json = result_data["result"] + + # First, unescape the JSON string properly + # Replace escaped backslashes and quotes + status_json = status_json.replace('\\\\', '\\') + status_json = status_json.replace('\\"', '"') + + # Now parse the cleaned JSON + status_data = json.loads(status_json) + return status_data + except Exception as e: + print(f"āŒ Failed to parse WiFi status: {e}") + # Try to show raw response for debugging + if "results" in response and response["results"]: + print(f"šŸ“ Raw result: {response['results'][0]}") + + return {} + + def connect_wifi(self) -> bool: + """Attempt to connect to configured WiFi""" + print("šŸ”— Attempting WiFi connection...") + response = self.send_command("connect_wifi") + + if "error" in response: + print(f"āŒ WiFi connection failed: {response['error']}") + return False + + print("āœ… WiFi connection attempt started") + return True + + def start_streaming(self) -> bool: + """Start streaming mode""" + print("šŸš€ Starting streaming mode...") + response = self.send_command("start_streaming") + + if "error" in response: + print(f"āŒ Failed to start streaming: {response['error']}") + return False + + print("āœ… Streaming mode started") + return True + + def switch_mode(self, mode: str) -> bool: + """Switch device mode between WiFi, UVC, and Auto""" + print(f"šŸ”„ Switching device mode to '{mode}'...") + + params = {"mode": mode} + response = self.send_command("switch_mode", params) + + if "error" in response: + print(f"āŒ Failed to switch mode: {response['error']}") + return False + + print(f"āœ… Device mode switched to '{mode}' successfully!") + print("šŸ”„ Please restart the device for changes to take effect") + return True + + def get_device_mode(self) -> str: + """Get current device mode""" + response = self.send_command("get_device_mode") + + if "error" in response: + print(f"āŒ Failed to get device mode: {response['error']}") + return "unknown" + + try: + results = response.get("results", []) + if results: + result_data = json.loads(results[0]) + mode_data = json.loads(result_data["result"]) + return mode_data.get("mode", "unknown") + except Exception as e: + print(f"āŒ Failed to parse mode response: {e}") + return "unknown" + + def monitor_logs(self): + """Monitor device logs until interrupted""" + print("šŸ“‹ Monitoring device logs (Press Ctrl+C to exit)...") + print("-" * 60) + + if not self.connection or not self.connection.is_open: + print("āŒ Not connected to device") + return + + try: + while True: + try: + if self.connection.in_waiting > 0: + line = self.connection.readline().decode().strip() + if line: + # Skip JSON command responses, show raw logs + if not (line.startswith('{') and line.endswith('}')): + print(line) + elif "heartbeat" not in line: + # Show non-heartbeat JSON responses + print(f"šŸ“” {line}") + else: + time.sleep(0.1) # Small delay to prevent busy waiting + except Exception: + continue + except KeyboardInterrupt: + print("\nšŸ›‘ Log monitoring stopped") + + +class OpenIrisDiscovery: + def __init__(self): + self.devices: Dict[str, OpenIrisDevice] = {} + self.discovery_active = False + + def discover_devices(self, timeout: int = 3) -> List[OpenIrisDevice]: + """Discover OpenIris devices via heartbeat - ultra-fast concurrent scanning""" + print(f"⚔ Fast-scanning for OpenIris devices...") + + # Get all serial ports + ports = list(serial.tools.list_ports.comports()) + if not ports: + print("āŒ No serial ports found") + return [] + + # Prioritize likely ESP32 USB ports for faster detection + priority_ports = [] + other_ports = [] + + for port in ports: + # Common ESP32 USB-to-serial descriptions + desc_lower = (port.description or "").lower() + # Include generic "USB Serial Device" which is common on Windows + if any(keyword in desc_lower for keyword in + ["cp210", "ch340", "ftdi", "esp32", "silicon labs", "usb-serial", "usb serial", "usb serial device"]): + priority_ports.append(port) + else: + other_ports.append(port) + + # Check priority ports first, then others + sorted_ports = priority_ports + other_ports + + if priority_ports: + print(f"šŸ“” Checking {len(sorted_ports)} ports ({len(priority_ports)} prioritized USB serial ports)...") + else: + print(f"šŸ“” Checking {len(sorted_ports)} serial ports...") + + discovered = {} + lock = threading.Lock() + threads = [] + + def check_port_fast(port_info): + """Check a single port for OpenIris heartbeat - optimized for speed""" + try: + # Initial connection timeout - 500ms + ser = serial.Serial(port_info.device, 115200, timeout=0.5) + ser.reset_input_buffer() + + # Wait up to 2 seconds for heartbeat + start_time = time.time() + while time.time() - start_time < 2.0: + try: + # Read timeout - 200ms + ser.timeout = 10 + if ser.in_waiting > 0: + line = ser.readline() + if line: + try: + data = json.loads(line.decode().strip()) + if (data.get("heartbeat") == "openiris_setup_mode" and + "serial" in data): + serial_num = data["serial"] + with lock: + if serial_num not in discovered: + device = OpenIrisDevice(port_info.device, serial_num, debug=False) + discovered[serial_num] = device + print(f"šŸ’“ Found {serial_num} on {port_info.device}") + # Return immediately to stop checking this port + ser.close() + return True + except (json.JSONDecodeError, UnicodeDecodeError): + pass + else: + time.sleep(0.05) # Very short sleep + except Exception: + pass + + ser.close() + except Exception: + # Port not available or not the right device + pass + return False + + # Start concurrent port checking + for port in sorted_ports: + thread = threading.Thread(target=check_port_fast, args=(port,)) + thread.daemon = True + thread.start() + threads.append(thread) + + # Wait for threads to complete or timeout + timeout_time = time.time() + timeout + for thread in threads: + remaining = timeout_time - time.time() + if remaining > 0: + thread.join(timeout=remaining) + + # If we found at least one device, return immediately + if discovered: + break + + devices = list(discovered.values()) + + if devices: + print(f"āœ… Found {len(devices)} OpenIris device(s)") + else: + print("āŒ No OpenIris devices found in {:.1f} seconds".format(time.time() - (timeout_time - timeout))) + print("šŸ’” Device has 20-second setup window after power on") + + return devices + + def _check_port(self, port: str, discovered: Dict, timeout: int): + """Check a single port for OpenIris heartbeat""" + try: + with serial.Serial(port, 115200, timeout=1) as ser: + start_time = time.time() + + while time.time() - start_time < timeout: + try: + line = ser.readline().decode().strip() + if line: + try: + data = json.loads(line) + if (data.get("heartbeat") == "openiris_setup_mode" and + "serial" in data): + + serial_num = data["serial"] + if serial_num not in discovered: + discovered[serial_num] = OpenIrisDevice(port, serial_num, debug=False) + print(f"šŸ’“ Found device {serial_num} on {port}") + return + except json.JSONDecodeError: + continue + except Exception: + continue + except Exception: + # Port not available or not a serial device + pass + + +def display_networks(networks: List[WiFiNetwork]): + """Display available WiFi networks in a formatted table""" + if not networks: + print("āŒ No networks available") + return + + print("\nšŸ“” Available WiFi Networks:") + print("-" * 85) + print(f"{'#':<3} {'SSID':<32} {'Channel':<8} {'Signal':<20} {'Security':<15}") + print("-" * 85) + + # Networks are already sorted by signal strength from scan_networks + for i, network in enumerate(networks, 1): + # Create signal strength visualization + signal_bars = "ā–“" * min(5, max(0, (network.rssi + 100) // 10)) + signal_str = f"{signal_bars:<5} ({network.rssi} dBm)" + + # Format SSID (show hidden networks as ) + ssid_display = network.ssid if network.ssid else "" + + print(f"{i:<3} {ssid_display:<32} {network.channel:<8} {signal_str:<20} {network.security_type:<15}") + + print("-" * 85) + + # Show channel distribution + channels = {} + for net in networks: + channels[net.channel] = channels.get(net.channel, 0) + 1 + + print(f"\nšŸ“Š Channel distribution: ", end="") + for ch in sorted(channels.keys()): + print(f"Ch{ch}: {channels[ch]} networks ", end="") + print() + + +def main(): + parser = argparse.ArgumentParser(description="OpenIris Setup CLI Tool") + parser.add_argument("--timeout", type=int, default=3, + help="Discovery timeout in seconds (default: 3)") + parser.add_argument("--port", type=str, + help="Skip discovery and connect directly to specified port") + parser.add_argument("--scan-timeout", type=int, default=30, + help="WiFi scan timeout in seconds (default: 30)") + parser.add_argument("--no-auto", action="store_true", + help="Don't auto-connect to first device found") + parser.add_argument("--debug", action="store_true", + help="Show debug output including raw serial data") + args = parser.parse_args() + + print("šŸ”§ OpenIris Setup Tool") + print("=" * 50) + + device = None + + try: + if args.port: + # Connect directly to specified port + print(f"šŸ“” Connecting directly to {args.port}...") + device = OpenIrisDevice(args.port, "direct", debug=args.debug) + if not device.connect(): + return 1 + else: + # Fast device discovery + discovery = OpenIrisDiscovery() + devices = discovery.discover_devices(args.timeout) + + if not devices: + print("\nāŒ No OpenIris devices found automatically") + print("\nšŸ’” Troubleshooting:") + print(" - Make sure device is connected via USB") + print(" - Device must be powered on within last 20 seconds") + print(" - Try specifying port manually with --port") + + # Show available ports to help user + print("\nšŸ“‹ Available serial ports:") + all_ports = list(serial.tools.list_ports.comports()) + for p in all_ports: + print(f" - {p.device}: {p.description}") + + # Offer manual port entry + manual_port = input("\nšŸ”Œ Enter serial port manually (e.g. COM15, /dev/ttyUSB0) or press Enter to exit: ").strip() + if manual_port: + device = OpenIrisDevice(manual_port, "manual", debug=args.debug) + if not device.connect(): + return 1 + else: + return 1 + else: + # Auto-connect to first device found (unless disabled) + if len(devices) == 1 or not args.no_auto: + device = devices[0] + device.debug = args.debug # Set debug mode + print(f"\nšŸŽÆ Auto-connecting to {device.serial_number}...") + if not device.connect(): + return 1 + else: + # Multiple devices found with no-auto flag + print("\nšŸ”¢ Multiple devices found. Select one:") + for i, dev in enumerate(devices, 1): + print(f" {i}. {dev.serial_number} on {dev.port}") + + while True: + try: + choice = int(input("\nEnter device number: ")) - 1 + if 0 <= choice < len(devices): + device = devices[choice] + break + else: + print("āŒ Invalid selection") + except ValueError: + print("āŒ Please enter a number") + + # Connect to selected device + device.debug = args.debug # Set debug mode + if not device.connect(): + return 1 + + # Main interaction loop + while True: + print("\nšŸ”§ Setup Options:") + print("1. šŸ” Scan for WiFi networks") + print("2. šŸ“” Show available networks") + print("3. šŸ” Configure WiFi") + print("4. šŸ“¶ Check WiFi status") + print("5. šŸ”— Connect to WiFi") + print("6. šŸš€ Start streaming mode") + print("7. šŸ”„ Switch device mode (WiFi/UVC/Auto)") + print("8. šŸ“‹ Monitor logs") + print("9. 🚪 Exit") + + choice = input("\nSelect option (1-9): ").strip() + + if choice == "1": + # Ask if user wants custom timeout + custom = input("Use custom scan timeout? (y/N): ").strip().lower() + if custom == 'y': + try: + timeout = int(input("Enter timeout in seconds (5-120): ")) + if 5 <= timeout <= 120: + device.scan_networks(timeout) + else: + print("āŒ Timeout must be between 5 and 120 seconds") + device.scan_networks(args.scan_timeout) + except ValueError: + print("āŒ Invalid timeout, using default") + device.scan_networks(args.scan_timeout) + else: + device.scan_networks(args.scan_timeout) + + elif choice == "2": + display_networks(device.networks) + + elif choice == "3": + if not device.networks: + print("āŒ No networks available. Please scan first.") + continue + + display_networks(device.networks) + + while True: + try: + net_choice = input("\nEnter network number (or 'back'): ").strip() + if net_choice.lower() == 'back': + break + + net_idx = int(net_choice) - 1 + sorted_networks = sorted(device.networks, key=lambda x: x.rssi, reverse=True) + + if 0 <= net_idx < len(sorted_networks): + selected_network = sorted_networks[net_idx] + + print(f"\nšŸ” Selected: {selected_network.ssid}") + print(f"Security: {selected_network.security_type}") + + if selected_network.auth_mode == 0: # Open network + password = "" + print("šŸ”“ Open network - no password required") + else: + password = input("Enter WiFi password: ") + + if device.set_wifi(selected_network.ssid, password): + print("āœ… WiFi configured successfully!") + print("šŸ’” Next steps:") + print(" 4. Check WiFi status") + print(" 5. Connect to WiFi (if needed)") + print(" 6. Start streaming when connected") + break + else: + print("āŒ Invalid network number") + except ValueError: + print("āŒ Please enter a number or 'back'") + + elif choice == "4": + # Check WiFi status + status = device.get_wifi_status() + if status: + print(f"šŸ“¶ WiFi Status: {status.get('status', 'unknown')}") + print(f"šŸ“” Networks configured: {status.get('networks_configured', 0)}") + if status.get('ip_address'): + print(f"🌐 IP Address: {status['ip_address']}") + else: + print("āŒ Unable to get WiFi status") + + elif choice == "5": + # Attempt WiFi connection + device.connect_wifi() + print("šŸ•°ļø Wait a few seconds then check status (option 4)") + + elif choice == "6": + device.start_streaming() + print("šŸš€ Streaming started! Use option 8 to monitor logs.") + + elif choice == "7": + # Switch device mode + current_mode = device.get_device_mode() + print(f"\nšŸ“ Current device mode: {current_mode}") + print("\nšŸ”„ Select new device mode:") + print("1. WiFi - Stream over WiFi connection") + print("2. UVC - Stream as USB webcam") + print("3. Auto - Automatic mode selection") + + mode_choice = input("\nSelect mode (1-3): ").strip() + + if mode_choice == "1": + device.switch_mode("wifi") + elif mode_choice == "2": + device.switch_mode("uvc") + elif mode_choice == "3": + device.switch_mode("auto") + else: + print("āŒ Invalid mode selection") + + elif choice == "8": + device.monitor_logs() + + elif choice == "9": + break + + else: + print("āŒ Invalid option") + + except KeyboardInterrupt: + print("\nšŸ›‘ Setup interrupted") + + finally: + if device: + device.disconnect() + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/tools/requirements.txt b/tools/requirements.txt new file mode 100644 index 0000000..29284eb --- /dev/null +++ b/tools/requirements.txt @@ -0,0 +1 @@ +pyserial>=3.5 \ No newline at end of file diff --git a/tools/setup.bat b/tools/setup.bat new file mode 100644 index 0000000..0da4843 --- /dev/null +++ b/tools/setup.bat @@ -0,0 +1,7 @@ +@echo off +echo Installing OpenIris Setup Tool dependencies... +pip install -r requirements.txt +echo. +echo Setup complete! Run the tool with: +echo python openiris_setup.py +pause \ No newline at end of file diff --git a/tools/setup.sh b/tools/setup.sh new file mode 100644 index 0000000..f70dc19 --- /dev/null +++ b/tools/setup.sh @@ -0,0 +1,6 @@ +#!/bin/bash +echo "Installing OpenIris Setup Tool dependencies..." +pip3 install -r requirements.txt +echo "" +echo "Setup complete! Run the tool with:" +echo "python3 openiris_setup.py" \ No newline at end of file diff --git a/tools/wifi_scanner.py b/tools/wifi_scanner.py new file mode 100644 index 0000000..d5397f6 --- /dev/null +++ b/tools/wifi_scanner.py @@ -0,0 +1,177 @@ +import serial +import time +import json +from typing import List, Dict + +class ESPWiFiScanner: + def __init__(self, port: str, baudrate: int = 115200): + self.port = port + self.baudrate = baudrate + self.serial = None + + def connect(self) -> bool: + try: + self.serial = serial.Serial( + port=self.port, + baudrate=self.baudrate, + timeout=1 + ) + return True + except serial.SerialException as e: + print(f"Error connecting to ESP32: {e}") + return False + + def scan_networks(self, timeout_seconds: int = 30) -> List[Dict]: + if not self.serial: + print("Not connected to ESP32") + return [] + + self.serial.reset_input_buffer() + + command = '{"commands":[{"command":"scan_networks","data":{}}]}\n' + self.serial.write(command.encode()) + + timeout_start = time.time() + response_buffer = "" + + while time.time() - timeout_start < timeout_seconds: + if self.serial.in_waiting: + data = self.serial.read(self.serial.in_waiting).decode('utf-8', errors='ignore') + response_buffer += data + + # Look for WiFi networks JSON directly (new format) + # The scan command now outputs JSON directly followed by command result + if '{"networks":[' in response_buffer: + import re + + # Look for the networks JSON pattern that appears first + networks_pattern = r'\{"networks":\[.*?\]\}' + matches = re.findall(networks_pattern, response_buffer, re.DOTALL) + + for match in matches: + try: + # Parse the networks JSON directly + networks_data = json.loads(match) + if "networks" in networks_data: + return networks_data["networks"] + except json.JSONDecodeError: + continue + + # Also check if we have the command result indicating completion + if '{"results":' in response_buffer and '"Networks scanned"' in response_buffer: + # We've received the completion message, parse any networks found + import re + networks_pattern = r'\{"networks":\[.*?\]\}' + matches = re.findall(networks_pattern, response_buffer, re.DOTALL) + + for match in matches: + try: + networks_data = json.loads(match) + if "networks" in networks_data: + return networks_data["networks"] + except json.JSONDecodeError: + continue + + # If we get here, scan completed but no networks found + return [] + else: + time.sleep(0.1) + + print("Failed to receive clean JSON response. Raw data:") + print("=" * 50) + print(response_buffer) + print("=" * 50) + return [] + + def close(self): + if self.serial: + self.serial.close() + +def main(): + import sys + import argparse + + parser = argparse.ArgumentParser(description='ESP32 WiFi Scanner') + parser.add_argument('port', nargs='?', default='COM15', help='Serial port (default: COM9)') + parser.add_argument('-t', '--timeout', type=int, default=30, + help='Scan timeout in seconds (default: 30)') + args = parser.parse_args() + + scanner = ESPWiFiScanner(args.port) + + if scanner.connect(): + print(f"Connected to ESP32 on {args.port}") + print(f"Scanning for WiFi networks (timeout: {args.timeout} seconds)...") + start_time = time.time() + networks = scanner.scan_networks(args.timeout) + scan_time = time.time() - start_time + + if networks: + # Sort by RSSI (strongest first) + networks.sort(key=lambda x: x.get('rssi', -100), reverse=True) + + print(f"\nāœ… Found {len(networks)} WiFi Networks in {scan_time:.1f} seconds:") + print("{:<32} | {:<7} | {:<15} | {:<17} | {:<9}".format( + "SSID", "Channel", "Signal", "MAC Address", "Security" + )) + print("-" * 85) + + # Track channels found + channels_found = set() + auth_modes = { + 0: "Open", + 1: "WEP", + 2: "WPA-PSK", + 3: "WPA2-PSK", + 4: "WPA/WPA2", + 5: "WPA2-Enterprise", + 6: "WPA3-PSK", + 7: "WPA2/WPA3", + 8: "WAPI-PSK" + } + + for network in networks: + ssid = network.get('ssid', '') + if not ssid: + ssid = "" + + channel = network.get('channel', 0) + channels_found.add(channel) + + # Create signal strength visualization + rssi = network.get('rssi', -100) + signal_bars = "ā–“" * min(5, max(0, (rssi + 100) // 10)) + signal_str = f"{signal_bars:<5} ({rssi} dBm)" + + auth_mode = network.get('auth_mode', 0) + security = auth_modes.get(auth_mode, f"Type {auth_mode}") + + print("{:<32} | {:<7} | {:<15} | {:<17} | {:<9}".format( + ssid[:32], # Truncate long SSIDs + channel, + signal_str, + network.get('mac_address', '?'), + security + )) + + # Show channel distribution + print(f"\nšŸ“Š Channels detected: {sorted(channels_found)}") + channel_counts = {} + for net in networks: + ch = net.get('channel', 0) + channel_counts[ch] = channel_counts.get(ch, 0) + 1 + + print("šŸ“Š Channel distribution: ", end="") + for ch in sorted(channel_counts.keys()): + print(f"Ch{ch}: {channel_counts[ch]} networks ", end="") + print() + + else: + print("āŒ No networks found or scan failed") + + scanner.close() + else: + print(f"Failed to connect to ESP32 on {args.port}") + +if __name__ == "__main__": + main() \ No newline at end of file From 9326746e1dc361e38d09e366e272686e3e7a45c2 Mon Sep 17 00:00:00 2001 From: Lorow Date: Tue, 29 Jul 2025 23:10:24 +0200 Subject: [PATCH 3/7] Fix device config redefinition issue --- main/openiris_main.cpp | 96 +++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 33 deletions(-) diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index a837f63..6355673 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -42,7 +42,7 @@ auto commandManager = std::make_shared(dependencyRegistry); WebSocketLogger webSocketLogger; Preferences preferences; -auto deviceConfig = std::make_shared(&preferences); +std::shared_ptr deviceConfig = std::make_shared(&preferences); auto wifiManager = std::make_shared(deviceConfig, eventQueue, stateManager); MDNSManager mdnsManager(deviceConfig, eventQueue); @@ -58,21 +58,25 @@ UVCStreamManager uvcStream; auto *ledManager = new LEDManager(BLINK_GPIO, CONFIG_LED_C_PIN_GPIO, ledStateQueue); auto *serialManager = new SerialManager(commandManager, &timerHandle, deviceConfig); -static void initNVSStorage() { +static void initNVSStorage() +{ esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) + { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); } -int websocket_logger(const char *format, va_list args) { +int websocket_logger(const char *format, va_list args) +{ webSocketLogger.log_message(format, args); return vprintf(format, args); } -void disable_serial_manager_task(TaskHandle_t serialManagerHandle) { +void disable_serial_manager_task(TaskHandle_t serialManagerHandle) +{ vTaskDelete(serialManagerHandle); } @@ -91,15 +95,18 @@ void start_video_streaming(void *arg) bool hasWifiCredentials = !deviceConfig->getWifiConfigs().empty() || strcmp(CONFIG_WIFI_SSID, "") != 0; bool wifiConnected = (wifiManager->GetCurrentWiFiState() == WiFiState_e::WiFiState_Connected); - if (deviceMode == StreamingMode::UVC) { + if (deviceMode == StreamingMode::UVC) + { #ifdef CONFIG_WIRED_MODE ESP_LOGI("[MAIN]", "Starting UVC streaming mode."); // Initialize UVC if not already done static bool uvcInitialized = false; - if (!uvcInitialized) { + if (!uvcInitialized) + { ESP_LOGI("[MAIN]", "Initializing UVC hardware..."); esp_err_t ret = uvcStream.setup(); - if (ret != ESP_OK) { + if (ret != ESP_OK) + { ESP_LOGE("[MAIN]", "Failed to initialize UVC: %s", esp_err_to_name(ret)); return; } @@ -113,13 +120,19 @@ void start_video_streaming(void *arg) #endif } - if ((deviceMode == StreamingMode::WIFI || deviceMode == StreamingMode::AUTO) && hasWifiCredentials && wifiConnected) { + if ((deviceMode == StreamingMode::WIFI || deviceMode == StreamingMode::AUTO) && hasWifiCredentials && wifiConnected) + { ESP_LOGI("[MAIN]", "Starting WiFi streaming mode."); streamServer.startStreamServer(); - } else { - if (hasWifiCredentials && !wifiConnected) { + } + else + { + if (hasWifiCredentials && !wifiConnected) + { ESP_LOGE("[MAIN]", "WiFi credentials configured but not connected. Try connecting first."); - } else { + } + else + { ESP_LOGE("[MAIN]", "No streaming mode available. Please configure WiFi."); } return; @@ -128,7 +141,8 @@ void start_video_streaming(void *arg) ESP_LOGI("[MAIN]", "Streaming started successfully."); // Optionally disable serial manager after explicit streaming start - if (arg != nullptr) { + if (arg != nullptr) + { ESP_LOGI("[MAIN]", "Disabling setup interfaces after streaming start."); const auto serialTaskHandle = static_cast(arg); disable_serial_manager_task(serialTaskHandle); @@ -142,13 +156,14 @@ void activate_streaming(TaskHandle_t serialTaskHandle = nullptr) } // Callback for automatic startup after delay -void startup_timer_callback(void* arg) +void startup_timer_callback(void *arg) { ESP_LOGI("[MAIN]", "Startup timer fired, startupCommandReceived=%s, startupPaused=%s", startupCommandReceived ? "true" : "false", startupPaused ? "true" : "false"); - if (!startupCommandReceived && !startupPaused) { + if (!startupCommandReceived && !startupPaused) + { ESP_LOGI("[MAIN]", "No command received during startup delay, proceeding with automatic mode startup"); // Get the stored device mode @@ -156,10 +171,11 @@ void startup_timer_callback(void* arg) ESP_LOGI("[MAIN]", "Stored device mode: %d", (int)deviceMode); // Get the serial manager handle to disable it after streaming starts - TaskHandle_t* serialHandle = getSerialManagerHandle(); + TaskHandle_t *serialHandle = getSerialManagerHandle(); TaskHandle_t serialTaskHandle = (serialHandle && *serialHandle) ? *serialHandle : nullptr; - if (deviceMode == StreamingMode::WIFI || deviceMode == StreamingMode::AUTO) { + if (deviceMode == StreamingMode::WIFI || deviceMode == StreamingMode::AUTO) + { // For WiFi mode, check if we have credentials and are connected bool hasWifiCredentials = !deviceConfig->getWifiConfigs().empty() || strcmp(CONFIG_WIFI_SSID, "") != 0; bool wifiConnected = (wifiManager->GetCurrentWiFiState() == WiFiState_e::WiFiState_Connected); @@ -168,17 +184,23 @@ void startup_timer_callback(void* arg) hasWifiCredentials ? "true" : "false", wifiConnected ? "true" : "false"); - if (hasWifiCredentials && wifiConnected) { + if (hasWifiCredentials && wifiConnected) + { ESP_LOGI("[MAIN]", "Starting WiFi streaming automatically"); activate_streaming(serialTaskHandle); - } else if (hasWifiCredentials && !wifiConnected) { + } + else if (hasWifiCredentials && !wifiConnected) + { ESP_LOGI("[MAIN]", "WiFi credentials exist but not connected, waiting..."); // Could retry connection here - } else { + } + else + { ESP_LOGI("[MAIN]", "No WiFi credentials, staying in setup mode"); } } - else if (deviceMode == StreamingMode::UVC) { + else if (deviceMode == StreamingMode::UVC) + { #ifdef CONFIG_WIRED_MODE ESP_LOGI("[MAIN]", "Starting UVC streaming automatically"); activate_streaming(serialTaskHandle); @@ -187,13 +209,19 @@ void startup_timer_callback(void* arg) ESP_LOGI("[MAIN]", "Device will stay in setup mode. Enable CONFIG_WIRED_MODE and rebuild."); #endif } - else { + else + { ESP_LOGI("[MAIN]", "Unknown device mode: %d", (int)deviceMode); } - } else { - if (startupPaused) { + } + else + { + if (startupPaused) + { ESP_LOGI("[MAIN]", "Startup paused, staying in heartbeat mode"); - } else { + } + else + { ESP_LOGI("[MAIN]", "Command received during startup, staying in heartbeat mode"); } } @@ -209,7 +237,8 @@ void notify_startup_command_received() startupCommandReceived = true; // Cancel the startup timer if it's still running - if (startupTimerHandle != nullptr) { + if (startupTimerHandle != nullptr) + { esp_timer_stop(startupTimerHandle); esp_timer_delete(startupTimerHandle); startupTimerHandle = nullptr; @@ -217,7 +246,8 @@ void notify_startup_command_received() } } -extern "C" void app_main(void) { +extern "C" void app_main(void) +{ dependencyRegistry->registerService(DependencyType::project_config, deviceConfig); dependencyRegistry->registerService(DependencyType::camera_manager, cameraHandler); dependencyRegistry->registerService(DependencyType::wifi_manager, wifiManager); @@ -327,12 +357,13 @@ extern "C" void app_main(void) { // Get the stored device mode StreamingMode deviceMode = deviceConfig->getDeviceMode(); ESP_LOGI("[MAIN]", "Stored device mode: %s (value: %d)", - deviceMode == StreamingMode::UVC ? "UVC" : - deviceMode == StreamingMode::WIFI ? "WiFi" : - "Auto", (int)deviceMode); + deviceMode == StreamingMode::UVC ? "UVC" : deviceMode == StreamingMode::WIFI ? "WiFi" + : "Auto", + (int)deviceMode); // If WiFi credentials exist, attempt connection but stay in setup mode - if (!deviceConfig->getWifiConfigs().empty()) { + if (!deviceConfig->getWifiConfigs().empty()) + { ESP_LOGI("[MAIN]", "WiFi credentials found, attempting connection in background"); // WiFi connection happens in wifiManager->Begin() above } @@ -346,8 +377,7 @@ extern "C" void app_main(void) { .arg = nullptr, .dispatch_method = ESP_TIMER_TASK, .name = "startup_timer", - .skip_unhandled_events = false - }; + .skip_unhandled_events = false}; ESP_ERROR_CHECK(esp_timer_create(&startup_timer_args, &startupTimerHandle)); ESP_ERROR_CHECK(esp_timer_start_once(startupTimerHandle, 20000000)); // 20 seconds in microseconds From 0b2939b7d9dcb36c6772238f08142cb21a1687f5 Mon Sep 17 00:00:00 2001 From: Summer <71572746+SummerSigh@users.noreply.github.com> Date: Thu, 7 Aug 2025 19:58:50 -0700 Subject: [PATCH 4/7] Add 3660 --- .vscode/settings.json | 4 ++ dependencies.lock | 2 +- sdkconfig | 135 +++++++++++++++++++++++++++++++++++------- sdkconfig.old | 133 ++++++++++++++++++++++++++++++++++------- 4 files changed, 230 insertions(+), 44 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d85f110 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "idf.flashType": "UART", + "idf.portWin": "COM3" +} \ No newline at end of file diff --git a/dependencies.lock b/dependencies.lock index 0530828..67c76b1 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -77,7 +77,7 @@ dependencies: idf: source: type: idf - version: 5.3.3 + version: 5.4.2 direct_dependencies: - espressif/esp32-camera - espressif/led_strip diff --git a/sdkconfig b/sdkconfig index 89fd862..7d33de9 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.3 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.4.2 Project Configuration # CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 @@ -138,6 +138,7 @@ CONFIG_SOC_I2C_SUPPORT_RTC=y CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y CONFIG_SOC_I2C_SLAVE_SUPPORT_BROADCAST=y CONFIG_SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS=y +CONFIG_SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE=y CONFIG_SOC_I2S_NUM=2 CONFIG_SOC_I2S_HW_VERSION_2=y CONFIG_SOC_I2S_SUPPORTS_XTAL=y @@ -151,6 +152,7 @@ CONFIG_SOC_I2S_PDM_MAX_RX_LINES=4 CONFIG_SOC_I2S_SUPPORTS_TDM=y CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y +CONFIG_SOC_LEDC_TIMER_NUM=4 CONFIG_SOC_LEDC_CHANNEL_NUM=8 CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y @@ -307,6 +309,7 @@ CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y CONFIG_SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY=y CONFIG_SOC_PM_CPU_RETENTION_BY_RTCCNTL=y CONFIG_SOC_PM_MODEM_RETENTION_BY_BACKUPDMA=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y @@ -368,10 +371,11 @@ CONFIG_SOC_ULP_HAS_ADC=y CONFIG_SOC_PHY_COMBO_MODULE=y CONFIG_IDF_CMAKE=y CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_INIT_VERSION="5.3.3" +CONFIG_IDF_INIT_VERSION="$IDF_INIT_VERSION" CONFIG_IDF_TARGET_ESP32S3=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 @@ -403,6 +407,10 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set @@ -411,6 +419,14 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set CONFIG_BOOTLOADER_LOG_LEVEL=3 +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + # # Serial Flash Configurations # @@ -481,6 +497,7 @@ CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG=y CONFIG_ESP_ROM_HAS_SW_FLOAT=y CONFIG_ESP_ROM_HAS_VERSION=y CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Boot ROM Behavior @@ -507,7 +524,6 @@ CONFIG_ESPTOOLPY_FLASHMODE="dio" CONFIG_ESPTOOLPY_FLASHFREQ_80M=y # CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set @@ -534,6 +550,7 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="min_spiffs.csv" CONFIG_PARTITION_TABLE_FILENAME="min_spiffs.csv" @@ -592,6 +609,7 @@ CONFIG_COMPILER_OPTIMIZATION_PERF=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set @@ -602,14 +620,18 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" # CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y +# CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options # @@ -699,6 +721,12 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations +# +# Legacy I2C Driver Configurations +# +# CONFIG_I2C_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2C Driver Configurations + # # Legacy PCNT Driver Configurations # @@ -786,6 +814,7 @@ CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # # CONFIG_I2C_ISR_IRAM_SAFE is not set # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # @@ -910,6 +939,7 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client # @@ -922,6 +952,7 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 # CONFIG_HTTPD_LOG_PURGE_DATA is not set CONFIG_HTTPD_WS_SUPPORT=y # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server # @@ -929,12 +960,14 @@ CONFIG_HTTPD_WS_SUPPORT=y # # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA # # ESP HTTPS server # # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server # @@ -1012,8 +1045,10 @@ CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y # GDMA Configurations # CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y -# CONFIG_GDMA_ISR_IRAM_SAFE is not set +CONFIG_GDMA_ISR_HANDLER_IN_IRAM=y +CONFIG_GDMA_OBJ_DRAM_SAFE=y # CONFIG_GDMA_ENABLE_DEBUG_LOG is not set +# CONFIG_GDMA_ISR_IRAM_SAFE is not set # end of GDMA Configurations # @@ -1027,29 +1062,28 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # end of Hardware Settings # -# LCD and Touch Panel -# - -# -# LCD Touch Drivers are maintained in the IDF Component Registry -# - -# -# LCD Peripheral Configuration +# ESP-Driver:LCD Controller Configurations # # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set # CONFIG_LCD_RGB_RESTART_IN_VSYNC is not set -# end of LCD Peripheral Configuration -# end of LCD and Touch Panel +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS is not set +# end of ESP-MM: Memory Management Configurations # # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set # CONFIG_ESP_NETIF_L2_TAP is not set # CONFIG_ESP_NETIF_BRIDGE_EN is not set @@ -1103,7 +1137,6 @@ CONFIG_SPIRAM_TYPE_AUTO=y # CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set -CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y CONFIG_SPIRAM_CLK_IO=30 CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_XIP_FROM_PSRAM is not set @@ -1114,6 +1147,7 @@ CONFIG_SPIRAM_SPEED_80M=y # CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM_SPEED=80 CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set # CONFIG_SPIRAM_USE_MEMMAP is not set # CONFIG_SPIRAM_USE_CAPS_ALLOC is not set @@ -1133,6 +1167,11 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf +# +# ESP Security Specific +# +# end of ESP Security Specific + # # ESP System Settings # @@ -1381,10 +1420,21 @@ CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y # CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 # CONFIG_FATFS_IMMEDIATE_FSYNC is not set # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y +# CONFIG_FATFS_USE_DYN_BUFFERS is not set + +# +# File system free space calculation behavior +# +CONFIG_FATFS_DONT_TRUST_FREE_CLUSTER_CNT=0 +CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0 +# end of File system free space calculation behavior # end of FAT Filesystem support # @@ -1406,6 +1456,7 @@ CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set @@ -1432,6 +1483,7 @@ CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y # CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set @@ -1440,6 +1492,12 @@ CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port +# +# Extra +# +CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y +# end of Extra + CONFIG_FREERTOS_PORT=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y @@ -1478,7 +1536,11 @@ CONFIG_HEAP_TRACING_OFF=y # end of Heap memory debugging # -# Log output +# Log +# + +# +# Log Level # # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set @@ -1491,11 +1553,29 @@ CONFIG_LOG_DEFAULT_LEVEL=3 # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE=y CONFIG_LOG_MAXIMUM_LEVEL=5 + +# +# Level Settings +# # CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# CONFIG_LOG_COLORS=y CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output +# end of Format +# end of Log # # LWIP @@ -1534,6 +1614,8 @@ CONFIG_LWIP_ESP_MLDV6_REPORT=y CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set @@ -1548,6 +1630,7 @@ CONFIG_LWIP_DHCPS=y CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server # CONFIG_LWIP_AUTOIP is not set @@ -1606,12 +1689,12 @@ CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 # CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # CONFIG_LWIP_SLIP_SUPPORT is not set # @@ -1732,6 +1815,7 @@ CONFIG_MBEDTLS_HAVE_TIME=y # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA1_C=y CONFIG_MBEDTLS_SHA512_C=y # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y @@ -1787,6 +1871,8 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y # end of Certificates CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y @@ -1811,6 +1897,7 @@ CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y +# CONFIG_MBEDTLS_ALLOW_WEAK_CERTIFICATE_VERIFICATION is not set # end of mbedTLS # @@ -1853,6 +1940,7 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y # CONFIG_NVS_ENCRYPTION is not set # CONFIG_NVS_ASSERT_ERROR_CHECK is not set # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM is not set # end of NVS # @@ -1921,10 +2009,10 @@ CONFIG_SPI_FLASH_HPM_AUTO=y CONFIG_SPI_FLASH_HPM_ON=y CONFIG_SPI_FLASH_HPM_DC_AUTO=y # CONFIG_SPI_FLASH_HPM_DC_DISABLE is not set -CONFIG_SPI_FLASH_SUSPEND_QVL_SUPPORTED=y # CONFIG_SPI_FLASH_AUTO_SUSPEND is not set CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2085,6 +2173,8 @@ CONFIG_VFS_MAX_COUNT=8 # CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y # end of Virtual file system # @@ -2122,7 +2212,7 @@ CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y # CONFIG_OV7725_SUPPORT is not set # CONFIG_NT99141_SUPPORT is not set CONFIG_OV2640_SUPPORT=y -# CONFIG_OV3660_SUPPORT is not set +CONFIG_OV3660_SUPPORT=y CONFIG_OV5640_SUPPORT=y # CONFIG_GC2145_SUPPORT is not set # CONFIG_GC032A_SUPPORT is not set @@ -2395,6 +2485,7 @@ CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y # CONFIG_HAL_ASSERTION_SILIENT is not set # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y diff --git a/sdkconfig.old b/sdkconfig.old index 125ee3c..c729d33 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.3 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.4.2 Project Configuration # CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 @@ -138,6 +138,7 @@ CONFIG_SOC_I2C_SUPPORT_RTC=y CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y CONFIG_SOC_I2C_SLAVE_SUPPORT_BROADCAST=y CONFIG_SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS=y +CONFIG_SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE=y CONFIG_SOC_I2S_NUM=2 CONFIG_SOC_I2S_HW_VERSION_2=y CONFIG_SOC_I2S_SUPPORTS_XTAL=y @@ -151,6 +152,7 @@ CONFIG_SOC_I2S_PDM_MAX_RX_LINES=4 CONFIG_SOC_I2S_SUPPORTS_TDM=y CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y +CONFIG_SOC_LEDC_TIMER_NUM=4 CONFIG_SOC_LEDC_CHANNEL_NUM=8 CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y @@ -307,6 +309,7 @@ CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y CONFIG_SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY=y CONFIG_SOC_PM_CPU_RETENTION_BY_RTCCNTL=y CONFIG_SOC_PM_MODEM_RETENTION_BY_BACKUPDMA=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y @@ -368,6 +371,7 @@ CONFIG_SOC_ULP_HAS_ADC=y CONFIG_SOC_PHY_COMBO_MODULE=y CONFIG_IDF_CMAKE=y CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s3" @@ -403,6 +407,10 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set @@ -411,6 +419,14 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set CONFIG_BOOTLOADER_LOG_LEVEL=3 +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + # # Serial Flash Configurations # @@ -481,6 +497,7 @@ CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG=y CONFIG_ESP_ROM_HAS_SW_FLOAT=y CONFIG_ESP_ROM_HAS_VERSION=y CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Boot ROM Behavior @@ -507,7 +524,6 @@ CONFIG_ESPTOOLPY_FLASHMODE="dio" CONFIG_ESPTOOLPY_FLASHFREQ_80M=y # CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set @@ -534,6 +550,7 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="min_spiffs.csv" CONFIG_PARTITION_TABLE_FILENAME="min_spiffs.csv" @@ -552,7 +569,7 @@ CONFIG_BLINK_GPIO=38 CONFIG_SUPPORTS_EXTERNAL_LED_CONTROL=y CONFIG_LED_C_PIN=1 CONFIG_BLINK_PERIOD=1000 -# CONFIG_WIRED_MODE is not set +CONFIG_WIRED_MODE=y CONFIG_MDNS_HOSTNAME="openiristracker" CONFIG_WIFI_SSID="" CONFIG_WIFI_PASSWORD="" @@ -592,6 +609,7 @@ CONFIG_COMPILER_OPTIMIZATION_PERF=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set @@ -602,14 +620,18 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" # CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y +# CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options # @@ -699,6 +721,12 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations +# +# Legacy I2C Driver Configurations +# +# CONFIG_I2C_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2C Driver Configurations + # # Legacy PCNT Driver Configurations # @@ -786,6 +814,7 @@ CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # # CONFIG_I2C_ISR_IRAM_SAFE is not set # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # @@ -910,6 +939,7 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client # @@ -922,6 +952,7 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 # CONFIG_HTTPD_LOG_PURGE_DATA is not set CONFIG_HTTPD_WS_SUPPORT=y # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server # @@ -929,12 +960,14 @@ CONFIG_HTTPD_WS_SUPPORT=y # # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA # # ESP HTTPS server # # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server # @@ -1012,8 +1045,10 @@ CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y # GDMA Configurations # CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y -# CONFIG_GDMA_ISR_IRAM_SAFE is not set +CONFIG_GDMA_ISR_HANDLER_IN_IRAM=y +CONFIG_GDMA_OBJ_DRAM_SAFE=y # CONFIG_GDMA_ENABLE_DEBUG_LOG is not set +# CONFIG_GDMA_ISR_IRAM_SAFE is not set # end of GDMA Configurations # @@ -1027,29 +1062,28 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # end of Hardware Settings # -# LCD and Touch Panel -# - -# -# LCD Touch Drivers are maintained in the IDF Component Registry -# - -# -# LCD Peripheral Configuration +# ESP-Driver:LCD Controller Configurations # # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set # CONFIG_LCD_RGB_RESTART_IN_VSYNC is not set -# end of LCD Peripheral Configuration -# end of LCD and Touch Panel +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS is not set +# end of ESP-MM: Memory Management Configurations # # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set # CONFIG_ESP_NETIF_L2_TAP is not set # CONFIG_ESP_NETIF_BRIDGE_EN is not set @@ -1103,7 +1137,6 @@ CONFIG_SPIRAM_TYPE_AUTO=y # CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set -CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y CONFIG_SPIRAM_CLK_IO=30 CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_XIP_FROM_PSRAM is not set @@ -1114,6 +1147,7 @@ CONFIG_SPIRAM_SPEED_80M=y # CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM_SPEED=80 CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set # CONFIG_SPIRAM_USE_MEMMAP is not set # CONFIG_SPIRAM_USE_CAPS_ALLOC is not set @@ -1133,6 +1167,11 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf +# +# ESP Security Specific +# +# end of ESP Security Specific + # # ESP System Settings # @@ -1381,10 +1420,21 @@ CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y # CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 # CONFIG_FATFS_IMMEDIATE_FSYNC is not set # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y +# CONFIG_FATFS_USE_DYN_BUFFERS is not set + +# +# File system free space calculation behavior +# +CONFIG_FATFS_DONT_TRUST_FREE_CLUSTER_CNT=0 +CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0 +# end of File system free space calculation behavior # end of FAT Filesystem support # @@ -1406,6 +1456,7 @@ CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set @@ -1432,6 +1483,7 @@ CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y # CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set @@ -1440,6 +1492,12 @@ CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port +# +# Extra +# +CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y +# end of Extra + CONFIG_FREERTOS_PORT=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y @@ -1478,7 +1536,11 @@ CONFIG_HEAP_TRACING_OFF=y # end of Heap memory debugging # -# Log output +# Log +# + +# +# Log Level # # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set @@ -1491,11 +1553,29 @@ CONFIG_LOG_DEFAULT_LEVEL=3 # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE=y CONFIG_LOG_MAXIMUM_LEVEL=5 + +# +# Level Settings +# # CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# CONFIG_LOG_COLORS=y CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output +# end of Format +# end of Log # # LWIP @@ -1534,6 +1614,8 @@ CONFIG_LWIP_ESP_MLDV6_REPORT=y CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set @@ -1548,6 +1630,7 @@ CONFIG_LWIP_DHCPS=y CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server # CONFIG_LWIP_AUTOIP is not set @@ -1606,12 +1689,12 @@ CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 # CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # CONFIG_LWIP_SLIP_SUPPORT is not set # @@ -1732,6 +1815,7 @@ CONFIG_MBEDTLS_HAVE_TIME=y # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA1_C=y CONFIG_MBEDTLS_SHA512_C=y # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y @@ -1787,6 +1871,8 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y # end of Certificates CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y @@ -1811,6 +1897,7 @@ CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y +# CONFIG_MBEDTLS_ALLOW_WEAK_CERTIFICATE_VERIFICATION is not set # end of mbedTLS # @@ -1853,6 +1940,7 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y # CONFIG_NVS_ENCRYPTION is not set # CONFIG_NVS_ASSERT_ERROR_CHECK is not set # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM is not set # end of NVS # @@ -1921,10 +2009,10 @@ CONFIG_SPI_FLASH_HPM_AUTO=y CONFIG_SPI_FLASH_HPM_ON=y CONFIG_SPI_FLASH_HPM_DC_AUTO=y # CONFIG_SPI_FLASH_HPM_DC_DISABLE is not set -CONFIG_SPI_FLASH_SUSPEND_QVL_SUPPORTED=y # CONFIG_SPI_FLASH_AUTO_SUSPEND is not set CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2085,6 +2173,8 @@ CONFIG_VFS_MAX_COUNT=8 # CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y # end of Virtual file system # @@ -2395,6 +2485,7 @@ CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y # CONFIG_HAL_ASSERTION_SILIENT is not set # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y From 5a86ae042f5165b0aaccdab5cb091810ab3ddcbb Mon Sep 17 00:00:00 2001 From: Lorow Date: Tue, 12 Aug 2025 23:48:44 +0200 Subject: [PATCH 5/7] Improvements and refactors after CR, add option to modify mdns name and simplify setup tool --- .../CommandManager/CommandManager.cpp | 76 ++--- .../CommandManager/CommandResult.hpp | 17 +- .../commands/device_commands.cpp | 110 ++++--- .../commands/device_commands.hpp | 7 + .../CommandManager/commands/scan_commands.cpp | 12 +- .../CommandManager/commands/scan_commands.hpp | 7 +- .../commands/simple_commands.cpp | 33 +- .../commands/simple_commands.hpp | 5 +- components/Helpers/Helpers/main_globals.cpp | 50 +-- components/Helpers/Helpers/main_globals.hpp | 16 +- .../ProjectConfig/ProjectConfig.hpp | 3 +- .../SerialManager/SerialManager.cpp | 54 ++-- .../SerialManager/SerialManager.hpp | 1 + components/UVCStream/UVCStream/UVCStream.cpp | 18 +- .../wifiManager/wifiManager/WiFiScanner.cpp | 166 +++++----- .../wifiManager/wifiManager/WiFiScanner.hpp | 9 +- .../wifiManager/wifiManager/wifiManager.cpp | 279 ++++++++-------- .../wifiManager/wifiManager/wifiManager.hpp | 3 - main/openiris_main.cpp | 74 +---- tools/openiris_setup.py | 298 +++++++++++------- tools/wifi_scanner.py | 4 +- 21 files changed, 668 insertions(+), 574 deletions(-) diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index 64cba54..5068496 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -25,66 +25,70 @@ std::unordered_map commandTypeMap = { {"get_device_mode", CommandType::GET_DEVICE_MODE}, }; -std::function CommandManager::createCommand(const CommandType type, std::string_view json) const { +std::function CommandManager::createCommand(const CommandType type, std::string_view json) const +{ switch (type) { case CommandType::PING: - return { PingCommand }; + return {PingCommand}; case CommandType::PAUSE: - return [json] { - PausePayload payload; - cJSON* root = cJSON_Parse(std::string(json).c_str()); - if (root) { - cJSON* pauseItem = cJSON_GetObjectItem(root, "pause"); - if (pauseItem && cJSON_IsBool(pauseItem)) { - payload.pause = cJSON_IsTrue(pauseItem); - } else { - payload.pause = true; // Default to pause if not specified - } - cJSON_Delete(root); - } else { - payload.pause = true; // Default to pause if parsing fails - } - return PauseCommand(payload); - }; + return [json] + { return PauseCommand(json); }; case CommandType::SET_STREAMING_MODE: - return [this, json] {return setDeviceModeCommand(this->registry, json); }; + return [this, json] + { return setDeviceModeCommand(this->registry, json); }; case CommandType::UPDATE_OTA_CREDENTIALS: - return [this, json] { return updateOTACredentialsCommand(this->registry, json); }; + return [this, json] + { return updateOTACredentialsCommand(this->registry, json); }; case CommandType::SET_WIFI: - return [this, json] { return setWiFiCommand(this->registry, json); }; + return [this, json] + { return setWiFiCommand(this->registry, json); }; case CommandType::UPDATE_WIFI: - return [this, json] { return updateWiFiCommand(this->registry, json); }; + return [this, json] + { return updateWiFiCommand(this->registry, json); }; case CommandType::UPDATE_AP_WIFI: - return [this, json] { return updateAPWiFiCommand(this->registry, json); }; + return [this, json] + { return updateAPWiFiCommand(this->registry, json); }; case CommandType::DELETE_NETWORK: - return [this, json] { return deleteWiFiCommand(this->registry, json); }; + return [this, json] + { return deleteWiFiCommand(this->registry, json); }; case CommandType::SET_MDNS: - return [this, json] { return setMDNSCommand(this->registry, json); }; + return [this, json] + { return setMDNSCommand(this->registry, json); }; case CommandType::UPDATE_CAMERA: - return [this, json] { return updateCameraCommand(this->registry, json); }; + return [this, json] + { return updateCameraCommand(this->registry, json); }; case CommandType::RESTART_CAMERA: - return [this, json] { return restartCameraCommand(this->registry, json); }; + return [this, json] + { return restartCameraCommand(this->registry, json); }; case CommandType::GET_CONFIG: - return [this] { return getConfigCommand(this->registry); }; + return [this] + { return getConfigCommand(this->registry); }; case CommandType::SAVE_CONFIG: - return [this] { return saveConfigCommand(this->registry); }; + return [this] + { return saveConfigCommand(this->registry); }; case CommandType::RESET_CONFIG: - return [this, json] { return resetConfigCommand(this->registry, json); }; + return [this, json] + { return resetConfigCommand(this->registry, json); }; case CommandType::RESTART_DEVICE: return restartDeviceCommand; case CommandType::SCAN_NETWORKS: - return [this] { return scanNetworksCommand(this->registry); }; + return [this] + { return scanNetworksCommand(this->registry); }; case CommandType::START_STREAMING: return startStreamingCommand; case CommandType::GET_WIFI_STATUS: - return [this] { return getWiFiStatusCommand(this->registry); }; + return [this] + { return getWiFiStatusCommand(this->registry); }; case CommandType::CONNECT_WIFI: - return [this] { return connectWiFiCommand(this->registry); }; + return [this] + { return connectWiFiCommand(this->registry); }; case CommandType::SWITCH_MODE: - return [this, json] { return switchModeCommand(this->registry, json); }; + return [this, json] + { return switchModeCommand(this->registry, json); }; case CommandType::GET_DEVICE_MODE: - return [this] { return getDeviceModeCommand(this->registry); }; + return [this] + { return getDeviceModeCommand(this->registry); }; default: return nullptr; } @@ -135,7 +139,7 @@ CommandResult CommandManager::executeFromJson(const std::string_view json) const cJSON_AddItemToArray(responses, response); } - char* jsonString = cJSON_Print(responseDocument); + char *jsonString = cJSON_Print(responseDocument); cJSON_Delete(responseDocument); cJSON_Delete(parsedJson); diff --git a/components/CommandManager/CommandManager/CommandResult.hpp b/components/CommandManager/CommandManager/CommandResult.hpp index b73fc8a..8f45abf 100644 --- a/components/CommandManager/CommandManager/CommandResult.hpp +++ b/components/CommandManager/CommandManager/CommandResult.hpp @@ -22,30 +22,30 @@ public: CommandResult(std::string message, const Status status) { this->status = status; - // Escape quotes and backslashes in the message for JSON std::string escapedMessage = message; size_t pos = 0; // First escape backslashes - while ((pos = escapedMessage.find('\\', pos)) != std::string::npos) { + while ((pos = escapedMessage.find('\\', pos)) != std::string::npos) + { escapedMessage.replace(pos, 1, "\\\\"); pos += 2; } // Then escape quotes pos = 0; - while ((pos = escapedMessage.find('"', pos)) != std::string::npos) { + while ((pos = escapedMessage.find('"', pos)) != std::string::npos) + { escapedMessage.replace(pos, 1, "\\\""); pos += 2; } - + if (status == Status::SUCCESS) { - // we gotta do it this way, because if we define it as { "result": " {} " } it crashes the compiler, lol - this->message = std::format("{}\"result\":\"{}\"{}", "{", escapedMessage, "}"); + this->message = std::format("{{\"result\":\"{}\"}}", escapedMessage); } else { - this->message = std::format("{}\"error\":\"{}\"{}", "{", escapedMessage, "}"); + this->message = std::format("{{\"error\":\"{}\"}}", escapedMessage); } } @@ -60,7 +60,7 @@ public: { return CommandResult(message, Status::FAILURE); } - + // Create a result that returns raw JSON without wrapper static CommandResult getRawJsonResult(const std::string &jsonMessage) { @@ -70,7 +70,6 @@ public: } std::string getResult() const { return this->message; } - }; #endif \ No newline at end of file diff --git a/components/CommandManager/CommandManager/commands/device_commands.cpp b/components/CommandManager/CommandManager/commands/device_commands.cpp index fa5d390..2ffc4dd 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.cpp +++ b/components/CommandManager/CommandManager/commands/device_commands.cpp @@ -1,25 +1,24 @@ #include "device_commands.hpp" -#include -#include -#include "esp_timer.h" -#include - // Implementation inspired by SummerSigh work, initial PR opened in openiris repo, adapted to this rewrite -CommandResult setDeviceModeCommand(std::shared_ptr registry, std::string_view jsonPayload) { +CommandResult setDeviceModeCommand(std::shared_ptr registry, std::string_view jsonPayload) +{ const auto parsedJson = cJSON_Parse(jsonPayload.data()); - if (parsedJson == nullptr) { + if (parsedJson == nullptr) + { return CommandResult::getErrorResult("Invalid payload"); } const auto modeObject = cJSON_GetObjectItem(parsedJson, "mode"); - if (modeObject == nullptr) { + if (modeObject == nullptr) + { return CommandResult::getErrorResult("Invalid payload - missing mode"); } const auto mode = modeObject->valueint; - if (mode < 0 || mode > 2) { + if (mode < 0 || mode > 2) + { return CommandResult::getErrorResult("Invalid payload - unsupported mode"); } @@ -29,10 +28,12 @@ CommandResult setDeviceModeCommand(std::shared_ptr registry, return CommandResult::getSuccessResult("Device mode set"); } -CommandResult updateOTACredentialsCommand(std::shared_ptr registry, std::string_view jsonPayload) { +CommandResult updateOTACredentialsCommand(std::shared_ptr registry, std::string_view jsonPayload) +{ const auto parsedJson = cJSON_Parse(jsonPayload.data()); - if (parsedJson == nullptr) { + if (parsedJson == nullptr) + { return CommandResult::getErrorResult("Invalid payload"); } @@ -42,18 +43,23 @@ CommandResult updateOTACredentialsCommand(std::shared_ptr re auto OTAPassword = oldDeviceConfig.OTAPassword; auto OTAPort = oldDeviceConfig.OTAPort; - if (const auto OTALoginObject = cJSON_GetObjectItem(parsedJson, "login"); OTALoginObject != nullptr) { - if (const auto newLogin = OTALoginObject->valuestring; strcmp(newLogin, "") != 0) { + if (const auto OTALoginObject = cJSON_GetObjectItem(parsedJson, "login"); OTALoginObject != nullptr) + { + if (const auto newLogin = OTALoginObject->valuestring; strcmp(newLogin, "") != 0) + { OTALogin = newLogin; } } - if (const auto OTAPasswordObject = cJSON_GetObjectItem(parsedJson, "password"); OTAPasswordObject != nullptr) { + if (const auto OTAPasswordObject = cJSON_GetObjectItem(parsedJson, "password"); OTAPasswordObject != nullptr) + { OTAPassword = OTAPasswordObject->valuestring; } - if (const auto OTAPortObject = cJSON_GetObjectItem(parsedJson, "port"); OTAPortObject != nullptr) { - if (const auto newPort = OTAPortObject->valueint; newPort >= 82) { + if (const auto OTAPortObject = cJSON_GetObjectItem(parsedJson, "port"); OTAPortObject != nullptr) + { + if (const auto newPort = OTAPortObject->valueint; newPort >= 82) + { OTAPort = newPort; } } @@ -62,70 +68,82 @@ CommandResult updateOTACredentialsCommand(std::shared_ptr re return CommandResult::getSuccessResult("OTA Config set"); } -CommandResult restartDeviceCommand() { +CommandResult restartDeviceCommand() +{ OpenIrisTasks::ScheduleRestart(2000); return CommandResult::getSuccessResult("Device restarted"); } -CommandResult startStreamingCommand() { +CommandResult startStreamingCommand() +{ activateStreaming(false); // Don't disable setup interfaces by default return CommandResult::getSuccessResult("Streaming started"); } -CommandResult switchModeCommand(std::shared_ptr registry, std::string_view jsonPayload) { +CommandResult switchModeCommand(std::shared_ptr registry, std::string_view jsonPayload) +{ const auto parsedJson = cJSON_Parse(jsonPayload.data()); - if (parsedJson == nullptr) { + if (parsedJson == nullptr) + { return CommandResult::getErrorResult("Invalid payload"); } const auto modeObject = cJSON_GetObjectItem(parsedJson, "mode"); - if (modeObject == nullptr) { + if (modeObject == nullptr) + { return CommandResult::getErrorResult("Invalid payload - missing mode"); } - const char* modeStr = modeObject->valuestring; + const char *modeStr = modeObject->valuestring; StreamingMode newMode; - + ESP_LOGI("[DEVICE_COMMANDS]", "Switch mode command received with mode: %s", modeStr); - - if (strcmp(modeStr, "uvc") == 0 || strcmp(modeStr, "UVC") == 0) { + + if (strcmp(modeStr, "uvc") == 0) + { newMode = StreamingMode::UVC; - } else if (strcmp(modeStr, "wifi") == 0 || strcmp(modeStr, "WiFi") == 0 || strcmp(modeStr, "WIFI") == 0) { + } + else if (strcmp(modeStr, "wifi") == 0) + { newMode = StreamingMode::WIFI; - } else if (strcmp(modeStr, "auto") == 0 || strcmp(modeStr, "AUTO") == 0) { + } + else if (strcmp(modeStr, "auto") == 0) + { newMode = StreamingMode::AUTO; - } else { + } + else + { return CommandResult::getErrorResult("Invalid mode - use 'uvc', 'wifi', or 'auto'"); } const auto projectConfig = registry->resolve(DependencyType::project_config); ESP_LOGI("[DEVICE_COMMANDS]", "Setting device mode to: %d", (int)newMode); projectConfig->setDeviceMode(newMode); - + cJSON_Delete(parsedJson); return CommandResult::getSuccessResult("Device mode switched, restart to apply"); } -CommandResult getDeviceModeCommand(std::shared_ptr registry) { +CommandResult getDeviceModeCommand(std::shared_ptr registry) +{ const auto projectConfig = registry->resolve(DependencyType::project_config); StreamingMode currentMode = projectConfig->getDeviceMode(); - - const char* modeStr = "unknown"; - switch (currentMode) { - case StreamingMode::UVC: - modeStr = "UVC"; - break; - case StreamingMode::WIFI: - modeStr = "WiFi"; - break; - case StreamingMode::AUTO: - modeStr = "Auto"; - break; + + const char *modeStr = "unknown"; + switch (currentMode) + { + case StreamingMode::UVC: + modeStr = "UVC"; + break; + case StreamingMode::WIFI: + modeStr = "WiFi"; + break; + case StreamingMode::AUTO: + modeStr = "Auto"; + break; } - - char result[100]; - sprintf(result, "{\"mode\":\"%s\",\"value\":%d}", modeStr, (int)currentMode); - + + auto result = std::format("{{ \"mode\": \"{}\", \"value\": {} }}", modeStr, static_cast(currentMode)); return CommandResult::getSuccessResult(result); } diff --git a/components/CommandManager/CommandManager/commands/device_commands.hpp b/components/CommandManager/CommandManager/commands/device_commands.hpp index 5685f13..4eb1b3d 100644 --- a/components/CommandManager/CommandManager/commands/device_commands.hpp +++ b/components/CommandManager/CommandManager/commands/device_commands.hpp @@ -1,6 +1,13 @@ #include "CommandResult.hpp" +#include "ProjectConfig.hpp" #include "OpenIrisTasks.hpp" #include "DependencyRegistry.hpp" +#include "esp_timer.h" +#include "cJSON.h" +#include "main_globals.hpp" + +#include +#include CommandResult setDeviceModeCommand(std::shared_ptr registry, std::string_view jsonPayload); diff --git a/components/CommandManager/CommandManager/commands/scan_commands.cpp b/components/CommandManager/CommandManager/commands/scan_commands.cpp index 054a621..6844344 100644 --- a/components/CommandManager/CommandManager/commands/scan_commands.cpp +++ b/components/CommandManager/CommandManager/commands/scan_commands.cpp @@ -1,11 +1,10 @@ #include "scan_commands.hpp" -#include "cJSON.h" -#include "esp_log.h" -#include -CommandResult scanNetworksCommand(std::shared_ptr registry) { +CommandResult scanNetworksCommand(std::shared_ptr registry) +{ auto wifiManager = registry->resolve(DependencyType::wifi_manager); - if (!wifiManager) { + if (!wifiManager) + { return CommandResult::getErrorResult("WiFiManager not available"); } @@ -15,7 +14,8 @@ CommandResult scanNetworksCommand(std::shared_ptr registry) cJSON *networksArray = cJSON_CreateArray(); cJSON_AddItemToObject(root, "networks", networksArray); - for (const auto& network : networks) { + for (const auto &network : networks) + { cJSON *networkObject = cJSON_CreateObject(); cJSON_AddStringToObject(networkObject, "ssid", network.ssid.c_str()); cJSON_AddNumberToObject(networkObject, "channel", network.channel); diff --git a/components/CommandManager/CommandManager/commands/scan_commands.hpp b/components/CommandManager/CommandManager/commands/scan_commands.hpp index 7e7df86..df2e0da 100644 --- a/components/CommandManager/CommandManager/commands/scan_commands.hpp +++ b/components/CommandManager/CommandManager/commands/scan_commands.hpp @@ -1,9 +1,12 @@ #ifndef SCAN_COMMANDS_HPP #define SCAN_COMMANDS_HPP -#include "../CommandResult.hpp" -#include "../DependencyRegistry.hpp" +#include "CommandResult.hpp" +#include "DependencyRegistry.hpp" +#include "esp_log.h" +#include #include +#include CommandResult scanNetworksCommand(std::shared_ptr registry); diff --git a/components/CommandManager/CommandManager/commands/simple_commands.cpp b/components/CommandManager/CommandManager/commands/simple_commands.cpp index 909568a..33cd04d 100644 --- a/components/CommandManager/CommandManager/commands/simple_commands.cpp +++ b/components/CommandManager/CommandManager/commands/simple_commands.cpp @@ -1,24 +1,39 @@ #include "simple_commands.hpp" -#include "main_globals.hpp" -#include "esp_log.h" -static const char* TAG = "SimpleCommands"; +static const char *TAG = "SimpleCommands"; CommandResult PingCommand() { return CommandResult::getSuccessResult("pong"); }; -CommandResult PauseCommand(const PausePayload& payload) +CommandResult PauseCommand(std::string_view jsonPayload) { + PausePayload payload; + // pause by default if this command gets executed, even if the payload was invalid + payload.pause = true; + + cJSON *root = cJSON_Parse(std::string(jsonPayload).c_str()); + if (root) + { + cJSON *pauseItem = cJSON_GetObjectItem(root, "pause"); + if (pauseItem && cJSON_IsBool(pauseItem)) + { + payload.pause = cJSON_IsTrue(pauseItem); + } + cJSON_Delete(root); + } + ESP_LOGI(TAG, "Pause command received: %s", payload.pause ? "true" : "false"); - - startupPaused = payload.pause; - - if (payload.pause) { + + setStartupPaused(payload.pause); + if (payload.pause) + { ESP_LOGI(TAG, "Startup paused - device will remain in configuration mode"); return CommandResult::getSuccessResult("Startup paused"); - } else { + } + else + { ESP_LOGI(TAG, "Startup resumed"); return CommandResult::getSuccessResult("Startup resumed"); } diff --git a/components/CommandManager/CommandManager/commands/simple_commands.hpp b/components/CommandManager/CommandManager/commands/simple_commands.hpp index 9db7ea9..23c2972 100644 --- a/components/CommandManager/CommandManager/commands/simple_commands.hpp +++ b/components/CommandManager/CommandManager/commands/simple_commands.hpp @@ -4,8 +4,11 @@ #include #include "CommandResult.hpp" #include "CommandSchema.hpp" +#include "main_globals.hpp" +#include "esp_log.h" +#include CommandResult PingCommand(); -CommandResult PauseCommand(const PausePayload& payload); +CommandResult PauseCommand(std::string_view jsonPayload); #endif \ No newline at end of file diff --git a/components/Helpers/Helpers/main_globals.cpp b/components/Helpers/Helpers/main_globals.cpp index 8ed665d..cab36f8 100644 --- a/components/Helpers/Helpers/main_globals.cpp +++ b/components/Helpers/Helpers/main_globals.cpp @@ -4,37 +4,47 @@ // Forward declarations extern void start_video_streaming(void *arg); -// Global variables to be set by main -static esp_timer_handle_t* g_streaming_timer_handle = nullptr; -static TaskHandle_t* g_serial_manager_handle = nullptr; - -// Functions for main to set the global handles -void setStreamingTimerHandle(esp_timer_handle_t* handle) { - g_streaming_timer_handle = handle; +bool startupCommandReceived = false; +bool getStartupCommandReceived() +{ + return startupCommandReceived; } -void setSerialManagerHandle(TaskHandle_t* handle) { - g_serial_manager_handle = handle; +void setStartupCommandReceived(bool startupCommandReceived) +{ + startupCommandReceived = startupCommandReceived; } -// Functions for components to access the handles -esp_timer_handle_t* getStreamingTimerHandle() { - return g_streaming_timer_handle; -} - -TaskHandle_t* getSerialManagerHandle() { +static TaskHandle_t *g_serial_manager_handle = nullptr; +TaskHandle_t *getSerialManagerHandle() +{ return g_serial_manager_handle; } +void setSerialManagerHandle(TaskHandle_t *serialManagerHandle) +{ + g_serial_manager_handle = serialManagerHandle; +} + // Global pause state bool startupPaused = false; +bool getStartupPaused() +{ + return startupPaused; +} + +void setStartupPaused(bool startupPaused) +{ + startupPaused = startupPaused; +} // Function to manually activate streaming -void activateStreaming(bool disableSetup) { +void activateStreaming(bool disableSetup) +{ ESP_LOGI("[MAIN_GLOBALS]", "Manually activating streaming, disableSetup=%s", disableSetup ? "true" : "false"); - - TaskHandle_t* serialHandle = disableSetup ? g_serial_manager_handle : nullptr; - void* serialTaskHandle = (serialHandle && *serialHandle) ? *serialHandle : nullptr; - + + TaskHandle_t *serialHandle = disableSetup ? g_serial_manager_handle : nullptr; + void *serialTaskHandle = (serialHandle && *serialHandle) ? *serialHandle : nullptr; + start_video_streaming(serialTaskHandle); } \ No newline at end of file diff --git a/components/Helpers/Helpers/main_globals.hpp b/components/Helpers/Helpers/main_globals.hpp index d13f7fc..5602c2c 100644 --- a/components/Helpers/Helpers/main_globals.hpp +++ b/components/Helpers/Helpers/main_globals.hpp @@ -7,22 +7,18 @@ #include "freertos/task.h" // Functions for main to set global handles -void setStreamingTimerHandle(esp_timer_handle_t* handle); -void setSerialManagerHandle(TaskHandle_t* handle); // Functions to access global handles from components -esp_timer_handle_t* getStreamingTimerHandle(); -TaskHandle_t* getSerialManagerHandle(); +TaskHandle_t *getSerialManagerHandle(); +void setSerialManagerHandle(TaskHandle_t *serialManagerHandle); // Function to manually activate streaming void activateStreaming(bool disableSetup = false); -// Function to notify that a command was received during startup -extern void notify_startup_command_received(); +bool getStartupCommandReceived(); +void setStartupCommandReceived(bool startupCommandReceived); -// Global variables for startup state -extern bool startupCommandReceived; -extern esp_timer_handle_t startupTimerHandle; -extern bool startupPaused; +bool getStartupPaused(); +void setStartupPaused(bool startupPaused); #endif \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp index b256c22..045a8a6 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp @@ -9,7 +9,6 @@ #include "Models.hpp" #include - int getNetworkCount(Preferences *pref); void saveNetworkCount(Preferences *pref, int count); @@ -60,7 +59,7 @@ public: const std::string &password, uint8_t channel); void setWiFiTxPower(uint8_t power); - void setDeviceMode(StreamingMode deviceMode); + void setDeviceMode(StreamingMode deviceMode); StreamingMode getDeviceMode(); private: diff --git a/components/SerialManager/SerialManager/SerialManager.cpp b/components/SerialManager/SerialManager/SerialManager.cpp index d1c60c9..c666acf 100644 --- a/components/SerialManager/SerialManager/SerialManager.cpp +++ b/components/SerialManager/SerialManager/SerialManager.cpp @@ -4,8 +4,9 @@ #define BUF_SIZE (1024) -SerialManager::SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle, std::shared_ptr deviceConfig) - : commandManager(commandManager), timerHandle(timerHandle), deviceConfig(deviceConfig) { +SerialManager::SerialManager(std::shared_ptr commandManager, esp_timer_handle_t *timerHandle, std::shared_ptr deviceConfig) + : commandManager(commandManager), timerHandle(timerHandle), deviceConfig(deviceConfig) +{ this->data = static_cast(malloc(BUF_SIZE)); this->temp_data = static_cast(malloc(256)); } @@ -40,47 +41,62 @@ void SerialManager::try_receive() // Notify main that a command was received during startup notify_startup_command_received(); - + const auto result = this->commandManager->executeFromJson(std::string_view(reinterpret_cast(this->data))); const auto resultMessage = result.getResult(); usb_serial_jtag_write_bytes(resultMessage.c_str(), resultMessage.length(), 1000 / 20); } } +// Function to notify that a command was received during startup +void SerialManager::notify_startup_command_received() +{ + setStartupCommandReceived(true); + + // Cancel the startup timer if it's still running + if (timerHandle != nullptr) + { + esp_timer_stop(*timerHandle); + esp_timer_delete(*timerHandle); + timerHandle = nullptr; + ESP_LOGI("[MAIN]", "Startup timer cancelled, staying in heartbeat mode"); + } +} + void SerialManager::send_heartbeat() { // Get the MAC address as unique identifier uint8_t mac[6]; esp_read_mac(mac, ESP_MAC_WIFI_STA); - + // Format as serial number string char serial_number[18]; - sprintf(serial_number, "%02X%02X%02X%02X%02X%02X", + sprintf(serial_number, "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - + // Create heartbeat JSON with serial number char heartbeat[128]; sprintf(heartbeat, "{\"heartbeat\":\"openiris_setup_mode\",\"serial\":\"%s\"}\n", serial_number); - + usb_serial_jtag_write_bytes(heartbeat, strlen(heartbeat), 1000 / 20); } bool SerialManager::should_send_heartbeat() { // Always send heartbeat during startup delay or if no WiFi configured - extern bool startupCommandReceived; - extern esp_timer_handle_t startupTimerHandle; - + // If startup timer is still running, always send heartbeat - if (startupTimerHandle != nullptr) { + if (timerHandle != nullptr) + { return true; } - + // If in heartbeat mode after startup, continue sending - if (startupCommandReceived) { + if (getStartupCommandReceived()) + { return true; } - + // Otherwise, only send if no WiFi credentials configured const auto wifiConfigs = deviceConfig->getWifiConfigs(); return wifiConfigs.empty(); @@ -95,16 +111,16 @@ void HandleSerialManagerTask(void *pvParameters) while (true) { serialManager->try_receive(); - + // Send heartbeat every 2 seconds, but only if no WiFi credentials are set TickType_t currentTime = xTaskGetTickCount(); - if ((currentTime - lastHeartbeat) >= heartbeatInterval) { - if (serialManager->should_send_heartbeat()) { + if ((currentTime - lastHeartbeat) >= heartbeatInterval) + { + if (serialManager->should_send_heartbeat()) + { serialManager->send_heartbeat(); } lastHeartbeat = currentTime; } - - vTaskDelay(pdMS_TO_TICKS(50)); // Small delay to prevent busy waiting } } \ No newline at end of file diff --git a/components/SerialManager/SerialManager/SerialManager.hpp b/components/SerialManager/SerialManager/SerialManager.hpp index a8c92c9..5205a69 100644 --- a/components/SerialManager/SerialManager/SerialManager.hpp +++ b/components/SerialManager/SerialManager/SerialManager.hpp @@ -26,6 +26,7 @@ public: void try_receive(); void send_heartbeat(); bool should_send_heartbeat(); + void notify_startup_command_received(); private: std::shared_ptr commandManager; diff --git a/components/UVCStream/UVCStream/UVCStream.cpp b/components/UVCStream/UVCStream/UVCStream.cpp index e4ad8a7..1c381b9 100644 --- a/components/UVCStream/UVCStream/UVCStream.cpp +++ b/components/UVCStream/UVCStream/UVCStream.cpp @@ -3,25 +3,29 @@ constexpr int UVC_MAX_FRAMESIZE_SIZE(75 * 1024); static const char *UVC_STREAM_TAG = "[UVC DEVICE]"; -extern "C" { +extern "C" +{ static char serial_number_str[13]; - const char *get_uvc_device_name() { + const char *get_uvc_device_name() + { return deviceConfig->getMDNSConfig().hostname.c_str(); } - const char *get_serial_number(void) { - if (serial_number_str[0] == '\0') { + const char *get_serial_number(void) + { + if (serial_number_str[0] == '\0') + { uint8_t mac_address[6]; esp_err_t result = esp_efuse_mac_get_default(mac_address); - if (result != ESP_OK) { + if (result != ESP_OK) + { ESP_LOGE(UVC_STREAM_TAG, "Failed to get MAC address of the board, returning default serial number"); return CONFIG_TUSB_SERIAL_NUM; } sniprintf(serial_number_str, sizeof(serial_number_str), "%02x:%02x:%02x:%02x:%02x:%02x", - mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5] - ); + mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]); } return serial_number_str; } diff --git a/components/wifiManager/wifiManager/WiFiScanner.cpp b/components/wifiManager/wifiManager/WiFiScanner.cpp index 8e7f171..5135c32 100644 --- a/components/wifiManager/wifiManager/WiFiScanner.cpp +++ b/components/wifiManager/wifiManager/WiFiScanner.cpp @@ -1,32 +1,38 @@ #include "WiFiScanner.hpp" #include +static const char *TAG = "WiFiScanner"; + WiFiScanner::WiFiScanner() {} -void WiFiScanner::scanResultCallback(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) { - auto* scanner = static_cast(arg); - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { +void WiFiScanner::scanResultCallback(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + auto *scanner = static_cast(arg); + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) + { uint16_t ap_count = 0; esp_wifi_scan_get_ap_num(&ap_count); - - if (ap_count == 0) { + + if (ap_count == 0) + { ESP_LOGI(TAG, "No access points found"); return; } - wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count]; + wifi_ap_record_t *ap_records = new wifi_ap_record_t[ap_count]; ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, ap_records)); scanner->networks.clear(); - for (uint16_t i = 0; i < ap_count; i++) { + for (uint16_t i = 0; i < ap_count; i++) + { WiFiNetwork network; - network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); + network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); network.channel = ap_records[i].primary; network.rssi = ap_records[i].rssi; memcpy(network.mac, ap_records[i].bssid, 6); network.auth_mode = ap_records[i].authmode; - + scanner->networks.push_back(network); } @@ -35,81 +41,88 @@ void WiFiScanner::scanResultCallback(void* arg, esp_event_base_t event_base, } } -std::vector WiFiScanner::scanNetworks() { +// todo this is garbage +std::vector WiFiScanner::scanNetworks() +{ std::vector scan_results; - + // Check if WiFi is initialized wifi_mode_t mode; esp_err_t err = esp_wifi_get_mode(&mode); - if (err == ESP_ERR_WIFI_NOT_INIT) { + if (err == ESP_ERR_WIFI_NOT_INIT) + { ESP_LOGE(TAG, "WiFi not initialized"); return scan_results; } - - + // Give WiFi more time to be ready vTaskDelay(pdMS_TO_TICKS(500)); - + // Stop any ongoing scan esp_wifi_scan_stop(); - + // Try sequential channel scanning as a workaround - bool try_sequential_scan = true; // Enable sequential scan - - if (!try_sequential_scan) { + bool try_sequential_scan = true; // Enable sequential scan + + if (!try_sequential_scan) + { // Normal all-channel scan wifi_scan_config_t scan_config = { .ssid = nullptr, .bssid = nullptr, - .channel = 0, // 0 means scan all channels + .channel = 0, // 0 means scan all channels .show_hidden = true, - .scan_type = WIFI_SCAN_TYPE_ACTIVE, // Active scan + .scan_type = WIFI_SCAN_TYPE_ACTIVE, // Active scan .scan_time = { .active = { - .min = 120, // Min per channel - .max = 300 // Max per channel + .min = 120, // Min per channel + .max = 300 // Max per channel }, - .passive = 360 - }, - .home_chan_dwell_time = 0, // 0 for default - .channel_bitmap = 0 // 0 for all channels + .passive = 360}, + .home_chan_dwell_time = 0, // 0 for default + .channel_bitmap = 0 // 0 for all channels }; err = esp_wifi_scan_start(&scan_config, false); - if (err != ESP_OK) { + if (err != ESP_OK) + { ESP_LOGE(TAG, "Failed to start scan: %s", esp_err_to_name(err)); return scan_results; } - } else { + } + else + { // Sequential channel scan - scan each channel individually std::vector all_records; - - for (uint8_t ch = 1; ch <= 13; ch++) { + + for (uint8_t ch = 1; ch <= 13; ch++) + { wifi_scan_config_t scan_config = { .ssid = nullptr, .bssid = nullptr, - .channel = ch, // Specific channel + .channel = ch, .show_hidden = true, .scan_type = WIFI_SCAN_TYPE_ACTIVE, .scan_time = { .active = { .min = 100, - .max = 200 - }, - .passive = 300 - }, + .max = 200}, + .passive = 300}, .home_chan_dwell_time = 0, - .channel_bitmap = 0 - }; - + .channel_bitmap = 0}; + err = esp_wifi_scan_start(&scan_config, true); // Blocking scan - if (err == ESP_OK) { + if (err == ESP_OK) + { uint16_t ch_count = 0; esp_wifi_scan_get_ap_num(&ch_count); - if (ch_count > 0) { - wifi_ap_record_t* ch_records = new wifi_ap_record_t[ch_count]; - if (esp_wifi_scan_get_ap_records(&ch_count, ch_records) == ESP_OK) { - for (uint16_t i = 0; i < ch_count; i++) { + if (ch_count > 0) + { + wifi_ap_record_t *ch_records = new wifi_ap_record_t[ch_count]; + if (esp_wifi_scan_get_ap_records(&ch_count, ch_records) == ESP_OK) + { + for (uint16_t i = 0; i < ch_count; i++) + { all_records.push_back(ch_records[i]); } } @@ -118,59 +131,66 @@ std::vector WiFiScanner::scanNetworks() { } vTaskDelay(pdMS_TO_TICKS(50)); } - + // Process all collected records - for (const auto& record : all_records) { + for (const auto &record : all_records) + { WiFiNetwork network; - network.ssid = std::string(reinterpret_cast(record.ssid)); + network.ssid = std::string(reinterpret_cast(record.ssid)); network.channel = record.primary; network.rssi = record.rssi; memcpy(network.mac, record.bssid, 6); network.auth_mode = record.authmode; scan_results.push_back(network); } - + // Skip the normal result processing return scan_results; } - + // Wait for scan completion with timeout int timeout_ms = 15000; // 15 second timeout int elapsed_ms = 0; - - while (elapsed_ms < timeout_ms) { + + while (elapsed_ms < timeout_ms) + { uint16_t temp_count = 0; esp_err_t count_err = esp_wifi_scan_get_ap_num(&temp_count); - - if (count_err == ESP_OK) { + + if (count_err == ESP_OK) + { // Wait a bit longer after finding networks to ensure scan is complete - if (temp_count > 0 && elapsed_ms > 5000) { + if (temp_count > 0 && elapsed_ms > 5000) + { break; } } - + vTaskDelay(pdMS_TO_TICKS(200)); elapsed_ms += 200; } - - if (elapsed_ms >= timeout_ms) { + + if (elapsed_ms >= timeout_ms) + { ESP_LOGE(TAG, "Scan timeout after %d ms", timeout_ms); esp_wifi_scan_stop(); return scan_results; } - + // Get scan results uint16_t ap_count = 0; esp_wifi_scan_get_ap_num(&ap_count); - - if (ap_count == 0) { + + if (ap_count == 0) + { ESP_LOGI(TAG, "No access points found"); return scan_results; } - wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count]; + wifi_ap_record_t *ap_records = new wifi_ap_record_t[ap_count]; err = esp_wifi_scan_get_ap_records(&ap_count, ap_records); - if (err != ESP_OK) { + if (err != ESP_OK) + { ESP_LOGE(TAG, "Failed to get scan records: %s", esp_err_to_name(err)); delete[] ap_records; return scan_results; @@ -178,28 +198,26 @@ std::vector WiFiScanner::scanNetworks() { // Build the results vector and track channels found bool channels_found[15] = {false}; // Track channels 0-14 - - for (uint16_t i = 0; i < ap_count; i++) { + + for (uint16_t i = 0; i < ap_count; i++) + { WiFiNetwork network; - network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); + network.ssid = std::string(reinterpret_cast(ap_records[i].ssid)); network.channel = ap_records[i].primary; network.rssi = ap_records[i].rssi; memcpy(network.mac, ap_records[i].bssid, 6); network.auth_mode = ap_records[i].authmode; - - if (network.channel <= 14) { + + if (network.channel <= 14) + { channels_found[network.channel] = true; } - + scan_results.push_back(network); } - delete[] ap_records; ESP_LOGI(TAG, "Found %d access points", ap_count); - - // Also update the member variable for compatibility - networks = scan_results; - + return scan_results; } \ No newline at end of file diff --git a/components/wifiManager/wifiManager/WiFiScanner.hpp b/components/wifiManager/wifiManager/WiFiScanner.hpp index acb4d6e..f3e23dd 100644 --- a/components/wifiManager/wifiManager/WiFiScanner.hpp +++ b/components/wifiManager/wifiManager/WiFiScanner.hpp @@ -7,7 +7,8 @@ #include "esp_wifi.h" #include "esp_log.h" -struct WiFiNetwork { +struct WiFiNetwork +{ std::string ssid; uint8_t channel; int8_t rssi; @@ -15,14 +16,14 @@ struct WiFiNetwork { wifi_auth_mode_t auth_mode; }; -class WiFiScanner { +class WiFiScanner +{ public: WiFiScanner(); std::vector scanNetworks(); - static void scanResultCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); + static void scanResultCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); private: - static constexpr char const* TAG = "WiFiScanner"; std::vector networks; }; diff --git a/components/wifiManager/wifiManager/wifiManager.cpp b/components/wifiManager/wifiManager/wifiManager.cpp index ffbae5c..53b52f5 100644 --- a/components/wifiManager/wifiManager/wifiManager.cpp +++ b/components/wifiManager/wifiManager/wifiManager.cpp @@ -2,7 +2,6 @@ static auto WIFI_MANAGER_TAG = "[WIFI_MANAGER]"; -// Define the global variables declared as extern in the header int s_retry_num = 0; EventGroupHandle_t s_wifi_event_group; @@ -19,9 +18,9 @@ void WiFiManagerHelpers::event_handler(void *arg, esp_event_base_t event_base, } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; + const auto *disconnected = static_cast(event_data); ESP_LOGI(WIFI_MANAGER_TAG, "Disconnect reason: %d", disconnected->reason); - + if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { esp_wifi_connect(); @@ -51,55 +50,52 @@ void WiFiManager::SetCredentials(const char *ssid, const char *password) { // Clear the config first memset(&_wifi_cfg, 0, sizeof(_wifi_cfg)); - + // Copy SSID with null termination size_t ssid_len = std::min(strlen(ssid), sizeof(_wifi_cfg.sta.ssid) - 1); memcpy(_wifi_cfg.sta.ssid, ssid, ssid_len); _wifi_cfg.sta.ssid[ssid_len] = '\0'; - + // Copy password with null termination size_t pass_len = std::min(strlen(password), sizeof(_wifi_cfg.sta.password) - 1); memcpy(_wifi_cfg.sta.password, password, pass_len); _wifi_cfg.sta.password[pass_len] = '\0'; - + // Set other required fields // Use open auth if no password, otherwise allow any WPA variant - if (strlen(password) == 0) { + if (strlen(password) == 0) + { _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; - } else { + } + else + { // IMPORTANT: Set threshold to WEP to accept ANY security mode >= WEP // This allows WPA, WPA2, WPA3, etc. The driver will negotiate the highest common mode _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WEP; } - + // CRITICAL: Disable PMF completely - this often causes handshake timeouts _wifi_cfg.sta.pmf_cfg.capable = false; _wifi_cfg.sta.pmf_cfg.required = false; - + // IMPORTANT: Set scan method to ALL channels _wifi_cfg.sta.scan_method = WIFI_ALL_CHANNEL_SCAN; - _wifi_cfg.sta.bssid_set = 0; // Don't use specific BSSID - _wifi_cfg.sta.channel = 0; // Scan all channels - + _wifi_cfg.sta.bssid_set = 0; // Don't use specific BSSID + _wifi_cfg.sta.channel = 0; // Scan all channels + // Additional settings that might help with compatibility - _wifi_cfg.sta.listen_interval = 0; // Default listen interval - _wifi_cfg.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; // Connect to strongest signal - + _wifi_cfg.sta.listen_interval = 0; // Default listen interval + _wifi_cfg.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; // Connect to strongest signal + // IMPORTANT: For WPA/WPA2 Personal networks - _wifi_cfg.sta.threshold.rssi = -127; // Accept any signal strength - _wifi_cfg.sta.sae_pwe_h2e = WPA3_SAE_PWE_UNSPECIFIED; // Let driver decide SAE mode - + _wifi_cfg.sta.threshold.rssi = -127; // Accept any signal strength + _wifi_cfg.sta.sae_pwe_h2e = WPA3_SAE_PWE_UNSPECIFIED; // Let driver decide SAE mode + // Log what we're trying to connect to with detailed debugging ESP_LOGI(WIFI_MANAGER_TAG, "Setting credentials for SSID: '%s' (length: %d)", ssid, (int)strlen(ssid)); ESP_LOGI(WIFI_MANAGER_TAG, "Password: '%s' (length: %d)", password, (int)strlen(password)); - ESP_LOGI(WIFI_MANAGER_TAG, "Auth mode: %d, PMF capable: %d", + ESP_LOGI(WIFI_MANAGER_TAG, "Auth mode: %d, PMF capable: %d", _wifi_cfg.sta.threshold.authmode, _wifi_cfg.sta.pmf_cfg.capable); - - // Print hex dump of SSID to catch any hidden characters - ESP_LOG_BUFFER_HEX_LEVEL(WIFI_MANAGER_TAG, _wifi_cfg.sta.ssid, strlen((char*)_wifi_cfg.sta.ssid), ESP_LOG_INFO); - - // Print hex dump of password to catch any hidden characters - ESP_LOG_BUFFER_HEX_LEVEL(WIFI_MANAGER_TAG, _wifi_cfg.sta.password, strlen((char*)_wifi_cfg.sta.password), ESP_LOG_INFO); } void WiFiManager::ConnectWithHardcodedCredentials() @@ -164,11 +160,11 @@ void WiFiManager::ConnectWithStoredCredentials() // Stop WiFi once before the loop esp_wifi_stop(); vTaskDelay(pdMS_TO_TICKS(100)); - + // Ensure we're in STA mode ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - for (const auto& network : networks) + for (const auto &network : networks) { // Reset retry counter for each network attempt s_retry_num = 0; @@ -177,19 +173,14 @@ void WiFiManager::ConnectWithStoredCredentials() // Update config without stopping WiFi again ESP_LOGI(WIFI_MANAGER_TAG, "Attempting to connect to SSID: '%s'", network.ssid.c_str()); - - // Double-check the actual config being sent to WiFi driver - ESP_LOGI(WIFI_MANAGER_TAG, "Final SSID in config: '%s' (len: %d)", - (char*)_wifi_cfg.sta.ssid, (int)strlen((char*)_wifi_cfg.sta.ssid)); - ESP_LOGI(WIFI_MANAGER_TAG, "Final password in config: '%s' (len: %d)", - (char*)_wifi_cfg.sta.password, (int)strlen((char*)_wifi_cfg.sta.password)); - + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &_wifi_cfg)); xQueueSend(this->eventQueue, &event, 10); // Start WiFi if not already started esp_err_t start_err = esp_wifi_start(); - if (start_err != ESP_OK && start_err != ESP_ERR_WIFI_STATE) { + if (start_err != ESP_OK && start_err != ESP_ERR_WIFI_STATE) + { ESP_LOGE(WIFI_MANAGER_TAG, "Failed to start WiFi: %s", esp_err_to_name(start_err)); continue; } @@ -214,7 +205,7 @@ void WiFiManager::ConnectWithStoredCredentials() } ESP_LOGE(WIFI_MANAGER_TAG, "Failed to connect to SSID:%s, trying next stored network", network.ssid.c_str()); - + // Disconnect before trying next network esp_wifi_disconnect(); vTaskDelay(pdMS_TO_TICKS(100)); @@ -249,107 +240,117 @@ void WiFiManager::SetupAccessPoint() ESP_LOGI(WIFI_MANAGER_TAG, "AP started."); } -std::vector WiFiManager::ScanNetworks() { - wifi_mode_t current_mode; - esp_err_t err = esp_wifi_get_mode(¤t_mode); - - if (err == ESP_ERR_WIFI_NOT_INIT) { - ESP_LOGE(WIFI_MANAGER_TAG, "WiFi not initialized for scanning"); - return std::vector(); +std::vector WiFiManager::ScanNetworks() +{ + wifi_mode_t current_mode; + esp_err_t err = esp_wifi_get_mode(¤t_mode); + + if (err == ESP_ERR_WIFI_NOT_INIT) + { + ESP_LOGE(WIFI_MANAGER_TAG, "WiFi not initialized for scanning"); + return std::vector(); + } + + // If we're in AP-only mode, we need STA interface for scanning + if (current_mode == WIFI_MODE_AP) + { + ESP_LOGI(WIFI_MANAGER_TAG, "AP mode detected, checking for STA interface"); + + // Check if STA netif already exists + esp_netif_t *sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + bool sta_netif_exists = (sta_netif != nullptr); + + if (!sta_netif_exists) + { + ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface for scanning"); + sta_netif = esp_netif_create_default_wifi_sta(); } - - // If we're in AP-only mode, we need STA interface for scanning - if (current_mode == WIFI_MODE_AP) { - ESP_LOGI(WIFI_MANAGER_TAG, "AP mode detected, checking for STA interface"); - - // Check if STA netif already exists - esp_netif_t* sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); - bool sta_netif_exists = (sta_netif != nullptr); - - if (!sta_netif_exists) { - ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface for scanning"); - sta_netif = esp_netif_create_default_wifi_sta(); - } - - ESP_LOGI(WIFI_MANAGER_TAG, "Switching to APSTA mode for scanning"); - err = esp_wifi_set_mode(WIFI_MODE_APSTA); - if (err != ESP_OK) { - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to set APSTA mode: %s", esp_err_to_name(err)); - if (!sta_netif_exists && sta_netif) { - esp_netif_destroy(sta_netif); - } - return std::vector(); - } - - // Configure STA with empty config to prevent auto-connect - wifi_config_t empty_config = {}; - esp_wifi_set_config(WIFI_IF_STA, &empty_config); - - // Ensure STA is disconnected and not trying to connect - esp_wifi_disconnect(); - vTaskDelay(pdMS_TO_TICKS(500)); - - // Longer delay for mode to stabilize and enable all channels - vTaskDelay(pdMS_TO_TICKS(1500)); - - // Perform scan - auto networks = wifiScanner->scanNetworks(); - - // Restore AP-only mode - ESP_LOGI(WIFI_MANAGER_TAG, "Restoring AP-only mode"); - esp_wifi_set_mode(WIFI_MODE_AP); - - // Clean up STA interface if we created it - if (!sta_netif_exists && sta_netif) { - esp_netif_destroy(sta_netif); - } - - return networks; + + ESP_LOGI(WIFI_MANAGER_TAG, "Switching to APSTA mode for scanning"); + err = esp_wifi_set_mode(WIFI_MODE_APSTA); + if (err != ESP_OK) + { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to set APSTA mode: %s", esp_err_to_name(err)); + if (!sta_netif_exists && sta_netif) + { + esp_netif_destroy(sta_netif); + } + return std::vector(); } - - // If already in STA or APSTA mode, scan directly - return wifiScanner->scanNetworks(); + + // Configure STA with empty config to prevent auto-connect + wifi_config_t empty_config = {}; + esp_wifi_set_config(WIFI_IF_STA, &empty_config); + + // Ensure STA is disconnected and not trying to connect + esp_wifi_disconnect(); + // Longer delay for mode to stabilize and enable all channels + vTaskDelay(pdMS_TO_TICKS(2000)); + + // Perform scan + auto networks = wifiScanner->scanNetworks(); + + // Restore AP-only mode + ESP_LOGI(WIFI_MANAGER_TAG, "Restoring AP-only mode"); + esp_wifi_set_mode(WIFI_MODE_AP); + + // Clean up STA interface if we created it + if (!sta_netif_exists && sta_netif) + { + esp_netif_destroy(sta_netif); + } + + return networks; + } + + // If already in STA or APSTA mode, scan directly + return wifiScanner->scanNetworks(); } -WiFiState_e WiFiManager::GetCurrentWiFiState() { - return this->stateManager->GetWifiState(); +WiFiState_e WiFiManager::GetCurrentWiFiState() +{ + return this->stateManager->GetWifiState(); } -void WiFiManager::TryConnectToStoredNetworks() { - ESP_LOGI(WIFI_MANAGER_TAG, "Manual WiFi connection attempt requested"); - - // Check current WiFi mode - wifi_mode_t current_mode; - esp_err_t err = esp_wifi_get_mode(¤t_mode); - if (err != ESP_OK) { - ESP_LOGE(WIFI_MANAGER_TAG, "Failed to get WiFi mode: %s", esp_err_to_name(err)); - return; +void WiFiManager::TryConnectToStoredNetworks() +{ + ESP_LOGI(WIFI_MANAGER_TAG, "Manual WiFi connection attempt requested"); + + // Check current WiFi mode + wifi_mode_t current_mode; + esp_err_t err = esp_wifi_get_mode(¤t_mode); + if (err != ESP_OK) + { + ESP_LOGE(WIFI_MANAGER_TAG, "Failed to get WiFi mode: %s", esp_err_to_name(err)); + return; + } + + // If in AP mode, we need to properly transition to STA mode + if (current_mode == WIFI_MODE_AP || current_mode == WIFI_MODE_APSTA) + { + ESP_LOGI(WIFI_MANAGER_TAG, "Currently in AP mode, transitioning to STA mode"); + + // Stop WiFi first + esp_wifi_stop(); + vTaskDelay(pdMS_TO_TICKS(100)); + + // Check if STA interface exists, create if needed + esp_netif_t *sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + if (sta_netif == nullptr) + { + ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface"); + sta_netif = esp_netif_create_default_wifi_sta(); } - - // If in AP mode, we need to properly transition to STA mode - if (current_mode == WIFI_MODE_AP || current_mode == WIFI_MODE_APSTA) { - ESP_LOGI(WIFI_MANAGER_TAG, "Currently in AP mode, transitioning to STA mode"); - - // Stop WiFi first - esp_wifi_stop(); - vTaskDelay(pdMS_TO_TICKS(100)); - - // Check if STA interface exists, create if needed - esp_netif_t* sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); - if (sta_netif == nullptr) { - ESP_LOGI(WIFI_MANAGER_TAG, "Creating STA interface"); - sta_netif = esp_netif_create_default_wifi_sta(); - } - - // Set to STA mode - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - vTaskDelay(pdMS_TO_TICKS(100)); - } - - // Reset retry counter and clear all event bits - s_retry_num = 0; - xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); - this->ConnectWithStoredCredentials(); + + // Set to STA mode + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + // Reset retry counter and clear all event bits + s_retry_num = 0; + xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT); + this->ConnectWithStoredCredentials(); } void WiFiManager::Begin() @@ -363,18 +364,6 @@ void WiFiManager::Begin() wifi_init_config_t esp_wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&esp_wifi_init_config)); - // Set WiFi country to enable all channels (1-14) - wifi_country_t country_config = { - .cc = "JP", // Japan allows channels 1-14 (most permissive) - .schan = 1, - .nchan = 14, - .max_tx_power = 20, - .policy = WIFI_COUNTRY_POLICY_AUTO - }; - ESP_ERROR_CHECK(esp_wifi_set_country(&country_config)); - - - ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &WiFiManagerHelpers::event_handler, @@ -387,8 +376,8 @@ void WiFiManager::Begin() &instance_got_ip)); _wifi_cfg = {}; - _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; // Start with open, will be set properly by SetCredentials - _wifi_cfg.sta.pmf_cfg.capable = false; // Disable PMF by default + _wifi_cfg.sta.threshold.authmode = WIFI_AUTH_OPEN; // Start with open, will be set properly by SetCredentials + _wifi_cfg.sta.pmf_cfg.capable = false; // Disable PMF by default _wifi_cfg.sta.pmf_cfg.required = false; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); diff --git a/components/wifiManager/wifiManager/wifiManager.hpp b/components/wifiManager/wifiManager/wifiManager.hpp index 8a78826..27d9a36 100644 --- a/components/wifiManager/wifiManager/wifiManager.hpp +++ b/components/wifiManager/wifiManager/wifiManager.hpp @@ -19,9 +19,6 @@ #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 -extern int s_retry_num; -extern EventGroupHandle_t s_wifi_event_group; - namespace WiFiManagerHelpers { void event_handler(void *arg, esp_event_base_t event_base, diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index 6355673..3fdc793 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -30,10 +30,8 @@ #define CONFIG_LED_C_PIN_GPIO (gpio_num_t) CONFIG_LED_C_PIN esp_timer_handle_t timerHandle; -esp_timer_handle_t startupTimerHandle; QueueHandle_t eventQueue = xQueueCreate(10, sizeof(SystemEvent)); QueueHandle_t ledStateQueue = xQueueCreate(10, sizeof(uint32_t)); -bool startupCommandReceived = false; auto *stateManager = new StateManager(eventQueue, ledStateQueue); auto dependencyRegistry = std::make_shared(); @@ -99,22 +97,16 @@ void start_video_streaming(void *arg) { #ifdef CONFIG_WIRED_MODE ESP_LOGI("[MAIN]", "Starting UVC streaming mode."); - // Initialize UVC if not already done - static bool uvcInitialized = false; - if (!uvcInitialized) + ESP_LOGI("[MAIN]", "Initializing UVC hardware..."); + esp_err_t ret = uvcStream.setup(); + if (ret != ESP_OK) { - ESP_LOGI("[MAIN]", "Initializing UVC hardware..."); - esp_err_t ret = uvcStream.setup(); - if (ret != ESP_OK) - { - ESP_LOGE("[MAIN]", "Failed to initialize UVC: %s", esp_err_to_name(ret)); - return; - } - uvcInitialized = true; + ESP_LOGE("[MAIN]", "Failed to initialize UVC: %s", esp_err_to_name(ret)); + return; } uvcStream.start(); #else - ESP_LOGE("[MAIN]", "UVC mode selected but CONFIG_WIRED_MODE not enabled in build!"); + ESP_LOGE("[MAIN]", "UVC mode selected but the board likely does not support it."); ESP_LOGI("[MAIN]", "Falling back to WiFi mode if credentials available"); deviceMode = StreamingMode::WIFI; #endif @@ -159,10 +151,10 @@ void activate_streaming(TaskHandle_t serialTaskHandle = nullptr) void startup_timer_callback(void *arg) { ESP_LOGI("[MAIN]", "Startup timer fired, startupCommandReceived=%s, startupPaused=%s", - startupCommandReceived ? "true" : "false", - startupPaused ? "true" : "false"); + getStartupCommandReceived() ? "true" : "false", + getStartupPaused() ? "true" : "false"); - if (!startupCommandReceived && !startupPaused) + if (!getStartupCommandReceived() && !getStartupPaused()) { ESP_LOGI("[MAIN]", "No command received during startup delay, proceeding with automatic mode startup"); @@ -216,7 +208,7 @@ void startup_timer_callback(void *arg) } else { - if (startupPaused) + if (getStartupPaused()) { ESP_LOGI("[MAIN]", "Startup paused, staying in heartbeat mode"); } @@ -227,23 +219,8 @@ void startup_timer_callback(void *arg) } // Delete the timer after it fires - esp_timer_delete(startupTimerHandle); - startupTimerHandle = nullptr; -} - -// Function to notify that a command was received during startup -void notify_startup_command_received() -{ - startupCommandReceived = true; - - // Cancel the startup timer if it's still running - if (startupTimerHandle != nullptr) - { - esp_timer_stop(startupTimerHandle); - esp_timer_delete(startupTimerHandle); - startupTimerHandle = nullptr; - ESP_LOGI("[MAIN]", "Startup timer cancelled, staying in heartbeat mode"); - } + esp_timer_delete(timerHandle); + timerHandle = nullptr; } extern "C" void app_main(void) @@ -337,9 +314,6 @@ extern "C" void app_main(void) restAPI->begin(); cameraHandler->setupCamera(); - // Don't initialize UVC here - wait for the timer to decide - // UVC will be initialized when streaming actually starts - xTaskCreate( HandleRestAPIPollTask, "HandleRestAPIPollTask", @@ -354,23 +328,6 @@ extern "C" void app_main(void) ESP_LOGI("[MAIN]", "====================================="); ESP_LOGI("[MAIN]", "Device will wait 20 seconds for commands..."); - // Get the stored device mode - StreamingMode deviceMode = deviceConfig->getDeviceMode(); - ESP_LOGI("[MAIN]", "Stored device mode: %s (value: %d)", - deviceMode == StreamingMode::UVC ? "UVC" : deviceMode == StreamingMode::WIFI ? "WiFi" - : "Auto", - (int)deviceMode); - - // If WiFi credentials exist, attempt connection but stay in setup mode - if (!deviceConfig->getWifiConfigs().empty()) - { - ESP_LOGI("[MAIN]", "WiFi credentials found, attempting connection in background"); - // WiFi connection happens in wifiManager->Begin() above - } - - // Reset startup state - startupCommandReceived = false; - // Create a one-shot timer for 20 seconds const esp_timer_create_args_t startup_timer_args = { .callback = &startup_timer_callback, @@ -379,13 +336,10 @@ extern "C" void app_main(void) .name = "startup_timer", .skip_unhandled_events = false}; - ESP_ERROR_CHECK(esp_timer_create(&startup_timer_args, &startupTimerHandle)); - ESP_ERROR_CHECK(esp_timer_start_once(startupTimerHandle, 20000000)); // 20 seconds in microseconds + ESP_ERROR_CHECK(esp_timer_create(&startup_timer_args, &timerHandle)); + ESP_ERROR_CHECK(esp_timer_start_once(timerHandle, 20000000)); // 20 seconds in microseconds ESP_LOGI("[MAIN]", "Started 20-second startup timer"); ESP_LOGI("[MAIN]", "Send any command within 20 seconds to enter heartbeat mode"); - - // Set global handles for component access - setStreamingTimerHandle(&timerHandle); setSerialManagerHandle(&serialManagerHandle); } diff --git a/tools/openiris_setup.py b/tools/openiris_setup.py index e4996eb..c14eddf 100644 --- a/tools/openiris_setup.py +++ b/tools/openiris_setup.py @@ -6,11 +6,13 @@ This tool automatically discovers OpenIris devices via heartbeat, allows WiFi configuration, and monitors the device logs. """ +import re import json import time import threading import argparse import sys +import string from typing import Dict, List, Optional, Tuple import serial import serial.tools.list_ports @@ -98,7 +100,6 @@ class OpenIrisDevice: cmd_obj["commands"][0]["data"] = params cmd_json = json.dumps(cmd_obj) + '\n' - try: # Clear any pending data self.connection.reset_input_buffer() @@ -130,9 +131,6 @@ class OpenIrisDevice: print(f"šŸ“” Raw: {repr(data)}") print(f"šŸ“ Buffer: {repr(response_buffer[-200:])}") - # Clean buffer and look for JSON - import re - # Remove ANSI escape sequences clean_buffer = re.sub(r'\x1b\[[0-9;]*m', '', response_buffer) clean_buffer = clean_buffer.replace('\r', '') @@ -303,6 +301,26 @@ class OpenIrisDevice: print("āœ… WiFi credentials set successfully") return True + def set_mdns_name(self, name: str) -> bool: + """Configure the MDNS hostname""" + + print(f"šŸ”§ Setting MDNS name to '{name}'...") + print(" The device should be accessible under") + print(f"http://{name}.local/") + print("\n Note, this will also modify the name of the UVC device") + + params = { + "hostname": name + } + + response = self.send_command("set_mdns", params) + if "error" in response: + print(f"āŒ MDNS name setup failed: {response['error']}") + return False + + print("āœ… MDNS name set successfully") + return True + def get_wifi_status(self) -> Dict: """Get current WiFi connection status""" response = self.send_command("get_wifi_status") @@ -561,8 +579,89 @@ class OpenIrisDiscovery: pass -def display_networks(networks: List[WiFiNetwork]): +def scan_networks(device: OpenIrisDevice, args = None): + should_use_custom_timeout = input("Use custom scan timeout? (y/N): ").strip().lower() + if should_use_custom_timeout == 'y': + try: + timeout = int(input("Enter timeout in seconds (5-120): ")) + if 5 <= timeout <= 120: + device.scan_networks(timeout) + else: + print("āŒ Timeout must be between 5 and 120 seconds") + device.scan_networks(args.scan_timeout) + except ValueError: + print("āŒ Invalid timeout, using default") + device.scan_networks(args.scan_timeout) + else: + device.scan_networks(args.scan_timeout) + + +def configure_wifi(device: OpenIrisDevice, args = None): + if not device.networks: + print("āŒ No networks available. Please scan first.") + return + + display_networks(device) + + while True: + net_choice = input("\nEnter network number (or 'back'): ").strip() + if net_choice.lower() == 'back': + break + + try: + net_idx = int(net_choice) - 1 + except ValueError: + print("āŒ Please enter a number or 'back'") + continue + + sorted_networks = sorted(device.networks, key=lambda x: x.rssi, reverse=True) + + if 0 <= net_idx < len(sorted_networks): + selected_network = sorted_networks[net_idx] + + print(f"\nšŸ” Selected: {selected_network.ssid}") + print(f"Security: {selected_network.security_type}") + + if selected_network.auth_mode == 0: # Open network + password = "" + print("šŸ”“ Open network - no password required") + else: + password = input("Enter WiFi password: ") + + if device.set_wifi(selected_network.ssid, password): + print("āœ… WiFi configured successfully!") + print("šŸ’” Next steps:") + print(" 4. Check WiFi status") + print(" 5. Connect to WiFi (if needed)") + print(" 6. Start streaming when connected") + break + else: + print("āŒ Invalid network number") + + +def configure_mdns(device: OpenIrisDevice, args = None): + print("šŸ’” Please enter your preferred device name, your board will be accessible under http://.local/") + print("šŸ’” Please avoid spaces and special characters") + print(" To back out, enter `back`") + print("\n Note, this will also modify the name of the UVC device") + while True: + name_choice = input("\nDevice name: ").strip() + if any(space in name_choice for space in string.whitespace): + print("āŒ Please avoid spaces and special characters") + else: + break + + if name_choice.lower() == "back": + return + + if device.set_mdns_name(name_choice): + print("āœ… MDNS configured successfully!") + + +def display_networks(device: OpenIrisDevice, args = None): """Display available WiFi networks in a formatted table""" + networks = device.networks + if not networks: print("āŒ No networks available") return @@ -596,6 +695,65 @@ def display_networks(networks: List[WiFiNetwork]): print() +def check_wifi_status(device: OpenIrisDevice, args = None): + status = device.get_wifi_status() + if status: + print(f"šŸ“¶ WiFi Status: {status.get('status', 'unknown')}") + print(f"šŸ“” Networks configured: {status.get('networks_configured', 0)}") + if status.get('ip_address'): + print(f"🌐 IP Address: {status['ip_address']}") + else: + print("āŒ Unable to get WiFi status") + + +def attempt_wifi_connection(device: OpenIrisDevice, args = None): + device.connect_wifi() + print("šŸ•°ļø Wait a few seconds then check status (option 4)") + + +def start_streaming(device: OpenIrisDevice, args = None): + device.start_streaming() + print("šŸš€ Streaming started! Use option 8 to monitor logs.") + + +def switch_device_mode(device: OpenIrisDevice, args = None): + current_mode = device.get_device_mode() + print(f"\nšŸ“ Current device mode: {current_mode}") + print("\nšŸ”„ Select new device mode:") + print("1. WiFi - Stream over WiFi connection") + print("2. UVC - Stream as USB webcam") + print("3. Auto - Automatic mode selection") + + mode_choice = input("\nSelect mode (1-3): ").strip() + + if mode_choice == "1": + device.switch_mode("wifi") + elif mode_choice == "2": + device.switch_mode("uvc") + elif mode_choice == "3": + device.switch_mode("auto") + else: + print("āŒ Invalid mode selection") + + +def monitor_logs(device: OpenIrisDevice, args = None): + device.monitor_logs() + + +COMMANDS_MAP = { + "1": scan_networks, + "2": display_networks, + "3": configure_wifi, + "4": configure_mdns, + "5": configure_mdns, + "6": check_wifi_status, + "7": attempt_wifi_connection, + "8": start_streaming, + "9": switch_device_mode, + "10": monitor_logs, +} + + def main(): parser = argparse.ArgumentParser(description="OpenIris Setup CLI Tool") parser.add_argument("--timeout", type=int, default=3, @@ -684,123 +842,25 @@ def main(): print("1. šŸ” Scan for WiFi networks") print("2. šŸ“” Show available networks") print("3. šŸ” Configure WiFi") - print("4. šŸ“¶ Check WiFi status") - print("5. šŸ”— Connect to WiFi") - print("6. šŸš€ Start streaming mode") - print("7. šŸ”„ Switch device mode (WiFi/UVC/Auto)") - print("8. šŸ“‹ Monitor logs") - print("9. 🚪 Exit") + print("4. 🌐 Configure MDNS") + print("5. šŸ’» Configure UVC Name") + print("6. šŸ“¶ Check WiFi status") + print("7. šŸ”— Connect to WiFi") + print("8. šŸš€ Start streaming mode") + print("9. šŸ”„ Switch device mode (WiFi/UVC/Auto)") + print("10. šŸ“‹ Monitor logs") + print("exit. 🚪 Exit") + choice = input("\nSelect option (1-10): ").strip() - choice = input("\nSelect option (1-9): ").strip() - - if choice == "1": - # Ask if user wants custom timeout - custom = input("Use custom scan timeout? (y/N): ").strip().lower() - if custom == 'y': - try: - timeout = int(input("Enter timeout in seconds (5-120): ")) - if 5 <= timeout <= 120: - device.scan_networks(timeout) - else: - print("āŒ Timeout must be between 5 and 120 seconds") - device.scan_networks(args.scan_timeout) - except ValueError: - print("āŒ Invalid timeout, using default") - device.scan_networks(args.scan_timeout) - else: - device.scan_networks(args.scan_timeout) - - elif choice == "2": - display_networks(device.networks) - - elif choice == "3": - if not device.networks: - print("āŒ No networks available. Please scan first.") - continue - - display_networks(device.networks) - - while True: - try: - net_choice = input("\nEnter network number (or 'back'): ").strip() - if net_choice.lower() == 'back': - break - - net_idx = int(net_choice) - 1 - sorted_networks = sorted(device.networks, key=lambda x: x.rssi, reverse=True) - - if 0 <= net_idx < len(sorted_networks): - selected_network = sorted_networks[net_idx] - - print(f"\nšŸ” Selected: {selected_network.ssid}") - print(f"Security: {selected_network.security_type}") - - if selected_network.auth_mode == 0: # Open network - password = "" - print("šŸ”“ Open network - no password required") - else: - password = input("Enter WiFi password: ") - - if device.set_wifi(selected_network.ssid, password): - print("āœ… WiFi configured successfully!") - print("šŸ’” Next steps:") - print(" 4. Check WiFi status") - print(" 5. Connect to WiFi (if needed)") - print(" 6. Start streaming when connected") - break - else: - print("āŒ Invalid network number") - except ValueError: - print("āŒ Please enter a number or 'back'") - - elif choice == "4": - # Check WiFi status - status = device.get_wifi_status() - if status: - print(f"šŸ“¶ WiFi Status: {status.get('status', 'unknown')}") - print(f"šŸ“” Networks configured: {status.get('networks_configured', 0)}") - if status.get('ip_address'): - print(f"🌐 IP Address: {status['ip_address']}") - else: - print("āŒ Unable to get WiFi status") - - elif choice == "5": - # Attempt WiFi connection - device.connect_wifi() - print("šŸ•°ļø Wait a few seconds then check status (option 4)") - - elif choice == "6": - device.start_streaming() - print("šŸš€ Streaming started! Use option 8 to monitor logs.") - - elif choice == "7": - # Switch device mode - current_mode = device.get_device_mode() - print(f"\nšŸ“ Current device mode: {current_mode}") - print("\nšŸ”„ Select new device mode:") - print("1. WiFi - Stream over WiFi connection") - print("2. UVC - Stream as USB webcam") - print("3. Auto - Automatic mode selection") - - mode_choice = input("\nSelect mode (1-3): ").strip() - - if mode_choice == "1": - device.switch_mode("wifi") - elif mode_choice == "2": - device.switch_mode("uvc") - elif mode_choice == "3": - device.switch_mode("auto") - else: - print("āŒ Invalid mode selection") - - elif choice == "8": - device.monitor_logs() - - elif choice == "9": + if choice == "exit": break - - else: + + command_to_run = COMMANDS_MAP.get(choice, None) + if not command_to_run: print("āŒ Invalid option") + continue + + command_to_run(device, args) except KeyboardInterrupt: print("\nšŸ›‘ Setup interrupted") diff --git a/tools/wifi_scanner.py b/tools/wifi_scanner.py index d5397f6..de9394a 100644 --- a/tools/wifi_scanner.py +++ b/tools/wifi_scanner.py @@ -28,7 +28,7 @@ class ESPWiFiScanner: self.serial.reset_input_buffer() - command = '{"commands":[{"command":"scan_networks","data":{}}]}\n' + command = '{"commands":[{"command":"scan_networks"}]}\n' self.serial.write(command.encode()) timeout_start = time.time() @@ -92,7 +92,7 @@ def main(): import argparse parser = argparse.ArgumentParser(description='ESP32 WiFi Scanner') - parser.add_argument('port', nargs='?', default='COM15', help='Serial port (default: COM9)') + parser.add_argument('port', nargs='?', help='Serial port - COM1, /dev/ttyUSB0, etc.') parser.add_argument('-t', '--timeout', type=int, default=30, help='Scan timeout in seconds (default: 30)') args = parser.parse_args() From 3a97548f3cf8a4b8f08b611080411713c5c8acdb Mon Sep 17 00:00:00 2001 From: Lorow Date: Wed, 13 Aug 2025 23:17:14 +0200 Subject: [PATCH 6/7] Add missing lastHeartbeat after fixing merge conflicts --- components/SerialManager/SerialManager/SerialManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/SerialManager/SerialManager/SerialManager.cpp b/components/SerialManager/SerialManager/SerialManager.cpp index 2b63ac3..c666acf 100644 --- a/components/SerialManager/SerialManager/SerialManager.cpp +++ b/components/SerialManager/SerialManager/SerialManager.cpp @@ -105,6 +105,8 @@ bool SerialManager::should_send_heartbeat() void HandleSerialManagerTask(void *pvParameters) { auto const serialManager = static_cast(pvParameters); + TickType_t lastHeartbeat = xTaskGetTickCount(); + const TickType_t heartbeatInterval = pdMS_TO_TICKS(2000); // 2 second heartbeat while (true) { From 4b9db0ef7cf3729956ea85e4454690e083631a6c Mon Sep 17 00:00:00 2001 From: Lorow Date: Fri, 15 Aug 2025 16:19:31 +0200 Subject: [PATCH 7/7] Update sdkconfigs --- sdkconfig | 2 +- sdkconfig.base_defaults | 391 ++++++++++++++++++++++++++++------------ 2 files changed, 273 insertions(+), 120 deletions(-) diff --git a/sdkconfig b/sdkconfig index bbb9dd7..e183fa7 100644 --- a/sdkconfig +++ b/sdkconfig @@ -577,7 +577,7 @@ CONFIG_GENERAL_UVC_DELAY=30 # # OpenIris: Camera Configuration # -CONFIG_CAMERA_USB_XCLK_FREQ=10000000 +CONFIG_CAMERA_USB_XCLK_FREQ=23000000 CONFIG_CAMERA_WIFI_XCLK_FREQ=16500000 # end of OpenIris: Camera Configuration diff --git a/sdkconfig.base_defaults b/sdkconfig.base_defaults index 5553cc8..98f6833 100644 --- a/sdkconfig.base_defaults +++ b/sdkconfig.base_defaults @@ -1,6 +1,6 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.4.2 Project Configuration # CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 @@ -64,6 +64,7 @@ CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_SIMD_INSTRUCTION_SUPPORTED=y CONFIG_SOC_XTAL_SUPPORT_40M=y CONFIG_SOC_APPCPU_HAS_CLOCK_GATING_BUG=y CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y @@ -101,6 +102,7 @@ CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_SIMD_PREFERRED_DATA_ALIGNMENT=16 CONFIG_SOC_DS_SIGNATURE_MAX_BIT_LEN=4096 CONFIG_SOC_DS_KEY_PARAM_MD_IV_LENGTH=16 CONFIG_SOC_DS_KEY_CHECK_MAX_WAIT_US=1100 @@ -136,6 +138,7 @@ CONFIG_SOC_I2C_SUPPORT_RTC=y CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y CONFIG_SOC_I2C_SLAVE_SUPPORT_BROADCAST=y CONFIG_SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS=y +CONFIG_SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE=y CONFIG_SOC_I2S_NUM=2 CONFIG_SOC_I2S_HW_VERSION_2=y CONFIG_SOC_I2S_SUPPORTS_XTAL=y @@ -149,6 +152,7 @@ CONFIG_SOC_I2S_PDM_MAX_RX_LINES=4 CONFIG_SOC_I2S_SUPPORTS_TDM=y CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y +CONFIG_SOC_LEDC_TIMER_NUM=4 CONFIG_SOC_LEDC_CHANNEL_NUM=8 CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y @@ -203,6 +207,7 @@ CONFIG_SOC_RTCIO_PIN_COUNT=22 CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_LP_IO_CLOCK_IS_INDEPENDENT=y CONFIG_SOC_SDM_GROUPS=y CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 CONFIG_SOC_SDM_CLK_SUPPORT_APB=y @@ -243,6 +248,8 @@ CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=54 CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 CONFIG_SOC_TOUCH_SENSOR_VERSION=2 CONFIG_SOC_TOUCH_SENSOR_NUM=15 CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y @@ -302,6 +309,7 @@ CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y CONFIG_SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY=y CONFIG_SOC_PM_CPU_RETENTION_BY_RTCCNTL=y CONFIG_SOC_PM_MODEM_RETENTION_BY_BACKUPDMA=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y @@ -363,10 +371,11 @@ CONFIG_SOC_ULP_HAS_ADC=y CONFIG_SOC_PHY_COMBO_MODULE=y CONFIG_IDF_CMAKE=y CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_INIT_VERSION="5.3.2" +CONFIG_IDF_INIT_VERSION="$IDF_INIT_VERSION" CONFIG_IDF_TARGET_ESP32S3=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 @@ -398,6 +407,10 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set @@ -406,6 +419,14 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set CONFIG_BOOTLOADER_LOG_LEVEL=3 +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format +# end of Log + # # Serial Flash Configurations # @@ -476,6 +497,7 @@ CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG=y CONFIG_ESP_ROM_HAS_SW_FLOAT=y CONFIG_ESP_ROM_HAS_VERSION=y CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y # # Boot ROM Behavior @@ -502,7 +524,6 @@ CONFIG_ESPTOOLPY_FLASHMODE="dio" CONFIG_ESPTOOLPY_FLASHFREQ_80M=y # CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set @@ -529,6 +550,7 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # CONFIG_PARTITION_TABLE_SINGLE_APP is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="min_spiffs.csv" CONFIG_PARTITION_TABLE_FILENAME="min_spiffs.csv" @@ -536,6 +558,49 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# ENV_Caps +# +CONFIG_ENV_GPIO_RANGE_MIN=0 +CONFIG_ENV_GPIO_RANGE_MAX=48 +CONFIG_ENV_GPIO_IN_RANGE_MAX=48 +CONFIG_ENV_GPIO_OUT_RANGE_MAX=48 +# end of ENV_Caps + +# +# OpenIris: General Configuration +# +# CONFIG_GENERAL_WIRED_MODE is not set +# CONFIG_GENERAL_UVC_DELAY is not set +# end of OpenIris: General Configuration + +# +# OpenIris: Camera Configuration +# +CONFIG_CAMERA_USB_XCLK_FREQ=23000000 +CONFIG_CAMERA_WIFI_XCLK_FREQ=16500000 +# end of OpenIris: Camera Configuration + +# +# OpenIris: WiFi Configuration +# +CONFIG_WIFI_MDNS_HOSTNAME="openiristracker" +CONFIG_WIFI_SSID="" +CONFIG_WIFI_PASSWORD="" +CONFIG_WIFI_AP_SSID="EyeTrackVR" +CONFIG_WIFI_AP_PASSWORD="12345678" +# end of OpenIris: WiFi Configuration + +# +# OpenIris: LED Configuration +# +CONFIG_LED_BLINK_GPIO=8 +CONFIG_LED_EXTERNAL_GPIO=1 +CONFIG_LED_EXTERNAL_CONTROL=y +CONFIG_LED_EXTERNAL_PWM_FREQ=5000 +CONFIG_LED_EXTERNAL_PWM_DUTY_CYCLE=100 +# end of OpenIris: LED Configuration + # # Camera sensor pinout configuration # @@ -568,6 +633,7 @@ CONFIG_COMPILER_OPTIMIZATION_PERF=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set @@ -578,14 +644,18 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set # CONFIG_COMPILER_DUMP_RTL_FILES is not set CONFIG_COMPILER_RT_LIB_GCCLIB=y CONFIG_COMPILER_RT_LIB_NAME="gcc" # CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y +# CONFIG_COMPILER_STATIC_ANALYZER is not set # end of Compiler options # @@ -609,7 +679,12 @@ CONFIG_APPTRACE_LOCK_ENABLE=y # Bluetooth # # CONFIG_BT_ENABLED is not set -CONFIG_BT_ALARM_MAX_NUM=50 + +# +# Common Options +# +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# end of Common Options # end of Bluetooth # @@ -633,6 +708,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy ADC Driver Configuration # # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set # # Legacy ADC Calibration Configuration @@ -645,42 +721,55 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y # Legacy MCPWM Driver Configurations # # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy MCPWM Driver Configurations # # Legacy Timer Group Driver Configurations # # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Timer Group Driver Configurations # # Legacy RMT Driver Configurations # # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy RMT Driver Configurations # # Legacy I2S Driver Configurations # # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy I2S Driver Configurations +# +# Legacy I2C Driver Configurations +# +# CONFIG_I2C_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2C Driver Configurations + # # Legacy PCNT Driver Configurations # # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy PCNT Driver Configurations # # Legacy SDM Driver Configurations # # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy SDM Driver Configurations # # Legacy Temperature Sensor Driver Configurations # # CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_TEMP_SENSOR_SKIP_LEGACY_CONFLICT_CHECK is not set # end of Legacy Temperature Sensor Driver Configurations # end of Driver Configurations @@ -740,6 +829,7 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +CONFIG_GPTIMER_OBJ_CACHE_SAFE=y # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set # end of ESP-Driver:GPTimer Configurations @@ -748,6 +838,7 @@ CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y # # CONFIG_I2C_ISR_IRAM_SAFE is not set # CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set # end of ESP-Driver:I2C Configurations # @@ -858,6 +949,13 @@ CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y CONFIG_ESP_GDBSTUB_MAX_TASKS=32 # end of GDB Stub +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + # # ESP HTTP client # @@ -865,6 +963,7 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set # CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client # @@ -877,6 +976,7 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 # CONFIG_HTTPD_LOG_PURGE_DATA is not set CONFIG_HTTPD_WS_SUPPORT=y # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # end of HTTP Server # @@ -884,12 +984,14 @@ CONFIG_HTTPD_WS_SUPPORT=y # # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set # CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA # # ESP HTTPS server # # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS server # @@ -967,8 +1069,10 @@ CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y # GDMA Configurations # CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y -# CONFIG_GDMA_ISR_IRAM_SAFE is not set +CONFIG_GDMA_ISR_HANDLER_IN_IRAM=y +CONFIG_GDMA_OBJ_DRAM_SAFE=y # CONFIG_GDMA_ENABLE_DEBUG_LOG is not set +# CONFIG_GDMA_ISR_IRAM_SAFE is not set # end of GDMA Configurations # @@ -982,29 +1086,28 @@ CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y # end of Hardware Settings # -# LCD and Touch Panel -# - -# -# LCD Touch Drivers are maintained in the IDF Component Registry -# - -# -# LCD Peripheral Configuration +# ESP-Driver:LCD Controller Configurations # # CONFIG_LCD_ENABLE_DEBUG_LOG is not set # CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set # CONFIG_LCD_RGB_RESTART_IN_VSYNC is not set -# end of LCD Peripheral Configuration -# end of LCD and Touch Panel +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS is not set +# end of ESP-MM: Memory Management Configurations # # ESP NETIF Adapter # CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set # CONFIG_ESP_NETIF_L2_TAP is not set # CONFIG_ESP_NETIF_BRIDGE_EN is not set @@ -1032,6 +1135,7 @@ CONFIG_ESP_PHY_RF_CAL_PARTIAL=y # CONFIG_ESP_PHY_RF_CAL_FULL is not set CONFIG_ESP_PHY_CALIBRATION_MODE=0 # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set # end of PHY # @@ -1057,7 +1161,6 @@ CONFIG_SPIRAM_TYPE_AUTO=y # CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set # CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set -CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y CONFIG_SPIRAM_CLK_IO=30 CONFIG_SPIRAM_CS_IO=26 # CONFIG_SPIRAM_XIP_FROM_PSRAM is not set @@ -1068,6 +1171,7 @@ CONFIG_SPIRAM_SPEED_80M=y # CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM_SPEED=80 CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set # CONFIG_SPIRAM_USE_MEMMAP is not set # CONFIG_SPIRAM_USE_CAPS_ALLOC is not set @@ -1087,6 +1191,11 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set # end of ESP Ringbuf +# +# ESP Security Specific +# +# end of ESP Security Specific + # # ESP System Settings # @@ -1232,9 +1341,9 @@ CONFIG_ESP_WIFI_ENABLED=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 @@ -1244,7 +1353,6 @@ CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=6 CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP_WIFI_RX_BA_WIN=6 -# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP_WIFI_NVS_ENABLED=y CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set @@ -1336,10 +1444,21 @@ CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y # CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 # CONFIG_FATFS_IMMEDIATE_FSYNC is not set # CONFIG_FATFS_USE_LABEL is not set CONFIG_FATFS_LINK_LOCK=y +# CONFIG_FATFS_USE_DYN_BUFFERS is not set + +# +# File system free space calculation behavior +# +CONFIG_FATFS_DONT_TRUST_FREE_CLUSTER_CNT=0 +CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0 +# end of File system free space calculation behavior # end of FAT Filesystem support # @@ -1361,6 +1480,7 @@ CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set # CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set @@ -1387,6 +1507,7 @@ CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y CONFIG_FREERTOS_ISR_STACKSIZE=1536 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y # CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set @@ -1395,6 +1516,12 @@ CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set # end of Port +# +# Extra +# +CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y +# end of Extra + CONFIG_FREERTOS_PORT=y CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y @@ -1415,7 +1542,6 @@ CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 CONFIG_HAL_WDT_USE_ROM_IMPL=y CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set # end of Hardware Abstraction Layer (HAL) and Low Level (LL) # @@ -1434,7 +1560,11 @@ CONFIG_HEAP_TRACING_OFF=y # end of Heap memory debugging # -# Log output +# Log +# + +# +# Log Level # # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set @@ -1447,11 +1577,29 @@ CONFIG_LOG_DEFAULT_LEVEL=3 # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE=y CONFIG_LOG_MAXIMUM_LEVEL=5 + +# +# Level Settings +# # CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# CONFIG_LOG_COLORS=y CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output +# end of Format +# end of Log # # LWIP @@ -1490,6 +1638,8 @@ CONFIG_LWIP_ESP_MLDV6_REPORT=y CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set @@ -1504,6 +1654,7 @@ CONFIG_LWIP_DHCPS=y CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y # end of DHCP server # CONFIG_LWIP_AUTOIP is not set @@ -1562,12 +1713,12 @@ CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 # CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # CONFIG_LWIP_SLIP_SUPPORT is not set # @@ -1688,6 +1839,7 @@ CONFIG_MBEDTLS_HAVE_TIME=y # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA1_C=y CONFIG_MBEDTLS_SHA512_C=y # CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y @@ -1743,6 +1895,8 @@ CONFIG_MBEDTLS_X509_CSR_PARSE_C=y # end of Certificates CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y # CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y @@ -1767,6 +1921,7 @@ CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y # CONFIG_MBEDTLS_THREADING_C is not set CONFIG_MBEDTLS_ERROR_STRINGS=y CONFIG_MBEDTLS_FS_IO=y +# CONFIG_MBEDTLS_ALLOW_WEAK_CERTIFICATE_VERIFICATION is not set # end of mbedTLS # @@ -1809,6 +1964,7 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y # CONFIG_NVS_ENCRYPTION is not set # CONFIG_NVS_ASSERT_ERROR_CHECK is not set # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM is not set # end of NVS # @@ -1817,25 +1973,10 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y # CONFIG_OPENTHREAD_ENABLED is not set # -# Thread Operational Dataset +# OpenThread Spinel # -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" -CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" -CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 -CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" -CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" -CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" -# end of Thread Operational Dataset - -CONFIG_OPENTHREAD_XTAL_ACCURACY=130 # CONFIG_OPENTHREAD_SPINEL_ONLY is not set -CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y - -# -# Thread Address Query Config -# -# end of Thread Address Query Config +# end of OpenThread Spinel # end of OpenThread # @@ -1844,6 +1985,7 @@ CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y # end of Protocomm # @@ -1891,10 +2033,10 @@ CONFIG_SPI_FLASH_HPM_AUTO=y CONFIG_SPI_FLASH_HPM_ON=y CONFIG_SPI_FLASH_HPM_DC_AUTO=y # CONFIG_SPI_FLASH_HPM_DC_DISABLE is not set -CONFIG_SPI_FLASH_SUSPEND_QVL_SUPPORTED=y # CONFIG_SPI_FLASH_AUTO_SUSPEND is not set CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 # CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND is not set # end of Optional and Experimental Features (READ DOCS FIRST) # end of Main Flash configuration @@ -2055,6 +2197,8 @@ CONFIG_VFS_MAX_COUNT=8 # CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y # end of Virtual file system # @@ -2074,78 +2218,6 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager -# -# CMake Utilities -# -# CONFIG_CU_RELINKER_ENABLE is not set -# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set -CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y -# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set -# CONFIG_CU_GCC_LTO_ENABLE is not set -# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set -# end of CMake Utilities - -# -# Camera configuration -# -# CONFIG_OV7670_SUPPORT is not set -# CONFIG_OV7725_SUPPORT is not set -# CONFIG_NT99141_SUPPORT is not set -CONFIG_OV2640_SUPPORT=y -# CONFIG_OV3660_SUPPORT is not set -CONFIG_OV5640_SUPPORT=y -# CONFIG_GC2145_SUPPORT is not set -# CONFIG_GC032A_SUPPORT is not set -# CONFIG_GC0308_SUPPORT is not set -# CONFIG_BF3005_SUPPORT is not set -# CONFIG_BF20A6_SUPPORT is not set -# CONFIG_SC101IOT_SUPPORT is not set -# CONFIG_SC030IOT_SUPPORT is not set -# CONFIG_SC031GS_SUPPORT is not set -# CONFIG_SCCB_HARDWARE_I2C_PORT0 is not set -CONFIG_SCCB_HARDWARE_I2C_PORT1=y -CONFIG_SCCB_CLK_FREQ=100000 -CONFIG_CAMERA_TASK_STACK_SIZE=30720 -CONFIG_CAMERA_CORE0=y -# CONFIG_CAMERA_CORE1 is not set -# CONFIG_CAMERA_NO_AFFINITY is not set -CONFIG_CAMERA_DMA_BUFFER_SIZE_MAX=32768 -CONFIG_CAMERA_JPEG_MODE_FRAME_SIZE_AUTO=y -# CONFIG_CAMERA_JPEG_MODE_FRAME_SIZE_CUSTOM is not set -# CONFIG_CAMERA_CONVERTER_ENABLED is not set -# CONFIG_LCD_CAM_ISR_IRAM_SAFE is not set -# end of Camera configuration - -# -# mDNS -# -CONFIG_MDNS_MAX_INTERFACES=3 -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -CONFIG_MDNS_ACTION_QUEUE_LEN=16 -CONFIG_MDNS_TASK_STACK_SIZE=4096 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set -# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set -# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set -CONFIG_MDNS_ENABLE_CONSOLE_CLI=y -# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set -CONFIG_MDNS_MULTIPLE_INSTANCE=y - -# -# MDNS Predefined interfaces -# -CONFIG_MDNS_PREDEF_NETIF_STA=y -CONFIG_MDNS_PREDEF_NETIF_AP=y -CONFIG_MDNS_PREDEF_NETIF_ETH=y -# end of MDNS Predefined interfaces -# end of mDNS - # # USB Device UVC # @@ -2214,6 +2286,90 @@ CONFIG_UVC_CAM1_TASK_PRIORITY=3 CONFIG_UVC_CAM1_TASK_CORE=-1 # end of UVC Task Config # end of USB Device UVC + +# +# CMake Utilities +# +# CONFIG_CU_RELINKER_ENABLE is not set +# CONFIG_CU_DIAGNOSTICS_COLOR_NEVER is not set +CONFIG_CU_DIAGNOSTICS_COLOR_ALWAYS=y +# CONFIG_CU_DIAGNOSTICS_COLOR_AUTO is not set +# CONFIG_CU_GCC_LTO_ENABLE is not set +# CONFIG_CU_GCC_STRING_1BYTE_ALIGN is not set +# end of CMake Utilities + +# +# Camera configuration +# +# CONFIG_OV7670_SUPPORT is not set +# CONFIG_OV7725_SUPPORT is not set +# CONFIG_NT99141_SUPPORT is not set +CONFIG_OV2640_SUPPORT=y +CONFIG_OV3660_SUPPORT=y +CONFIG_OV5640_SUPPORT=y +# CONFIG_GC2145_SUPPORT is not set +# CONFIG_GC032A_SUPPORT is not set +# CONFIG_GC0308_SUPPORT is not set +# CONFIG_BF3005_SUPPORT is not set +# CONFIG_BF20A6_SUPPORT is not set +# CONFIG_SC101IOT_SUPPORT is not set +# CONFIG_SC030IOT_SUPPORT is not set +# CONFIG_SC031GS_SUPPORT is not set +CONFIG_MEGA_CCM_SUPPORT=y +# CONFIG_SCCB_HARDWARE_I2C_PORT0 is not set +CONFIG_SCCB_HARDWARE_I2C_PORT1=y +CONFIG_SCCB_CLK_FREQ=100000 +CONFIG_CAMERA_TASK_STACK_SIZE=30720 +CONFIG_CAMERA_CORE0=y +# CONFIG_CAMERA_CORE1 is not set +# CONFIG_CAMERA_NO_AFFINITY is not set +CONFIG_CAMERA_DMA_BUFFER_SIZE_MAX=32768 +CONFIG_CAMERA_JPEG_MODE_FRAME_SIZE_AUTO=y +# CONFIG_CAMERA_JPEG_MODE_FRAME_SIZE_CUSTOM is not set +# CONFIG_CAMERA_CONVERTER_ENABLED is not set +# CONFIG_LCD_CAM_ISR_IRAM_SAFE is not set +# end of Camera configuration + +# +# mDNS +# +CONFIG_MDNS_MAX_INTERFACES=3 +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_ACTION_QUEUE_LEN=16 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 + +# +# MDNS Memory Configuration +# +# CONFIG_MDNS_TASK_CREATE_FROM_SPIRAM is not set +CONFIG_MDNS_TASK_CREATE_FROM_INTERNAL=y +# CONFIG_MDNS_MEMORY_ALLOC_SPIRAM is not set +CONFIG_MDNS_MEMORY_ALLOC_INTERNAL=y +# CONFIG_MDNS_MEMORY_CUSTOM_IMPL is not set +# end of MDNS Memory Configuration + +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +# CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES is not set +# CONFIG_MDNS_ENABLE_DEBUG_PRINTS is not set +CONFIG_MDNS_ENABLE_CONSOLE_CLI=y +# CONFIG_MDNS_RESPOND_REVERSE_QUERIES is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +CONFIG_MDNS_PREDEF_NETIF_ETH=y +# end of MDNS Predefined interfaces +# end of mDNS # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -2307,7 +2463,6 @@ CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y CONFIG_ESP32S3_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y CONFIG_ESP32S3_BROWNOUT_DET=y -CONFIG_ESP32S3_BROWNOUT_DET=y CONFIG_BROWNOUT_DET_LVL_SEL_7=y CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y # CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set @@ -2330,17 +2485,14 @@ CONFIG_ESP32_WIFI_ENABLED=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP32_WIFI_NVS_ENABLED=y CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set @@ -2369,6 +2521,7 @@ CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y # CONFIG_HAL_ASSERTION_SILIENT is not set # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y