How to re-provision ESP with wifi credentials without forcing a reboot?

karunt
Posts: 41
Joined: Sat Apr 03, 2021 7:58 am

How to re-provision ESP with wifi credentials without forcing a reboot?

Postby karunt » Mon Jan 17, 2022 8:07 am

ESP documentation sates:
If provisioning state needs to be reset, any of the following approaches may be taken :
the associated part of NVS partition has to be erased manually

main application must implement some logic to call esp_wifi_ APIs for erasing the credentials at runtime

main application must implement some logic to force start the provisioning irrespective of the provisioning state
If I take the first approach (manually erase associated part of NVS partition) and then try to resend wifi credentials, I still get an error because prov_ctx->prov_state is WIFI_PROV_STATE_SUCCESS, so I'm unable to re-provision the chip with new credentials other than manually forcing a restart by calling

Code: Select all

ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(security, pop, service_name, service_key))
. Here's my code to erase NVS:

Code: Select all

   ESP_ERROR_CHECK(nvs_flash_erase());
            esp_err_t ret = nvs_flash_init();
            if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
                ESP_ERROR_CHECK(nvs_flash_erase());
                ESP_ERROR_CHECK(nvs_flash_init());
            }
            wifi_config_t wifi_cfg_empty;
            memset(&wifi_cfg_empty, 0, sizeof(wifi_config_t));
            esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_cfg_empty);
Any idea how to accomplish this simply after erasing associated part of NVS partition?

ESP_Mahavir
Posts: 101
Joined: Wed Jan 24, 2018 6:51 am

Re: How to re-provision ESP with wifi credentials without forcing a reboot?

Postby ESP_Mahavir » Thu Feb 03, 2022 4:57 pm

Hi Karun,

- Provisioning manager has an API to reset persistent credentials `wifi_prov_mgr_reset_provisioning()`, please refer to usage at https://github.com/espressif/esp-idf/bl ... ain.c#L233
- Additionally there is also an API to reset provisioning manager state in case of failure `wifi_prov_mgr_reset_sm_state_on_failure()` which resets internal state machine and also clears any NVS credentials, please refer to usage at https://github.com/espressif/esp-idf/bl ... main.c#L74

For your case, you can use first API to clear WiFi credentials from NVS partition. Since in your case, provisioning was successful, 2nd API may not help. In this case, I would recommend that you stop WiFi provisioning manager service and then restart it. That should help to achieve your aim.

Please let us know if you face any issues here.

Thanks.
Mahavir

karunt
Posts: 41
Joined: Sat Apr 03, 2021 7:58 am

Re: How to re-provision ESP with wifi credentials without forcing a reboot?

Postby karunt » Thu Feb 17, 2022 5:19 pm

Thank you. So `wifi_prov_mgr_reset_provisioning()` calls `esp_wifi_restore()`, but where can I find the code for `esp_wifi_restore()`? Doesn't appear to be anywhere in the files within the components folder besides being defined in esp_wifi.h. Or is the code for esp_wifi_restore hidden and not available to users to understand and possibly customize?

ESP_Mahavir
Posts: 101
Joined: Wed Jan 24, 2018 6:51 am

Re: How to re-provision ESP with wifi credentials without forcing a reboot?

Postby ESP_Mahavir » Fri Feb 18, 2022 12:43 pm

Hello,

`esp_wifi_restore` API comes from WiFi library (no source code) and its documented at https://github.com/espressif/esp-idf/bl ... #L322-L335. It is responsible to reset WiFi settings from NVS to default values. If you need anything in addition, you may use direct NVS APIs.

Hope this helps!
Mahavir

karunt
Posts: 41
Joined: Sat Apr 03, 2021 7:58 am

Re: How to re-provision ESP with wifi credentials without forcing a reboot?

Postby karunt » Fri Feb 18, 2022 3:11 pm

I was able to find `esp_wifi_restore()` in the esp_wifi library, but still trying to get my arms around how it resets NVS values to default if there's no code besides just being defined in the esp_wifi library. I see the 4 other apis it uses (`esp_wifi_set_bandwidth`,
`esp_wifi_set_protocol`, `esp_wifi_set_config_related`, and `esp_wifi_set_mode`) to reset the values to default, but again, without a code that calls those 4 apis, how does `esp_wifi_restore` accomplish its goal? That's confusing me quite a bit. Thanks.

karunt
Posts: 41
Joined: Sat Apr 03, 2021 7:58 am

Re: How to re-provision ESP with wifi credentials without forcing a reboot?

Postby karunt » Thu Mar 24, 2022 3:32 pm

Follow up question to your proposal to use esp_wifi_restore() to reprovision ESP chip. When I execute ble write to write a command to the characteristic associated with the custom handler to reboot the chip, my write function always results in an error. It appears what's happening is that the response to the ble write command isn't sent back because the chip is forced to restore and reboot. How to avoid this situation? I mean, I'd like for ESP32 to respond to the write command to let the client side know that the write operation was successful, then begin the restore/reboot process. Here's my custom handler code:

Code: Select all

esp_err_t custom_prov_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen,
                                          uint8_t **outbuf, ssize_t *outlen, void *priv_data)
{   
    if (strncmp((char *)inbuf, "reboot", inlen) == 0) {
        ESP_LOGI(TAG, "Received data: %.*s", inlen, (char *)inbuf);
        char service_name[12];
        get_device_service_name(service_name, sizeof(service_name));
        wifi_prov_security_t security = WIFI_PROV_SECURITY_0;
        const char *pop = "abcd1234";
        const char *service_key = NULL;
        wifi_prov_mgr_stop_provisioning();
        ESP_ERROR_CHECK(esp_wifi_restore());
        ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(security, pop, service_name, service_key));
    }

    char response[] = "SUCCESS";
    *outbuf = (uint8_t *)strdup(response);
    if (*outbuf == NULL) {
        ESP_LOGE(TAG, "System out of memory");
        return ESP_ERR_NO_MEM;
    }
    *outlen = strlen(response) + 1; // +1 for NULL terminating byte

    return ESP_OK;
}

Who is online

Users browsing this forum: No registered users and 38 guests