Skip to content

Commit

Permalink
Merge branch 'feature/esp_https_ota_events' into 'master'
Browse files Browse the repository at this point in the history
esp_https_ota: Added support for esp_events

See merge request espressif/esp-idf!20898
  • Loading branch information
mahavirj committed Nov 14, 2022
2 parents eae70a8 + a80dfe8 commit f727494
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 1 deletion.
2 changes: 1 addition & 1 deletion components/esp_https_ota/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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")
32 changes: 32 additions & 0 deletions components/esp_https_ota/include/esp_https_ota.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,42 @@
#include "esp_app_desc.h"
#include <sdkconfig.h>

#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, /*!< 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);

Expand Down
40 changes: 40 additions & 0 deletions components/esp_https_ota/src/esp_https_ota.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <errno.h>
#include <sys/param.h>

ESP_EVENT_DEFINE_BASE(ESP_HTTPS_OTA_EVENT);

#define IMAGE_HEADER_SIZE (1024)

/* This is kept sufficiently large enough to cover image format headers
Expand Down Expand Up @@ -168,9 +170,31 @@ 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)
{
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) {
ESP_LOGE(TAG, "Decrypt callback failed %d", ret);
Expand Down Expand Up @@ -202,6 +226,8 @@ 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;
}
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);
#endif
Expand All @@ -216,6 +242,8 @@ 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)
{
esp_https_ota_dispatch_event(ESP_HTTPS_OTA_START, NULL, 0);

esp_err_t err;

if (handle == NULL || ota_config == NULL || ota_config->http_config == NULL) {
Expand Down Expand Up @@ -298,6 +326,8 @@ 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 {
esp_https_ota_dispatch_event(ESP_HTTPS_OTA_CONNECTED, NULL, 0);
}

if (!https_ota_handle->partial_http_download) {
Expand Down Expand Up @@ -382,6 +412,8 @@ 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)
{
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.
// It is recommended to retrieve image description through decryption callback in application layer.
Expand Down Expand Up @@ -415,6 +447,8 @@ 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)
{
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;
Expand Down Expand Up @@ -601,14 +635,20 @@ 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 {
esp_https_ota_dispatch_event(ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION, (void *)(&handle->update_partition->subtype), sizeof(esp_partition_subtype_t));
}
}
free(handle);
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)
{
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) {
return ESP_ERR_INVALID_ARG;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,43 @@ 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: %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: %d written", *(int *)event_data);
break;
case ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION:
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");
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) {
Expand Down Expand Up @@ -192,6 +229,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.
Expand Down

0 comments on commit f727494

Please sign in to comment.