mirror of
https://github.com/esphome/esphome.git
synced 2026-09-09 22:38:48 +00:00
Ack chunks on receipt where the socket stack has its own task
With raw lwIP in the main loop the radio is deaf while a sector is written, so the ESP8266 and RP2040 keep the client quiet until the block is in flash; with BSD or lwIP sockets the next block can arrive while this one is written.
This commit is contained in:
@@ -537,7 +537,7 @@ void ESPHomeOTAComponent::handle_data_() {
|
||||
error_code = this->write_flash_(buf, read);
|
||||
if (error_code != ota::OTA_RESPONSE_OK)
|
||||
goto error; // NOLINT(cppcoreguidelines-avoid-goto)
|
||||
this->send_chunk_acks_(xfer);
|
||||
this->ack_written_(xfer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -794,6 +794,7 @@ ssize_t ESPHomeOTAComponent::receive_data_(uint8_t *buf, DataTransfer &xfer) {
|
||||
const uint32_t now = millis();
|
||||
xfer.last_data_ms = now;
|
||||
xfer.total += read;
|
||||
this->ack_received_(xfer);
|
||||
if (now - xfer.last_progress > OTA_PROGRESS_INTERVAL_MS) {
|
||||
xfer.last_progress = now;
|
||||
float percentage = (xfer.total * 100.0f) / xfer.ota_size;
|
||||
@@ -850,14 +851,14 @@ ota::OTAResponseTypes ESPHomeOTAComponent::inflate_data_(uint8_t *in, size_t ima
|
||||
session.error = ota::OTA_RESPONSE_OK;
|
||||
ota_inflate_init(&session, session.window, OTA_INFLATE_WINDOW_SIZE);
|
||||
// Pulls the next compressed chunk when the decoder runs dry. Everything
|
||||
// received so far is decoded by then, so it is written and acked first,
|
||||
// keeping a chunk ack meaning "in flash" as on the uncompressed path.
|
||||
// received so far is decoded by then, so it is written first and, on the
|
||||
// platforms that ack after the write, acked.
|
||||
session.source_read_cb = [](OtaInflateState *d) -> int {
|
||||
auto *s = static_cast<InflateSession *>(d);
|
||||
s->error = s->self->inflate_flush_(*s);
|
||||
if (s->error != ota::OTA_RESPONSE_OK)
|
||||
return -1;
|
||||
s->self->send_chunk_acks_(*s->xfer);
|
||||
s->self->ack_written_(*s->xfer);
|
||||
if (s->xfer->total >= s->xfer->ota_size) {
|
||||
ESP_LOGW(TAG, "Inflate size mismatch");
|
||||
return -1;
|
||||
@@ -889,7 +890,7 @@ ota::OTAResponseTypes ESPHomeOTAComponent::inflate_data_(uint8_t *in, size_t ima
|
||||
ota::OTAResponseTypes flush_result = this->inflate_flush_(session);
|
||||
if (flush_result != ota::OTA_RESPONSE_OK)
|
||||
return flush_result;
|
||||
this->send_chunk_acks_(xfer);
|
||||
this->ack_written_(xfer);
|
||||
} while (res != OTA_INFLATE_DONE);
|
||||
|
||||
if (session.written != image_size || xfer.total != xfer.ota_size) {
|
||||
|
||||
@@ -135,8 +135,23 @@ class ESPHomeOTAComponent final : public ota::OTAComponent {
|
||||
// Receives up to OTA_BUFFER_SIZE bytes of upload data into buf, waiting up to
|
||||
// the data timeout, and updates xfer. Returns bytes read, -1 on failure (logged).
|
||||
inline ssize_t receive_data_(uint8_t *buf, DataTransfer &xfer);
|
||||
// Acks every received block once it is in flash, so an ack means written
|
||||
// When lwIP runs in this loop the radio is deaf while a sector is written, so
|
||||
// the client is kept quiet until the block is in flash; with a socket task the
|
||||
// ack goes out on receipt so the next block arrives while this one is written
|
||||
#ifdef USE_SOCKET_IMPL_LWIP_TCP
|
||||
static constexpr bool ACK_AFTER_WRITE = true;
|
||||
#else
|
||||
static constexpr bool ACK_AFTER_WRITE = false;
|
||||
#endif
|
||||
inline void send_chunk_acks_(DataTransfer &xfer);
|
||||
inline void ack_received_(DataTransfer &xfer) {
|
||||
if (!ACK_AFTER_WRITE)
|
||||
this->send_chunk_acks_(xfer);
|
||||
}
|
||||
inline void ack_written_(DataTransfer &xfer) {
|
||||
if (ACK_AFTER_WRITE)
|
||||
this->send_chunk_acks_(xfer);
|
||||
}
|
||||
// Reads a 4 byte MSB first size field into size
|
||||
inline bool read_size_(uint8_t *buf, size_t &size, const LogString *desc);
|
||||
// Writes to the backend and logs a failure
|
||||
|
||||
Reference in New Issue
Block a user