mirror of
https://github.com/esphome/esphome.git
synced 2026-08-24 07:06:20 +00:00
Retry a dropped connections-free update
Field bug on a Pico W: the slot freed device-side but the API client kept free=0 with the address still allocated. send_message drops the response when the TCP buffer is full (a boot storm makes that likely right when HA reconnects), and nothing ever resent it - the client's slot state is verbatim the last response received, so it stayed stale until reboot. The cached response is current by construction, so a pending bit retried from loop() is an idempotent resync; the subscribe-time send heals through the same bit.
This commit is contained in:
@@ -475,6 +475,11 @@ void BluetoothProxy::loop() {
|
||||
for (uint8_t i = 0; i < this->connection_count_; i++) {
|
||||
this->connections_[i]->process_pending_services();
|
||||
}
|
||||
if (this->connections_free_pending_ && this->api_connection_ != nullptr) {
|
||||
// Resend a dropped slot-state update once the TCP buffer drains.
|
||||
this->connections_free_pending_ = false;
|
||||
this->send_connections_free(this->api_connection_);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Run advertisement flush / scanner-state poll every 100ms
|
||||
@@ -629,7 +634,10 @@ void BluetoothProxy::send_connections_free() {
|
||||
}
|
||||
|
||||
void BluetoothProxy::send_connections_free(api::APIConnection *api_connection) {
|
||||
api_connection->send_message(this->connections_free_response_);
|
||||
if (!api_connection->send_message(this->connections_free_response_)) {
|
||||
ESP_LOGD(TAG, "Connections-free update deferred, TCP buffer full");
|
||||
this->connections_free_pending_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothProxy::send_gatt_services_done(uint64_t address) {
|
||||
|
||||
@@ -254,6 +254,10 @@ class BluetoothProxy final : public Component {
|
||||
|
||||
// Group 4: 1-byte types grouped together
|
||||
bool active_;
|
||||
// A dropped send (full TCP buffer) would leave the API client with a stale
|
||||
// slot state forever; the cached response is current by construction, so
|
||||
// retrying it from loop() is an idempotent resync.
|
||||
bool connections_free_pending_{false};
|
||||
uint8_t connection_count_{0};
|
||||
bool configured_scan_active_{false}; // Configured scan mode from YAML
|
||||
#ifndef USE_BLE_SCANNER_STATE_CALLBACK
|
||||
|
||||
Reference in New Issue
Block a user