diff --git a/esphome/components/esphome/ota/ota_esphome.cpp b/esphome/components/esphome/ota/ota_esphome.cpp index 13d67842aa..b39fe94adf 100644 --- a/esphome/components/esphome/ota/ota_esphome.cpp +++ b/esphome/components/esphome/ota/ota_esphome.cpp @@ -185,6 +185,16 @@ void ESPHomeOTAComponent::handle_handshake_() { } case OTAState::FEATURE_ACK: { + // No password: switch to blocking before writing so the feature ACK + // byte is flushed to the wire before entering the blocking data phase. + // lwIP may not transmit data written in non-blocking mode when the + // socket immediately switches to blocking and blocks in recv(). +#ifdef USE_OTA_PASSWORD + if (this->password_.empty()) +#endif + { + this->client_->setblocking(true); + } // Acknowledge header - 1 byte if (!this->try_write_(1, LOG_STR("ack feature"))) { return; @@ -283,11 +293,6 @@ void ESPHomeOTAComponent::handle_data_() { this->client_->setsockopt(SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); this->client_->setblocking(true); - // Yield to flush any pending non-blocking writes (e.g. the feature ACK byte) - // before entering the blocking data transfer. lwIP may not transmit data - // written in non-blocking mode until the task yields. - delay(0); - // Acknowledge auth OK - 1 byte this->write_byte_(ota::OTA_RESPONSE_AUTH_OK);