Merge branch 'bugfix/fix_provisioning_change_wifi_storage' into 'master'

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

Closes IDF-1654

See merge request espressif/esp-idf!12772
This commit is contained in:
Mahavir Jain
2021-03-30 14:12:29 +00:00

View File

@@ -33,6 +33,8 @@
#include "wifi_provisioning_priv.h" #include "wifi_provisioning_priv.h"
#define WIFI_PROV_MGR_VERSION "v1.1" #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 MAX_SCAN_RESULTS CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES
#define ACQUIRE_LOCK(mux) assert(xSemaphoreTake(mux, portMAX_DELAY) == pdTRUE) #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, esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const char *pop,
const char *service_name, const char *service_key) const char *service_name, const char *service_key)
{ {
uint8_t restore_wifi_flag = 0;
if (!prov_ctx_lock) { if (!prov_ctx_lock) {
ESP_LOGE(TAG, "Provisioning manager not initialized"); ESP_LOGE(TAG, "Provisioning manager not initialized");
return ESP_ERR_INVALID_STATE; 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. /* Start Wi-Fi in Station Mode.
* This is necessary for scanning to work */ * This is necessary for scanning to work */
esp_err_t err = esp_wifi_set_mode(WIFI_MODE_STA); ret = esp_wifi_set_mode(WIFI_MODE_STA);
if (err != ESP_OK) { if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to set Wi-Fi mode to STA"); ESP_LOGE(TAG, "Failed to set Wi-Fi mode to STA");
RELEASE_LOCK(prov_ctx_lock); goto err;
return err;
} }
err = esp_wifi_start(); ret = esp_wifi_start();
if (err != ESP_OK) { if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to start Wi-Fi"); ESP_LOGE(TAG, "Failed to start Wi-Fi");
RELEASE_LOCK(prov_ctx_lock); goto err;
return err;
} }
/* Change Wi-Fi storage to RAM temporarily and erase any old /* 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 * call disconnect to make sure device doesn't remain connected
* to the AP whose credentials were present earlier */ * to the AP whose credentials were present earlier */
wifi_config_t wifi_cfg_empty, wifi_cfg_old; wifi_config_t wifi_cfg_empty, wifi_cfg_old;
memset(&wifi_cfg_empty, 0, sizeof(wifi_config_t)); memset(&wifi_cfg_empty, 0, sizeof(wifi_config_t));
esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg_old); esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg_old);
err = esp_wifi_set_storage(WIFI_STORAGE_RAM); ret = esp_wifi_set_storage(WIFI_STORAGE_RAM);
if (err != ESP_OK) { if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to set Wi-Fi storage to RAM"); ESP_LOGE(TAG, "Failed to set Wi-Fi storage to RAM");
RELEASE_LOCK(prov_ctx_lock); goto err;
return 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"); ESP_LOGE(TAG, "Failed to set empty Wi-Fi credentials");
RELEASE_LOCK(prov_ctx_lock); goto err;
return err;
} }
err = esp_wifi_disconnect(); /* WiFi settings needs to be restored if provisioning error before exiting this API */
if (err != ESP_OK) { restore_wifi_flag |= WIFI_PROV_SETTING_BIT;
ret = esp_wifi_disconnect();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to disconnect"); ESP_LOGE(TAG, "Failed to disconnect");
RELEASE_LOCK(prov_ctx_lock); goto err;
return err;
} }
/* Initialize app data */ /* Initialize app data */
@@ -1526,10 +1534,15 @@ esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const
err: err:
prov_ctx->prov_state = WIFI_PROV_STATE_IDLE; prov_ctx->prov_state = WIFI_PROV_STATE_IDLE;
esp_wifi_set_storage(WIFI_STORAGE_FLASH); if (restore_wifi_flag & WIFI_PROV_SETTING_BIT) {
esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg_old); /* Restore current WiFi settings, since provisioning start has failed */
esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg_old);
}
exit: 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); RELEASE_LOCK(prov_ctx_lock);
return ret; return ret;
} }