ESPHome 2026.5.0-dev
Loading...
Searching...
No Matches
ota_backend_esp_idf.cpp
Go to the documentation of this file.
1#ifdef USE_ESP32
3
6#include "esphome/core/log.h"
7
8#include <esp_ota_ops.h>
9#include <esp_task_wdt.h>
10#include <spi_flash_mmap.h>
11
12namespace esphome::ota {
13
14static const char *const TAG = "ota.idf";
15
16std::unique_ptr<IDFOTABackend> make_ota_backend() { return make_unique<IDFOTABackend>(); }
17
19#ifdef USE_OTA_ROLLBACK
20 // If we're starting an OTA, the current boot is good enough - mark it valid
21 // to prevent rollback and allow the OTA to proceed even if the safe mode
22 // timer hasn't expired yet.
23 esp_ota_mark_app_valid_cancel_rollback();
24#endif
25
26 this->partition_ = esp_ota_get_next_update_partition(nullptr);
27 if (this->partition_ == nullptr) {
29 }
30
31#if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
32 // The following function takes longer than the 5 seconds timeout of WDT
33 esp_task_wdt_config_t wdtc;
34 wdtc.idle_core_mask = 0;
35#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
36 wdtc.idle_core_mask |= (1 << 0);
37#endif
38#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
39 wdtc.idle_core_mask |= (1 << 1);
40#endif
41 wdtc.timeout_ms = 15000;
42 wdtc.trigger_panic = false;
43 esp_task_wdt_reconfigure(&wdtc);
44#endif
45
46 esp_err_t err = esp_ota_begin(this->partition_, image_size, &this->update_handle_);
47
48#if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
49 // Set the WDT back to the configured timeout
50 wdtc.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000;
51 esp_task_wdt_reconfigure(&wdtc);
52#endif
53
54 if (err != ESP_OK) {
55 esp_ota_abort(this->update_handle_);
56 this->update_handle_ = 0;
57 if (err == ESP_ERR_INVALID_SIZE) {
59 } else if (err == ESP_ERR_FLASH_OP_TIMEOUT || err == ESP_ERR_FLASH_OP_FAIL) {
61 }
63 }
64 this->md5_.init();
65 return OTA_RESPONSE_OK;
66}
67
68void IDFOTABackend::set_update_md5(const char *expected_md5) {
69 memcpy(this->expected_bin_md5_, expected_md5, 32);
70 this->md5_set_ = true;
71}
72
74 esp_err_t err = esp_ota_write(this->update_handle_, data, len);
75 this->md5_.add(data, len);
76 if (err != ESP_OK) {
77 if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
79 } else if (err == ESP_ERR_FLASH_OP_TIMEOUT || err == ESP_ERR_FLASH_OP_FAIL) {
81 }
83 }
84 return OTA_RESPONSE_OK;
85}
86
88 if (this->md5_set_) {
89 this->md5_.calculate();
90 if (!this->md5_.equals_hex(this->expected_bin_md5_)) {
91 this->abort();
93 }
94 }
95 esp_err_t err = esp_ota_end(this->update_handle_);
96 this->update_handle_ = 0;
97 if (err == ESP_OK) {
98 err = esp_ota_set_boot_partition(this->partition_);
99 if (err == ESP_OK) {
100 return OTA_RESPONSE_OK;
101 }
102 }
103 if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
104#ifdef USE_OTA_SIGNED_VERIFICATION
105 ESP_LOGE(TAG, "OTA validation failed (err=0x%X) - possible signature verification failure", err);
107#else
109#endif
110 }
111 if (err == ESP_ERR_FLASH_OP_TIMEOUT || err == ESP_ERR_FLASH_OP_FAIL) {
113 }
115}
116
118 esp_ota_abort(this->update_handle_);
119 this->update_handle_ = 0;
120}
121
122} // namespace esphome::ota
123#endif // USE_ESP32
bool equals_hex(const char *expected)
Compare the hash against a provided hex-encoded hash.
Definition hash_base.h:35
void calculate() override
Compute the digest, based on the provided data.
Definition md5.cpp:17
void add(const uint8_t *data, size_t len) override
Add bytes of data for the digest.
Definition md5.cpp:15
void init() override
Initialize a new MD5 digest computation.
Definition md5.cpp:10
void set_update_md5(const char *md5)
OTAResponseTypes write(uint8_t *data, size_t len)
OTAResponseTypes begin(size_t image_size)
@ OTA_RESPONSE_ERROR_MD5_MISMATCH
Definition ota_backend.h:38
@ OTA_RESPONSE_ERROR_ESP32_NOT_ENOUGH_SPACE
Definition ota_backend.h:36
@ OTA_RESPONSE_ERROR_WRITING_FLASH
Definition ota_backend.h:30
@ OTA_RESPONSE_ERROR_UPDATE_END
Definition ota_backend.h:31
@ OTA_RESPONSE_ERROR_SIGNATURE_INVALID
Definition ota_backend.h:40
@ OTA_RESPONSE_ERROR_UNKNOWN
Definition ota_backend.h:41
@ OTA_RESPONSE_ERROR_NO_UPDATE_PARTITION
Definition ota_backend.h:37
@ OTA_RESPONSE_ERROR_MAGIC
Definition ota_backend.h:27
std::unique_ptr< ArduinoLibreTinyOTABackend > make_ota_backend()
std::string size_t len
Definition helpers.h:1045