[bluetooth_proxy] Only advance the scanner-state detector when the frame was sent (#18154)

This commit is contained in:
Edvard Filistovič
2026-08-07 15:01:50 +00:00
committed by GitHub
parent 8b0e23d55b
commit 1bbe8b415f
2 changed files with 16 additions and 8 deletions
@@ -59,7 +59,6 @@ void BluetoothProxy::setup() {
// Capture the configured scan mode from YAML before any API changes
this->configured_scan_active_ = this->hub_->scan_active();
this->last_scan_running_ = this->hub_->scan_running();
// The hub delivers raw advertisements on the ESPHome main loop:
// mac is least-significant octet first (BLE controller convention).
@@ -93,19 +92,21 @@ void BluetoothProxy::on_raw_advertisement_(const ble_device_base::RawAdvertiseme
}
void BluetoothProxy::send_bluetooth_scanner_state_() {
// Records what goes on the wire so loop()'s change detector cannot report the
// same transition twice; every caller relies on this instead of updating
// last_scan_running_ itself.
this->last_scan_running_ = this->hub_->scan_running();
// One read feeds both the frame and the change detector; the detector only
// advances if the frame was accepted, so a dropped send (WOULD_BLOCK on a
// full TX buffer) is retried from loop() instead of leaving a stale state.
const bool running = this->hub_->scan_running();
api::BluetoothScannerStateResponse resp;
resp.state = this->last_scan_running_ ? api::enums::BluetoothScannerState::BLUETOOTH_SCANNER_STATE_RUNNING
: api::enums::BluetoothScannerState::BLUETOOTH_SCANNER_STATE_IDLE;
resp.state = running ? api::enums::BluetoothScannerState::BLUETOOTH_SCANNER_STATE_RUNNING
: api::enums::BluetoothScannerState::BLUETOOTH_SCANNER_STATE_IDLE;
resp.mode = this->hub_->scan_active() ? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
: api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE;
resp.configured_mode = this->configured_scan_active_
? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
: api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE;
this->api_connection_->send_message(resp);
if (this->api_connection_->send_message(resp)) {
this->last_scan_running_ = running;
}
}
#endif // USE_ESP32
@@ -23,6 +23,13 @@ HUB_PLATFORM_FRAMEWORKS = [
]
def test_hub_platform_list_covers_every_hub_platform() -> None:
# A platform added to _HUB_PLATFORMS (bk72xx is planned) would otherwise
# get no gate coverage at all.
covered = {pf.value[0] for pf in HUB_PLATFORM_FRAMEWORKS}
assert covered == set(bluetooth_proxy._HUB_PLATFORMS)
def _set_platform(platform: str | None) -> None:
# For arms set_core_config cannot express (bare platform, no framework).
CORE.data.setdefault(KEY_CORE, {})[KEY_TARGET_PLATFORM] = platform