ESPHome  2024.11.0
ota_backend_esp_idf.cpp
Go to the documentation of this file.
1 #ifdef USE_ESP_IDF
2 #include "ota_backend_esp_idf.h"
3 
5 #include "esphome/core/defines.h"
6 
7 #include <esp_ota_ops.h>
8 #include <esp_task_wdt.h>
9 
10 #if ESP_IDF_VERSION_MAJOR >= 5
11 #include <spi_flash_mmap.h>
12 #endif
13 
14 namespace esphome {
15 namespace ota {
16 
17 std::unique_ptr<ota::OTABackend> make_ota_backend() { return make_unique<ota::IDFOTABackend>(); }
18 
20  this->partition_ = esp_ota_get_next_update_partition(nullptr);
21  if (this->partition_ == nullptr) {
23  }
24 
25 #if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
26  // The following function takes longer than the 5 seconds timeout of WDT
27 #if ESP_IDF_VERSION_MAJOR >= 5
28  esp_task_wdt_config_t wdtc;
29  wdtc.idle_core_mask = 0;
30 #if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
31  wdtc.idle_core_mask |= (1 << 0);
32 #endif
33 #if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
34  wdtc.idle_core_mask |= (1 << 1);
35 #endif
36  wdtc.timeout_ms = 15000;
37  wdtc.trigger_panic = false;
38  esp_task_wdt_reconfigure(&wdtc);
39 #else
40  esp_task_wdt_init(15, false);
41 #endif
42 #endif
43 
44  esp_err_t err = esp_ota_begin(this->partition_, image_size, &this->update_handle_);
45 
46 #if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
47  // Set the WDT back to the configured timeout
48 #if ESP_IDF_VERSION_MAJOR >= 5
49  wdtc.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000;
50  esp_task_wdt_reconfigure(&wdtc);
51 #else
52  esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false);
53 #endif
54 #endif
55 
56  if (err != ESP_OK) {
57  esp_ota_abort(this->update_handle_);
58  this->update_handle_ = 0;
59  if (err == ESP_ERR_INVALID_SIZE) {
61  } else if (err == ESP_ERR_FLASH_OP_TIMEOUT || err == ESP_ERR_FLASH_OP_FAIL) {
63  }
65  }
66  this->md5_.init();
67  return OTA_RESPONSE_OK;
68 }
69 
70 void IDFOTABackend::set_update_md5(const char *expected_md5) { memcpy(this->expected_bin_md5_, expected_md5, 32); }
71 
72 OTAResponseTypes IDFOTABackend::write(uint8_t *data, size_t len) {
73  esp_err_t err = esp_ota_write(this->update_handle_, data, len);
74  this->md5_.add(data, len);
75  if (err != ESP_OK) {
76  if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
78  } else if (err == ESP_ERR_FLASH_OP_TIMEOUT || err == ESP_ERR_FLASH_OP_FAIL) {
80  }
82  }
83  return OTA_RESPONSE_OK;
84 }
85 
87  this->md5_.calculate();
88  if (!this->md5_.equals_hex(this->expected_bin_md5_)) {
89  this->abort();
91  }
92  esp_err_t err = esp_ota_end(this->update_handle_);
93  this->update_handle_ = 0;
94  if (err == ESP_OK) {
95  err = esp_ota_set_boot_partition(this->partition_);
96  if (err == ESP_OK) {
97  return OTA_RESPONSE_OK;
98  }
99  }
100  if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
102  }
103  if (err == ESP_ERR_FLASH_OP_TIMEOUT || err == ESP_ERR_FLASH_OP_FAIL) {
105  }
107 }
108 
110  esp_ota_abort(this->update_handle_);
111  this->update_handle_ = 0;
112 }
113 
114 } // namespace ota
115 } // namespace esphome
116 #endif
void init()
Initialize a new MD5 digest computation.
Definition: md5.cpp:11
bool equals_hex(const char *expected)
Compare the digest against a provided hex-encoded digest (32 bytes).
Definition: md5.cpp:60
OTAResponseTypes begin(size_t image_size) override
void add(const uint8_t *data, size_t len)
Add bytes of data for the digest.
Definition: md5.cpp:16
std::unique_ptr< ota::OTABackend > make_ota_backend()
std::string size_t len
Definition: helpers.h:293
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
OTAResponseTypes write(uint8_t *data, size_t len) override
void calculate()
Compute the digest, based on the provided data.
Definition: md5.cpp:18
void set_update_md5(const char *md5) override
OTAResponseTypes end() override