provisioning: Fix WiFi credentials not saved to NVS due to wifi_prov_mgr_start_provisioning change the WiFi storage to RAM

Closes https://github.com/espressif/esp-idf/issues/5178
This commit is contained in:
yuanjm 2021-03-17 11:49:20 +08:00 committed by bot
parent e9ae42dbf0
commit 06ae78b531

View File

@ -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;
}