[bk72xx_ble] Codegen-sized StaticVector for scan listeners (#18055)

This commit is contained in:
Edvard Filistovič
2026-08-04 04:31:43 +00:00
committed by GitHub
parent 4ceae9cf85
commit dbf7167622
5 changed files with 36 additions and 2 deletions
+20
View File
@@ -24,6 +24,7 @@ from esphome.components import libretiny
from esphome.components.libretiny.const import FAMILY_BK7231N, FAMILY_BK7238
import esphome.config_validation as cv
from esphome.const import CONF_ENABLE_ON_BOOT, CONF_ID
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.types import ConfigType
DEPENDENCIES = ["bk72xx"]
@@ -45,6 +46,23 @@ CONFIG_SCHEMA = cv.Schema(
).extend(cv.COMPONENT_SCHEMA)
KEY_SCAN_LISTENER_COUNT = "bk72xx_ble_scan_listener_count"
def request_scan_listener_slot() -> None:
"""Called from a consumer's codegen once per registered scan listener; sizes
the controller's StaticVector listener storage (heap-free, mirrors the
tracker's ble_device_base listener storage)."""
CORE.data[KEY_SCAN_LISTENER_COUNT] = CORE.data.get(KEY_SCAN_LISTENER_COUNT, 0) + 1
@coroutine_with_priority(CoroPriority.FINAL)
async def _add_listener_count() -> None:
# FINAL: every consumer's to_code has requested its slot by now.
if count := CORE.data.get(KEY_SCAN_LISTENER_COUNT, 0):
cg.add_define("BK72XX_BLE_SCAN_LISTENER_COUNT", count)
async def to_code(config: ConfigType) -> None:
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
@@ -92,3 +110,5 @@ async def to_code(config: ConfigType) -> None:
)
cg.add_define("USE_BK72XX_BLE")
CORE.add_job(_add_listener_count)
@@ -179,8 +179,10 @@ void BK72xxBLE::loop() {
if (report == nullptr)
return;
do {
#ifdef BK72XX_BLE_SCAN_LISTENER_COUNT
for (auto *listener : this->scan_listeners_)
listener->on_scan_report(*report);
#endif
this->report_pool_.release(report);
} while ((report = this->report_queue_.pop()) != nullptr);
+10 -2
View File
@@ -6,10 +6,10 @@
#include "esphome/core/component.h"
#include "esphome/core/event_pool.h"
#include "esphome/core/helpers.h"
#include "esphome/core/lock_free_queue.h"
#include <cstdint>
#include <vector>
namespace esphome::bk72xx_ble {
@@ -62,8 +62,12 @@ class BK72xxBLE final : public Component {
/// Controller BLE address, least-significant octet first (BLE convention).
void get_mac_lsb_first(uint8_t out[6]) const;
#ifdef BK72XX_BLE_SCAN_LISTENER_COUNT
/// Register a consumer for scan reports (delivered on the main task via loop()).
/// Storage is codegen-sized: the consumer's codegen requests a slot via
/// request_scan_listener_slot(), which emits BK72XX_BLE_SCAN_LISTENER_COUNT.
void register_scan_listener(BLEScanListener *listener) { this->scan_listeners_.push_back(listener); }
#endif
/// Start the controller scan. Interval/window are in BLE units (0.625 ms).
/// Enables the stack first if needed. Returns false on controller failure.
@@ -78,7 +82,11 @@ class BK72xxBLE final : public Component {
protected:
void resolve_mac_();
std::vector<BLEScanListener *> scan_listeners_;
#ifdef BK72XX_BLE_SCAN_LISTENER_COUNT
// Codegen-sized: no heap allocation, no std::vector template instantiation —
// the same StaticVector pattern as the tracker's ble_device_base listeners.
StaticVector<BLEScanListener *, BK72XX_BLE_SCAN_LISTENER_COUNT> scan_listeners_;
#endif
// Report ring: the BDK notice callback (BLE task) allocates a report from the
// pool, fills it and pushes the pointer; loop() pops, dispatches and releases.
// Lock-free SPSC, zero allocation at steady state — the esp32_ble pattern.
@@ -69,6 +69,9 @@ async def to_code(config: ConfigType) -> None:
parent = await cg.get_variable(config[CONF_BK72XX_BLE_ID])
cg.add(var.set_parent(parent))
# The tracker registers itself as a controller scan listener in setup();
# request the codegen-sized StaticVector slot for it.
bk72xx_ble.request_scan_listener_slot()
# Get notified when an OTA update starts, to pause scanning (esp32_ble_tracker parity)
ota.request_ota_state_listeners()
+1
View File
@@ -454,6 +454,7 @@
#ifdef USE_LIBRETINY
#define USE_BK72XX_BLE
#define BK72XX_BLE_SCAN_LISTENER_COUNT 1
#define USE_LN882H_BLE
#define LN882H_BLE_SCAN_LISTENER_COUNT 1
#define USE_CAPTIVE_PORTAL