mirror of
https://github.com/esphome/esphome.git
synced 2026-05-30 15:28:34 +08:00
[esp32_ble] Devirtualize BLE event handler dispatch (#15310)
This commit is contained in:
@@ -134,10 +134,38 @@ class HandlerCounts:
|
|||||||
_handler_counts = HandlerCounts()
|
_handler_counts = HandlerCounts()
|
||||||
|
|
||||||
|
|
||||||
|
def _add_callback(
|
||||||
|
parent_var: cg.MockObj,
|
||||||
|
method: str,
|
||||||
|
handler_var: cg.MockObj,
|
||||||
|
params: str,
|
||||||
|
call_args: str,
|
||||||
|
) -> None:
|
||||||
|
"""Generate a lambda callback that forwards to a handler method.
|
||||||
|
|
||||||
|
Uses a braced scope with a local pointer variable so the generated C++
|
||||||
|
lambda captures only that pointer, avoiding GCC warnings about capturing
|
||||||
|
variables with static storage duration.
|
||||||
|
"""
|
||||||
|
cg.add(
|
||||||
|
cg.RawStatement(
|
||||||
|
f"{{ auto *h = {handler_var}; "
|
||||||
|
f"{parent_var}->{method}("
|
||||||
|
f"[h]({params}) {{ h->{call_args}; }}); }}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def register_gap_event_handler(parent_var: cg.MockObj, handler_var: cg.MockObj) -> None:
|
def register_gap_event_handler(parent_var: cg.MockObj, handler_var: cg.MockObj) -> None:
|
||||||
"""Register a GAP event handler and track the count."""
|
"""Register a GAP event handler and track the count."""
|
||||||
_handler_counts.gap_event += 1
|
_handler_counts.gap_event += 1
|
||||||
cg.add(parent_var.register_gap_event_handler(handler_var))
|
_add_callback(
|
||||||
|
parent_var,
|
||||||
|
"add_gap_event_callback",
|
||||||
|
handler_var,
|
||||||
|
"esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param",
|
||||||
|
"gap_event_handler(event, param)",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def register_gap_scan_event_handler(
|
def register_gap_scan_event_handler(
|
||||||
@@ -145,7 +173,13 @@ def register_gap_scan_event_handler(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Register a GAP scan event handler and track the count."""
|
"""Register a GAP scan event handler and track the count."""
|
||||||
_handler_counts.gap_scan_event += 1
|
_handler_counts.gap_scan_event += 1
|
||||||
cg.add(parent_var.register_gap_scan_event_handler(handler_var))
|
_add_callback(
|
||||||
|
parent_var,
|
||||||
|
"add_gap_scan_event_callback",
|
||||||
|
handler_var,
|
||||||
|
"const esphome::esp32_ble::BLEScanResult &scan_result",
|
||||||
|
"gap_scan_event_handler(scan_result)",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def register_gattc_event_handler(
|
def register_gattc_event_handler(
|
||||||
@@ -153,7 +187,13 @@ def register_gattc_event_handler(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Register a GATTc event handler and track the count."""
|
"""Register a GATTc event handler and track the count."""
|
||||||
_handler_counts.gattc_event += 1
|
_handler_counts.gattc_event += 1
|
||||||
cg.add(parent_var.register_gattc_event_handler(handler_var))
|
_add_callback(
|
||||||
|
parent_var,
|
||||||
|
"add_gattc_event_callback",
|
||||||
|
handler_var,
|
||||||
|
"esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param",
|
||||||
|
"gattc_event_handler(event, gattc_if, param)",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def register_gatts_event_handler(
|
def register_gatts_event_handler(
|
||||||
@@ -161,7 +201,13 @@ def register_gatts_event_handler(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Register a GATTs event handler and track the count."""
|
"""Register a GATTs event handler and track the count."""
|
||||||
_handler_counts.gatts_event += 1
|
_handler_counts.gatts_event += 1
|
||||||
cg.add(parent_var.register_gatts_event_handler(handler_var))
|
_add_callback(
|
||||||
|
parent_var,
|
||||||
|
"add_gatts_event_callback",
|
||||||
|
handler_var,
|
||||||
|
"esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param",
|
||||||
|
"gatts_event_handler(event, gatts_if, param)",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def register_ble_status_event_handler(
|
def register_ble_status_event_handler(
|
||||||
@@ -169,7 +215,13 @@ def register_ble_status_event_handler(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Register a BLE status event handler and track the count."""
|
"""Register a BLE status event handler and track the count."""
|
||||||
_handler_counts.ble_status_event += 1
|
_handler_counts.ble_status_event += 1
|
||||||
cg.add(parent_var.register_ble_status_event_handler(handler_var))
|
_add_callback(
|
||||||
|
parent_var,
|
||||||
|
"add_ble_status_event_callback",
|
||||||
|
handler_var,
|
||||||
|
"",
|
||||||
|
"ble_before_disabled_event_handler()",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def register_bt_logger(*loggers: BTLoggers) -> None:
|
def register_bt_logger(*loggers: BTLoggers) -> None:
|
||||||
@@ -225,10 +277,6 @@ NO_BLUETOOTH_VARIANTS = [const.VARIANT_ESP32S2]
|
|||||||
esp32_ble_ns = cg.esphome_ns.namespace("esp32_ble")
|
esp32_ble_ns = cg.esphome_ns.namespace("esp32_ble")
|
||||||
ESP32BLE = esp32_ble_ns.class_("ESP32BLE", cg.Component)
|
ESP32BLE = esp32_ble_ns.class_("ESP32BLE", cg.Component)
|
||||||
|
|
||||||
GAPEventHandler = esp32_ble_ns.class_("GAPEventHandler")
|
|
||||||
GATTcEventHandler = esp32_ble_ns.class_("GATTcEventHandler")
|
|
||||||
GATTsEventHandler = esp32_ble_ns.class_("GATTsEventHandler")
|
|
||||||
|
|
||||||
BLEEnabledCondition = esp32_ble_ns.class_("BLEEnabledCondition", automation.Condition)
|
BLEEnabledCondition = esp32_ble_ns.class_("BLEEnabledCondition", automation.Condition)
|
||||||
BLEEnableAction = esp32_ble_ns.class_("BLEEnableAction", automation.Action)
|
BLEEnableAction = esp32_ble_ns.class_("BLEEnableAction", automation.Action)
|
||||||
BLEDisableAction = esp32_ble_ns.class_("BLEDisableAction", automation.Action)
|
BLEDisableAction = esp32_ble_ns.class_("BLEDisableAction", automation.Action)
|
||||||
|
|||||||
@@ -408,9 +408,7 @@ void ESP32BLE::loop() {
|
|||||||
esp_gatt_if_t gatts_if = ble_event->event_.gatts.gatts_if;
|
esp_gatt_if_t gatts_if = ble_event->event_.gatts.gatts_if;
|
||||||
esp_ble_gatts_cb_param_t *param = &ble_event->event_.gatts.gatts_param;
|
esp_ble_gatts_cb_param_t *param = &ble_event->event_.gatts.gatts_param;
|
||||||
ESP_LOGV(TAG, "gatts_event [esp_gatt_if: %d] - %d", gatts_if, event);
|
ESP_LOGV(TAG, "gatts_event [esp_gatt_if: %d] - %d", gatts_if, event);
|
||||||
for (auto *gatts_handler : this->gatts_event_handlers_) {
|
this->gatts_event_callbacks_.call(event, gatts_if, param);
|
||||||
gatts_handler->gatts_event_handler(event, gatts_if, param);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -420,9 +418,7 @@ void ESP32BLE::loop() {
|
|||||||
esp_gatt_if_t gattc_if = ble_event->event_.gattc.gattc_if;
|
esp_gatt_if_t gattc_if = ble_event->event_.gattc.gattc_if;
|
||||||
esp_ble_gattc_cb_param_t *param = &ble_event->event_.gattc.gattc_param;
|
esp_ble_gattc_cb_param_t *param = &ble_event->event_.gattc.gattc_param;
|
||||||
ESP_LOGV(TAG, "gattc_event [esp_gatt_if: %d] - %d", gattc_if, event);
|
ESP_LOGV(TAG, "gattc_event [esp_gatt_if: %d] - %d", gattc_if, event);
|
||||||
for (auto *gattc_handler : this->gattc_event_handlers_) {
|
this->gattc_event_callbacks_.call(event, gattc_if, param);
|
||||||
gattc_handler->gattc_event_handler(event, gattc_if, param);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -431,10 +427,7 @@ void ESP32BLE::loop() {
|
|||||||
switch (gap_event) {
|
switch (gap_event) {
|
||||||
case ESP_GAP_BLE_SCAN_RESULT_EVT:
|
case ESP_GAP_BLE_SCAN_RESULT_EVT:
|
||||||
#ifdef ESPHOME_ESP32_BLE_GAP_SCAN_EVENT_HANDLER_COUNT
|
#ifdef ESPHOME_ESP32_BLE_GAP_SCAN_EVENT_HANDLER_COUNT
|
||||||
// Use the new scan event handler - no memcpy!
|
this->gap_scan_event_callbacks_.call(ble_event->scan_result());
|
||||||
for (auto *scan_handler : this->gap_scan_event_handlers_) {
|
|
||||||
scan_handler->gap_scan_event_handler(ble_event->scan_result());
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -478,9 +471,7 @@ void ESP32BLE::loop() {
|
|||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
// Dispatch to all registered handlers
|
// Dispatch to all registered handlers
|
||||||
for (auto *gap_handler : this->gap_event_handlers_) {
|
this->gap_event_callbacks_.call(gap_event, param);
|
||||||
gap_handler->gap_event_handler(gap_event, param);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@@ -518,9 +509,7 @@ void ESP32BLE::loop_handle_state_transition_not_active_() {
|
|||||||
ESP_LOGD(TAG, "Disabling");
|
ESP_LOGD(TAG, "Disabling");
|
||||||
|
|
||||||
#ifdef ESPHOME_ESP32_BLE_BLE_STATUS_EVENT_HANDLER_COUNT
|
#ifdef ESPHOME_ESP32_BLE_BLE_STATUS_EVENT_HANDLER_COUNT
|
||||||
for (auto *ble_event_handler : this->ble_status_event_handlers_) {
|
this->ble_status_event_callbacks_.call();
|
||||||
ble_event_handler->ble_before_disabled_event_handler();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!ble_dismantle_()) {
|
if (!ble_dismantle_()) {
|
||||||
|
|||||||
@@ -87,37 +87,6 @@ enum BLEComponentState : uint8_t {
|
|||||||
BLE_COMPONENT_STATE_ACTIVE,
|
BLE_COMPONENT_STATE_ACTIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
class GAPEventHandler {
|
|
||||||
public:
|
|
||||||
virtual void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GAPScanEventHandler {
|
|
||||||
public:
|
|
||||||
virtual void gap_scan_event_handler(const BLEScanResult &scan_result) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef USE_ESP32_BLE_CLIENT
|
|
||||||
class GATTcEventHandler {
|
|
||||||
public:
|
|
||||||
virtual void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
|
||||||
esp_ble_gattc_cb_param_t *param) = 0;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_ESP32_BLE_SERVER
|
|
||||||
class GATTsEventHandler {
|
|
||||||
public:
|
|
||||||
virtual void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
|
||||||
esp_ble_gatts_cb_param_t *param) = 0;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class BLEStatusEventHandler {
|
|
||||||
public:
|
|
||||||
virtual void ble_before_disabled_event_handler() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ESP32BLE : public Component {
|
class ESP32BLE : public Component {
|
||||||
public:
|
public:
|
||||||
void set_io_capability(IoCapability io_capability) { this->io_cap_ = (esp_ble_io_cap_t) io_capability; }
|
void set_io_capability(IoCapability io_capability) { this->io_cap_ = (esp_ble_io_cap_t) io_capability; }
|
||||||
@@ -154,22 +123,28 @@ class ESP32BLE : public Component {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ESPHOME_ESP32_BLE_GAP_EVENT_HANDLER_COUNT
|
#ifdef ESPHOME_ESP32_BLE_GAP_EVENT_HANDLER_COUNT
|
||||||
void register_gap_event_handler(GAPEventHandler *handler) { this->gap_event_handlers_.push_back(handler); }
|
template<typename F> void add_gap_event_callback(F &&callback) {
|
||||||
|
this->gap_event_callbacks_.add(std::forward<F>(callback));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef ESPHOME_ESP32_BLE_GAP_SCAN_EVENT_HANDLER_COUNT
|
#ifdef ESPHOME_ESP32_BLE_GAP_SCAN_EVENT_HANDLER_COUNT
|
||||||
void register_gap_scan_event_handler(GAPScanEventHandler *handler) {
|
template<typename F> void add_gap_scan_event_callback(F &&callback) {
|
||||||
this->gap_scan_event_handlers_.push_back(handler);
|
this->gap_scan_event_callbacks_.add(std::forward<F>(callback));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_ESP32_BLE_CLIENT) && defined(ESPHOME_ESP32_BLE_GATTC_EVENT_HANDLER_COUNT)
|
#if defined(USE_ESP32_BLE_CLIENT) && defined(ESPHOME_ESP32_BLE_GATTC_EVENT_HANDLER_COUNT)
|
||||||
void register_gattc_event_handler(GATTcEventHandler *handler) { this->gattc_event_handlers_.push_back(handler); }
|
template<typename F> void add_gattc_event_callback(F &&callback) {
|
||||||
|
this->gattc_event_callbacks_.add(std::forward<F>(callback));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_ESP32_BLE_SERVER) && defined(ESPHOME_ESP32_BLE_GATTS_EVENT_HANDLER_COUNT)
|
#if defined(USE_ESP32_BLE_SERVER) && defined(ESPHOME_ESP32_BLE_GATTS_EVENT_HANDLER_COUNT)
|
||||||
void register_gatts_event_handler(GATTsEventHandler *handler) { this->gatts_event_handlers_.push_back(handler); }
|
template<typename F> void add_gatts_event_callback(F &&callback) {
|
||||||
|
this->gatts_event_callbacks_.add(std::forward<F>(callback));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef ESPHOME_ESP32_BLE_BLE_STATUS_EVENT_HANDLER_COUNT
|
#ifdef ESPHOME_ESP32_BLE_BLE_STATUS_EVENT_HANDLER_COUNT
|
||||||
void register_ble_status_event_handler(BLEStatusEventHandler *handler) {
|
template<typename F> void add_ble_status_event_callback(F &&callback) {
|
||||||
this->ble_status_event_handlers_.push_back(handler);
|
this->ble_status_event_callbacks_.add(std::forward<F>(callback));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void set_enable_on_boot(bool enable_on_boot) { this->enable_on_boot_ = enable_on_boot; }
|
void set_enable_on_boot(bool enable_on_boot) { this->enable_on_boot_ = enable_on_boot; }
|
||||||
@@ -202,21 +177,27 @@ class ESP32BLE : public Component {
|
|||||||
private:
|
private:
|
||||||
template<typename... Args> friend void enqueue_ble_event(Args... args);
|
template<typename... Args> friend void enqueue_ble_event(Args... args);
|
||||||
|
|
||||||
// Handler vectors - use StaticVector when counts are known at compile time
|
|
||||||
#ifdef ESPHOME_ESP32_BLE_GAP_EVENT_HANDLER_COUNT
|
#ifdef ESPHOME_ESP32_BLE_GAP_EVENT_HANDLER_COUNT
|
||||||
StaticVector<GAPEventHandler *, ESPHOME_ESP32_BLE_GAP_EVENT_HANDLER_COUNT> gap_event_handlers_;
|
StaticCallbackManager<ESPHOME_ESP32_BLE_GAP_EVENT_HANDLER_COUNT,
|
||||||
|
void(esp_gap_ble_cb_event_t, esp_ble_gap_cb_param_t *)>
|
||||||
|
gap_event_callbacks_;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ESPHOME_ESP32_BLE_GAP_SCAN_EVENT_HANDLER_COUNT
|
#ifdef ESPHOME_ESP32_BLE_GAP_SCAN_EVENT_HANDLER_COUNT
|
||||||
StaticVector<GAPScanEventHandler *, ESPHOME_ESP32_BLE_GAP_SCAN_EVENT_HANDLER_COUNT> gap_scan_event_handlers_;
|
StaticCallbackManager<ESPHOME_ESP32_BLE_GAP_SCAN_EVENT_HANDLER_COUNT, void(const BLEScanResult &)>
|
||||||
|
gap_scan_event_callbacks_;
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_ESP32_BLE_CLIENT) && defined(ESPHOME_ESP32_BLE_GATTC_EVENT_HANDLER_COUNT)
|
#if defined(USE_ESP32_BLE_CLIENT) && defined(ESPHOME_ESP32_BLE_GATTC_EVENT_HANDLER_COUNT)
|
||||||
StaticVector<GATTcEventHandler *, ESPHOME_ESP32_BLE_GATTC_EVENT_HANDLER_COUNT> gattc_event_handlers_;
|
StaticCallbackManager<ESPHOME_ESP32_BLE_GATTC_EVENT_HANDLER_COUNT,
|
||||||
|
void(esp_gattc_cb_event_t, esp_gatt_if_t, esp_ble_gattc_cb_param_t *)>
|
||||||
|
gattc_event_callbacks_;
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_ESP32_BLE_SERVER) && defined(ESPHOME_ESP32_BLE_GATTS_EVENT_HANDLER_COUNT)
|
#if defined(USE_ESP32_BLE_SERVER) && defined(ESPHOME_ESP32_BLE_GATTS_EVENT_HANDLER_COUNT)
|
||||||
StaticVector<GATTsEventHandler *, ESPHOME_ESP32_BLE_GATTS_EVENT_HANDLER_COUNT> gatts_event_handlers_;
|
StaticCallbackManager<ESPHOME_ESP32_BLE_GATTS_EVENT_HANDLER_COUNT,
|
||||||
|
void(esp_gatts_cb_event_t, esp_gatt_if_t, esp_ble_gatts_cb_param_t *)>
|
||||||
|
gatts_event_callbacks_;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ESPHOME_ESP32_BLE_BLE_STATUS_EVENT_HANDLER_COUNT
|
#ifdef ESPHOME_ESP32_BLE_BLE_STATUS_EVENT_HANDLER_COUNT
|
||||||
StaticVector<BLEStatusEventHandler *, ESPHOME_ESP32_BLE_BLE_STATUS_EVENT_HANDLER_COUNT> ble_status_event_handlers_;
|
StaticCallbackManager<ESPHOME_ESP32_BLE_BLE_STATUS_EVENT_HANDLER_COUNT, void()> ble_status_event_callbacks_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Large objects (size depends on template parameters, but typically aligned to 4 bytes)
|
// Large objects (size depends on template parameters, but typically aligned to 4 bytes)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ esp32_ble_beacon_ns = cg.esphome_ns.namespace("esp32_ble_beacon")
|
|||||||
ESP32BLEBeacon = esp32_ble_beacon_ns.class_(
|
ESP32BLEBeacon = esp32_ble_beacon_ns.class_(
|
||||||
"ESP32BLEBeacon",
|
"ESP32BLEBeacon",
|
||||||
cg.Component,
|
cg.Component,
|
||||||
esp32_ble.GAPEventHandler,
|
|
||||||
cg.Parented.template(esp32_ble.ESP32BLE),
|
cg.Parented.template(esp32_ble.ESP32BLE),
|
||||||
)
|
)
|
||||||
CONF_MAJOR = "major"
|
CONF_MAJOR = "major"
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ using esp_ble_ibeacon_t = struct {
|
|||||||
|
|
||||||
using namespace esp32_ble;
|
using namespace esp32_ble;
|
||||||
|
|
||||||
class ESP32BLEBeacon : public Component, public GAPEventHandler, public Parented<ESP32BLE> {
|
class ESP32BLEBeacon : public Component, public Parented<ESP32BLE> {
|
||||||
public:
|
public:
|
||||||
explicit ESP32BLEBeacon(const std::array<uint8_t, 16> &uuid) : uuid_(uuid) {}
|
explicit ESP32BLEBeacon(const std::array<uint8_t, 16> &uuid) : uuid_(uuid) {}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ class ESP32BLEBeacon : public Component, public GAPEventHandler, public Parented
|
|||||||
#ifndef CONFIG_ESP_HOSTED_ENABLE_BT_BLUEDROID
|
#ifndef CONFIG_ESP_HOSTED_ENABLE_BT_BLUEDROID
|
||||||
void set_tx_power(esp_power_level_t val) { this->tx_power_ = val; }
|
void set_tx_power(esp_power_level_t val) { this->tx_power_ = val; }
|
||||||
#endif
|
#endif
|
||||||
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
|
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void on_advertise_();
|
void on_advertise_();
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ BLECharacteristic_ns = esp32_ble_server_ns.namespace("BLECharacteristic")
|
|||||||
BLEServer = esp32_ble_server_ns.class_(
|
BLEServer = esp32_ble_server_ns.class_(
|
||||||
"BLEServer",
|
"BLEServer",
|
||||||
cg.Component,
|
cg.Component,
|
||||||
esp32_ble.GATTsEventHandler,
|
|
||||||
cg.Parented.template(esp32_ble.ESP32BLE),
|
cg.Parented.template(esp32_ble.ESP32BLE),
|
||||||
)
|
)
|
||||||
esp32_ble_server_automations_ns = esp32_ble_server_ns.namespace(
|
esp32_ble_server_automations_ns = esp32_ble_server_ns.namespace(
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace esp32_ble_server {
|
|||||||
using namespace esp32_ble;
|
using namespace esp32_ble;
|
||||||
using namespace bytebuffer;
|
using namespace bytebuffer;
|
||||||
|
|
||||||
class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEventHandler, public Parented<ESP32BLE> {
|
class BLEServer : public Component, public Parented<ESP32BLE> {
|
||||||
public:
|
public:
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
@@ -53,10 +53,9 @@ class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEv
|
|||||||
const uint16_t *get_clients() const { return this->clients_; }
|
const uint16_t *get_clients() const { return this->clients_; }
|
||||||
uint8_t get_client_count() const { return this->client_count_; }
|
uint8_t get_client_count() const { return this->client_count_; }
|
||||||
|
|
||||||
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
|
||||||
esp_ble_gatts_cb_param_t *param) override;
|
|
||||||
|
|
||||||
void ble_before_disabled_event_handler() override;
|
void ble_before_disabled_event_handler();
|
||||||
|
|
||||||
// Direct callback registration - supports multiple callbacks
|
// Direct callback registration - supports multiple callbacks
|
||||||
void on_connect(std::function<void(uint16_t)> &&callback) {
|
void on_connect(std::function<void(uint16_t)> &&callback) {
|
||||||
|
|||||||
@@ -90,8 +90,6 @@ esp32_ble_tracker_ns = cg.esphome_ns.namespace("esp32_ble_tracker")
|
|||||||
ESP32BLETracker = esp32_ble_tracker_ns.class_(
|
ESP32BLETracker = esp32_ble_tracker_ns.class_(
|
||||||
"ESP32BLETracker",
|
"ESP32BLETracker",
|
||||||
cg.Component,
|
cg.Component,
|
||||||
esp32_ble.GAPEventHandler,
|
|
||||||
esp32_ble.GATTcEventHandler,
|
|
||||||
cg.Parented.template(esp32_ble.ESP32BLE),
|
cg.Parented.template(esp32_ble.ESP32BLE),
|
||||||
)
|
)
|
||||||
ESPBTClient = esp32_ble_tracker_ns.class_("ESPBTClient")
|
ESPBTClient = esp32_ble_tracker_ns.class_("ESPBTClient")
|
||||||
|
|||||||
@@ -291,10 +291,6 @@ class ESPBTClient : public ESPBTDeviceListener {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class ESP32BLETracker : public Component,
|
class ESP32BLETracker : public Component,
|
||||||
public GAPEventHandler,
|
|
||||||
public GAPScanEventHandler,
|
|
||||||
public GATTcEventHandler,
|
|
||||||
public BLEStatusEventHandler,
|
|
||||||
#ifdef USE_OTA_STATE_LISTENER
|
#ifdef USE_OTA_STATE_LISTENER
|
||||||
public ota::OTAGlobalStateListener,
|
public ota::OTAGlobalStateListener,
|
||||||
#endif
|
#endif
|
||||||
@@ -325,11 +321,10 @@ class ESP32BLETracker : public Component,
|
|||||||
void start_scan();
|
void start_scan();
|
||||||
void stop_scan();
|
void stop_scan();
|
||||||
|
|
||||||
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
|
||||||
esp_ble_gattc_cb_param_t *param) override;
|
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
|
||||||
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
|
void gap_scan_event_handler(const BLEScanResult &scan_result);
|
||||||
void gap_scan_event_handler(const BLEScanResult &scan_result) override;
|
void ble_before_disabled_event_handler();
|
||||||
void ble_before_disabled_event_handler() override;
|
|
||||||
|
|
||||||
#ifdef USE_OTA_STATE_LISTENER
|
#ifdef USE_OTA_STATE_LISTENER
|
||||||
void on_ota_global_state(ota::OTAState state, float progress, uint8_t error, ota::OTAComponent *comp) override;
|
void on_ota_global_state(ota::OTAState state, float progress, uint8_t error, ota::OTAComponent *comp) override;
|
||||||
|
|||||||
@@ -1830,6 +1830,38 @@ template<typename... Ts> class CallbackManager<void(Ts...)> {
|
|||||||
std::vector<Callback<void(Ts...)>> callbacks_;
|
std::vector<Callback<void(Ts...)>> callbacks_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** CallbackManager backed by StaticVector for compile-time-known callback counts.
|
||||||
|
*
|
||||||
|
* Drop-in replacement for CallbackManager that avoids std::vector template bloat
|
||||||
|
* (_M_realloc_insert, etc.) when the maximum number of callbacks is known at compile time.
|
||||||
|
*
|
||||||
|
* @tparam N Maximum number of callbacks (compile-time constant, typically from cg.add_define())
|
||||||
|
* @tparam Ts The arguments for the callbacks, wrapped in void().
|
||||||
|
*/
|
||||||
|
template<size_t N, typename... X> class StaticCallbackManager;
|
||||||
|
|
||||||
|
template<size_t N, typename... Ts> class StaticCallbackManager<N, void(Ts...)> {
|
||||||
|
public:
|
||||||
|
/// Add any callable. Small trivially-copyable callables (like [this] lambdas)
|
||||||
|
/// are stored inline without heap allocation.
|
||||||
|
template<typename F> void add(F &&callback) { this->add_(Callback<void(Ts...)>::create(std::forward<F>(callback))); }
|
||||||
|
|
||||||
|
/// Call all callbacks in this manager.
|
||||||
|
void call(Ts... args) {
|
||||||
|
for (auto &cb : this->callbacks_)
|
||||||
|
cb.call(args...);
|
||||||
|
}
|
||||||
|
size_t size() const { return this->callbacks_.size(); }
|
||||||
|
|
||||||
|
/// Call all callbacks in this manager.
|
||||||
|
void operator()(Ts... args) { call(args...); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Non-template core to avoid code duplication per lambda type.
|
||||||
|
void add_(Callback<void(Ts...)> cb) { this->callbacks_.push_back(cb); }
|
||||||
|
StaticVector<Callback<void(Ts...)>, N> callbacks_;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename... X> class LazyCallbackManager;
|
template<typename... X> class LazyCallbackManager;
|
||||||
|
|
||||||
/** Lazy-allocating callback manager that only allocates memory when callbacks are registered.
|
/** Lazy-allocating callback manager that only allocates memory when callbacks are registered.
|
||||||
|
|||||||
Reference in New Issue
Block a user