mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[ble_device_base] Advertise runtime scan-mode switching in HubCapabilities (#18079)
This commit is contained in:
@@ -91,7 +91,9 @@ class BK72xxBLETracker : public Component,
|
||||
// controller never solicits scan responses and never merges them; consumers
|
||||
// relying on scan-response fields (device names) get them only where the
|
||||
// receiver merges per address (Home Assistant does). No GATT client either.
|
||||
return {.active_scan = false, .merges_scan_response = false, .gatt = false};
|
||||
// scan_mode_switch stays false for the same reason: with no active-scan
|
||||
// path there is no mode to switch to.
|
||||
return {.active_scan = false, .merges_scan_response = false, .gatt = false, .scan_mode_switch = false};
|
||||
}
|
||||
bool request_scan_mode(bool active) override {
|
||||
// Passive-only controller: a passive request is already honored, an active
|
||||
|
||||
@@ -59,6 +59,11 @@ struct HubCapabilities {
|
||||
/// GATT client connections are available (today: esp32 only, but a chip SDK
|
||||
/// gaining GATT support only has to flip this bit).
|
||||
bool gatt;
|
||||
/// request_scan_mode() is honored at runtime. Distinct from active_scan:
|
||||
/// a passive-only controller (bk72xx) can never switch, and a hub may
|
||||
/// support active scanning yet still refuse the runtime switch
|
||||
/// (esp32_ble_tracker drives its mode through its own tracker API).
|
||||
bool scan_mode_switch;
|
||||
};
|
||||
|
||||
class BLEHub {
|
||||
@@ -86,9 +91,9 @@ class BLEHub {
|
||||
/// picks it up on its next start. The default cannot-change keeps hubs
|
||||
/// without a mode switch (and out-of-tree trackers) building unchanged.
|
||||
/// Independent of HubCapabilities::active_scan: that bit describes what the
|
||||
/// CONTROLLER can do, this method describes whether the hub exposes a
|
||||
/// runtime switch — a hub may support active scanning and still refuse
|
||||
/// (esp32_ble_tracker drives its mode through its own tracker API).
|
||||
/// CONTROLLER can do; whether this method honors requests is advertised by
|
||||
/// HubCapabilities::scan_mode_switch, so consumers can gate features on the
|
||||
/// switch without probing.
|
||||
virtual bool request_scan_mode(bool active) { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -242,7 +242,10 @@ class ESP32BLETracker final : public Component,
|
||||
this->raw_advertisement_callback_ = callback;
|
||||
}
|
||||
ble_device_base::HubCapabilities get_capabilities() const override {
|
||||
return {/* active_scan = */ true, /* merges_scan_response = */ true, /* gatt = */ true};
|
||||
// scan_mode_switch is false: the mode is driven through this tracker's own
|
||||
// API (set_scan_active + restart), not the neutral request_scan_mode().
|
||||
return {/* active_scan = */ true, /* merges_scan_response = */ true, /* gatt = */ true,
|
||||
/* scan_mode_switch = */ false};
|
||||
}
|
||||
void get_adapter_mac(uint8_t out[6]) override;
|
||||
bool scan_running() override { return this->scanner_state_ == ScannerState::RUNNING; }
|
||||
|
||||
@@ -72,7 +72,8 @@ class LN882HBLETracker : public Component,
|
||||
// The LN882H controller supports active scanning; adv + scan response arrive
|
||||
// as separate reports and are merged by this tracker (Bluedroid semantics).
|
||||
// The SDK's GATT client is not exposed.
|
||||
return {.active_scan = true, .merges_scan_response = true, .gatt = false};
|
||||
// scan_mode_switch: request_scan_mode() is implemented (restart-if-running).
|
||||
return {.active_scan = true, .merges_scan_response = true, .gatt = false, .scan_mode_switch = true};
|
||||
}
|
||||
// The controller stores the address LSB-first (BLE convention); the contract
|
||||
// wants printable (MSB-first) order.
|
||||
|
||||
@@ -64,7 +64,7 @@ class RP2BLETracker : public Component,
|
||||
// than merging them into the advertisement — consumers relying on
|
||||
// scan-response fields (device names) get them only where the receiver
|
||||
// merges per address (Home Assistant does). No GATT path yet.
|
||||
return {.active_scan = true, .merges_scan_response = false, .gatt = false};
|
||||
return {.active_scan = true, .merges_scan_response = false, .gatt = false, .scan_mode_switch = true};
|
||||
}
|
||||
// The controller stores the address in printable (MSB-first) order, which is
|
||||
// exactly what the contract wants.
|
||||
|
||||
@@ -29,7 +29,7 @@ class DefaultHub : public BLEHub {
|
||||
|
||||
class SwitchingHub : public DefaultHub {
|
||||
public:
|
||||
HubCapabilities get_capabilities() const override { return {true, false, false}; }
|
||||
HubCapabilities get_capabilities() const override { return {true, false, false, /* scan_mode_switch = */ true}; }
|
||||
bool request_scan_mode(bool active) override {
|
||||
this->active_ = active;
|
||||
return true;
|
||||
@@ -57,6 +57,7 @@ TEST(BLEHubScanModeRequest, DefaultRefusesAndChangesNothing) {
|
||||
|
||||
TEST(BLEHubScanModeRequest, OverrideHonorsAndApplies) {
|
||||
SwitchingHub hub;
|
||||
EXPECT_TRUE(hub.get_capabilities().scan_mode_switch);
|
||||
EXPECT_TRUE(hub.request_scan_mode(true));
|
||||
EXPECT_TRUE(hub.scan_active());
|
||||
EXPECT_TRUE(hub.request_scan_mode(false));
|
||||
@@ -66,6 +67,8 @@ TEST(BLEHubScanModeRequest, OverrideHonorsAndApplies) {
|
||||
TEST(BLEHubScanModeRequest, CapabilityAndSwitchAreIndependent) {
|
||||
CapableRefusingHub hub;
|
||||
EXPECT_TRUE(hub.get_capabilities().active_scan);
|
||||
// The esp32 shape advertises no runtime switch, and the request refuses.
|
||||
EXPECT_FALSE(hub.get_capabilities().scan_mode_switch);
|
||||
EXPECT_FALSE(hub.request_scan_mode(false));
|
||||
EXPECT_TRUE(hub.scan_active());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user