From d5d722c66f39ba66f8b6d64235e8ac5da8d5d4ac Mon Sep 17 00:00:00 2001 From: lucastcox Date: Mon, 23 Nov 2020 10:10:25 +0530 Subject: [PATCH 1/3] app_update: Add definition for esp_ota_abort Closes: https://github.com/espressif/esp-idf/issues/5329 Merges: https://github.com/espressif/esp-idf/pull/5331 Signed-off-by: Shubham Kulkarni --- components/app_update/esp_ota_ops.c | 25 +++++++++++++++++---- components/app_update/include/esp_ota_ops.h | 12 ++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index cabfe87cff..ae164f3011 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -302,16 +302,33 @@ esp_err_t esp_ota_write_with_offset(esp_ota_handle_t handle, const void *data, s return ESP_ERR_INVALID_ARG; } -esp_err_t esp_ota_end(esp_ota_handle_t handle) +static ota_ops_entry_t *get_ota_ops_entry(esp_ota_handle_t handle) { - ota_ops_entry_t *it; - esp_err_t ret = ESP_OK; - + ota_ops_entry_t *it = NULL; for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) { if (it->handle == handle) { break; } } + return it; +} + +esp_err_t esp_ota_abort(esp_ota_handle_t handle) +{ + ota_ops_entry_t *it = get_ota_ops_entry(handle); + + if (it == NULL) { + return ESP_ERR_NOT_FOUND; + } + LIST_REMOVE(it, entries); + free(it); + return ESP_OK; +} + +esp_err_t esp_ota_end(esp_ota_handle_t handle) +{ + ota_ops_entry_t *it = get_ota_ops_entry(handle); + esp_err_t ret = ESP_OK; if (it == NULL) { return ESP_ERR_NOT_FOUND; diff --git a/components/app_update/include/esp_ota_ops.h b/components/app_update/include/esp_ota_ops.h index f16ed6b1f6..c37f96f931 100644 --- a/components/app_update/include/esp_ota_ops.h +++ b/components/app_update/include/esp_ota_ops.h @@ -157,6 +157,18 @@ esp_err_t esp_ota_write_with_offset(esp_ota_handle_t handle, const void *data, s */ esp_err_t esp_ota_end(esp_ota_handle_t handle); +/** + * @brief Abort OTA update, free the handle and memory associated with it. + * + * @param handle obtained from esp_ota_begin(). + * + * @return + * - ESP_OK: Handle and its associated memory is freed successfully. + * - ESP_ERR_NOT_FOUND: OTA handle was not found. + */ +esp_err_t esp_ota_abort(esp_ota_handle_t handle); + + /** * @brief Configure OTA data for a new boot partition * From bc78b8f2da0bebd246a5a543fc23d2b25cd9f4ae Mon Sep 17 00:00:00 2001 From: Shubham Kulkarni Date: Fri, 14 Aug 2020 15:54:15 +0530 Subject: [PATCH 2/3] esp_https_ota: Add definition for esp_https_ota_abort Update esp_https_ota API to use esp_https_ota_abort in case of error --- .../esp_https_ota/include/esp_https_ota.h | 20 +++++++++ components/esp_https_ota/src/esp_https_ota.c | 44 ++++++++++++++++--- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/components/esp_https_ota/include/esp_https_ota.h b/components/esp_https_ota/include/esp_https_ota.h index 81d9383424..2966c5d0a3 100644 --- a/components/esp_https_ota/include/esp_https_ota.h +++ b/components/esp_https_ota/include/esp_https_ota.h @@ -135,6 +135,7 @@ bool esp_https_ota_is_complete_data_received(esp_https_ota_handle_t https_ota_ha * * @note If this API returns successfully, esp_restart() must be called to * boot from the new firmware image + * esp_https_ota_finish should not be called after calling esp_https_ota_abort * * @param[in] https_ota_handle pointer to esp_https_ota_handle_t structure * @@ -147,6 +148,25 @@ bool esp_https_ota_is_complete_data_received(esp_https_ota_handle_t https_ota_ha esp_err_t esp_https_ota_finish(esp_https_ota_handle_t https_ota_handle); +/** + * @brief Clean-up HTTPS OTA Firmware upgrade and close HTTPS connection + * + * This function closes the HTTP connection and frees the ESP HTTPS OTA context. + * + * @note esp_https_ota_abort should not be called after calling esp_https_ota_finish + * + * @param[in] https_ota_handle pointer to esp_https_ota_handle_t structure + * + * @return + * - ESP_OK: Clean-up successful + * - ESP_ERR_INVALID_STATE: Invalid ESP HTTPS OTA state + * - ESP_FAIL: OTA not started + * - ESP_ERR_NOT_FOUND: OTA handle not found + * - ESP_ERR_INVALID_ARG: Invalid argument + */ +esp_err_t esp_https_ota_abort(esp_https_ota_handle_t https_ota_handle); + + /** * @brief Reads app description from image header. The app description provides information * like the "Firmware version" of the image. diff --git a/components/esp_https_ota/src/esp_https_ota.c b/components/esp_https_ota/src/esp_https_ota.c index eedb2139bc..6af168e4ae 100644 --- a/components/esp_https_ota/src/esp_https_ota.c +++ b/components/esp_https_ota/src/esp_https_ota.c @@ -381,6 +381,40 @@ esp_err_t esp_https_ota_finish(esp_https_ota_handle_t https_ota_handle) return err; } +esp_err_t esp_https_ota_abort(esp_https_ota_handle_t https_ota_handle) +{ + esp_https_ota_t *handle = (esp_https_ota_t *)https_ota_handle; + if (handle == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (handle->state < ESP_HTTPS_OTA_BEGIN) { + return ESP_FAIL; + } + + esp_err_t err = ESP_OK; + switch (handle->state) { + case ESP_HTTPS_OTA_SUCCESS: + case ESP_HTTPS_OTA_IN_PROGRESS: + err = esp_ota_abort(handle->update_handle); + /* falls through */ + case ESP_HTTPS_OTA_BEGIN: + if (handle->ota_upgrade_buf) { + free(handle->ota_upgrade_buf); + } + if (handle->http_client) { + _http_cleanup(handle->http_client); + } + break; + default: + err = ESP_ERR_INVALID_STATE; + ESP_LOGE(TAG, "Invalid ESP HTTPS OTA State"); + break; + } + free(handle); + return err; +} + int esp_https_ota_get_image_len_read(esp_https_ota_handle_t https_ota_handle) { esp_https_ota_t *handle = (esp_https_ota_t *)https_ota_handle; @@ -417,13 +451,13 @@ esp_err_t esp_https_ota(const esp_http_client_config_t *config) } } - esp_err_t ota_finish_err = esp_https_ota_finish(https_ota_handle); if (err != ESP_OK) { - /* If there was an error in esp_https_ota_perform(), - then it is given more precedence than error in esp_https_ota_finish() - */ + esp_https_ota_abort(https_ota_handle); return err; - } else if (ota_finish_err != ESP_OK) { + } + + esp_err_t ota_finish_err = esp_https_ota_finish(https_ota_handle); + if (ota_finish_err != ESP_OK) { return ota_finish_err; } return ESP_OK; From 4874f52d96ec992f80d87cfde7ddfbfa9704a223 Mon Sep 17 00:00:00 2001 From: Shubham Kulkarni Date: Tue, 22 Sep 2020 15:55:31 +0530 Subject: [PATCH 3/3] Update advanced_https_ota_example and native_ota_example to use esp_ota_abort in case of error --- .../main/advanced_https_ota_example.c | 28 +++++++++++-------- .../main/native_ota_example.c | 4 +++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c index a00a281e72..0b9abf1c10 100644 --- a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c +++ b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c @@ -144,21 +144,25 @@ void advanced_ota_example_task(void *pvParameter) if (esp_https_ota_is_complete_data_received(https_ota_handle) != true) { // the OTA image was not completely received and user can customise the response to this situation. ESP_LOGE(TAG, "Complete data was not received."); + } else { + ota_finish_err = esp_https_ota_finish(https_ota_handle); + if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) { + ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ..."); + vTaskDelay(1000 / portTICK_PERIOD_MS); + esp_restart(); + } else { + if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) { + ESP_LOGE(TAG, "Image validation failed, image is corrupted"); + } + ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err); + vTaskDelete(NULL); + } } ota_end: - ota_finish_err = esp_https_ota_finish(https_ota_handle); - if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) { - ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ..."); - vTaskDelay(1000 / portTICK_PERIOD_MS); - esp_restart(); - } else { - if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) { - ESP_LOGE(TAG, "Image validation failed, image is corrupted"); - } - ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed %d", ota_finish_err); - vTaskDelete(NULL); - } + esp_https_ota_abort(https_ota_handle); + ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed"); + vTaskDelete(NULL); } void app_main(void) diff --git a/examples/system/ota/native_ota_example/main/native_ota_example.c b/examples/system/ota/native_ota_example/main/native_ota_example.c index a81cf9d7a2..6da57f3140 100644 --- a/examples/system/ota/native_ota_example/main/native_ota_example.c +++ b/examples/system/ota/native_ota_example/main/native_ota_example.c @@ -187,18 +187,21 @@ static void ota_example_task(void *pvParameter) if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err)); http_cleanup(client); + esp_ota_abort(update_handle); task_fatal_error(); } ESP_LOGI(TAG, "esp_ota_begin succeeded"); } else { ESP_LOGE(TAG, "received package is not fit len"); http_cleanup(client); + esp_ota_abort(update_handle); task_fatal_error(); } } err = esp_ota_write( update_handle, (const void *)ota_write_data, data_read); if (err != ESP_OK) { http_cleanup(client); + esp_ota_abort(update_handle); task_fatal_error(); } binary_file_length += data_read; @@ -222,6 +225,7 @@ static void ota_example_task(void *pvParameter) if (esp_http_client_is_complete_data_received(client) != true) { ESP_LOGE(TAG, "Error in receiving complete file"); http_cleanup(client); + esp_ota_abort(update_handle); task_fatal_error(); }