ESPHome 2026.8.0b4
Loading...
Searching...
No Matches
rp2_ble_tracker.h
Go to the documentation of this file.
1#pragma once
2
3#ifdef USE_RP2
4
11
12#include <cstdint>
13
14#ifdef USE_OTA_STATE_LISTENER
16#endif
17
19
20class RP2BLETracker : public Component,
22 public Parented<rp2040_ble::RP2040BLE>
23#ifdef USE_OTA_STATE_LISTENER
24 ,
26#endif
27{
28 public:
29 // ---- ESPHome Component ----
30 void setup() override;
31 void loop() override;
32 void dump_config() override;
33 float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
34
35#ifdef USE_OTA_STATE_LISTENER
36 // Pause scanning while an OTA update runs (the BLE scan competes with the OTA
37 // download on the shared CYW43 radio); mirrors esp32_ble_tracker.
38 void on_ota_global_state(ota::OTAState state, float progress, uint8_t error, ota::OTAComponent *comp) override;
39#endif
40
41 // ---- YAML configuration setters ----
42 void set_scan_interval(uint32_t scan_interval) { this->scan_interval_ = scan_interval; }
43 void set_scan_window(uint32_t scan_window) { this->scan_window_ = scan_window; }
44 void set_scan_duration(uint32_t scan_duration) { this->scan_duration_ = scan_duration; }
46 void set_scan_continuous(bool scan_continuous) { this->scan_continuous_ = scan_continuous; }
47
48 // ---- Public scan control ----
49 // Mirrors esp32_ble_tracker: set_scan_continuous() + start_scan() / stop_scan().
50 void start_scan();
51 void stop_scan();
52
53 // ---- ble_device_base::BLEHub contract ----
61 // BTstack delivers scan responses as separate advertisement reports; this
62 // tracker merges the pair before delivery (shared ScanResponseMerger,
63 // Bluedroid semantics). GATT is available when the BTstack connection
64 // backend is compiled in (bluetooth_proxy active).
65#ifdef USE_BLE_GATT_CLIENT
66 constexpr bool has_gatt = true;
67#else
68 constexpr bool has_gatt = false;
69#endif
70 return {.active_scan = true, .merges_scan_response = true, .gatt = has_gatt, .scan_mode_switch = true};
71 }
72 // The controller stores the address in printable (MSB-first) order, which is
73 // exactly what the contract wants.
74 void get_adapter_mac(uint8_t out[MAC_ADDRESS_SIZE]) { this->parent_->get_mac_msb_first(out); }
75 bool scan_running() { return this->scan_running_; }
76 bool scan_active() { return this->scan_active_; }
77 bool request_scan_mode(bool active);
78
79 // ---- rp2040_ble::BLEScanListener ----
80 // Delivered by the controller's loop() on the ESPHome main loop — the
81 // IRQ → main-loop handoff already happened in the controller's queue.
82 void on_scan_report(const rp2040_ble::BLEScanReport &report) override;
83
84 protected:
85 void start_scan_();
87 void stop_scan_();
88 void fire_scan_end_();
89
90 // Defaults: 30 % duty cycle (interval 100 ms / window 30 ms), in 0.625 ms
91 // BLE units — same defaults as bk72xx_ble_tracker.
92 uint32_t scan_interval_{160}; // 160 × 0.625 ms = 100 ms
93 uint32_t scan_window_{48}; // 48 × 0.625 ms = 30 ms (30/100 = 30 %)
95 uint32_t last_scan_start_attempt_{0}; // loop time of last start_scan_() attempt; rate-limits retries
96 uint32_t scan_period_start_{0}; // loop time at start of current scan period; rate-limits on_scan_end()
97 bool scan_running_{false};
98 bool scan_active_{true};
99 bool scan_continuous_{true};
100#ifdef USE_OTA_STATE_LISTENER
101 bool scan_continuous_before_ota_{false}; // continuous mode saved at OTA start, restored on OTA failure
102 bool scan_pending_before_ota_{false}; // one-shot scan in flight at OTA start, resumed on OTA failure
103#endif
104
105 // Shared adv + scan-response merge and frame dispatch (ble_device_base).
106 // All calls run on the main loop. Merger clock: stash_adv() reads the
107 // PARENT's cached loop time (on_scan_report runs inside rp2040_ble's queue
108 // drain), sweep() this component's — same App.loop() pass, so the delta
109 // stays non-negative and the 300 ms timeout holds.
112};
113
114} // namespace esphome::rp2_ble_tracker
115
116#endif // USE_RP2
Helper class to easily give an object a parent of type T.
Definition helpers.h:1907
The delivery half of a split-report tracker, shared so the dispatch contract (raw-callback ordering,...
void set_raw_advertisement_callback(RawAdvertisementCallback callback)
void register_listener(ESPBTDeviceListener *listener)
Listener interface for global OTA state changes (includes OTA component pointer).
Consumer interface for controller scan reports.
Definition rp2040_ble.h:49
void get_mac_msb_first(uint8_t out[MAC_ADDRESS_SIZE]) const
Controller BLE address in printable (MSB-first) order, as gap_local_bd_addr() delivers it — note BLES...
void set_scan_continuous(bool scan_continuous)
ble_device_base::AdvDispatcher dispatcher_
void set_raw_advertisement_callback(ble_device_base::RawAdvertisementCallback callback)
static constexpr ble_device_base::HubCapabilities get_capabilities()
void set_scan_duration(uint32_t scan_duration)
void set_scan_window(uint32_t scan_window)
void on_scan_report(const rp2040_ble::BLEScanReport &report) override
ble_device_base::ScanResponseMerger merger_
void register_listener(ble_device_base::ESPBTDeviceListener *listener)
void get_adapter_mac(uint8_t out[MAC_ADDRESS_SIZE])
void set_scan_interval(uint32_t scan_interval)
void on_ota_global_state(ota::OTAState state, float progress, uint8_t error, ota::OTAComponent *comp) override
bool state
Definition fan.h:2
constexpr float AFTER_WIFI
For components that should be initialized after WiFi is connected.
Definition component.h:55
static void uint32_t
What a tracker's controller/SDK can do — consumers branch on data, not #ifdefs.
Definition ble_hub.h:73
Subscriber slot for the raw-advertisement stream (the bluetooth_proxy path).
Definition ble_hub.h:43
One advertisement report from the controller.
Definition rp2040_ble.h:27