From f7b1e9ae658beafe428f15df735e9e1c9ad7800b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 9 Aug 2026 09:04:31 -0500 Subject: [PATCH] Shrink the disconnect timestamp to a tick so the backend packs to 48 bytes --- .../bluetooth_connection/bluetooth_connection_bluedroid.cpp | 5 +++-- .../bluetooth_connection/bluetooth_connection_bluedroid.h | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.cpp b/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.cpp index fc47cff541..92ee9f4d0c 100644 --- a/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.cpp +++ b/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.cpp @@ -78,7 +78,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. @@ -436,7 +437,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 910caecfce..5050c86755 100644 --- a/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.h +++ b/esphome/components/bluetooth_connection/bluetooth_connection_bluedroid.h @@ -123,7 +123,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_{}; @@ -131,6 +130,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};