diff --git a/components/CommandManager/CommandManager/CommandManager.cpp b/components/CommandManager/CommandManager/CommandManager.cpp index 644ff0a..b666029 100644 --- a/components/CommandManager/CommandManager/CommandManager.cpp +++ b/components/CommandManager/CommandManager/CommandManager.cpp @@ -74,8 +74,8 @@ std::function CommandManager::createCommand(const CommandType t case CommandType::RESTART_DEVICE: return restartDeviceCommand; case CommandType::SCAN_NETWORKS: - return [this] - { return scanNetworksCommand(this->registry); }; + return [this, json] + { return scanNetworksCommand(this->registry, json); }; case CommandType::START_STREAMING: return startStreamingCommand; case CommandType::GET_WIFI_STATUS: diff --git a/components/CommandManager/CommandManager/commands/scan_commands.cpp b/components/CommandManager/CommandManager/commands/scan_commands.cpp index cffd089..4553b10 100644 --- a/components/CommandManager/CommandManager/commands/scan_commands.cpp +++ b/components/CommandManager/CommandManager/commands/scan_commands.cpp @@ -1,7 +1,7 @@ #include "scan_commands.hpp" #include "sdkconfig.h" -CommandResult scanNetworksCommand(std::shared_ptr registry) +CommandResult scanNetworksCommand(std::shared_ptr registry, const nlohmann::json &json) { #if !CONFIG_GENERAL_ENABLE_WIRELESS return CommandResult::getErrorResult("Not supported by current firmware"); @@ -12,7 +12,14 @@ CommandResult scanNetworksCommand(std::shared_ptr registry) return CommandResult::getErrorResult("Not supported by current firmware"); } - auto networks = wifiManager->ScanNetworks(); + // Extract timeout from JSON if provided, default to 15000ms (15 seconds) + int timeout_ms = 15000; + if (json.contains("timeout_ms") && json["timeout_ms"].is_number_integer()) + { + timeout_ms = json["timeout_ms"].get(); + } + + auto networks = wifiManager->ScanNetworks(timeout_ms); nlohmann::json result; std::vector networksJson; diff --git a/components/CommandManager/CommandManager/commands/scan_commands.hpp b/components/CommandManager/CommandManager/commands/scan_commands.hpp index a65a4c9..4e6ba2b 100644 --- a/components/CommandManager/CommandManager/commands/scan_commands.hpp +++ b/components/CommandManager/CommandManager/commands/scan_commands.hpp @@ -8,6 +8,6 @@ #include #include -CommandResult scanNetworksCommand(std::shared_ptr registry); +CommandResult scanNetworksCommand(std::shared_ptr registry, const nlohmann::json &json); #endif \ No newline at end of file diff --git a/components/wifiManager/wifiManager/WiFiScanner.cpp b/components/wifiManager/wifiManager/WiFiScanner.cpp index 5135c32..509b9a2 100644 --- a/components/wifiManager/wifiManager/WiFiScanner.cpp +++ b/components/wifiManager/wifiManager/WiFiScanner.cpp @@ -1,5 +1,6 @@ #include "WiFiScanner.hpp" #include +#include "esp_timer.h" static const char *TAG = "WiFiScanner"; @@ -42,7 +43,7 @@ void WiFiScanner::scanResultCallback(void *arg, esp_event_base_t event_base, } // todo this is garbage -std::vector WiFiScanner::scanNetworks() +std::vector WiFiScanner::scanNetworks(int timeout_ms) { std::vector scan_results; @@ -92,11 +93,22 @@ std::vector WiFiScanner::scanNetworks() } else { - // Sequential channel scan - scan each channel individually + // Sequential channel scan - scan each channel individually with timeout tracking std::vector all_records; + int64_t start_time = esp_timer_get_time() / 1000; // Convert to ms for (uint8_t ch = 1; ch <= 13; ch++) { + // Check if we've exceeded the timeout + int64_t current_time = esp_timer_get_time() / 1000; + int64_t elapsed = current_time - start_time; + + if (elapsed >= timeout_ms) + { + ESP_LOGW(TAG, "Sequential scan timeout after %lld ms at channel %d", elapsed, ch); + break; + } + wifi_scan_config_t scan_config = { .ssid = nullptr, .bssid = nullptr, @@ -144,35 +156,42 @@ std::vector WiFiScanner::scanNetworks() scan_results.push_back(network); } + int64_t total_time = (esp_timer_get_time() / 1000) - start_time; + ESP_LOGI(TAG, "Sequential scan completed in %lld ms, found %d APs", total_time, scan_results.size()); + // 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; + int64_t start_time = esp_timer_get_time() / 1000; // Convert to ms + int64_t elapsed_ms = 0; + bool scan_done = false; while (elapsed_ms < timeout_ms) { + // Check if scan is actually complete by trying to get AP count + // When scan is done, this will return ESP_OK with a valid count uint16_t temp_count = 0; esp_err_t count_err = esp_wifi_scan_get_ap_num(&temp_count); - if (count_err == ESP_OK) + // If we can successfully get the AP count, the scan is likely complete + // However, we should still wait for the scan to fully finish + if (count_err == ESP_OK && temp_count > 0) { - // Wait a bit longer after finding networks to ensure scan is complete - if (temp_count > 0 && elapsed_ms > 5000) - { - break; - } + // Give it a bit more time to ensure all channels are scanned + vTaskDelay(pdMS_TO_TICKS(500)); + scan_done = true; + break; } vTaskDelay(pdMS_TO_TICKS(200)); - elapsed_ms += 200; + elapsed_ms = (esp_timer_get_time() / 1000) - start_time; } - if (elapsed_ms >= timeout_ms) + if (!scan_done && elapsed_ms >= timeout_ms) { - ESP_LOGE(TAG, "Scan timeout after %d ms", timeout_ms); + ESP_LOGE(TAG, "Scan timeout after %lld ms", elapsed_ms); esp_wifi_scan_stop(); return scan_results; } diff --git a/components/wifiManager/wifiManager/WiFiScanner.hpp b/components/wifiManager/wifiManager/WiFiScanner.hpp index f3e23dd..16902a7 100644 --- a/components/wifiManager/wifiManager/WiFiScanner.hpp +++ b/components/wifiManager/wifiManager/WiFiScanner.hpp @@ -20,7 +20,7 @@ class WiFiScanner { public: WiFiScanner(); - std::vector scanNetworks(); + std::vector scanNetworks(int timeout_ms = 15000); static void scanResultCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); private: diff --git a/components/wifiManager/wifiManager/wifiManager.cpp b/components/wifiManager/wifiManager/wifiManager.cpp index d7099ed..1fe72e7 100644 --- a/components/wifiManager/wifiManager/wifiManager.cpp +++ b/components/wifiManager/wifiManager/wifiManager.cpp @@ -240,7 +240,7 @@ void WiFiManager::SetupAccessPoint() ESP_LOGI(WIFI_MANAGER_TAG, "AP started."); } -std::vector WiFiManager::ScanNetworks() +std::vector WiFiManager::ScanNetworks(int timeout_ms) { wifi_mode_t current_mode; esp_err_t err = esp_wifi_get_mode(¤t_mode); @@ -288,7 +288,7 @@ std::vector WiFiManager::ScanNetworks() vTaskDelay(pdMS_TO_TICKS(2000)); // Perform scan - auto networks = wifiScanner->scanNetworks(); + auto networks = wifiScanner->scanNetworks(timeout_ms); // Restore AP-only mode ESP_LOGI(WIFI_MANAGER_TAG, "Restoring AP-only mode"); @@ -304,7 +304,7 @@ std::vector WiFiManager::ScanNetworks() } // If already in STA or APSTA mode, scan directly - return wifiScanner->scanNetworks(); + return wifiScanner->scanNetworks(timeout_ms); } WiFiState_e WiFiManager::GetCurrentWiFiState() diff --git a/components/wifiManager/wifiManager/wifiManager.hpp b/components/wifiManager/wifiManager/wifiManager.hpp index 27d9a36..6fef805 100644 --- a/components/wifiManager/wifiManager/wifiManager.hpp +++ b/components/wifiManager/wifiManager/wifiManager.hpp @@ -49,7 +49,7 @@ private: public: WiFiManager(std::shared_ptr deviceConfig, QueueHandle_t eventQueue, StateManager *stateManager); void Begin(); - std::vector ScanNetworks(); + std::vector ScanNetworks(int timeout_ms = 15000); WiFiState_e GetCurrentWiFiState(); void TryConnectToStoredNetworks(); }; diff --git a/tools/setup_openiris.py b/tools/setup_openiris.py index ac1cd0d..c8caa89 100644 --- a/tools/setup_openiris.py +++ b/tools/setup_openiris.py @@ -228,7 +228,12 @@ class WiFiScanner: print( f"🔍 Scanning for WiFi networks (this may take up to {timeout} seconds)..." ) - response = self.device.send_command("scan_networks", timeout=timeout) + # Convert timeout from seconds to milliseconds for the ESP + timeout_ms = timeout * 1000 + # Send timeout_ms in the command data AND as serial timeout + response = self.device.send_command( + "scan_networks", params={"timeout_ms": timeout_ms}, timeout=timeout + ) if has_command_failed(response): print(f"❌ Scan failed: {response['error']}") return