diff --git a/components/wifi_provisioning/src/manager.c b/components/wifi_provisioning/src/manager.c index a2a816af57..94e141ebcf 100644 --- a/components/wifi_provisioning/src/manager.c +++ b/components/wifi_provisioning/src/manager.c @@ -102,6 +102,9 @@ struct wifi_prov_mgr_ctx { /* Handle for Provisioning Auto Stop timer */ esp_timer_handle_t autostop_timer; + /* Handle for delayed Wi-Fi connection timer */ + esp_timer_handle_t wifi_connect_timer; + /* State of Wi-Fi Station */ wifi_prov_sta_state_t wifi_state; @@ -566,13 +569,19 @@ static bool wifi_prov_mgr_stop_service(bool blocking) return false; } - /* Timer not needed anymore */ + /* Timers not needed anymore */ if (prov_ctx->autostop_timer) { esp_timer_stop(prov_ctx->autostop_timer); esp_timer_delete(prov_ctx->autostop_timer); prov_ctx->autostop_timer = NULL; } + if (prov_ctx->wifi_connect_timer) { + esp_timer_stop(prov_ctx->wifi_connect_timer); + esp_timer_delete(prov_ctx->wifi_connect_timer); + prov_ctx->wifi_connect_timer = NULL; + } + ESP_LOGD(TAG, "Stopping provisioning"); prov_ctx->prov_state = WIFI_PROV_STATE_STOPPING; @@ -1106,6 +1115,13 @@ esp_err_t wifi_prov_mgr_is_provisioned(bool *provisioned) return ESP_OK; } +static void wifi_connect_timer_cb(void *arg) +{ + if (esp_wifi_connect() != ESP_OK) { + ESP_LOGE(TAG, "Failed to connect Wi-Fi"); + } +} + esp_err_t wifi_prov_mgr_configure_sta(wifi_config_t *wifi_cfg) { if (!prov_ctx_lock) { @@ -1152,14 +1168,13 @@ esp_err_t wifi_prov_mgr_configure_sta(wifi_config_t *wifi_cfg) RELEASE_LOCK(prov_ctx_lock); return ESP_FAIL; } - /* Connect to AP */ - if (esp_wifi_connect() != ESP_OK) { - ESP_LOGE(TAG, "Failed to connect Wi-Fi"); + /* Connect to AP after one second so that the response can + * be sent to the client successfully, before a channel change happens*/ + if (esp_timer_start_once(prov_ctx->wifi_connect_timer, 1000 * 1000U) != ESP_OK) { + ESP_LOGE(TAG, "Failed to start Wi-Fi connect timer"); RELEASE_LOCK(prov_ctx_lock); return ESP_FAIL; } - /* This delay allows channel change to complete */ - vTaskDelay(1000 / portTICK_PERIOD_MS); /* Reset Wi-Fi station state for provisioning app */ prov_ctx->wifi_state = WIFI_PROV_STA_CONNECTING; @@ -1455,6 +1470,20 @@ esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const } prov_ctx->security = security; + + esp_timer_create_args_t wifi_connect_timer_conf = { + .callback = wifi_connect_timer_cb, + .arg = NULL, + .dispatch_method = ESP_TIMER_TASK, + .name = "wifi_prov_connect_tm" + }; + ret = esp_timer_create(&wifi_connect_timer_conf, &prov_ctx->wifi_connect_timer); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to create Wi-Fi connect timer"); + free((void *)prov_ctx->pop.data); + goto err; + } + /* If auto stop on completion is enabled (default) create the stopping timer */ if (!prov_ctx->mgr_info.capabilities.no_auto_stop) { /* Create timer object as a member of app data */ @@ -1467,6 +1496,7 @@ esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const ret = esp_timer_create(&autostop_timer_conf, &prov_ctx->autostop_timer); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to create auto-stop timer"); + esp_timer_delete(prov_ctx->wifi_connect_timer); free((void *)prov_ctx->pop.data); goto err; } @@ -1482,6 +1512,7 @@ esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const ret = wifi_prov_mgr_start_service(service_name, service_key); if (ret != ESP_OK) { esp_timer_delete(prov_ctx->autostop_timer); + esp_timer_delete(prov_ctx->wifi_connect_timer); free((void *)prov_ctx->pop.data); } ACQUIRE_LOCK(prov_ctx_lock);