mirror of
https://github.com/esphome/esphome.git
synced 2026-09-24 13:34:07 +00:00
[ota] Fix OTA handshake failure by switching to blocking before feature ACK write
Switch to blocking mode before writing the feature ACK byte in the no-password path. lwIP may not transmit data written in non-blocking mode when the socket immediately switches to blocking and blocks in recv(). Writing the feature ACK in blocking mode ensures it is flushed to the wire before entering the blocking data transfer phase.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user