From 868f317c19915a30c8d5937f5eac1ffa35294f35 Mon Sep 17 00:00:00 2001 From: Piyush Shah Date: Fri, 3 Jan 2020 20:17:10 +0530 Subject: [PATCH] wifi_prov_manager: Delay the Wi-Fi connect call For SoftAP provisioning, if we start Wi-Fi connection as soon as the apply config request is received, it has been observed that the clients (Phone apps mostly) do not get the response for this as we switch the Wi-Fi channel, causing a momentary disconnection. Delaying the connection calls helps mitigate the issue. Signed-off-by: Piyush Shah --- components/wifi_provisioning/src/manager.c | 43 +++++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/components/wifi_provisioning/src/manager.c b/components/wifi_provisioning/src/manager.c index a2a816af5..94e141ebc 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);