diff --git a/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.cpp b/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.cpp index 668bb7958d..577eed93d0 100644 --- a/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.cpp +++ b/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.cpp @@ -79,7 +79,8 @@ void BluedroidGattClient::loop() { // The loop only drives the bootstrap and the disconnect safety timeout. this->disable_loop(); } else if (st == ClientState::DISCONNECTING && - millis() - this->disconnecting_started_ > ble_device_base::GATT_DISCONNECT_TIMEOUT_MS) { + static_cast(static_cast(millis() >> 8) - this->disconnecting_tick_) > + (ble_device_base::GATT_DISCONNECT_TIMEOUT_MS >> 8)) { ESP_LOGE(TAG, "[%d] Timeout waiting for CLOSE_EVT, forcing IDLE", this->connection_index_); // Release before idling: unconditional disconnect does not release, and a // lost CLOSE/DISCONNECT would otherwise leak the table and the cache. @@ -437,7 +438,7 @@ void BluedroidGattClient::set_idle_() { } void BluedroidGattClient::set_disconnecting_() { - this->disconnecting_started_ = millis(); + this->disconnecting_tick_ = static_cast(millis() >> 8); this->set_state_(ClientState::DISCONNECTING); // The loop may be disabled while idle; the safety timeout needs it. this->enable_loop(); diff --git a/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.h b/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.h index 80c47e6a4c..897ba2f2de 100644 --- a/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.h +++ b/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.h @@ -125,7 +125,6 @@ class BluedroidGattClient final : public esp32_ble_tracker::ESPBTClient, public #endif // Group 2: 4-byte types int gattc_if_{ESP_GATT_IF_NONE}; - uint32_t disconnecting_started_{0}; // Group 3: arrays esp_bd_addr_t remote_bda_{}; @@ -133,6 +132,10 @@ class BluedroidGattClient final : public esp32_ble_tracker::ESPBTClient, public // Group 4: 2-byte types uint16_t conn_id_{0xFFFF}; uint16_t service_total_{0}; + // 256 ms ticks (millis() >> 8), wrap-safe for the 10 s net; a uint16 keeps + // the object on the 48-byte boundary (a full uint32 costs 4 B of field + // plus 4 B of per-slot storage padding). + uint16_t disconnecting_tick_{0}; #ifdef USE_BLE_GATT_SERVICE_TABLE // Filled element counts of the materialized table (0 when none). uint16_t table_char_total_{0};