From 72751210fb6a0365e3e1b7cbfdeca4fdc02a43d0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 22 May 2026 22:22:05 -0500 Subject: [PATCH] [bluetooth_proxy] Don't disable loop while DISCONNECTING so safety timeout can fire --- .../components/bluetooth_proxy/bluetooth_connection.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/esphome/components/bluetooth_proxy/bluetooth_connection.cpp b/esphome/components/bluetooth_proxy/bluetooth_connection.cpp index 21573f0184..d78506e067 100644 --- a/esphome/components/bluetooth_proxy/bluetooth_connection.cpp +++ b/esphome/components/bluetooth_proxy/bluetooth_connection.cpp @@ -135,8 +135,11 @@ void BluetoothConnection::loop() { // - For V3_WITH_CACHE: Services are never sent, disable after INIT state // - For V3_WITHOUT_CACHE: Disable only after service discovery is complete // (send_service_ == DONE_SENDING_SERVICES, which is only set after services are sent) - if (this->state() != espbt::ClientState::INIT && (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE || - this->send_service_ == DONE_SENDING_SERVICES)) { + // Never disable while DISCONNECTING — BLEClientBase::loop() needs to keep running so the + // 10s safety timeout can force IDLE if CLOSE_EVT is never delivered. + if (this->state() != espbt::ClientState::INIT && this->state() != espbt::ClientState::DISCONNECTING && + (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE || + this->send_service_ == DONE_SENDING_SERVICES)) { this->disable_loop(); } }