diff --git a/esphome/components/ble_client/ble_client.cpp b/esphome/components/ble_client/ble_client.cpp index 18a87877b3..d9927e9bc7 100644 --- a/esphome/components/ble_client/ble_client.cpp +++ b/esphome/components/ble_client/ble_client.cpp @@ -57,7 +57,13 @@ void BLEClient::set_enabled(bool enabled) { if (!enabled) { ESP_LOGI(TAG, "[%s] Disabling BLE client.", this->address_str()); this->disconnect(); + return; } +#ifdef USE_BLE_CLIENT_GATT_NODES + // A re-enable clears the backoff (neutral-engine parity). + this->gatt_consecutive_failures_ = 0; + this->gatt_hold_off_ms_ = 0; +#endif } bool BLEClient::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t esp_gattc_if, @@ -301,6 +307,7 @@ int BLEClient::notify_characteristic(uint16_t handle, bool enable) { if (enable) { for (uint8_t i = 0; i < this->pending_gatt_reg_count_; i++) { if (this->pending_gatt_regs_[i] == handle) { + // ESP_OK: the in-flight registration's completion fans out to all nodes. ESP_LOGW(TAG, "[%s] Notify registration already pending for handle 0x%04x", this->address_str(), handle); return ESP_OK; } diff --git a/esphome/components/bluetooth_connection/gatt_service_table_bluedroid.cpp b/esphome/components/bluetooth_connection/gatt_service_table_bluedroid.cpp index e80f060dbf..66a6cf9824 100644 --- a/esphome/components/bluetooth_connection/gatt_service_table_bluedroid.cpp +++ b/esphome/components/bluetooth_connection/gatt_service_table_bluedroid.cpp @@ -111,6 +111,7 @@ bool BluedroidServiceTable::build(esp_gatt_if_t gattc_if, uint16_t conn_id, uint }); if (!counted) { ESP_LOGW(TAG, "[%d] Service table walk failed during count", this->log_index_); + this->free(); return false; } @@ -124,6 +125,7 @@ bool BluedroidServiceTable::build(esp_gatt_if_t gattc_if, uint16_t conn_id, uint if (this->storage_ == nullptr) { ESP_LOGW(TAG, "[%d] Service table allocation failed (%u bytes)", this->log_index_, static_cast(total_bytes)); + this->free(); return false; } auto *services = reinterpret_cast(this->storage_); diff --git a/esphome/components/bluetooth_connection/gatt_service_table_bluedroid.h b/esphome/components/bluetooth_connection/gatt_service_table_bluedroid.h index 49d9f7f6e9..79c6847e52 100644 --- a/esphome/components/bluetooth_connection/gatt_service_table_bluedroid.h +++ b/esphome/components/bluetooth_connection/gatt_service_table_bluedroid.h @@ -41,13 +41,14 @@ class BluedroidServiceTable { this->desc_total_}; } + // Always resets the counts: a failed build must never leave a non-zero + // service_total_ behind a null table. void free() { - if (this->storage_ == nullptr) { - return; + if (this->storage_ != nullptr) { + RAMAllocator allocator(RAMAllocator::ALLOC_INTERNAL); + allocator.deallocate(this->storage_, 0); + this->storage_ = nullptr; } - RAMAllocator allocator(RAMAllocator::ALLOC_INTERNAL); - allocator.deallocate(this->storage_, 0); - this->storage_ = nullptr; this->service_total_ = 0; this->char_total_ = 0; this->desc_total_ = 0;