From 784089bf09569b60341155feab6759a1ed38e2f5 Mon Sep 17 00:00:00 2001 From: Harshit Malpani Date: Wed, 2 Nov 2022 11:05:19 +0530 Subject: [PATCH 1/2] esp_https_ota: Added support for esp_events --- components/esp_https_ota/CMakeLists.txt | 2 +- .../esp_https_ota/include/esp_https_ota.h | 17 ++++++++ components/esp_https_ota/src/esp_https_ota.c | 38 ++++++++++++++++++ .../main/advanced_https_ota_example.c | 39 +++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) diff --git a/components/esp_https_ota/CMakeLists.txt b/components/esp_https_ota/CMakeLists.txt index ef037f8b0f96..b4d88d02a52c 100644 --- a/components/esp_https_ota/CMakeLists.txt +++ b/components/esp_https_ota/CMakeLists.txt @@ -1,6 +1,6 @@ idf_component_register(SRCS "src/esp_https_ota.c" INCLUDE_DIRS "include" - REQUIRES esp_http_client bootloader_support esp_app_format + REQUIRES esp_http_client bootloader_support esp_app_format esp_event PRIV_REQUIRES log app_update) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/esp_https_ota/include/esp_https_ota.h b/components/esp_https_ota/include/esp_https_ota.h index ba13ad619ea6..c51ddfc17cad 100644 --- a/components/esp_https_ota/include/esp_https_ota.h +++ b/components/esp_https_ota/include/esp_https_ota.h @@ -10,11 +10,28 @@ #include #include "esp_app_desc.h" #include +#include "esp_event.h" #ifdef __cplusplus extern "C" { #endif +ESP_EVENT_DECLARE_BASE(ESP_HTTPS_OTA_EVENT); +/** + * @brief Events generated by OTA process + */ +typedef enum { + ESP_HTTPS_OTA_START, + ESP_HTTPS_OTA_CONNECTED, + ESP_HTTPS_OTA_GET_IMG_DESC, + ESP_HTTPS_OTA_VERIFY_CHIP_ID, + ESP_HTTPS_OTA_DECRYPT_CB, + ESP_HTTPS_OTA_WRITE_FLASH, + ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION, + ESP_HTTPS_OTA_FINISH, + ESP_HTTPS_OTA_ABORT, +} esp_https_ota_event_t; + typedef void *esp_https_ota_handle_t; typedef esp_err_t(*http_client_init_cb_t)(esp_http_client_handle_t); diff --git a/components/esp_https_ota/src/esp_https_ota.c b/components/esp_https_ota/src/esp_https_ota.c index 9d162c6387ef..9d427029a523 100644 --- a/components/esp_https_ota/src/esp_https_ota.c +++ b/components/esp_https_ota/src/esp_https_ota.c @@ -13,6 +13,8 @@ #include #include +ESP_EVENT_DEFINE_BASE(ESP_HTTPS_OTA_EVENT); + #define IMAGE_HEADER_SIZE (1024) /* This is kept sufficiently large enough to cover image format headers @@ -171,6 +173,10 @@ static void _http_cleanup(esp_http_client_handle_t client) #if CONFIG_ESP_HTTPS_OTA_DECRYPT_CB static esp_err_t esp_https_ota_decrypt_cb(esp_https_ota_t *handle, decrypt_cb_arg_t *args) { + if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_DECRYPT_CB, NULL, 0, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event"); + } + esp_err_t ret = handle->decrypt_cb(args, handle->decrypt_user_ctx); if (ret != ESP_OK) { ESP_LOGE(TAG, "Decrypt callback failed %d", ret); @@ -202,6 +208,10 @@ static esp_err_t _ota_write(esp_https_ota_t *https_ota_handle, const void *buffe ESP_LOGD(TAG, "Written image length %d", https_ota_handle->binary_file_len); err = ESP_ERR_HTTPS_OTA_IN_PROGRESS; } + if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_WRITE_FLASH, NULL, 0, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event"); + } + #if CONFIG_ESP_HTTPS_OTA_DECRYPT_CB esp_https_ota_decrypt_cb_free_buf((void *) buffer); #endif @@ -216,6 +226,10 @@ static bool is_server_verification_enabled(const esp_https_ota_config_t *ota_con esp_err_t esp_https_ota_begin(const esp_https_ota_config_t *ota_config, esp_https_ota_handle_t *handle) { + if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_START, NULL, 0, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event"); + } + esp_err_t err; if (handle == NULL || ota_config == NULL || ota_config->http_config == NULL) { @@ -298,6 +312,10 @@ esp_err_t esp_https_ota_begin(const esp_https_ota_config_t *ota_config, esp_http if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to establish HTTP connection"); goto http_cleanup; + } else { + if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_CONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event"); + } } if (!https_ota_handle->partial_http_download) { @@ -382,6 +400,10 @@ static esp_err_t read_header(esp_https_ota_t *handle) esp_err_t esp_https_ota_get_img_desc(esp_https_ota_handle_t https_ota_handle, esp_app_desc_t *new_app_info) { + if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_GET_IMG_DESC, NULL, 0, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event"); + } + #if CONFIG_ESP_HTTPS_OTA_DECRYPT_CB // This API is not supported in case firmware image is encrypted in nature. // It is recommended to retrieve image description through decryption callback in application layer. @@ -414,6 +436,10 @@ esp_err_t esp_https_ota_get_img_desc(esp_https_ota_handle_t https_ota_handle, es static esp_err_t esp_ota_verify_chip_id(const void *arg) { + if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_VERIFY_CHIP_ID, NULL, 0, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event"); + } + esp_image_header_t *data = (esp_image_header_t *)(arg); if (data->chip_id != CONFIG_IDF_FIRMWARE_CHIP_ID) { ESP_LOGE(TAG, "Mismatch chip id, expected %d, found %d", CONFIG_IDF_FIRMWARE_CHIP_ID, data->chip_id); @@ -601,14 +627,26 @@ esp_err_t esp_https_ota_finish(esp_https_ota_handle_t https_ota_handle) esp_err_t err = esp_ota_set_boot_partition(handle->update_partition); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%x", err); + } else { + if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION, NULL, 0, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event"); + } } } free(handle); + if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_FINISH, NULL, 0, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event"); + } + return err; } esp_err_t esp_https_ota_abort(esp_https_ota_handle_t https_ota_handle) { + if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_ABORT, NULL, 0, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event"); + } + esp_https_ota_t *handle = (esp_https_ota_t *)https_ota_handle; if (handle == NULL) { return ESP_ERR_INVALID_ARG; 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 434f612ca2b8..1869f90f4ff4 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 @@ -38,6 +38,44 @@ extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end"); #define OTA_URL_SIZE 256 + +/* Event handler for catching system events */ +static void event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + if (event_base == ESP_HTTPS_OTA_EVENT) { + switch (event_id) { + case ESP_HTTPS_OTA_START: + ESP_LOGI(TAG, "OTA started"); + break; + case ESP_HTTPS_OTA_CONNECTED: + ESP_LOGI(TAG, "Connected to server"); + break; + case ESP_HTTPS_OTA_GET_IMG_DESC: + ESP_LOGI(TAG, "Reading Image Description"); + break; + case ESP_HTTPS_OTA_VERIFY_CHIP_ID: + ESP_LOGI(TAG, "Verifying chip id of new image"); + break; + case ESP_HTTPS_OTA_DECRYPT_CB: + ESP_LOGI(TAG, "Callback to decrypt function"); + break; + case ESP_HTTPS_OTA_WRITE_FLASH: + ESP_LOGD(TAG, "Writing to flash"); + break; + case ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION: + ESP_LOGI(TAG, "Boot partition updated"); + break; + case ESP_HTTPS_OTA_FINISH: + ESP_LOGI(TAG, "OTA finish"); + break; + case ESP_HTTPS_OTA_ABORT: + ESP_LOGI(TAG, "OTA abort"); + break; + } + } +} + static esp_err_t validate_image_header(esp_app_desc_t *new_app_info) { if (new_app_info == NULL) { @@ -192,6 +230,7 @@ void app_main(void) ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); + ESP_ERROR_CHECK(esp_event_handler_register(ESP_HTTPS_OTA_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. * Read "Establishing Wi-Fi or Ethernet Connection" section in * examples/protocols/README.md for more information about this function. From a80dfe85bc1162b8d6ee5a636f50468dc7f5572b Mon Sep 17 00:00:00 2001 From: Harshit Malpani Date: Wed, 2 Nov 2022 14:48:43 +0530 Subject: [PATCH 2/2] esp_https_ota: Send data to event handler --- .../esp_https_ota/include/esp_https_ota.h | 33 ++++++++--- components/esp_https_ota/src/esp_https_ota.c | 58 ++++++++++--------- .../main/advanced_https_ota_example.c | 7 +-- 3 files changed, 57 insertions(+), 41 deletions(-) diff --git a/components/esp_https_ota/include/esp_https_ota.h b/components/esp_https_ota/include/esp_https_ota.h index c51ddfc17cad..f880862f2869 100644 --- a/components/esp_https_ota/include/esp_https_ota.h +++ b/components/esp_https_ota/include/esp_https_ota.h @@ -10,28 +10,43 @@ #include #include "esp_app_desc.h" #include + #include "esp_event.h" +#include "esp_partition.h" #ifdef __cplusplus extern "C" { #endif ESP_EVENT_DECLARE_BASE(ESP_HTTPS_OTA_EVENT); + /** * @brief Events generated by OTA process + * + * @note Expected data type for different OTA events: + * - ESP_HTTPS_OTA_START : NULL + * - ESP_HTTPS_OTA_CONNECTED : NULL + * - ESP_HTTPS_OTA_GET_IMG_DESC : NULL + * - ESP_HTTPS_OTA_VERIFY_CHIP_ID : esp_chip_id_t + * - ESP_HTTPS_OTA_DECRYPT_CB : NULL + * - ESP_HTTPS_OTA_WRITE_FLASH : int + * - ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION : esp_partition_subtype_t + * - ESP_HTTPS_OTA_FINISH : NULL + * - ESP_HTTPS_OTA_ABORT : NULL */ typedef enum { - ESP_HTTPS_OTA_START, - ESP_HTTPS_OTA_CONNECTED, - ESP_HTTPS_OTA_GET_IMG_DESC, - ESP_HTTPS_OTA_VERIFY_CHIP_ID, - ESP_HTTPS_OTA_DECRYPT_CB, - ESP_HTTPS_OTA_WRITE_FLASH, - ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION, - ESP_HTTPS_OTA_FINISH, - ESP_HTTPS_OTA_ABORT, + ESP_HTTPS_OTA_START, /*!< OTA started */ + ESP_HTTPS_OTA_CONNECTED, /*!< Connected to server */ + ESP_HTTPS_OTA_GET_IMG_DESC, /*!< Read app description from image header */ + ESP_HTTPS_OTA_VERIFY_CHIP_ID, /*!< Verify chip id of new image */ + ESP_HTTPS_OTA_DECRYPT_CB, /*!< Callback to decrypt function */ + ESP_HTTPS_OTA_WRITE_FLASH, /*!< Flash write operation */ + ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION, /*!< Boot partition update after successful ota update */ + ESP_HTTPS_OTA_FINISH, /*!< OTA finished */ + ESP_HTTPS_OTA_ABORT, /*!< OTA aborted */ } esp_https_ota_event_t; + typedef void *esp_https_ota_handle_t; typedef esp_err_t(*http_client_init_cb_t)(esp_http_client_handle_t); diff --git a/components/esp_https_ota/src/esp_https_ota.c b/components/esp_https_ota/src/esp_https_ota.c index 9d427029a523..9302830d921c 100644 --- a/components/esp_https_ota/src/esp_https_ota.c +++ b/components/esp_https_ota/src/esp_https_ota.c @@ -170,12 +170,30 @@ static void _http_cleanup(esp_http_client_handle_t client) esp_http_client_cleanup(client); } +// Table to lookup ota event name +static const char* ota_event_name_table[] = { + "ESP_HTTPS_OTA_START", + "ESP_HTTPS_OTA_CONNECTED", + "ESP_HTTPS_OTA_GET_IMG_DESC", + "ESP_HTTPS_OTA_VERIFY_CHIP_ID", + "ESP_HTTPS_OTA_DECRYPT_CB", + "ESP_HTTPS_OTA_WRITE_FLASH", + "ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION", + "ESP_HTTPS_OTA_FINISH", + "ESP_HTTPS_OTA_ABORT", +}; + +static void esp_https_ota_dispatch_event(int32_t event_id, const void* event_data, size_t event_data_size) +{ + if (esp_event_post(ESP_HTTPS_OTA_EVENT, event_id, event_data, event_data_size, portMAX_DELAY) != ESP_OK) { + ESP_LOGE(TAG, "Failed to post https_ota event: %s", ota_event_name_table[event_id]); + } +} + #if CONFIG_ESP_HTTPS_OTA_DECRYPT_CB static esp_err_t esp_https_ota_decrypt_cb(esp_https_ota_t *handle, decrypt_cb_arg_t *args) { - if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_DECRYPT_CB, NULL, 0, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "Failed to post https_ota event"); - } + esp_https_ota_dispatch_event(ESP_HTTPS_OTA_DECRYPT_CB, NULL, 0); esp_err_t ret = handle->decrypt_cb(args, handle->decrypt_user_ctx); if (ret != ESP_OK) { @@ -208,9 +226,7 @@ static esp_err_t _ota_write(esp_https_ota_t *https_ota_handle, const void *buffe ESP_LOGD(TAG, "Written image length %d", https_ota_handle->binary_file_len); err = ESP_ERR_HTTPS_OTA_IN_PROGRESS; } - if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_WRITE_FLASH, NULL, 0, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "Failed to post https_ota event"); - } + esp_https_ota_dispatch_event(ESP_HTTPS_OTA_WRITE_FLASH, (void *)(&https_ota_handle->binary_file_len), sizeof(int)); #if CONFIG_ESP_HTTPS_OTA_DECRYPT_CB esp_https_ota_decrypt_cb_free_buf((void *) buffer); @@ -226,9 +242,7 @@ static bool is_server_verification_enabled(const esp_https_ota_config_t *ota_con esp_err_t esp_https_ota_begin(const esp_https_ota_config_t *ota_config, esp_https_ota_handle_t *handle) { - if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_START, NULL, 0, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "Failed to post https_ota event"); - } + esp_https_ota_dispatch_event(ESP_HTTPS_OTA_START, NULL, 0); esp_err_t err; @@ -313,9 +327,7 @@ esp_err_t esp_https_ota_begin(const esp_https_ota_config_t *ota_config, esp_http ESP_LOGE(TAG, "Failed to establish HTTP connection"); goto http_cleanup; } else { - if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_CONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "Failed to post https_ota event"); - } + esp_https_ota_dispatch_event(ESP_HTTPS_OTA_CONNECTED, NULL, 0); } if (!https_ota_handle->partial_http_download) { @@ -400,9 +412,7 @@ static esp_err_t read_header(esp_https_ota_t *handle) esp_err_t esp_https_ota_get_img_desc(esp_https_ota_handle_t https_ota_handle, esp_app_desc_t *new_app_info) { - if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_GET_IMG_DESC, NULL, 0, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "Failed to post https_ota event"); - } + esp_https_ota_dispatch_event(ESP_HTTPS_OTA_GET_IMG_DESC, NULL, 0); #if CONFIG_ESP_HTTPS_OTA_DECRYPT_CB // This API is not supported in case firmware image is encrypted in nature. @@ -436,11 +446,9 @@ esp_err_t esp_https_ota_get_img_desc(esp_https_ota_handle_t https_ota_handle, es static esp_err_t esp_ota_verify_chip_id(const void *arg) { - if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_VERIFY_CHIP_ID, NULL, 0, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "Failed to post https_ota event"); - } - esp_image_header_t *data = (esp_image_header_t *)(arg); + esp_https_ota_dispatch_event(ESP_HTTPS_OTA_VERIFY_CHIP_ID, (void *)(&data->chip_id), sizeof(esp_chip_id_t)); + if (data->chip_id != CONFIG_IDF_FIRMWARE_CHIP_ID) { ESP_LOGE(TAG, "Mismatch chip id, expected %d, found %d", CONFIG_IDF_FIRMWARE_CHIP_ID, data->chip_id); return ESP_ERR_INVALID_VERSION; @@ -628,24 +636,18 @@ esp_err_t esp_https_ota_finish(esp_https_ota_handle_t https_ota_handle) if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%x", err); } else { - if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION, NULL, 0, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "Failed to post https_ota event"); - } + esp_https_ota_dispatch_event(ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION, (void *)(&handle->update_partition->subtype), sizeof(esp_partition_subtype_t)); } } free(handle); - if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_FINISH, NULL, 0, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "Failed to post https_ota event"); - } + esp_https_ota_dispatch_event(ESP_HTTPS_OTA_FINISH, NULL, 0); return err; } esp_err_t esp_https_ota_abort(esp_https_ota_handle_t https_ota_handle) { - if (esp_event_post(ESP_HTTPS_OTA_EVENT, ESP_HTTPS_OTA_ABORT, NULL, 0, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "Failed to post https_ota event"); - } + esp_https_ota_dispatch_event(ESP_HTTPS_OTA_ABORT, NULL, 0); esp_https_ota_t *handle = (esp_https_ota_t *)https_ota_handle; if (handle == NULL) { 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 1869f90f4ff4..2b7cb218de77 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 @@ -38,7 +38,6 @@ extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end"); #define OTA_URL_SIZE 256 - /* Event handler for catching system events */ static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) @@ -55,16 +54,16 @@ static void event_handler(void* arg, esp_event_base_t event_base, ESP_LOGI(TAG, "Reading Image Description"); break; case ESP_HTTPS_OTA_VERIFY_CHIP_ID: - ESP_LOGI(TAG, "Verifying chip id of new image"); + ESP_LOGI(TAG, "Verifying chip id of new image: %d", *(esp_chip_id_t *)event_data); break; case ESP_HTTPS_OTA_DECRYPT_CB: ESP_LOGI(TAG, "Callback to decrypt function"); break; case ESP_HTTPS_OTA_WRITE_FLASH: - ESP_LOGD(TAG, "Writing to flash"); + ESP_LOGD(TAG, "Writing to flash: %d written", *(int *)event_data); break; case ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION: - ESP_LOGI(TAG, "Boot partition updated"); + ESP_LOGI(TAG, "Boot partition updated. Next Partition: %d", *(esp_partition_subtype_t *)event_data); break; case ESP_HTTPS_OTA_FINISH: ESP_LOGI(TAG, "OTA finish");