[esp32_ble] Drop queued events and settle the scanner when the stack is dismantled

Events the old stack queued while going down were replayed after the next
ble.enable against a fresh stack that hands out the same interface ids, and
the scanner relied on that replay to leave STOPPING. Drain the queue after
the teardown and put the scanner back to IDLE from the before-disabled
handler, since no completion can arrive anymore.
This commit is contained in:
J. Nick Koston
2026-09-10 07:39:51 -05:00
parent a84269d6b0
commit 8c772b4dd4
2 changed files with 17 additions and 0 deletions
+8
View File
@@ -580,6 +580,14 @@ void ESP32BLE::loop_handle_state_transition_not_active_() {
this->mark_failed();
return;
}
// Whatever the old stack queued while going down (close events for the
// links it tore down, scan completions) must not replay against the next
// stack, which hands out the same interface ids.
BLEEvent *ble_event;
while ((ble_event = this->ble_events_.pop()) != nullptr) {
this->ble_event_pool_.release(ble_event);
}
this->ble_events_.get_and_reset_dropped_count();
this->state_ = BLE_COMPONENT_STATE_DISABLED;
} else if (this->state_ == BLE_COMPONENT_STATE_ENABLE) {
ESP_LOGD(TAG, "Enabling");
@@ -225,6 +225,15 @@ void ESP32BLETracker::ble_before_disabled_event_handler() {
client->ble_before_disabled_event_handler();
}
#endif
// The stop above never completes: the stack is torn down and its queued
// events are dropped, so settle the scanner here. start_scan_() refuses
// anything but IDLE once the stack is back.
if (this->scanner_state_ != ScannerState::IDLE) {
#ifdef ESPHOME_ESP32_BLE_TRACKER_CLIENT_COUNT
this->skip_next_scan_end_ = false;
#endif
this->cleanup_scan_state_(true);
}
}
bool ESP32BLETracker::stop_scan_() {