From c3b29fbfabc8aa8fb0445ec9837bf801994a2198 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Sat, 19 Oct 2024 20:00:19 +0200 Subject: [PATCH] Add connect, disconnect and fix notify --- .../components/esp32_ble_server/__init__.py | 30 +++++++---- .../esp32_ble_server/ble_characteristic.cpp | 53 ++++++++++++++----- .../esp32_ble_server/ble_characteristic.h | 10 ++-- .../esp32_ble_server/ble_descriptor.cpp | 5 +- .../esp32_ble_server/ble_descriptor.h | 5 +- .../esp32_ble_server/ble_server.cpp | 14 ++--- .../components/esp32_ble_server/ble_server.h | 22 +++++--- .../ble_server_automations.cpp | 34 ++++++++---- .../esp32_ble_server/ble_server_automations.h | 12 +++-- .../esp32_ble_server/ble_service.cpp | 13 ++--- .../components/esp32_ble_server/ble_service.h | 6 --- tests/components/esp32_ble_server/common.yaml | 23 +++++--- 12 files changed, 143 insertions(+), 84 deletions(-) diff --git a/esphome/components/esp32_ble_server/__init__.py b/esphome/components/esp32_ble_server/__init__.py index 1e9dc834fa..20868eb493 100644 --- a/esphome/components/esp32_ble_server/__init__.py +++ b/esphome/components/esp32_ble_server/__init__.py @@ -11,6 +11,8 @@ from esphome.const import ( CONF_SERVICES, CONF_VALUE, CONF_NOTIFY, + CONF_ON_CONNECT, + CONF_ON_DISCONNECT, ) from esphome.core import CORE @@ -142,7 +144,7 @@ def create_description_cud(char_config): def create_notify_cccd(char_config): - if not char_config[CONF_NOTIFY]: + if not char_config[CONF_NOTIFY] and not char_config[CONF_INDICATE]: return char_config # If the CCCD descriptor is already present, return the config for desc in char_config[CONF_DESCRIPTORS]: @@ -206,9 +208,7 @@ DESCRIPTOR_SCHEMA = cv.Schema( cv.Required(CONF_UUID): cv.Any(bt_uuid, cv.hex_uint32_t), cv.Optional(CONF_READ, default=True): cv.boolean, cv.Optional(CONF_WRITE, default=True): cv.boolean, - cv.Optional(CONF_ON_WRITE): automation.validate_automation( - {cv.GenerateID(): cv.declare_id(BLEDescriptor)}, single=True - ), + cv.Optional(CONF_ON_WRITE): automation.validate_automation(single=True), cv.Required(CONF_VALUE): VALUE_SCHEMA, }, extra_schemas=[validate_descritor_value_length, validate_desc_on_write], @@ -226,9 +226,7 @@ SERVICE_CHARACTERISTIC_SCHEMA = ( cv.Optional(CONF_DESCRIPTORS, default=[]): cv.ensure_list( DESCRIPTOR_SCHEMA ), - cv.Optional(CONF_ON_WRITE): automation.validate_automation( - {cv.GenerateID(): cv.declare_id(BLECharacteristic)}, single=True - ), + cv.Optional(CONF_ON_WRITE): automation.validate_automation(single=True), cv.Optional(CONF_DESCRIPTION): cv.string, cv.GenerateID(CONF_CUD_ID_): cv.declare_id(BLEDescriptor), cv.GenerateID(CONF_CUD_VALUE_BUFFER_): cv.declare_id(ByteBuffer), @@ -264,6 +262,8 @@ CONFIG_SCHEMA = cv.Schema( cv.Optional(CONF_MANUFACTURER_DATA): cv.Schema([cv.uint8_t]), cv.Optional(CONF_MODEL): cv.string, cv.Optional(CONF_SERVICES, default=[]): cv.ensure_list(SERVICE_SCHEMA), + cv.Optional(CONF_ON_CONNECT): automation.validate_automation(single=True), + cv.Optional(CONF_ON_DISCONNECT): automation.validate_automation(single=True), } ).extend(cv.COMPONENT_SCHEMA) @@ -380,7 +380,7 @@ async def to_code_descriptor(descriptor_conf, char_var): on_write_conf = descriptor_conf[CONF_ON_WRITE] await automation.build_automation( BLETriggers_ns.create_descriptor_on_write_trigger(desc_var), - [(cg.std_vector.template(cg.uint8), "x")], + [(cg.std_vector.template(cg.uint8), "x"), (cg.uint16, "id")], on_write_conf, ) @@ -397,7 +397,7 @@ async def to_code_characteristic(service_var, char_conf): on_write_conf = char_conf[CONF_ON_WRITE] await automation.build_automation( BLETriggers_ns.create_characteristic_on_write_trigger(char_var), - [(cg.std_vector.template(cg.uint8), "x")], + [(cg.std_vector.template(cg.uint8), "x"), (cg.uint16, "id")], on_write_conf, ) if CONF_VALUE in char_conf: @@ -447,6 +447,18 @@ async def to_code(config): for char_conf in service_config[CONF_CHARACTERISTICS]: await to_code_characteristic(service_var, char_conf) cg.add(var.enqueue_start_service(service_var)) + if CONF_ON_CONNECT in config: + await automation.build_automation( + BLETriggers_ns.create_server_on_connect_trigger(var), + [(cg.uint16, "id")], + config[CONF_ON_CONNECT], + ) + if CONF_ON_DISCONNECT in config: + await automation.build_automation( + BLETriggers_ns.create_server_on_disconnect_trigger(var), + [(cg.uint16, "id")], + config[CONF_ON_DISCONNECT], + ) cg.add_define("USE_ESP32_BLE_SERVER") if CORE.using_esp_idf: add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True) diff --git a/esphome/components/esp32_ble_server/ble_characteristic.cpp b/esphome/components/esp32_ble_server/ble_characteristic.cpp index 4a4aaa3569..c08963c243 100644 --- a/esphome/components/esp32_ble_server/ble_characteristic.cpp +++ b/esphome/components/esp32_ble_server/ble_characteristic.cpp @@ -38,19 +38,25 @@ void BLECharacteristic::set_value(ByteBuffer buffer) { xSemaphoreGive(this->set_value_lock_); } -void BLECharacteristic::notify(bool require_ack) { - if (require_ack) { - ESP_LOGW(TAG, "require_ack=true is not yet supported (i.e. INDICATE is not yet supported)"); - // TODO: Handle when require_ack=true - } +void BLECharacteristic::notify() { if (this->service_ == nullptr || this->service_->get_server() == nullptr || this->service_->get_server()->get_connected_client_count() == 0) return; for (auto &client : this->service_->get_server()->get_clients()) { size_t length = this->value_.size(); - esp_err_t err = esp_ble_gatts_send_indicate(this->service_->get_server()->get_gatts_if(), client.first, - this->handle_, length, this->value_.data(), false); + // If the client is not in the list of clients to notify, skip it + if (this->clients_to_notify_.count(client) == 0) + continue; + // If the client is in the list of clients to notify, check if it requires an ack (i.e. INDICATE) + bool require_ack = this->clients_to_notify_[client]; + // TODO: Remove this block when INDICATE acknowledgment is supported + if (require_ack) { + ESP_LOGW(TAG, "INDICATE acknowledgment is not yet supported (i.e. it works as a NOTIFY)"); + require_ack = false; + } + esp_err_t err = esp_ble_gatts_send_indicate(this->service_->get_server()->get_gatts_if(), client, + this->handle_, length, this->value_.data(), require_ack); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ble_gatts_send_indicate failed %d", err); return; @@ -58,7 +64,27 @@ void BLECharacteristic::notify(bool require_ack) { } } -void BLECharacteristic::add_descriptor(BLEDescriptor *descriptor) { this->descriptors_.push_back(descriptor); } +void BLECharacteristic::add_descriptor(BLEDescriptor *descriptor) { + // If the descriptor is the CCCD descriptor, listen to its write event to know if the client wants to be notified + if (descriptor->get_uuid() == ESPBTUUID::from_uint16(ESP_GATT_UUID_CHAR_CLIENT_CONFIG)) { + descriptor->on( + BLEDescriptorEvt::VectorEvt::ON_WRITE, + [this](const std::vector &value, uint16_t conn_id) { + if (value.size() != 2) + return; + uint16_t cccd = (value[1] << 8) | value[0]; + bool notify = (cccd & 1) != 0; + bool indicate = (cccd & 2) != 0; + if (notify || indicate) { + this->clients_to_notify_[conn_id] = indicate; + } else { + this->clients_to_notify_.erase(conn_id); + } + } + ); + } + this->descriptors_.push_back(descriptor); +} void BLECharacteristic::remove_descriptor(BLEDescriptor *descriptor) { this->descriptors_.erase(std::remove(this->descriptors_.begin(), this->descriptors_.end(), descriptor), @@ -178,7 +204,8 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt if (!param->read.need_rsp) break; // For some reason you can request a read but not want a response - this->EventEmitter::emit_(BLECharacteristicEvt::EmptyEvt::ON_READ); + this->EventEmitter::emit_( + BLECharacteristicEvt::EmptyEvt::ON_READ, param->read.conn_id); uint16_t max_offset = 22; @@ -246,8 +273,8 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt } if (!param->write.is_prep) { - this->EventEmitter>::emit_( - BLECharacteristicEvt::VectorEvt::ON_WRITE, this->value_); + this->EventEmitter, uint16_t>::emit_( + BLECharacteristicEvt::VectorEvt::ON_WRITE, this->value_, param->write.conn_id); } break; @@ -258,8 +285,8 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt break; this->write_event_ = false; if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) { - this->EventEmitter>::emit_( - BLECharacteristicEvt::VectorEvt::ON_WRITE, this->value_); + this->EventEmitter, uint16_t>::emit_( + BLECharacteristicEvt::VectorEvt::ON_WRITE, this->value_, param->exec_write.conn_id); } esp_err_t err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, nullptr); diff --git a/esphome/components/esp32_ble_server/ble_characteristic.h b/esphome/components/esp32_ble_server/ble_characteristic.h index 03d6c5034e..15a01c30df 100644 --- a/esphome/components/esp32_ble_server/ble_characteristic.h +++ b/esphome/components/esp32_ble_server/ble_characteristic.h @@ -6,6 +6,7 @@ #include "esphome/core/bytebuffer.h" #include +#include #ifdef USE_ESP32 @@ -34,8 +35,8 @@ enum EmptyEvt { }; } // namespace BLECharacteristicEvt -class BLECharacteristic : public EventEmitter>, - public EventEmitter { +class BLECharacteristic : public EventEmitter, uint16_t>, + public EventEmitter { public: BLECharacteristic(ESPBTUUID uuid, uint32_t properties); ~BLECharacteristic(); @@ -49,10 +50,10 @@ class BLECharacteristic : public EventEmitternotify(true); } - void notify(bool require_ack = false); + void notify(); void do_create(BLEService *service); + void do_delete() { this->clients_to_notify_.clear(); } void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); void add_descriptor(BLEDescriptor *descriptor); @@ -84,6 +85,7 @@ class BLECharacteristic : public EventEmitter descriptors_; + std::unordered_map clients_to_notify_; esp_gatt_perm_t permissions_ = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE; diff --git a/esphome/components/esp32_ble_server/ble_descriptor.cpp b/esphome/components/esp32_ble_server/ble_descriptor.cpp index a1196c8a27..095ace1755 100644 --- a/esphome/components/esp32_ble_server/ble_descriptor.cpp +++ b/esphome/components/esp32_ble_server/ble_descriptor.cpp @@ -72,9 +72,10 @@ void BLEDescriptor::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_ break; this->value_.attr_len = param->write.len; memcpy(this->value_.attr_value, param->write.value, param->write.len); - this->EventEmitter>::emit_( + this->emit_( BLEDescriptorEvt::VectorEvt::ON_WRITE, - std::vector(param->write.value, param->write.value + param->write.len) + std::vector(param->write.value, param->write.value + param->write.len), + param->write.conn_id ); break; } diff --git a/esphome/components/esp32_ble_server/ble_descriptor.h b/esphome/components/esp32_ble_server/ble_descriptor.h index f9e9f2d458..57d4c449e0 100644 --- a/esphome/components/esp32_ble_server/ble_descriptor.h +++ b/esphome/components/esp32_ble_server/ble_descriptor.h @@ -20,13 +20,14 @@ namespace BLEDescriptorEvt { enum VectorEvt { ON_WRITE, }; -} // namespace BLECharacteristicEvt +} // namespace BLEDescriptorEvt -class BLEDescriptor : public EventEmitter> { +class BLEDescriptor : public EventEmitter, uint16_t> { public: BLEDescriptor(ESPBTUUID uuid, uint16_t max_len = 100, bool read = true, bool write = true); virtual ~BLEDescriptor(); void do_create(BLECharacteristic *characteristic); + ESPBTUUID get_uuid() const { return this->uuid_; } void set_value(ByteBuffer buffer); diff --git a/esphome/components/esp32_ble_server/ble_server.cpp b/esphome/components/esp32_ble_server/ble_server.cpp index 4b4b31183b..4ce4a0394a 100644 --- a/esphome/components/esp32_ble_server/ble_server.cpp +++ b/esphome/components/esp32_ble_server/ble_server.cpp @@ -182,21 +182,15 @@ void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t ga switch (event) { case ESP_GATTS_CONNECT_EVT: { ESP_LOGD(TAG, "BLE Client connected"); - this->add_client_(param->connect.conn_id, (void *) this); - this->connected_clients_++; - for (auto &pair : this->services_) { - pair.second->emit_client_connect(param->connect.conn_id); - } + this->add_client_(param->connect.conn_id); + this->emit_(BLEServerEvt::EmptyEvt::ON_CONNECT, param->connect.conn_id); break; } case ESP_GATTS_DISCONNECT_EVT: { ESP_LOGD(TAG, "BLE Client disconnected"); - if (this->remove_client_(param->disconnect.conn_id)) - this->connected_clients_--; + this->remove_client_(param->disconnect.conn_id); this->parent_->advertising_start(); - for (auto &pair : this->services_) { - pair.second->emit_client_disconnect(param->disconnect.conn_id); - } + this->emit_(BLEServerEvt::EmptyEvt::ON_DISCONNECT, param->disconnect.conn_id); break; } case ESP_GATTS_REG_EVT: { diff --git a/esphome/components/esp32_ble_server/ble_server.h b/esphome/components/esp32_ble_server/ble_server.h index 5923b112d2..97c0b88fa8 100644 --- a/esphome/components/esp32_ble_server/ble_server.h +++ b/esphome/components/esp32_ble_server/ble_server.h @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef USE_ESP32 @@ -26,7 +27,15 @@ namespace esp32_ble_server { using namespace esp32_ble; -class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEventHandler, public Parented { +namespace BLEServerEvt { +enum EmptyEvt { + ON_CONNECT, + ON_DISCONNECT, +}; +} // namespace BLEServerEvt + +class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEventHandler, + public Parented, public EventEmitter { public: void setup() override; void loop() override; @@ -50,8 +59,8 @@ class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEv void enqueue_start_service(BLEService *service) { this->services_to_start_.push_back(service); } esp_gatt_if_t get_gatts_if() { return this->gatts_if_; } - uint32_t get_connected_client_count() { return this->connected_clients_; } - const std::unordered_map &get_clients() { return this->clients_; } + uint32_t get_connected_client_count() { return this->clients_.size(); } + const std::unordered_set &get_clients() { return this->clients_; } void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) override; @@ -63,8 +72,8 @@ class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEv bool create_device_characteristics_(); void restart_advertising_(); - void add_client_(uint16_t conn_id, void *client) { this->clients_.emplace(conn_id, client); } - bool remove_client_(uint16_t conn_id) { return this->clients_.erase(conn_id) > 0; } + void add_client_(uint16_t conn_id) { this->clients_.insert(conn_id); } + void remove_client_(uint16_t conn_id) { this->clients_.erase(conn_id); } std::string manufacturer_; optional model_; @@ -72,8 +81,7 @@ class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEv esp_gatt_if_t gatts_if_{0}; bool registered_{false}; - uint32_t connected_clients_{0}; - std::unordered_map clients_; + std::unordered_set clients_; std::unordered_map services_; std::vector services_to_start_; BLEService *device_information_service_; diff --git a/esphome/components/esp32_ble_server/ble_server_automations.cpp b/esphome/components/esp32_ble_server/ble_server_automations.cpp index 1721e338b1..d373b8f17f 100644 --- a/esphome/components/esp32_ble_server/ble_server_automations.cpp +++ b/esphome/components/esp32_ble_server/ble_server_automations.cpp @@ -9,24 +9,36 @@ namespace esp32_ble_server_automations { using namespace esp32_ble; -Trigger> *BLETriggers::create_characteristic_on_write_trigger(BLECharacteristic *characteristic) { - Trigger> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory) - new Trigger>(); - characteristic->EventEmitter>::on( +Trigger, uint16_t> *BLETriggers::create_characteristic_on_write_trigger(BLECharacteristic *characteristic) { + Trigger, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory) + new Trigger, uint16_t>(); + characteristic->EventEmitter, uint16_t>::on( BLECharacteristicEvt::VectorEvt::ON_WRITE, - [on_write_trigger](const std::vector &data) { on_write_trigger->trigger(data); }); + [on_write_trigger](const std::vector &data, uint16_t id) { on_write_trigger->trigger(data, id); }); return on_write_trigger; } -Trigger> *BLETriggers::create_descriptor_on_write_trigger(BLEDescriptor *descriptor) { - Trigger> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory) - new Trigger>(); - descriptor->EventEmitter>::on( +Trigger, uint16_t> *BLETriggers::create_descriptor_on_write_trigger(BLEDescriptor *descriptor) { + Trigger, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory) + new Trigger, uint16_t>(); + descriptor->on( BLEDescriptorEvt::VectorEvt::ON_WRITE, - [on_write_trigger](const std::vector &data) { on_write_trigger->trigger(data); }); + [on_write_trigger](const std::vector &data, uint16_t id) { on_write_trigger->trigger(data, id); }); return on_write_trigger; } +Trigger *BLETriggers::create_server_on_connect_trigger(BLEServer *server) { + Trigger *on_connect_trigger = new Trigger(); // NOLINT(cppcoreguidelines-owning-memory) + server->on(BLEServerEvt::EmptyEvt::ON_CONNECT, [on_connect_trigger](uint16_t conn_id) { on_connect_trigger->trigger(conn_id); }); + return on_connect_trigger; +} + +Trigger *BLETriggers::create_server_on_disconnect_trigger(BLEServer *server) { + Trigger *on_disconnect_trigger = new Trigger(); // NOLINT(cppcoreguidelines-owning-memory) + server->on(BLEServerEvt::EmptyEvt::ON_DISCONNECT, [on_disconnect_trigger](uint16_t conn_id) { on_disconnect_trigger->trigger(conn_id); }); + return on_disconnect_trigger; +} + void BLECharacteristicSetValueActionManager::set_listener(BLECharacteristic *characteristic, EventEmitterListenerID listener_id, const std::function &pre_notify_listener) { @@ -37,7 +49,7 @@ void BLECharacteristicSetValueActionManager::set_listener(BLECharacteristic *cha EventEmitterListenerID old_listener_id = listener_pairs.first; EventEmitterListenerID old_pre_notify_listener_id = listener_pairs.second; // Remove the previous listener - characteristic->EventEmitter::off(BLECharacteristicEvt::EmptyEvt::ON_READ, + characteristic->EventEmitter::off(BLECharacteristicEvt::EmptyEvt::ON_READ, old_listener_id); // Remove the pre-notify listener this->off(BLECharacteristicSetValueActionEvt::PRE_NOTIFY, old_pre_notify_listener_id); diff --git a/esphome/components/esp32_ble_server/ble_server_automations.h b/esphome/components/esp32_ble_server/ble_server_automations.h index 227d7f7eb4..f45451cfe9 100644 --- a/esphome/components/esp32_ble_server/ble_server_automations.h +++ b/esphome/components/esp32_ble_server/ble_server_automations.h @@ -1,6 +1,8 @@ #pragma once +#include "ble_server.h" #include "ble_characteristic.h" +#include "ble_descriptor.h" #include "esphome/core/event_emitter.h" #include "esphome/core/automation.h" @@ -21,8 +23,10 @@ using namespace esp32_ble; class BLETriggers { public: - static Trigger> *create_characteristic_on_write_trigger(BLECharacteristic *characteristic); - static Trigger> *create_descriptor_on_write_trigger(BLEDescriptor *descriptor); + static Trigger, uint16_t> *create_characteristic_on_write_trigger(BLECharacteristic *characteristic); + static Trigger, uint16_t> *create_descriptor_on_write_trigger(BLEDescriptor *descriptor); + static Trigger *create_server_on_connect_trigger(BLEServer *server); + static Trigger *create_server_on_disconnect_trigger(BLEServer *server); }; enum BLECharacteristicSetValueActionEvt { @@ -62,8 +66,8 @@ template class BLECharacteristicSetValueAction : public Actionparent_->set_value(this->buffer_.value(x...)); // Set the listener for read events - this->listener_id_ = this->parent_->EventEmitter::on( - BLECharacteristicEvt::EmptyEvt::ON_READ, [this, x...]() { + this->listener_id_ = this->parent_->EventEmitter::on( + BLECharacteristicEvt::EmptyEvt::ON_READ, [this, x...](uint16_t id) { // Set the value of the characteristic every time it is read this->parent_->set_value(this->buffer_.value(x...)); }); diff --git a/esphome/components/esp32_ble_server/ble_service.cpp b/esphome/components/esp32_ble_server/ble_service.cpp index 8096111dcd..96fedf2346 100644 --- a/esphome/components/esp32_ble_server/ble_service.cpp +++ b/esphome/components/esp32_ble_server/ble_service.cpp @@ -58,22 +58,15 @@ void BLEService::do_create(BLEServer *server) { this->state_ = CREATING; } -void BLEService::emit_client_connect(const uint16_t conn_id) { - if (this->on_client_connect_ && this->is_running()) - this->on_client_connect_(conn_id); -} - -void BLEService::emit_client_disconnect(const uint16_t conn_id) { - if (this->on_client_disconnect_ && this->is_running()) - this->on_client_disconnect_(conn_id); -} - void BLEService::do_delete() { if (this->state_ == DELETING || this->state_ == DELETED) return; this->state_ = DELETING; this->created_characteristic_count_ = 0; this->last_created_characteristic_ = nullptr; + // Call all characteristics to delete + for (auto *characteristic : this->characteristics_) + characteristic->do_delete(); this->stop_(); esp_err_t err = esp_ble_gatts_delete_service(this->handle_); if (err != ESP_OK) { diff --git a/esphome/components/esp32_ble_server/ble_service.h b/esphome/components/esp32_ble_server/ble_service.h index b0463816e4..dcfad5f501 100644 --- a/esphome/components/esp32_ble_server/ble_service.h +++ b/esphome/components/esp32_ble_server/ble_service.h @@ -50,10 +50,6 @@ class BLEService { bool is_running() { return this->state_ == RUNNING; } bool is_starting() { return this->state_ == STARTING; } bool is_deleted() { return this->state_ == DELETED; } - void on_client_connect(const std::function &&func) { this->on_client_connect_ = func; } - void on_client_disconnect(const std::function &&func) { this->on_client_disconnect_ = func; } - void emit_client_connect(uint16_t conn_id); - void emit_client_disconnect(uint16_t conn_id); protected: std::vector characteristics_; @@ -66,8 +62,6 @@ class BLEService { uint8_t inst_id_; bool advertise_{false}; bool should_start_{false}; - std::function on_client_connect_; - std::function on_client_disconnect_; bool do_create_characteristics_(); void stop_(); diff --git a/tests/components/esp32_ble_server/common.yaml b/tests/components/esp32_ble_server/common.yaml index 8e048b33b2..502d1fce4f 100644 --- a/tests/components/esp32_ble_server/common.yaml +++ b/tests/components/esp32_ble_server/common.yaml @@ -3,15 +3,22 @@ esp32_ble_server: manufacturer_data: [0x72, 0x4, 0x00, 0x23] manufacturer: ESPHome model: Test + on_connect: + - lambda: |- + ESP_LOGD("BLE", "Connection from %d", id); + on_disconnect: + - lambda: |- + ESP_LOGD("BLE", "Disconnection from %d", id); services: - - uuid: 2a24b789-7aab-4535-af3e-ee76a35cc42d + - uuid: 2a24b789-7aab-4535-af3e-ee76a35cc12d advertise: false characteristics: - id: test_notify_characteristic + description: "Notify characteristic" uuid: cad48e28-7fbe-41cf-bae9-d77a6c233423 read: true notify: true - value: [0, 1, 2] + value: [9, 9, 9] descriptors: - uuid: cad48e28-7fbe-41cf-bae9-d77a6c111111 value: 123.1 @@ -20,18 +27,22 @@ esp32_ble_server: advertise: false characteristics: - id: test_change_characteristic - uuid: 2a24b789-7a1b-4535-af3e-ee76a35cc11d + uuid: 2a24b789-7a1b-4535-af3e-ee76a35cc11c read: true value: "Initial" + description: "Change characteristic" descriptors: - - uuid: cad48e28-7fbe-41cf-bae9-d77a6c111111 + - uuid: 0x2312 value: 0x12 - - uuid: 2a24b789-7a1b-4535-af3e-ee76a35cc12d + on_write: + - lambda: |- + ESP_LOGD("BLE", "Descriptor received: %s from %d", std::string(x.begin(), x.end()).c_str(), id); + - uuid: 2a24b789-7a1b-4535-af3e-ee76a35cc99a write: true on_write: then: - lambda: |- - ESP_LOGD("BLE", "Received: %s", std::string(x.begin(), x.end()).c_str()); + ESP_LOGD("BLE", "Characteristic received: %s from %d", std::string(x.begin(), x.end()).c_str(), id); - ble_server.characteristic.set_value: id: test_change_characteristic value: !lambda 'return ByteBuffer::wrap({0x00, 0x01, 0x02});'