diff --git a/components/wifi_provisioning/src/manager.c b/components/wifi_provisioning/src/manager.c index a9431eedb7..a56b079d24 100644 --- a/components/wifi_provisioning/src/manager.c +++ b/components/wifi_provisioning/src/manager.c @@ -33,6 +33,8 @@ #include "wifi_provisioning_priv.h" #define WIFI_PROV_MGR_VERSION "v1.1" +#define WIFI_PROV_STORAGE_BIT BIT0 +#define WIFI_PROV_SETTING_BIT BIT1 #define MAX_SCAN_RESULTS CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES #define ACQUIRE_LOCK(mux) assert(xSemaphoreTake(mux, portMAX_DELAY) == pdTRUE) @@ -1389,6 +1391,8 @@ void wifi_prov_mgr_deinit(void) esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const char *pop, const char *service_name, const char *service_key) { + uint8_t restore_wifi_flag = 0; + if (!prov_ctx_lock) { ESP_LOGE(TAG, "Provisioning manager not initialized"); return ESP_ERR_INVALID_STATE; @@ -1415,43 +1419,47 @@ esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const /* Start Wi-Fi in Station Mode. * This is necessary for scanning to work */ - esp_err_t err = esp_wifi_set_mode(WIFI_MODE_STA); - if (err != ESP_OK) { + ret = esp_wifi_set_mode(WIFI_MODE_STA); + if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to set Wi-Fi mode to STA"); - RELEASE_LOCK(prov_ctx_lock); - return err; + goto err; } - err = esp_wifi_start(); - if (err != ESP_OK) { + ret = esp_wifi_start(); + if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to start Wi-Fi"); - RELEASE_LOCK(prov_ctx_lock); - return err; + goto err; } /* Change Wi-Fi storage to RAM temporarily and erase any old - * credentials (i.e. without erasing the copy on NVS). Also + * credentials in RAM(i.e. without erasing the copy on NVS). Also * call disconnect to make sure device doesn't remain connected * to the AP whose credentials were present earlier */ wifi_config_t wifi_cfg_empty, wifi_cfg_old; memset(&wifi_cfg_empty, 0, sizeof(wifi_config_t)); esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg_old); - err = esp_wifi_set_storage(WIFI_STORAGE_RAM); - if (err != ESP_OK) { + ret = esp_wifi_set_storage(WIFI_STORAGE_RAM); + if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to set Wi-Fi storage to RAM"); - RELEASE_LOCK(prov_ctx_lock); - return err; + goto err; } - esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg_empty); - if (err != ESP_OK) { + + /* WiFi storage needs to be restored before exiting this API */ + restore_wifi_flag |= WIFI_PROV_STORAGE_BIT; + /* Erase Wi-Fi credentials in RAM, when call disconnect and user code + * receive WIFI_EVENT_STA_DISCONNECTED and maybe call esp_wifi_connect, at + * this time Wi-Fi will have no configuration to connect */ + ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg_empty); + if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to set empty Wi-Fi credentials"); - RELEASE_LOCK(prov_ctx_lock); - return err; + goto err; } - err = esp_wifi_disconnect(); - if (err != ESP_OK) { + /* WiFi settings needs to be restored if provisioning error before exiting this API */ + restore_wifi_flag |= WIFI_PROV_SETTING_BIT; + + ret = esp_wifi_disconnect(); + if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to disconnect"); - RELEASE_LOCK(prov_ctx_lock); - return err; + goto err; } /* Initialize app data */ @@ -1526,10 +1534,15 @@ esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const err: prov_ctx->prov_state = WIFI_PROV_STATE_IDLE; - esp_wifi_set_storage(WIFI_STORAGE_FLASH); - esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg_old); - + if (restore_wifi_flag & WIFI_PROV_SETTING_BIT) { + /* Restore current WiFi settings, since provisioning start has failed */ + esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg_old); + } exit: + if (restore_wifi_flag & WIFI_PROV_STORAGE_BIT) { + /* Restore WiFi storage back to FLASH */ + esp_wifi_set_storage(WIFI_STORAGE_FLASH); + } RELEASE_LOCK(prov_ctx_lock); return ret; }