mirror of
https://github.com/esphome/esphome.git
synced 2026-09-12 07:47:33 +00:00
Merge branch 'esp32-proxy-hub-scanner-state' into esp32-tracker-parser-cleanup
This commit is contained in:
@@ -61,8 +61,9 @@ enum class ScannerState : uint8_t {
|
||||
};
|
||||
|
||||
/// Subscriber slot for scanner-state transitions; same shape as
|
||||
/// RawAdvertisementCallback. Hubs that cannot push simply never invoke it and
|
||||
/// the consumer falls back to polling scan_running().
|
||||
/// RawAdvertisementCallback, delivered on the ESPHome main loop. Hubs that
|
||||
/// cannot push drop the registration and the consumer falls back to polling
|
||||
/// scan_running().
|
||||
struct ScannerStateCallback {
|
||||
void *instance{nullptr};
|
||||
void (*fn)(void *instance, ScannerState state){nullptr};
|
||||
@@ -99,10 +100,19 @@ class BLEHub {
|
||||
/// Wire the raw-advertisement stream (bluetooth_proxy). One consumer at a time.
|
||||
virtual void set_raw_advertisement_callback(RawAdvertisementCallback callback) = 0;
|
||||
|
||||
/// Push subscriber for scanner-state transitions (stored here; hubs invoke
|
||||
/// scanner_state_callback_ where their state changes, if they can push).
|
||||
#ifdef USE_BLE_SCANNER_STATE_CALLBACK
|
||||
/// Push subscriber for scanner-state transitions; hubs that can push
|
||||
/// invoke scanner_state_callback_ where their state changes. Compiled only
|
||||
/// when a subscriber exists (bluetooth_proxy emits the define), so
|
||||
/// subscriber-less builds carry no storage.
|
||||
void set_scanner_state_callback(ScannerStateCallback callback) { this->scanner_state_callback_ = callback; }
|
||||
|
||||
protected:
|
||||
ScannerStateCallback scanner_state_callback_{};
|
||||
|
||||
public:
|
||||
#endif // USE_BLE_SCANNER_STATE_CALLBACK
|
||||
|
||||
virtual HubCapabilities get_capabilities() const = 0;
|
||||
|
||||
/// Adapter MAC in printable (MSB-first) order, out[0] = MSB.
|
||||
@@ -122,9 +132,6 @@ class BLEHub {
|
||||
/// HubCapabilities::scan_mode_switch, so consumers can gate features on the
|
||||
/// switch without probing.
|
||||
virtual bool request_scan_mode(bool active) { return false; }
|
||||
|
||||
protected:
|
||||
ScannerStateCallback scanner_state_callback_{};
|
||||
};
|
||||
|
||||
} // namespace esphome::ble_device_base
|
||||
|
||||
@@ -426,3 +426,5 @@ async def to_code(config: ConfigType) -> None:
|
||||
cg.add_define("BLUETOOTH_PROXY_ADVERTISEMENT_BATCH_SIZE", 16)
|
||||
|
||||
cg.add_define("USE_BLUETOOTH_PROXY")
|
||||
# Compiles the scanner-state push slot into the hub (see ble_hub.h).
|
||||
cg.add_define("USE_BLE_SCANNER_STATE_CALLBACK")
|
||||
|
||||
@@ -27,16 +27,20 @@ BluetoothProxy::BluetoothProxy() { global_bluetooth_proxy = this; }
|
||||
|
||||
// The neutral enum's values are the wire values.
|
||||
static_assert(static_cast<uint32_t>(ble_device_base::ScannerState::IDLE) == api::enums::BLUETOOTH_SCANNER_STATE_IDLE);
|
||||
static_assert(static_cast<uint32_t>(ble_device_base::ScannerState::STARTING) ==
|
||||
api::enums::BLUETOOTH_SCANNER_STATE_STARTING);
|
||||
static_assert(static_cast<uint32_t>(ble_device_base::ScannerState::RUNNING) ==
|
||||
api::enums::BLUETOOTH_SCANNER_STATE_RUNNING);
|
||||
static_assert(static_cast<uint32_t>(ble_device_base::ScannerState::FAILED) ==
|
||||
api::enums::BLUETOOTH_SCANNER_STATE_FAILED);
|
||||
static_assert(static_cast<uint32_t>(ble_device_base::ScannerState::STOPPING) ==
|
||||
api::enums::BLUETOOTH_SCANNER_STATE_STOPPING);
|
||||
static_assert(static_cast<uint32_t>(ble_device_base::ScannerState::STOPPED) ==
|
||||
api::enums::BLUETOOTH_SCANNER_STATE_STOPPED);
|
||||
|
||||
void BluetoothProxy::on_scanner_state_(ble_device_base::ScannerState state) {
|
||||
if (this->api_connection_ != nullptr) {
|
||||
this->send_bluetooth_scanner_state_(state);
|
||||
}
|
||||
}
|
||||
|
||||
bool BluetoothProxy::send_bluetooth_scanner_state_(ble_device_base::ScannerState state) {
|
||||
if (this->api_connection_ == nullptr)
|
||||
return false;
|
||||
api::BluetoothScannerStateResponse resp;
|
||||
resp.state = static_cast<api::enums::BluetoothScannerState>(state);
|
||||
resp.mode = this->hub_->scan_active() ? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
|
||||
@@ -72,7 +76,7 @@ void BluetoothProxy::setup() {
|
||||
static_cast<BluetoothProxy *>(self)->on_raw_advertisement_(adv);
|
||||
}});
|
||||
this->hub_->set_scanner_state_callback({this, [](void *self, ble_device_base::ScannerState state) {
|
||||
static_cast<BluetoothProxy *>(self)->on_scanner_state_(state);
|
||||
static_cast<BluetoothProxy *>(self)->send_bluetooth_scanner_state_(state);
|
||||
}});
|
||||
}
|
||||
|
||||
@@ -503,7 +507,8 @@ void BluetoothProxy::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
// The hub has no scanner-state listener interface; poll and report on change.
|
||||
// This hub doesn't push scanner-state transitions; poll and report on
|
||||
// change. A hub gaining push must also refresh last_scan_running_ here.
|
||||
if (this->hub_->scan_running() != this->last_scan_running_) {
|
||||
this->send_polled_scanner_state_();
|
||||
}
|
||||
@@ -614,7 +619,7 @@ void BluetoothProxy::subscribe_api_connection(api::APIConnection *api_connection
|
||||
}
|
||||
this->api_connection_ = api_connection;
|
||||
#ifdef USE_ESP32
|
||||
this->send_bluetooth_scanner_state_(static_cast<ble_device_base::ScannerState>(this->parent_()->get_scanner_state()));
|
||||
this->send_bluetooth_scanner_state_(this->parent_()->get_scanner_state());
|
||||
#else
|
||||
this->send_polled_scanner_state_();
|
||||
#endif
|
||||
|
||||
@@ -412,16 +412,14 @@ void ESP32BLETracker::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i
|
||||
#endif
|
||||
}
|
||||
|
||||
// The neutral enum mirrors this tracker's wire-aligned values.
|
||||
static_assert(static_cast<int>(ScannerState::IDLE) == static_cast<int>(ble_device_base::ScannerState::IDLE));
|
||||
static_assert(static_cast<int>(ScannerState::STOPPING) == static_cast<int>(ble_device_base::ScannerState::STOPPING));
|
||||
|
||||
void ESP32BLETracker::set_scanner_state_(ScannerState state) {
|
||||
this->scanner_state_ = state;
|
||||
this->state_version_++;
|
||||
#ifdef USE_BLE_SCANNER_STATE_CALLBACK
|
||||
if (this->scanner_state_callback_.is_set()) {
|
||||
this->scanner_state_callback_.invoke(static_cast<ble_device_base::ScannerState>(state));
|
||||
this->scanner_state_callback_.invoke(state);
|
||||
}
|
||||
#endif
|
||||
#ifdef ESPHOME_ESP32_BLE_TRACKER_SCANNER_STATE_LISTENER_COUNT
|
||||
for (auto *listener : this->scanner_state_listeners_) {
|
||||
listener->on_scanner_state(state);
|
||||
|
||||
@@ -89,18 +89,8 @@ using ClientState = ble_device_base::ClientState;
|
||||
using ConnectionType = ble_device_base::ConnectionType;
|
||||
using ble_device_base::client_state_to_string;
|
||||
|
||||
enum class ScannerState {
|
||||
// Scanner is idle, init state
|
||||
IDLE,
|
||||
// Scanner is starting
|
||||
STARTING,
|
||||
// Scanner is running
|
||||
RUNNING,
|
||||
// Scanner failed to start
|
||||
FAILED,
|
||||
// Scanner is stopping
|
||||
STOPPING,
|
||||
};
|
||||
// Neutral scanner lifecycle re-exported for backward compatibility.
|
||||
using ScannerState = ble_device_base::ScannerState;
|
||||
|
||||
/** Listener interface for BLE scanner state changes.
|
||||
*
|
||||
|
||||
@@ -252,6 +252,7 @@
|
||||
// platforms whose API/network types the proxy header cannot assume.
|
||||
#if defined(USE_ESP32) || defined(USE_LIBRETINY) || defined(USE_RP2)
|
||||
#define USE_BLUETOOTH_PROXY
|
||||
#define USE_BLE_SCANNER_STATE_CALLBACK
|
||||
// Mirror the codegen values per platform: _to_code_esp32() emits the connection
|
||||
// count (default 3), _to_code_ble_hub() emits the slot count (1 on rp2, 0 on
|
||||
// advertisement-only hubs) — so static analysis checks the same
|
||||
|
||||
Reference in New Issue
Block a user