[bluetooth_proxy] Release proxy slot when DISCONNECTING safety timeout fires

This commit is contained in:
J. Nick Koston
2026-05-22 22:26:58 -05:00
parent eee355eec5
commit 6bb912cdd5
4 changed files with 19 additions and 0 deletions

View File

@@ -144,6 +144,16 @@ void BluetoothConnection::loop() {
}
}
void BluetoothConnection::on_disconnect_timeout_() {
// The base class forced IDLE because CLOSE_EVT never arrived. Run the same slot
// cleanup the CLOSE_EVT path would have done so the proxy slot is freed, the API
// client is notified, and send_service_ is reset for the next connection.
if (this->address_ == 0) {
return;
}
this->reset_connection_(ESP_GATT_CONN_TIMEOUT);
}
void BluetoothConnection::reset_connection_(esp_err_t reason) {
// Send disconnection notification
this->proxy_->send_device_connection(this->address_, false, 0, reason);

View File

@@ -33,6 +33,8 @@ class BluetoothConnection final : public esp32_ble_client::BLEClientBase {
protected:
friend class BluetoothProxy;
void on_disconnect_timeout_() override;
bool supports_efficient_uuids_() const;
void send_service_for_discovery_();
void reset_connection_(esp_err_t reason);

View File

@@ -72,6 +72,9 @@ void BLEClientBase::loop() {
// never delivered CLOSE_EVT/DISCONNECT_EVT, services would leak without this call.
this->release_services();
this->set_idle_();
// Notify subclasses so they can release any extra per-connection state (e.g. bluetooth_proxy
// slot accounting) that would normally be cleared by the CLOSE_EVT handler.
this->on_disconnect_timeout_();
}
}

View File

@@ -140,6 +140,10 @@ class BLEClientBase : public espbt::ESPBTClient, public Component {
void log_gattc_warning_(const char *operation, esp_err_t err);
void log_connection_params_(const char *param_type);
void handle_connection_result_(esp_err_t ret);
/// Hook called from the DISCONNECTING safety timeout after the base class forces IDLE.
/// Subclasses with extra per-connection accounting (e.g. bluetooth_proxy slot state)
/// override this to perform the same cleanup the normal CLOSE_EVT path would do.
virtual void on_disconnect_timeout_() {}
/// Transition to IDLE and reset conn_id — call when the connection is fully dead.
void set_idle_() {
this->set_state(espbt::ClientState::IDLE);