ESP OTA Service

[中文]

Introduction

OTA Service is a subclass of ESP Service that implements a modular, extensible over-the-air firmware upgrade pipeline. It splits the upgrade process into four independent abstraction layers: data source, write target, version checker, and integrity verifier. Transport methods such as HTTP/HTTPS, filesystem, and BLE can be combined with write targets such as the application partition, data partition, and bootloader, without modifying the service implementation.

Feature List

  • Multiple data sources for download: HTTP/HTTPS, the local filesystem, and a BLE GATT peripheral that follows the official ESP BLE OTA APP protocol (optional); custom transports such as UART or SPI can also be integrated via the esp_ota_service_source_t interface

  • Multiple write targets: the application partition, raw data partition, and bootloader (optional); custom write targets can also be integrated via the esp_ota_service_target_t interface

  • Version check before download: three built-in checkers — application image header, semantic version header, and JSON manifest — automatically skip items that are already up to date

  • Streaming integrity verification: built-in SHA-256 and MD5 verifiers; signature or CRC schemes can also be integrated via the esp_ota_service_verifier_t interface

  • NVS-based resume support: the download offset is saved every few KB, allowing resumption from the breakpoint after a failure or reboot

  • Rollback support: esp_ota_service_confirm_update() / esp_ota_service_rollback() and pending-verify state detection (requires CONFIG_OTA_ENABLE_ROLLBACK)

  • Pause/resume during download: a running session can directly call esp_service_pause() / esp_service_resume()

  • The event bus covers 6 event types — session start, version check, item start/progress/end, and session end — without imposing a reboot policy

Technical Deep Dive

Pipeline Abstraction

Each esp_ota_upgrade_item_t describes one partition upgrade, and consists of two mandatory interfaces, source and target, plus two optional interfaces, checker and verifier. All four interface types are function-pointer structures that can be freely combined once implemented. The service takes ownership of every component in the list via esp_ota_service_set_upgrade_list(), so the caller should not call their destroy() functions directly afterward.

        flowchart TD
    Start([Item start]) --> Chk{checker?}
    Chk -- No --> Open[source.open]
    Chk -- Yes --> Check[checker.check]
    Check -- Not newer --> Skip([Skip])
    Check -- Newer version --> Open
    Open --> Vb{verifier?}
    Vb -- No --> TOpen[target.open]
    Vb -- Yes --> VBegin[verifier.verify_begin]
    VBegin -- Rejected --> Skip
    VBegin -- Accepted --> TOpen
    TOpen --> Loop{source.read loop}
    Loop --> Update[verifier.verify_update]
    Update -- Verification failed --> Fail([Abort])
    Update -- Passed --> Write[target.write] --> Loop
    Loop -- EOF --> Vf{verifier?}
    Vf -- No --> Commit[target.commit]
    Vf -- Yes --> VFinish[verifier.verify_finish]
    VFinish -- Verification failed --> Fail
    VFinish -- Passed --> Commit
    

Calling esp_service_start() returns immediately; the worker task runs in the background and reports progress via events, without blocking the caller’s task.

#include "esp_ota_service_default.h"  /* Aggregates the built-in source/target/checker/verifier headers */

esp_ota_service_t *svc = NULL;
esp_ota_service_create(&(esp_ota_service_cfg_t)ESP_OTA_SERVICE_CFG_DEFAULT(), &svc);

esp_ota_upgrade_item_t item = {
    .uri      = "http://example.com/firmware.bin",
    .source   = http_source,
    .target   = app_target,
    .checker  = manifest_checker,
    .verifier = sha256_verifier,
};
esp_ota_service_set_upgrade_list(svc, &item, 1);

esp_service_event_subscribe((esp_service_t *)svc, &sub);
esp_service_start((esp_service_t *)svc);

Important

After calling esp_ota_service_set_upgrade_list(), ownership of every source, target, checker, and verifier in the list is transferred to the service, even if the call fails; do not call their destroy() functions directly afterward — esp_ota_service_destroy() will release them uniformly.

Choosing the Right Combination

Component selection for common scenarios: for HTTP OTA combined with manifest version checking and SHA-256 verification, use esp_ota_service_source_http_create() + esp_ota_service_checker_manifest_create() + esp_ota_service_verifier_sha256_create() + esp_ota_service_target_app_create(); the verifier can be omitted when only version checking is needed without streaming verification; for SD card or USB flash drive deployment, use esp_ota_service_source_fs_create() together with the same application target; for data partition upgrades, use esp_ota_service_checker_data_version_create() and esp_ota_service_target_data_create() instead. For batch upgrades across multiple partitions, a single session can configure separate items for the application partition and data partition, sharing the same event stream.

Events and Progress

After subscribing via esp_service_event_subscribe(), the payload field of the adf_event_t received in each callback points to an esp_ota_service_event_t. The id field must be read first, followed by accessing the corresponding union branch: ESP_OTA_SERVICE_EVT_ITEM_VER_CHECK reports the version check result, ESP_OTA_SERVICE_EVT_ITEM_PROGRESS updates the downloaded byte count approximately once per second, ESP_OTA_SERVICE_EVT_ITEM_END carries the success/skip/failure result of a single partition, and ESP_OTA_SERVICE_EVT_SESSION_END carries the summary statistics for the entire session. The caller can also directly poll the download progress percentage of the current item using esp_ota_service_get_progress().

Resume and Rollback

When CONFIG_OTA_ENABLE_RESUME (enabled by default) is turned on, the service saves the download offset to NVS at a fixed byte interval. For data sources that do not implement seek() (such as BLE) or targets that do not implement set_write_offset() (the data partition or bootloader), the resumable field of the corresponding item must be set to false; otherwise esp_ota_service_set_upgrade_list() returns ESP_ERR_NOT_SUPPORTED. When CONFIG_OTA_ENABLE_ROLLBACK is enabled, after the new firmware boots it should first check whether it is in the pending-verify state using esp_ota_service_is_pending_verify(), and call esp_ota_service_confirm_update() to cancel the rollback timer once self-testing passes; otherwise every reboot will trigger an automatic rollback.

Application Examples

  • examples/ota_http/ demonstrates HTTP + manifest version checking + SHA-256 verification + resume support

  • examples/ota_fs/ demonstrates offline deployment from an SD card/USB flash drive and batch upgrades across multiple partitions

  • examples/ota_ble/ demonstrates BLE GATT firmware push in scenarios without Wi-Fi

FAQ

Q1: resumable is set to true, but ESP_ERR_NOT_SUPPORTED is still returned. Why?

The data source does not implement seek(), or the write target does not implement set_write_offset(). The data partition and bootloader targets erase the entire region during open(), so they inherently do not support resume; currently, only the application partition target, together with data sources that support random-access seek, can resume.

Q2: How can bricking be avoided after a failed upgrade?

Application partition upgrades rely on the A/B dual-image mechanism, allowing a fallback to the old partition on failure. However, bootloader OTA (CONFIG_OTA_ENABLE_BOOTLOADER_OTA) writes through a staging partition and provides no atomicity guarantee; a power loss during the copy process carries a risk of bricking the device, so additional evaluation and a fallback plan are required before mass production.

API Reference

Header File

Functions

esp_err_t esp_ota_service_create(const esp_ota_service_cfg_t *cfg, esp_ota_service_t **out_svc)

Create and initialise an OTA service instance.

    Allocates the service object, initialises the ADF service base, and
    creates the internal stop semaphore.  No network or flash operations occur.
Parameters:
  • cfg[in] Service configuration

  • out_svc[out] Receives the created service handle

Returns:

  • ESP_OK On success

  • ESP_ERR_NO_MEM On allocation failure (service object or stop semaphore)

  • ESP_ERR_INVALID_ARG If cfg or out_svc is NULL, or write_chunk_size / stop_timeout_ms in cfg is invalid

  • Other Error code returned by esp_service_init() on ADF base initialisation failure

esp_err_t esp_ota_service_destroy(esp_ota_service_t *svc)

Destroy an OTA service instance and free all resources.

    Calls esp_service_stop() to abort any in-progress upgrade, destroys the
    source/target/verifier/checker instances in the current upgrade list, deinits the
    ADF service base, and frees the service object.
Parameters:

svc[in] Service handle obtained from esp_ota_service_create()

Returns:

  • ESP_OK On success

  • ESP_ERR_INVALID_ARG If svc is NULL

esp_err_t esp_ota_service_set_upgrade_list(esp_ota_service_t *svc, const esp_ota_upgrade_item_t *list, int count)

Set (or replace) the upgrade item list.

    The service makes a shallow copy of the list array and deep-copies the
    @c uri and @c partition_label strings. The @c source / @c target /
    @c verifier / @c checker pointers inside each item are owned by the
    service from the moment this function is ENTERED — the caller must not
    destroy them afterwards, even if the call fails. If validation or
    allocation fails, the service destroys every item's source/target/
    verifier/checker before returning.

    If a previous list exists, its source/target/verifier/checker destroy()
    functions are called before the list is replaced. Any saved NVS resume
    records are cleared at this point, because the new list may not match
    the previous item layout.

    Allowed only while the service is in INITIALIZED or PAUSED. Not allowed
    in RUNNING while the worker is downloading.
Parameters:
  • svc[in] Service instance

  • list[in] Array of upgrade item descriptors

  • count[in] Number of items in the array (must be > 0)

Returns:

  • ESP_OK On success

  • ESP_ERR_INVALID_ARG If svc/list is NULL, count <= 0, item uri/source/target is NULL, or a uri exceeds the resume store’s capacity (255 chars)

  • ESP_ERR_INVALID_STATE If called while the service is neither INITIALIZED nor PAUSED

  • ESP_ERR_NOT_SUPPORTED If item.resumable=true but the source has no seek() or the target has no set_write_offset() (data / bootloader targets cannot resume)

  • ESP_ERR_NO_MEM If the list or deep-copied strings cannot be allocated

esp_err_t esp_ota_service_check_update(esp_ota_service_t *svc, int item_index, esp_ota_service_update_info_t *out_info)

Check if a newer firmware is available without performing OTA.

    Calls @c checker->check() on the item at @a item_index. No flash write.
    Requires @c esp_ota_service_set_upgrade_list() first, and the item must have a
    non-NULL @c checker.
Parameters:
  • svc[in] Service instance

  • item_index[in] Index into the upgrade list (0-based)

  • out_info[out] Receives update information

Returns:

  • ESP_OK On success (inspect out_info->upgrade_available)

  • ESP_ERR_INVALID_ARG If svc or out_info is NULL, item_index is invalid, upgrade list is unset, or item’s checker is NULL

  • Other Error from checker->check()

esp_err_t esp_ota_service_get_progress(const esp_ota_service_t *svc, uint32_t *out_written, uint32_t *out_total, int32_t *out_percent)

Query current download progress.

    Values reflect the item currently being processed.
Parameters:
  • svc[in] Service instance

  • out_written[out] Bytes written so far for the current item; NULL to omit

  • out_total[out] Total bytes for the current item (UINT32_MAX if unknown); NULL to omit

  • out_percent[out] Approximate progress 0–100 for the current item from out_written / out_total; -1 if total size is unknown; NULL to omit

Returns:

  • ESP_OK On success

  • ESP_ERR_INVALID_ARG If svc is NULL

esp_err_t esp_ota_service_confirm_update(void)

Confirm that the currently running OTA image is valid.

    Call this after verifying that the new firmware works correctly.
    Cancels the automatic rollback that would occur on next reboot.
    Operates only on the currently running application partition (no slot
    or item index is passed); IDF must report ESP_OTA_IMG_PENDING_VERIFY there.
    Only effective when CONFIG_OTA_ENABLE_ROLLBACK is enabled.
Returns:

  • ESP_OK On success (rollback cancelled)

  • ESP_ERR_INVALID_STATE If the running image is not pending verification

  • ESP_ERR_NOT_SUPPORTED If CONFIG_OTA_ENABLE_ROLLBACK is disabled

  • Other Error code returned by esp_ota_mark_app_valid_cancel_rollback() on failure

esp_err_t esp_ota_service_rollback(void)

Mark current image as invalid and reboot to the previous firmware.

Note

Does not return on success — the device reboots.

Returns:

  • ESP_ERR_NOT_SUPPORTED If CONFIG_OTA_ENABLE_ROLLBACK is disabled

  • Other Error code returned by esp_ota_mark_app_invalid_rollback_and_reboot() on failure

esp_err_t esp_ota_service_is_pending_verify(bool *out_pending)

Check whether the currently running image is in ESP_OTA_IMG_PENDING_VERIFY.

    Safe to call at any time from any task.  Does not depend on an OTA service handle
    and does not allocate.  Intended to be called early in @c app_main() so the
    application can run its self-test and resolve the state with
    @c esp_ota_service_confirm_update() or @c esp_ota_service_rollback() before any
    subsequent reset would otherwise trigger bootloader auto-rollback.
Parameters:

out_pending[out] Receives true when the running image needs confirmation.

Returns:

  • ESP_OK On success (inspect *out_pending)

  • ESP_ERR_INVALID_ARG If out_pending is NULL

  • ESP_ERR_INVALID_STATE If esp_ota_get_running_partition() returned NULL

  • ESP_ERR_NOT_SUPPORTED If CONFIG_OTA_ENABLE_ROLLBACK is disabled; *out_pending is set to false for caller convenience

  • Other Error returned by esp_ota_get_state_partition() on failure

Structures

struct esp_ota_service_event_t

OTA service event payload.

    Published on the service-bound Event Hub; subscribe with
    esp_service_event_subscribe((esp_service_t *)svc, &info).  The handler's
    @c adf_event_t::payload is a heap @c esp_ota_service_event_t owned by the hub (including
    a deep copy of @c item_label); both stay valid until the hub releases it.

    @c item_index == -1 marks a session-scoped event (@c SESSION_BEGIN, and
    @c SESSION_END on normal completion); when @c session_end.aborted is true,
    @c item_index carries the in-progress list index.

    Inspect @c id first, then read the matching union branch (reading the wrong
    branch is undefined):

     - SESSION_BEGIN  : no union field
     - ITEM_VER_CHECK : @c ver_check, @c error (checker outcome)
     - ITEM_BEGIN     : no union field
     - ITEM_PROGRESS  : @c progress
     - ITEM_END       : @c item_end, @c error
     - SESSION_END    : @c session_end, @c error

Public Members

esp_ota_service_event_id_t id

Event identifier

esp_err_t error

Semantics depend on id (e.g. ITEM_VER_CHECK checker result; ITEM_PROGRESS is ESP_OK; ITEM_END carries skip / fail / OK).

int item_index

Upgrade-list index; -1 when the event is session-scoped (SESSION_BEGIN, and SESSION_END on normal completion).

const char *item_label

Partition label for that item; deep copy in payload. May be NULL.

uint32_t bytes_written

Bytes written so far for the current item.

uint32_t total_bytes

Total bytes for the current item (UINT32_MAX if unknown).

struct esp_ota_service_event_t::[anonymous]::[anonymous] progress

ESP_OTA_SERVICE_EVT_ITEM_PROGRESS

esp_ota_service_item_status_t status

OK / SKIPPED / FAILED

esp_ota_service_item_end_reason_t reason

ESP_OTA_SERVICE_ITEM_END_REASON_NONE when status is OK; otherwise coarse class

struct esp_ota_service_event_t::[anonymous]::[anonymous] item_end

ESP_OTA_SERVICE_EVT_ITEM_END

uint16_t success_count

Items with ESP_OTA_SERVICE_ITEM_STATUS_OK

uint16_t failed_count

Items with ESP_OTA_SERVICE_ITEM_STATUS_FAILED

uint16_t skipped_count

Items with ESP_OTA_SERVICE_ITEM_STATUS_SKIPPED

bool aborted

True when stopped by esp_service_stop()

struct esp_ota_service_event_t::[anonymous]::[anonymous] session_end

ESP_OTA_SERVICE_EVT_SESSION_END

uint32_t image_size

Incoming image size, or UINT32_MAX if unknown.

bool upgrade_available

If error != ESP_OK: always false (ignore for outcome). If error == ESP_OK: true = will upgrade, false = not newer.

struct esp_ota_service_event_t::[anonymous]::[anonymous] ver_check

ESP_OTA_SERVICE_EVT_ITEM_VER_CHECK

struct esp_ota_upgrade_item

Descriptor for a single partition upgrade.

    @c uri and @c partition_label are deep-copied, so stack-allocated items
    are safe.  Ownership of @c source / @c target / @c verifier / @c checker
    transfers to the service when @c esp_ota_service_set_upgrade_list() is entered:
    their @c destroy() runs when the list is replaced, the service is destroyed,
    or validation fails (set @c destroy = NULL to opt out).

    When @c checker is non-NULL, the worker runs a header-only version check
    before downloading and emits @c ESP_OTA_SERVICE_EVT_ITEM_VER_CHECK.  If the check
    reports @c !upgrade_available with @c error == ESP_OK, the item skips
    @c ITEM_BEGIN / @c ITEM_END.  The worker never loops on a single item.

Public Members

const char *uri

Passed to source->open(). Deep-copied. Required.

const char *partition_label

Passed to target->open(). Deep-copied. NULL selects the next OTA app slot. For esp_ota_service_target_data_create(), a typical image prefixes the payload with a 4-byte little-endian header: esp_ota_service_version_pack_semver() of the same semver string as esp_app_desc_t::version (see examples/ota_fs).

esp_ota_service_source_t *source

Data stream source for download. Required.

esp_ota_service_target_t *target

Write target. Required.

esp_ota_service_verifier_t *verifier

Optional streaming integrity verifier (SHA256, signature, etc.). NULL = no integrity verification during download.

esp_ota_service_checker_t *checker

Optional pre-download update checker. NULL = skip version check. Use esp_ota_service_checker_app_create() for app images, esp_ota_service_checker_data_version_create() for data partitions, esp_ota_service_checker_manifest_create() for JSON manifests, or implement esp_ota_service_checker_t for custom formats.

bool skip_on_fail

If true, continue to the next item on failure. If false (default), abort the entire session.

bool resumable

Enable NVS-based resume on failure/reboot. Requires source->seek and target->set_write_offset to be implemented; otherwise esp_ota_service_set_upgrade_list() returns ESP_ERR_NOT_SUPPORTED. Data-partition and bootloader targets erase the whole partition on open() and therefore cannot be resumed: only the app target and sources with random-access seek currently qualify.

struct esp_ota_service_task_cfg_t

Worker task configuration for the OTA download task.

    This task is distinct from the ADF service command-processing task.
    It performs the actual source read, verifier update, and target write loop.

Public Members

uint32_t stack_size

Worker task stack size in bytes. 0 = use ESP_OTA_SERVICE_DEFAULT_WORKER_STACK_SIZE.

uint8_t priority

Worker task FreeRTOS priority. 0 = use ESP_OTA_SERVICE_DEFAULT_WORKER_PRIORITY.

int8_t core_id

Core affinity. -1 = any core.

struct esp_ota_service_cfg_t

OTA service configuration.

Public Members

const char *name

ADF service / Event Hub domain name; NULL = ESP_OTA_SERVICE_DOMAIN

esp_ota_service_task_cfg_t worker_task

OTA download worker task config.

uint32_t write_chunk_size

Per-chunk read/write buffer size in bytes. 0 = ESP_OTA_SERVICE_DEFAULT_WRITE_CHUNK_SIZE. Valid range when non-zero: 512-65536.

uint32_t stop_timeout_ms

Max wait in ms for worker to exit in esp_service_stop(). 0 = ESP_OTA_SERVICE_DEFAULT_STOP_TIMEOUT_MS. Minimum when non-zero: 1000.

Macros

ESP_OTA_SERVICE_DOMAIN

Event Hub domain name for OTA service.

ESP_OTA_SERVICE_DEFAULT_WORKER_STACK_SIZE

Default OTA worker stack when esp_ota_service_task_cfg_t.stack_size is 0.

ESP_OTA_SERVICE_DEFAULT_WORKER_PRIORITY

Default OTA worker priority when esp_ota_service_task_cfg_t.priority is 0.

ESP_OTA_SERVICE_DEFAULT_WRITE_CHUNK_SIZE

Default read/write chunk size when esp_ota_service_cfg_t.write_chunk_size is 0.

ESP_OTA_SERVICE_DEFAULT_STOP_TIMEOUT_MS

Default esp_service_stop() wait when esp_ota_service_cfg_t.stop_timeout_ms is 0.

ESP_OTA_SERVICE_CFG_DEFAULT()

Convenience initialiser for esp_ota_service_cfg_t.

Type Definitions

typedef struct esp_ota_service esp_ota_service_t

Opaque OTA service handle (definition in esp_ota_service.c)

    The concrete object embeds @c esp_service_t as its first member: the handle pointer
    has the same address as that base.  ADF entry points take @c esp_service_t *, so use
    @c (esp_service_t *)svc only to satisfy the C type system (e.g. esp_service_event_subscribe()).
typedef struct esp_ota_upgrade_item esp_ota_upgrade_item_t

Descriptor for a single partition upgrade.

    @c uri and @c partition_label are deep-copied, so stack-allocated items
    are safe.  Ownership of @c source / @c target / @c verifier / @c checker
    transfers to the service when @c esp_ota_service_set_upgrade_list() is entered:
    their @c destroy() runs when the list is replaced, the service is destroyed,
    or validation fails (set @c destroy = NULL to opt out).

    When @c checker is non-NULL, the worker runs a header-only version check
    before downloading and emits @c ESP_OTA_SERVICE_EVT_ITEM_VER_CHECK.  If the check
    reports @c !upgrade_available with @c error == ESP_OK, the item skips
    @c ITEM_BEGIN / @c ITEM_END.  The worker never loops on a single item.
typedef esp_ota_service_check_result_t esp_ota_service_update_info_t

Information about available firmware update.

    Same layout as @c esp_ota_service_check_result_t.

Enumerations

enum esp_ota_service_event_id_t

OTA service event identifiers.

    Enumerators are listed in the typical emission order within one session.
    IDs start at 2 (0 is invalid for @c esp_service_publish_event(), 1 is
    reserved for @c ESP_SERVICE_EVENT_STATE_CHANGED); use the symbols — numeric
    values are not stable across releases.  @c ESP_OTA_SERVICE_EVT_MAX is a non-event
    upper-bound sentinel and is never published.

    @c ESP_OTA_SERVICE_EVT_ITEM_VER_CHECK fires only when @c checker is non-NULL; read
    @c error first, then @c ver_check.upgrade_available:
      - @c error != ESP_OK            — check failed; @c ITEM_END follows (no @c ITEM_BEGIN).
      - @c error == ESP_OK, not newer — skipped; neither @c ITEM_BEGIN nor @c ITEM_END.
      - @c error == ESP_OK, newer     — download proceeds with @c ITEM_BEGIN.

Values:

enumerator ESP_OTA_SERVICE_EVT_SESSION_BEGIN

OTA session started (before first item)

enumerator ESP_OTA_SERVICE_EVT_ITEM_VER_CHECK

Pre-download checker finished; see ver_check and error.

enumerator ESP_OTA_SERVICE_EVT_ITEM_BEGIN

Read/write loop about to start (after source/target open(), optional verifier verify_begin(), and internal resume setup). No union payload; only item_index / item_label.

enumerator ESP_OTA_SERVICE_EVT_ITEM_PROGRESS

Progress update for the current item (throttled, ~1s)

enumerator ESP_OTA_SERVICE_EVT_ITEM_END

Single partition upgrade finished. Payload carries item_end.status (OK / SKIPPED / FAILED), item_end.reason (classification when status is not OK), and error (ESP_OK for OK and SKIPPED; pipeline / checker / abort codes when FAILED).

enumerator ESP_OTA_SERVICE_EVT_SESSION_END

OTA session finished. Payload carries success/failed/skipped counts and aborted flag; consumers should handle this single event instead of three disjoint outcomes.

enumerator ESP_OTA_SERVICE_EVT_MAX

Sentinel; not a real event.

enum esp_ota_service_item_status_t

Per-item outcome reported in ESP_OTA_SERVICE_EVT_ITEM_END.

Values:

enumerator ESP_OTA_SERVICE_ITEM_STATUS_OK

Item written and committed successfully.

enumerator ESP_OTA_SERVICE_ITEM_STATUS_SKIPPED

Item was deliberately not applied; see esp_ota_service_item_end_reason_t.

enumerator ESP_OTA_SERVICE_ITEM_STATUS_FAILED

Item failed; esp_ota_service_event_t::error carries the reason.

enum esp_ota_service_item_end_reason_t

Coarse outcome detail for ESP_OTA_SERVICE_EVT_ITEM_END.

    When @c item_end.status is @c ESP_OTA_SERVICE_ITEM_STATUS_OK, the value is @c ESP_OTA_SERVICE_ITEM_END_REASON_NONE.
    For @c ESP_OTA_SERVICE_ITEM_STATUS_FAILED and @c ESP_OTA_SERVICE_ITEM_STATUS_SKIPPED, use @c reason together with
    @c esp_ota_service_event_t::error (especially for failures — @c error holds the precise @c esp_err_t).

Values:

enumerator ESP_OTA_SERVICE_ITEM_END_REASON_NONE

No extra classification (success path).

enumerator ESP_OTA_SERVICE_ITEM_END_REASON_VERIFIER_REJECTED

SKIPPED: streaming verifier rejected the image at verify_begin() or verify_finish().

enumerator ESP_OTA_SERVICE_ITEM_END_REASON_CHECK_FAILED

FAILED: pre-download checker returned an error.

enumerator ESP_OTA_SERVICE_ITEM_END_REASON_ABORTED

FAILED: session stop / user abort before item finished.

enumerator ESP_OTA_SERVICE_ITEM_END_REASON_PIPELINE

FAILED: download / write / commit path (error).

Header File