diff --git a/main/main.c b/main/main.c index e163823..cb7d067 100644 --- a/main/main.c +++ b/main/main.c @@ -479,6 +479,10 @@ static app_error_t pump_init(void) { // WiFi functions // ============================================================================ +// Добавьте в глобальные переменные: +static bool g_wifi_test_in_progress = false; + +// Дополните существующий wifi_event_handler: static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { @@ -486,14 +490,16 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, ESP_LOGI(TAG, "Attempting to connect to WiFi..."); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - if (retry_count < MAX_RETRY_COUNT) { + if (g_wifi_test_in_progress) { + // Если идет тестирование, сразу сигнализируем об ошибке + xEventGroupSetBits(wifi_event_group, WIFI_FAIL_BIT); + } else if (retry_count < MAX_RETRY_COUNT) { esp_wifi_connect(); retry_count++; ESP_LOGI(TAG, "Retry connecting (%d/%d)...", retry_count, MAX_RETRY_COUNT); } else { xEventGroupSetBits(wifi_event_group, WIFI_FAIL_BIT); ESP_LOGE(TAG, "Failed to connect after %d retries", MAX_RETRY_COUNT); - handle_error(APP_ERR_WIFI_CONNECT_FAIL); } } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { @@ -504,6 +510,75 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, } } +bool test_wifi_credentials(const char* ssid, const char* password, int timeout_ms) { + wifi_config_t old_config; + esp_wifi_get_config(WIFI_IF_STA, &old_config); + + if (wifi_event_group == NULL) { + wifi_event_group = xEventGroupCreate(); + if (wifi_event_group == NULL) { + ESP_LOGE(TAG, "Failed to create event group"); + return false; + } + } + + // Очищаем предыдущие биты + xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT); + + // Устанавливаем флаг тестирования + g_wifi_test_in_progress = true; + + // Останавливаем текущее подключение если есть + esp_wifi_disconnect(); + vTaskDelay(pdMS_TO_TICKS(500)); + + // Настраиваем STA интерфейс с новыми credentials + wifi_config_t wifi_config = {0}; + strncpy((char*)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid) - 1); + strncpy((char*)wifi_config.sta.password, password, sizeof(wifi_config.sta.password) - 1); + wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + + esp_err_t ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_config); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to set WiFi config: %s", esp_err_to_name(ret)); + g_wifi_test_in_progress = false; + return false; + } + + // Запускаем подключение + ret = esp_wifi_connect(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to start WiFi connection: %s", esp_err_to_name(ret)); + g_wifi_test_in_progress = false; + return false; + } + + ESP_LOGI(TAG, "Testing WiFi connection to SSID: %s", ssid); + + // Ожидаем результат + EventBits_t bits = xEventGroupWaitBits(wifi_event_group, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + timeout_ms / portTICK_PERIOD_MS); + + bool success = (bits & WIFI_CONNECTED_BIT) != 0; + + if (success) { + ESP_LOGI(TAG, "✓ Successfully connected to %s", ssid); + esp_wifi_disconnect(); + + esp_wifi_set_config(WIFI_IF_STA, &old_config); + + vTaskDelay(pdMS_TO_TICKS(500)); + } else { + ESP_LOGE(TAG, "✗ Failed to connect to %s", ssid); + } + + g_wifi_test_in_progress = false; + return success; +} + static app_error_t wifi_softap_init(void) { CHECK_ERROR(esp_netif_init(), APP_ERR_WIFI_INIT_FAIL); CHECK_ERROR(esp_event_loop_create_default(), APP_ERR_WIFI_INIT_FAIL); @@ -517,6 +592,9 @@ static app_error_t wifi_softap_init(void) { wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); CHECK_ERROR(esp_wifi_init(&cfg), APP_ERR_WIFI_INIT_FAIL); + esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL); + esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL); + wifi_config_t wifi_config = { .ap = { .ssid = CONFIG_AP_WIFI_SSID, @@ -824,35 +902,12 @@ static esp_err_t parse_wifi_settings_json(const char *content, char *ssid, char return ESP_OK; } -bool test_wifi_credentials(const char* ssid, const char* password, int timeout_ms) { - wifi_config_t wifi_config = {0}; - strncpy((char*)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid) - 1); - strncpy((char*)wifi_config.sta.password, password, sizeof(wifi_config.sta.password) - 1); - - esp_wifi_set_config(WIFI_IF_STA, &wifi_config); - esp_wifi_start(); - - // Ожидание результата - EventBits_t bits = xEventGroupWaitBits(wifi_event_group, - WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, - pdFALSE, - pdFALSE, - timeout_ms / portTICK_PERIOD_MS); - - bool success = (bits & WIFI_CONNECTED_BIT) != 0; - - esp_wifi_stop(); - vEventGroupDelete(wifi_event_group); - - return success; -} - static esp_err_t setup_set_settings_handler(httpd_req_t *req) { char *content = NULL; if (receive_http_content(req, &content) != ESP_OK) { httpd_resp_set_type(req, "application/json"); - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "{\"message\": \"failed to receive content\"}"); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "{\"status\":\"error\",\"message\":\"Failed to receive content\"}"); return ESP_FAIL; } @@ -867,24 +922,51 @@ static esp_err_t setup_set_settings_handler(httpd_req_t *req) { } free(content); + // Проверяем, что пароль не пустой для защищенных сетей + if (strlen(ssid) == 0) { + httpd_resp_set_type(req, "application/json"); + httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "{\"status\":\"error\",\"message\":\"SSID cannot be empty\"}"); + return ESP_FAIL; + } + ESP_LOGI(TAG, "Testing WiFi connection to SSID: %s", ssid); - bool wifi_ok = test_wifi_credentials(ssid, password, 10000); + + // Сохраняем текущий режим WiFi перед тестированием + wifi_mode_t current_mode; + esp_wifi_get_mode(¤t_mode); + + // Убеждаемся, что STA режим активен + if (!(current_mode & WIFI_MODE_STA)) { + esp_wifi_set_mode(WIFI_MODE_APSTA); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + bool wifi_ok = test_wifi_credentials(ssid, password, 15000); // 15 секунд таймаут if (wifi_ok) { save_wifi_config(ssid, password); - send_json_response(req, "{\"success\":true,\"error\":\"Wi-Fi connected successfully. Rebooting...\"}"); + httpd_resp_set_type(req, "application/json"); + httpd_resp_set_status(req, HTTPD_200); + const char *success_response = "{\"status\":\"success\",\"message\":\"WiFi connected successfully! Rebooting in 2 seconds...\"}"; + httpd_resp_send(req, success_response, strlen(success_response)); - vTaskDelay(pdMS_TO_TICKS(1000)); + ESP_LOGI(TAG, "WiFi test SUCCESSFUL, rebooting..."); + vTaskDelay(pdMS_TO_TICKS(2000)); esp_restart(); } else { - send_json_response(req, "{\"success\":false,\"error\":\"Failed to connect to WiFi mode\"}"); + httpd_resp_set_type(req, "application/json"); + const char *error_response = "{\"status\":\"error\",\"message\":\"Failed to connect to WiFi. Please check SSID and password.\"}"; + httpd_resp_send(req, error_response, strlen(error_response)); + + ESP_LOGW(TAG, "WiFi test FAILED for SSID: %s", ssid); } return wifi_ok ? ESP_OK : ESP_FAIL; } + static esp_err_t setup_get_wifi_list_handler(httpd_req_t *req) { esp_err_t ret; uint16_t ap_count = 0;