mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[bluetooth_proxy] Reset every owed reply in one place (#18276)
This commit is contained in:
@@ -704,6 +704,31 @@ void BluetoothProxy::bluetooth_set_connection_params(const api::BluetoothSetConn
|
||||
|
||||
#endif // !BLUETOOTH_CONNECTION_HAS_GATT
|
||||
|
||||
void BluetoothProxy::reset_owed_replies_() {
|
||||
this->connections_free_pending_ = false;
|
||||
#ifdef USE_BLE_SCANNER_STATE_CALLBACK
|
||||
// Owed on unsubscribe; on subscribe the trailing send_scanner_state_()
|
||||
// re-drives it from the hub, so clearing it there is free.
|
||||
this->scanner_state_pending_ = false;
|
||||
#else
|
||||
// Force a poll-arm mismatch: a frame refused at subscribe time could
|
||||
// otherwise match the stale detector and never be retried. Inert on
|
||||
// unsubscribe: loop() returns at the no-subscriber gate before the
|
||||
// detector runs, and a re-subscribe re-arms this anyway.
|
||||
this->last_scan_running_ = !this->hub_->scan_running();
|
||||
#endif
|
||||
#ifdef BLUETOOTH_CONNECTION_HAS_GATT
|
||||
this->pending_unpairing_.clear();
|
||||
this->pending_disconnections_.fill({});
|
||||
for (uint8_t i = 0; i < this->connection_count_; i++) {
|
||||
// Neither a partial stream's tail nor an owed done belongs to the next
|
||||
// session; silence (the client's timeout) arbitrates.
|
||||
this->connections_[i]->park_service_stream_();
|
||||
this->connections_[i]->clear_pending_ack_();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void BluetoothProxy::subscribe_api_connection(api::APIConnection *api_connection, uint32_t flags) {
|
||||
if (api_connection != this->api_connection_) {
|
||||
if (this->api_connection_ != nullptr) {
|
||||
@@ -720,18 +745,7 @@ void BluetoothProxy::subscribe_api_connection(api::APIConnection *api_connection
|
||||
}
|
||||
// Stale retry latches belong to the previous subscriber's session; a
|
||||
// re-subscribe by the current one keeps what it is still owed.
|
||||
this->connections_free_pending_ = false;
|
||||
#ifdef BLUETOOTH_CONNECTION_HAS_GATT
|
||||
this->pending_unpairing_.clear();
|
||||
for (uint8_t i = 0; i < this->connection_count_; i++) {
|
||||
// Neither a partial stream's tail nor an owed done belongs to the new
|
||||
// session; silence (the client's timeout) arbitrates.
|
||||
this->connections_[i]->park_service_stream_();
|
||||
// An ack owed to the previous subscriber means nothing to the new one.
|
||||
this->connections_[i]->clear_pending_ack_();
|
||||
}
|
||||
this->pending_disconnections_.fill({});
|
||||
#endif
|
||||
this->reset_owed_replies_();
|
||||
}
|
||||
this->api_connection_ = api_connection;
|
||||
#ifdef USE_BLE_SCANNER_STATE_CALLBACK
|
||||
@@ -748,13 +762,7 @@ void BluetoothProxy::unsubscribe_api_connection(api::APIConnection *api_connecti
|
||||
return;
|
||||
}
|
||||
this->api_connection_ = nullptr;
|
||||
this->connections_free_pending_ = false;
|
||||
#ifdef BLUETOOTH_CONNECTION_HAS_GATT
|
||||
this->pending_unpairing_.clear();
|
||||
#endif
|
||||
#ifdef USE_BLE_SCANNER_STATE_CALLBACK
|
||||
this->scanner_state_pending_ = false;
|
||||
#endif
|
||||
this->reset_owed_replies_();
|
||||
}
|
||||
|
||||
void BluetoothProxy::send_connections_free() {
|
||||
|
||||
@@ -286,6 +286,12 @@ class BluetoothProxy final : public Component {
|
||||
void latch_pending_disconnection_(uint64_t address, conn_err_t error);
|
||||
#endif
|
||||
|
||||
/// Drop everything the ending session was owed. One list, so a new latch is
|
||||
/// one edit rather than two call sites where an omission looks deliberate.
|
||||
/// Drops state only, never sends: api_connection_ is the departing
|
||||
/// subscriber on subscribe and nullptr on unsubscribe.
|
||||
void reset_owed_replies_();
|
||||
|
||||
// Memory optimized layout for 32-bit systems
|
||||
// Group 1: Pointers (4 bytes each, naturally aligned)
|
||||
api::APIConnection *api_connection_{nullptr};
|
||||
|
||||
Reference in New Issue
Block a user