#pragma once #include "ble_service.h" #include "ble_characteristic.h" #include "esphome/components/esp32_ble/ble.h" #include "esphome/components/esp32_ble/ble_uuid.h" #include "esphome/components/bytebuffer/bytebuffer.h" #include "esphome/core/component.h" #include "esphome/core/helpers.h" #include #include #include #include #ifdef USE_ESP32 #include namespace esphome { namespace esp32_ble_server { using namespace esp32_ble; using namespace bytebuffer; class BLEServer : public Component, public Parented { public: void setup() override; void loop() override; void dump_config() override; float get_setup_priority() const override; bool can_proceed() override; ESPHOME_ALWAYS_INLINE bool is_running() { return this->parent_->is_active() && this->state_ == RUNNING; } void set_manufacturer_data(const std::vector &data) { this->manufacturer_data_ = data; this->restart_advertising_(); } void set_max_clients(uint8_t max_clients) { this->max_clients_ = max_clients; } uint8_t get_max_clients() const { return this->max_clients_; } BLEService *create_service(ESPBTUUID uuid, bool advertise = false, uint16_t num_handles = 15); void remove_service(ESPBTUUID uuid, uint8_t inst_id = 0); BLEService *get_service(ESPBTUUID uuid, uint8_t inst_id = 0); void enqueue_start_service(BLEService *service) { this->services_to_start_.push_back(service); } void set_device_information_service(BLEService *service) { this->device_information_service_ = service; } esp_gatt_if_t get_gatts_if() { return this->gatts_if_; } uint32_t get_connected_client_count() { return this->client_count_; } const uint16_t *get_clients() const { return this->clients_; } 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, esp_ble_gatts_cb_param_t *param); void ble_before_disabled_event_handler(); // Direct callback registration - supports multiple callbacks void on_connect(std::function &&callback) { this->callbacks_.push_back({CallbackType::ON_CONNECT, std::move(callback)}); } void on_disconnect(std::function &&callback) { this->callbacks_.push_back({CallbackType::ON_DISCONNECT, std::move(callback)}); } protected: enum class CallbackType : uint8_t { ON_CONNECT, ON_DISCONNECT, }; struct CallbackEntry { CallbackType type; std::function callback; }; struct ServiceEntry { ESPBTUUID uuid; uint8_t inst_id; BLEService *service; }; void restart_advertising_(); int8_t find_client_index_(uint16_t conn_id) const; void add_client_(uint16_t conn_id); void remove_client_(uint16_t conn_id); void dispatch_callbacks_(CallbackType type, uint16_t conn_id); std::vector callbacks_; std::vector manufacturer_data_{}; esp_gatt_if_t gatts_if_{0}; bool registered_{false}; uint16_t clients_[USE_ESP32_BLE_MAX_CONNECTIONS]{}; uint8_t client_count_{0}; uint8_t max_clients_{1}; std::vector services_{}; std::vector services_to_start_{}; BLEService *device_information_service_{}; enum State : uint8_t { INIT = 0x00, REGISTERING, STARTING_SERVICE, RUNNING, } state_{INIT}; }; // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) extern BLEServer *global_ble_server; } // namespace esp32_ble_server } // namespace esphome #endif