mirror of
https://github.com/esphome/esphome.git
synced 2026-08-24 15:16:20 +00:00
Address review: retry a dropped freed-slot notification too
The connections-free retry left its sibling asymmetric: on the same full buffer the slot could report free while the device still read as connected, with nothing resending the connected=false. A one-deep latch (address + error) drains at the same 100 ms cadence and re-latches on a repeat failure; a re-reservation of the address clears it, since the client re-requesting the connect has already acted on the disconnect and a late resend would shadow the new connection. A lost connected=true stays client-timeout territory.
This commit is contained in:
@@ -206,6 +206,11 @@ BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool rese
|
||||
return connection;
|
||||
|
||||
if (reserve && conn_addr == 0) {
|
||||
if (address == this->pending_disconnection_address_) {
|
||||
// The client re-requested this address: it already acted on the
|
||||
// disconnect, and a late resend would shadow the new connection.
|
||||
this->pending_disconnection_address_ = 0;
|
||||
}
|
||||
connection->send_service_ = INIT_SENDING_SERVICES;
|
||||
connection->set_address(address);
|
||||
// All connections must start at INIT
|
||||
@@ -487,6 +492,13 @@ void BluetoothProxy::loop() {
|
||||
return;
|
||||
this->last_advertisement_flush_time_ = now;
|
||||
|
||||
if (this->pending_disconnection_address_ != 0 && this->api_connection_ != nullptr) {
|
||||
// Paced resend of a dropped freed-slot notification; a repeat failure
|
||||
// re-latches through send_device_connection itself.
|
||||
uint64_t addr = this->pending_disconnection_address_;
|
||||
this->pending_disconnection_address_ = 0;
|
||||
this->send_device_connection(addr, false, 0, this->pending_disconnection_error_);
|
||||
}
|
||||
if (this->connections_free_pending_ && this->api_connection_ != nullptr) {
|
||||
// Resend a dropped slot-state update, paced by the 100 ms gate so the
|
||||
// retry does not hammer the congestion it exists to survive; the
|
||||
@@ -633,7 +645,12 @@ void BluetoothProxy::send_device_connection(uint64_t address, bool connected, ui
|
||||
call.connected = connected;
|
||||
call.mtu = mtu;
|
||||
call.error = error;
|
||||
this->api_connection_->send_message(call);
|
||||
if (!this->api_connection_->send_message(call) && !connected) {
|
||||
// The freed-slot notification must eventually arrive; a lost
|
||||
// connected=true is covered by the client's own connect timeout.
|
||||
this->pending_disconnection_address_ = address;
|
||||
this->pending_disconnection_error_ = error;
|
||||
}
|
||||
}
|
||||
void BluetoothProxy::send_connections_free() {
|
||||
if (this->api_connection_ != nullptr) {
|
||||
|
||||
@@ -251,6 +251,10 @@ class BluetoothProxy final : public Component {
|
||||
|
||||
// Pre-allocated response message - always ready to send
|
||||
api::BluetoothConnectionsFreeResponse connections_free_response_;
|
||||
// One-deep retry latch for a dropped connected=false notification (the
|
||||
// freed-slot half of the pair the connections-free retry covers).
|
||||
uint64_t pending_disconnection_address_{0};
|
||||
conn_err_t pending_disconnection_error_{0};
|
||||
|
||||
// Group 4: 1-byte types grouped together
|
||||
bool active_;
|
||||
|
||||
Reference in New Issue
Block a user