ESPHome 2026.9.0-dev
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; }
51 bool scan_continuous() const { return this->scan_continuous_; }
52 bool configured_continuous() const { return this->configured_continuous_; }
53
54 // ---- Public scan control ----
55 // Mirrors esp32_ble_tracker: set_scan_continuous() + start_scan() / stop_scan().
56 void start_scan();
57 void stop_scan();
58 // Re-anchors the one-shot duration clock only (bk72xx parity); no-op while
59 // idle. Policy lives in the action.
61
62 // ---- ble_device_base::BLEHub contract ----
70 // Scan responses arrive separately and are merged before delivery
71 // (Bluedroid semantics). GATT needs the BTstack connection backend.
72#ifdef USE_BLE_GATT_CLIENT
73 constexpr bool has_gatt = true;
74#else
75 constexpr bool has_gatt = false;
76#endif
77 return {.active_scan = true, .merges_scan_response = true, .gatt = has_gatt, .scan_mode_switch = true};
78 }
79 // The controller stores the address in printable (MSB-first) order, which is
80 // exactly what the contract wants.
81 void get_adapter_mac(uint8_t out[MAC_ADDRESS_SIZE]) { this->parent_->get_mac_msb_first(out); }
82 bool scan_running() { return this->scan_running_; }
83 bool scan_active() { return this->scan_active_; }
84 bool request_scan_mode(bool active);
85
86 // ---- rp2040_ble::BLEScanListener ----
87 // Delivered on the main loop; the controller's queue did the IRQ handoff.
88 void on_scan_report(const rp2040_ble::BLEScanReport &report) override;
89
90 protected:
91 void start_scan_();
93 void stop_scan_();
94 void fire_scan_end_();
95
96 // Defaults: 30 % duty cycle (interval 100 ms / window 30 ms), in 0.625 ms
97 // BLE units — same defaults as bk72xx_ble_tracker.
98 uint32_t scan_interval_{160}; // 160 × 0.625 ms = 100 ms
99 uint32_t scan_window_{48}; // 48 × 0.625 ms = 30 ms (30/100 = 30 %)
101 uint32_t last_scan_start_attempt_{0}; // loop time of last start_scan_() attempt; rate-limits retries
102 uint32_t scan_period_start_{0}; // continuous-mode on_scan_end period clock
103 uint32_t scan_start_time_{0}; // one-shot duration clock (bk72xx parity: kept separate from the period)
104 // Bit-packed (C++20 default member initializers on bit-fields);
105 // scan_continuous_ stays a plain bool because the merger binds its address.
106 bool scan_running_ : 1 {false};
107 bool pending_start_ : 1 {false}; // start_scan() latched before setup() or while the stack is
108 // not ACTIVE; loop() applies it once it is
109 bool last_start_failed_ : 1 {false}; // last controller start failed; gates the public start_scan() floor
110 bool scan_active_ : 1 {true};
111 bool configured_continuous_ : 1 {true}; // YAML scan_parameters.continuous; runtime stop_scan() must not lose it
113#ifdef USE_OTA_STATE_LISTENER
114 // Resume intent for a failed/aborted OTA: seeded at OTA start, overwritten
115 // by a start/stop during the download, except from the pause's own stop.
116 bool scan_continuous_before_ota_ : 1 {false}; // resume continuous
117 bool scan_pending_before_ota_ : 1 {false}; // resume a one-shot scan
118 bool ota_in_progress_ : 1 {false}; // OTA holds the radio; start_scan() defers to the resume path
119 bool ota_pausing_ : 1 {false}; // inside the OTA's own stop_scan(); its latch clear is skipped
120#endif
121
122 // Shared merge + dispatch (ble_device_base), all on the main loop.
123 // stash_adv() uses the parent's cached loop time and sweep() this one's -
124 // same App.loop() pass, so the merger delta stays non-negative.
127};
128
129} // namespace esphome::rp2_ble_tracker
130
131#endif // USE_RP2
Helper class to easily give an object a parent of type T.
Definition helpers.h:1910
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_configured_continuous(bool scan_continuous)
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