ESPHome 2026.10.2
Loading...
Searching...
No Matches
ota_backend_arduino_libretiny.cpp
Go to the documentation of this file.
1#ifdef USE_LIBRETINY
3#include "ota_backend.h"
4
7#include "esphome/core/log.h"
8
9#include <algorithm>
10
11#include <Update.h>
12
13namespace esphome::ota {
14
15static const char *const TAG = "ota";
16
17std::unique_ptr<ArduinoLibreTinyOTABackend> make_ota_backend() { return make_unique<ArduinoLibreTinyOTABackend>(); }
18
20 if (ota_type != OTA_TYPE_UPDATE_APP) {
22 }
23 // Handle UPDATE_SIZE_UNKNOWN (0) which is used by web server OTA
24 // where the exact firmware size is unknown due to multipart encoding
25 if (image_size == 0) {
26 image_size = UPDATE_SIZE_UNKNOWN;
27 }
28 bool ret = Update.begin(image_size, U_FLASH);
29 if (ret) {
30 this->md5_.init();
31 return OTA_RESPONSE_OK;
32 }
33
34 uint8_t error = Update.getError();
35 if (error == UPDATE_ERROR_SIZE)
37
38 ESP_LOGE(TAG, "Begin error: %d", error);
39
41}
42
44 // Checked in end(); a checksum that does not parse refuses the update
45 this->md5_set_ = true;
46 this->md5_parsed_ = parse_hex(md5, this->expected_md5_, 16);
47}
48
49bool ArduinoLibreTinyOTABackend::feed_(const uint8_t *data, size_t len) {
50 while (len != 0) {
51 const size_t chunk = std::min(len, MAX_FEED);
52 if (Update.write(data, chunk) != chunk) {
53 ESP_LOGE(TAG, "Write error: %d", Update.getError());
54 return false;
55 }
56 this->wrote_ = true;
57 data += chunk;
58 len -= chunk;
59 }
60 return true;
61}
62
64 if (len == 0)
65 return OTA_RESPONSE_OK;
66 this->md5_.add(data, len);
67 // Keep the last byte back so the image stays incomplete until end()
68 if ((this->has_pending_ && !this->feed_(&this->pending_, 1)) || !this->feed_(data, len - 1))
70 this->pending_ = data[len - 1];
71 this->has_pending_ = true;
72 return OTA_RESPONSE_OK;
73}
74
76 if (this->md5_set_) {
77 this->md5_.calculate();
78 if (!this->md5_parsed_ || !this->md5_.equals_bytes(this->expected_md5_)) {
79 ESP_LOGE(TAG, "MD5 mismatch");
81 }
82 }
83 if (this->has_pending_ && !this->feed_(&this->pending_, 1))
85 // Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
86 // This matches the behavior of the old web_server OTA implementation
87 if (Update.end(!this->md5_set_)) {
88 // Nothing for a later abort() to revert
89 this->wrote_ = false;
90 return OTA_RESPONSE_OK;
91 }
92
93 uint8_t error = Update.getError();
94 ESP_LOGE(TAG, "End error: %d", error);
95
97}
98
100 Update.abort();
101 // Bootloaders take a written image LibreTiny never marked: RTL8720C boots the
102 // valid one with the higher serial number, BK72xx and LN882H install a
103 // complete download. On LN882H the device image ends before the flasher
104 // blocks of a full UF2, so the held-back byte does not keep it incomplete.
105 if (!this->wrote_)
106 return;
107#ifdef USE_LN882X
108 // lt_ota_switch() ignores revert here; erasing the header voids the download
109 const bool reverted = lt_flash_erase_block(FLASH_OTA_OFFSET);
110#else
111 // On BK72xx this erases the download header
112 const bool reverted = lt_ota_switch(/* revert= */ true);
113#endif
114 if (!reverted) {
115 ESP_LOGE(TAG, "Revert failed");
116 }
117}
118
119} // namespace esphome::ota
120#endif // USE_LIBRETINY
bool equals_bytes(const uint8_t *expected)
Compare the hash against a provided byte-encoded hash.
Definition hash_base.h:32
void calculate() override
Compute the digest, based on the provided data.
Definition md5.cpp:16
void add(const uint8_t *data, size_t len) override
Add bytes of data for the digest.
Definition md5.cpp:14
void init() override
Initialize a new MD5 digest computation.
Definition md5.cpp:9
OTAResponseTypes begin(size_t image_size, OTAType ota_type=OTA_TYPE_UPDATE_APP)
OTAResponseTypes write(uint8_t *data, size_t len)
int ret
@ OTA_RESPONSE_ERROR_MD5_MISMATCH
Definition ota_backend.h:44
@ OTA_RESPONSE_ERROR_ESP32_NOT_ENOUGH_SPACE
Definition ota_backend.h:42
@ OTA_RESPONSE_ERROR_WRITING_FLASH
Definition ota_backend.h:36
@ OTA_RESPONSE_ERROR_UNSUPPORTED_OTA_TYPE
Definition ota_backend.h:47
@ OTA_RESPONSE_ERROR_UPDATE_END
Definition ota_backend.h:37
@ OTA_RESPONSE_ERROR_UNKNOWN
Definition ota_backend.h:54
std::unique_ptr< ArduinoLibreTinyOTABackend > make_ota_backend()
const void size_t len
Definition hal.h:64
size_t parse_hex(const char *str, size_t length, uint8_t *data, size_t count)
Parse bytes from a hex-encoded string into a byte array.
Definition helpers.cpp:301