ESPHome  2024.4.1
ota_backend_esp_idf.cpp
Go to the documentation of this file.
1 #include "esphome/core/defines.h"
2 #ifdef USE_ESP_IDF
3 
4 #include <esp_task_wdt.h>
5 
6 #include "ota_backend_esp_idf.h"
7 #include "ota_component.h"
8 #include <esp_ota_ops.h>
10 
11 #if ESP_IDF_VERSION_MAJOR >= 5
12 #include <spi_flash_mmap.h>
13 #endif
14 
15 namespace esphome {
16 namespace ota {
17 
19  this->partition_ = esp_ota_get_next_update_partition(nullptr);
20  if (this->partition_ == nullptr) {
22  }
23 
24 #if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
25  // The following function takes longer than the 5 seconds timeout of WDT
26 #if ESP_IDF_VERSION_MAJOR >= 5
27  esp_task_wdt_config_t wdtc;
28  wdtc.idle_core_mask = 0;
29 #if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
30  wdtc.idle_core_mask |= (1 << 0);
31 #endif
32 #if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
33  wdtc.idle_core_mask |= (1 << 1);
34 #endif
35  wdtc.timeout_ms = 15000;
36  wdtc.trigger_panic = false;
37  esp_task_wdt_reconfigure(&wdtc);
38 #else
39  esp_task_wdt_init(15, false);
40 #endif
41 #endif
42 
43  esp_err_t err = esp_ota_begin(this->partition_, image_size, &this->update_handle_);
44 
45 #if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
46  // Set the WDT back to the configured timeout
47 #if ESP_IDF_VERSION_MAJOR >= 5
48  wdtc.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000;
49  esp_task_wdt_reconfigure(&wdtc);
50 #else
51  esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false);
52 #endif
53 #endif
54 
55  if (err != ESP_OK) {
56  esp_ota_abort(this->update_handle_);
57  this->update_handle_ = 0;
58  if (err == ESP_ERR_INVALID_SIZE) {
60  } else if (err == ESP_ERR_FLASH_OP_TIMEOUT || err == ESP_ERR_FLASH_OP_FAIL) {
62  }
64  }
65  this->md5_.init();
66  return OTA_RESPONSE_OK;
67 }
68 
69 void IDFOTABackend::set_update_md5(const char *expected_md5) { memcpy(this->expected_bin_md5_, expected_md5, 32); }
70 
71 OTAResponseTypes IDFOTABackend::write(uint8_t *data, size_t len) {
72  esp_err_t err = esp_ota_write(this->update_handle_, data, len);
73  this->md5_.add(data, len);
74  if (err != ESP_OK) {
75  if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
77  } else if (err == ESP_ERR_FLASH_OP_TIMEOUT || err == ESP_ERR_FLASH_OP_FAIL) {
79  }
81  }
82  return OTA_RESPONSE_OK;
83 }
84 
86  this->md5_.calculate();
87  if (!this->md5_.equals_hex(this->expected_bin_md5_)) {
88  this->abort();
90  }
91  esp_err_t err = esp_ota_end(this->update_handle_);
92  this->update_handle_ = 0;
93  if (err == ESP_OK) {
94  err = esp_ota_set_boot_partition(this->partition_);
95  if (err == ESP_OK) {
96  return OTA_RESPONSE_OK;
97  }
98  }
99  if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
101  }
102  if (err == ESP_ERR_FLASH_OP_TIMEOUT || err == ESP_ERR_FLASH_OP_FAIL) {
104  }
106 }
107 
109  esp_ota_abort(this->update_handle_);
110  this->update_handle_ = 0;
111 }
112 
113 } // namespace ota
114 } // namespace esphome
115 #endif
void init()
Initialize a new MD5 digest computation.
Definition: md5.cpp:10
bool equals_hex(const char *expected)
Compare the digest against a provided hex-encoded digest (32 bytes).
Definition: md5.cpp:59
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:15
std::string size_t len
Definition: helpers.h:292
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
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:17
void set_update_md5(const char *md5) override
OTAResponseTypes end() override