diff --git a/components/wifi_provisioning/include/wifi_provisioning/manager.h b/components/wifi_provisioning/include/wifi_provisioning/manager.h index 417ff3af8e0..c65ed3dfde5 100644 --- a/components/wifi_provisioning/include/wifi_provisioning/manager.h +++ b/components/wifi_provisioning/include/wifi_provisioning/manager.h @@ -556,7 +556,8 @@ esp_err_t wifi_prov_mgr_reset_provisioning(void); /** * @brief Reset internal state machine and clear provisioned credentials. * - * This API can be used to restart provisioning in case invalid credentials are entered. + * This API should be used to restart provisioning ONLY in the case + * of provisioning failures without rebooting the device. * * @return * - ESP_OK : Reset provisioning state machine successfully @@ -565,6 +566,23 @@ esp_err_t wifi_prov_mgr_reset_provisioning(void); */ esp_err_t wifi_prov_mgr_reset_sm_state_on_failure(void); +/** + * @brief Reset internal state machine and clear provisioned credentials. + * + * This API can be used to restart provisioning ONLY in case the device is + * to be provisioned again for new credentials after a previous successful + * provisioning without rebooting the device. + * + * @note This API can be used only if provisioning auto-stop has been + * disabled using wifi_prov_mgr_disable_auto_stop() + * + * @return + * - ESP_OK : Reset provisioning state machine successfully + * - ESP_FAIL : Failed to reset provisioning state machine + * - ESP_ERR_INVALID_STATE : Manager not initialized + */ +esp_err_t wifi_prov_mgr_reset_sm_state_for_reprovision(void); + #ifdef __cplusplus } #endif diff --git a/components/wifi_provisioning/src/manager.c b/components/wifi_provisioning/src/manager.c index 1d36a38b0ab..64f445a4750 100644 --- a/components/wifi_provisioning/src/manager.c +++ b/components/wifi_provisioning/src/manager.c @@ -1617,3 +1617,52 @@ esp_err_t wifi_prov_mgr_reset_sm_state_on_failure(void) RELEASE_LOCK(prov_ctx_lock); return err; } + +esp_err_t wifi_prov_mgr_reset_sm_state_for_reprovision(void) +{ + if (!prov_ctx_lock) { + ESP_LOGE(TAG, "Provisioning manager not initialized"); + return ESP_ERR_INVALID_STATE; + } + + ACQUIRE_LOCK(prov_ctx_lock); + + esp_err_t ret = ESP_OK; + wifi_config_t wifi_cfg_empty = {0}; + uint8_t restore_wifi_flag = 0; + + if (!prov_ctx->mgr_info.capabilities.no_auto_stop) { + ESP_LOGE(TAG, "Execute wifi_prov_mgr_disable_auto_stop() before calling this API"); + ret = ESP_ERR_INVALID_STATE; + goto exit; + } + + ret = esp_wifi_set_storage(WIFI_STORAGE_RAM); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to set Wi-Fi storage to RAM"); + goto exit; + } + restore_wifi_flag |= WIFI_PROV_STORAGE_BIT; + + 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, 0x%x", ret); + goto exit; + } + + ret = esp_wifi_disconnect(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to disconnect wifi, 0x%x", ret); + goto exit; + } + + prov_ctx->prov_state = WIFI_PROV_STATE_STARTED; + execute_event_cb(WIFI_PROV_START, NULL, 0); + +exit: + if (restore_wifi_flag & WIFI_PROV_STORAGE_BIT) { + esp_wifi_set_storage(WIFI_STORAGE_FLASH); + } + RELEASE_LOCK(prov_ctx_lock); + return ret; +} diff --git a/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild b/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild index 269ad1866cf..edfee3d98ae 100644 --- a/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild +++ b/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild @@ -96,4 +96,11 @@ menu "Example Configuration" default y help This enables BLE 4.2 features for Bluedroid. + + config EXAMPLE_REPROVISIONING + bool "Re-provisioning" + help + Enable re-provisioning - allow the device to provision for new credentials + after previous successful provisioning. + endmenu diff --git a/examples/provisioning/wifi_prov_mgr/main/app_main.c b/examples/provisioning/wifi_prov_mgr/main/app_main.c index 9f17dfe1b24..4a5816e0f11 100644 --- a/examples/provisioning/wifi_prov_mgr/main/app_main.c +++ b/examples/provisioning/wifi_prov_mgr/main/app_main.c @@ -415,8 +415,13 @@ void app_main(void) * This call must be made before starting the provisioning. */ wifi_prov_mgr_endpoint_create("custom-data"); - /* Start provisioning service */ + /* Do not stop and de-init provisioning even after success, + * so that we can restart it later. */ +#ifdef CONFIG_EXAMPLE_REPROVISIONING + wifi_prov_mgr_disable_auto_stop(1000); +#endif + /* Start provisioning service */ ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(security, (const void *) sec_params, service_name, service_key)); /* The handler for the optional endpoint created above. @@ -448,11 +453,27 @@ void app_main(void) } /* Wait for Wi-Fi connection */ - xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_EVENT, false, true, portMAX_DELAY); + xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_EVENT, true, true, portMAX_DELAY); /* Start main application now */ +#if CONFIG_EXAMPLE_REPROVISIONING while (1) { - ESP_LOGI(TAG, "Hello World!"); - vTaskDelay(1000 / portTICK_PERIOD_MS); + for (int i = 0; i < 10; i++) { + ESP_LOGI(TAG, "Hello World!"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + + /* Resetting provisioning state machine to enable re-provisioning */ + wifi_prov_mgr_reset_sm_state_for_reprovision(); + + /* Wait for Wi-Fi connection */ + xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_EVENT, true, true, portMAX_DELAY); } +#else + while (1) { + ESP_LOGI(TAG, "Hello World!"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +#endif + }