10#include <esp_bt_device.h>
11#include <esp_bt_main.h>
12#include <esp_gap_ble_api.h>
13#include <freertos/FreeRTOS.h>
14#include <freertos/FreeRTOSConfig.h>
15#include <freertos/task.h>
19#include <esp32-hal-bt.h>
24static const char *
const TAG =
"esp32_ble";
29 ESP_LOGE(TAG,
"BLE could not be prepared for configuration");
35 if (this->enable_on_boot_) {
56#ifdef USE_ESP32_BLE_ADVERTISING
61 this->advertising_->
start();
117 esp_err_t err = nvs_flash_init();
119 ESP_LOGE(TAG,
"nvs_flash_init failed: %d", err);
125#ifdef USE_ESP32_BLE_ADVERTISING
127 if (this->advertising_ !=
nullptr)
129 this->advertising_ =
new BLEAdvertising(this->advertising_cycle_time_);
141 ESP_LOGE(TAG,
"btStart failed: %d", esp_bt_controller_get_status());
145 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
147 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE) {
148 esp_bt_controller_config_t cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
149 err = esp_bt_controller_init(&cfg);
151 ESP_LOGE(TAG,
"esp_bt_controller_init failed: %s", esp_err_to_name(err));
154 while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE)
157 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED) {
158 err = esp_bt_controller_enable(ESP_BT_MODE_BLE);
160 ESP_LOGE(TAG,
"esp_bt_controller_enable failed: %s", esp_err_to_name(err));
164 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
165 ESP_LOGE(TAG,
"esp bt controller enable failed");
171 esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
173 err = esp_bluedroid_init();
175 ESP_LOGE(TAG,
"esp_bluedroid_init failed: %d", err);
178 err = esp_bluedroid_enable();
180 ESP_LOGE(TAG,
"esp_bluedroid_enable failed: %d", err);
184 if (!this->gap_event_handlers_.empty()) {
187 ESP_LOGE(TAG,
"esp_ble_gap_register_callback failed: %d", err);
192#ifdef USE_ESP32_BLE_SERVER
193 if (!this->gatts_event_handlers_.empty()) {
196 ESP_LOGE(TAG,
"esp_ble_gatts_register_callback failed: %d", err);
202#ifdef USE_ESP32_BLE_CLIENT
203 if (!this->gattc_event_handlers_.empty()) {
206 ESP_LOGE(TAG,
"esp_ble_gattc_register_callback failed: %d", err);
214 name = this->name_.
value();
220 if (name.length() > 20) {
222 name.erase(name.begin() + 13, name.end() - 7);
224 name = name.substr(0, 20);
229 err = esp_ble_gap_set_device_name(name.c_str());
231 ESP_LOGE(TAG,
"esp_ble_gap_set_device_name failed: %d", err);
235 err = esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &(this->io_cap_),
sizeof(uint8_t));
237 ESP_LOGE(TAG,
"esp_ble_gap_set_security_param failed: %d", err);
248 esp_err_t err = esp_bluedroid_disable();
250 ESP_LOGE(TAG,
"esp_bluedroid_disable failed: %d", err);
253 err = esp_bluedroid_deinit();
255 ESP_LOGE(TAG,
"esp_bluedroid_deinit failed: %d", err);
261 ESP_LOGE(TAG,
"btStop failed: %d", esp_bt_controller_get_status());
265 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
267 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED) {
268 err = esp_bt_controller_disable();
270 ESP_LOGE(TAG,
"esp_bt_controller_disable failed: %s", esp_err_to_name(err));
273 while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED)
276 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED) {
277 err = esp_bt_controller_deinit();
279 ESP_LOGE(TAG,
"esp_bt_controller_deinit failed: %s", esp_err_to_name(err));
283 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
284 ESP_LOGE(TAG,
"esp bt controller disable failed");
293 switch (this->state_) {
298 ESP_LOGD(TAG,
"Disabling");
300 for (
auto *ble_event_handler : this->ble_status_event_handlers_) {
301 ble_event_handler->ble_before_disabled_event_handler();
305 ESP_LOGE(TAG,
"Could not be dismantled");
313 ESP_LOGD(TAG,
"Enabling");
317 ESP_LOGE(TAG,
"Could not be set up");
329 BLEEvent *ble_event = this->ble_events_.pop();
330 while (ble_event !=
nullptr) {
331 switch (ble_event->
type_) {
332#ifdef USE_ESP32_BLE_SERVER
334 esp_gatts_cb_event_t
event = ble_event->
event_.
gatts.gatts_event;
335 esp_gatt_if_t gatts_if = ble_event->
event_.
gatts.gatts_if;
336 esp_ble_gatts_cb_param_t *param = &ble_event->
event_.
gatts.gatts_param;
337 ESP_LOGV(TAG,
"gatts_event [esp_gatt_if: %d] - %d", gatts_if, event);
338 for (
auto *gatts_handler : this->gatts_event_handlers_) {
339 gatts_handler->gatts_event_handler(event, gatts_if, param);
344#ifdef USE_ESP32_BLE_CLIENT
346 esp_gattc_cb_event_t
event = ble_event->
event_.
gattc.gattc_event;
347 esp_gatt_if_t gattc_if = ble_event->
event_.
gattc.gattc_if;
348 esp_ble_gattc_cb_param_t *param = &ble_event->
event_.
gattc.gattc_param;
349 ESP_LOGV(TAG,
"gattc_event [esp_gatt_if: %d] - %d", gattc_if, event);
350 for (
auto *gattc_handler : this->gattc_event_handlers_) {
351 gattc_handler->gattc_event_handler(event, gattc_if, param);
357 esp_gap_ble_cb_event_t gap_event = ble_event->
event_.
gap.gap_event;
359 case ESP_GAP_BLE_SCAN_RESULT_EVT:
361 for (
auto *scan_handler : this->gap_scan_event_handlers_) {
362 scan_handler->gap_scan_event_handler(ble_event->
scan_result());
367 case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
368 case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
369 case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
374 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
375 for (
auto *gap_handler : this->gap_event_handlers_) {
376 gap_handler->gap_event_handler(
377 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.scan_complete));
382 case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
383 case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
384 case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
385 case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
386 case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
388 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
389 for (
auto *gap_handler : this->gap_event_handlers_) {
390 gap_handler->gap_event_handler(
391 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.adv_complete));
396 case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT:
397 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
398 for (
auto *gap_handler : this->gap_event_handlers_) {
399 gap_handler->gap_event_handler(
400 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.read_rssi_complete));
405 case ESP_GAP_BLE_AUTH_CMPL_EVT:
406 case ESP_GAP_BLE_SEC_REQ_EVT:
407 case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
408 case ESP_GAP_BLE_PASSKEY_REQ_EVT:
409 case ESP_GAP_BLE_NC_REQ_EVT:
410 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
411 for (
auto *gap_handler : this->gap_event_handlers_) {
412 gap_handler->gap_event_handler(
413 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.security));
419 ESP_LOGW(TAG,
"Unhandled GAP event type in loop: %d", gap_event);
428 this->ble_event_pool_.release(ble_event);
429 ble_event = this->ble_events_.pop();
431#ifdef USE_ESP32_BLE_ADVERTISING
432 if (this->advertising_ !=
nullptr) {
433 this->advertising_->
loop();
438 uint16_t dropped = this->ble_events_.get_and_reset_dropped_count();
440 ESP_LOGW(TAG,
"Dropped %u BLE events due to buffer overflow", dropped);
446 event->load_gap_event(e, p);
449#ifdef USE_ESP32_BLE_CLIENT
451 event->load_gattc_event(e, i, p);
455#ifdef USE_ESP32_BLE_SERVER
457 event->load_gatts_event(e, i, p);
464 if (event ==
nullptr) {
466 global_ble->ble_events_.increment_dropped_count();
480#ifdef USE_ESP32_BLE_SERVER
481template void enqueue_ble_event(esp_gatts_cb_event_t, esp_gatt_if_t, esp_ble_gatts_cb_param_t *);
483#ifdef USE_ESP32_BLE_CLIENT
484template void enqueue_ble_event(esp_gattc_cb_event_t, esp_gatt_if_t, esp_ble_gattc_cb_param_t *);
491 case ESP_GAP_BLE_SCAN_RESULT_EVT:
492 case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
493 case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
494 case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
496 case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
497 case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
498 case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
499 case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
500 case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
502 case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT:
504 case ESP_GAP_BLE_AUTH_CMPL_EVT:
505 case ESP_GAP_BLE_SEC_REQ_EVT:
506 case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
507 case ESP_GAP_BLE_PASSKEY_REQ_EVT:
508 case ESP_GAP_BLE_NC_REQ_EVT:
513 case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
514 case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT:
515 case ESP_GAP_BLE_PHY_UPDATE_COMPLETE_EVT:
516 case ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT:
522 ESP_LOGW(TAG,
"Ignoring unexpected GAP event type: %d", event);
525#ifdef USE_ESP32_BLE_SERVER
527 esp_ble_gatts_cb_param_t *param) {
532#ifdef USE_ESP32_BLE_CLIENT
534 esp_ble_gattc_cb_param_t *param) {
542 const uint8_t *mac_address = esp_bt_dev_get_address();
544 const char *io_capability_s;
545 switch (this->io_cap_) {
547 io_capability_s =
"display_only";
550 io_capability_s =
"display_yes_no";
553 io_capability_s =
"keyboard_only";
555 case ESP_IO_CAP_NONE:
556 io_capability_s =
"none";
558 case ESP_IO_CAP_KBDISP:
559 io_capability_s =
"keyboard_display";
562 io_capability_s =
"invalid";
568 " IO Capability: %s",
571 ESP_LOGCONFIG(TAG,
"Bluetooth stack is not enabled");
577 u |= uint64_t(
address[0] & 0xFF) << 40;
578 u |= uint64_t(
address[1] & 0xFF) << 32;
579 u |= uint64_t(
address[2] & 0xFF) << 24;
580 u |= uint64_t(
address[3] & 0xFF) << 16;
581 u |= uint64_t(
address[4] & 0xFF) << 8;
582 u |= uint64_t(
address[5] & 0xFF) << 0;
bool is_name_add_mac_suffix_enabled() const
const std::string & get_name() const
Get the name of this Application set by pre_setup().
virtual void mark_failed()
Mark this component as failed.
void set_manufacturer_data(const std::vector< uint8_t > &data)
void add_service_uuid(ESPBTUUID uuid)
void set_scan_response(bool scan_response)
void set_include_name(bool include_name)
void set_min_preferred_interval(uint16_t interval)
void set_service_data(const std::vector< uint8_t > &data)
void remove_service_uuid(ESPBTUUID uuid)
void register_raw_advertisement_callback(std::function< void(bool)> &&callback)
void set_appearance(uint16_t appearance)
BLEScanResult scan_result
struct esphome::esp32_ble::BLEEvent::@73::gatts_event gatts
union esphome::esp32_ble::BLEEvent::@73 event_
struct esphome::esp32_ble::BLEEvent::@73::gattc_event gattc
struct esphome::esp32_ble::BLEEvent::@73::gap_event gap
void advertising_set_manufacturer_data(const std::vector< uint8_t > &data)
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
static void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
friend void enqueue_ble_event(Args... args)
void advertising_register_raw_advertisement_callback(std::function< void(bool)> &&callback)
void advertising_set_service_data_and_name(std::span< const uint8_t > data, bool include_name)
void advertising_add_service_uuid(ESPBTUUID uuid)
void dump_config() override
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
void advertising_set_service_data(const std::vector< uint8_t > &data)
float get_setup_priority() const override
void advertising_remove_service_uuid(ESPBTUUID uuid)
value_type const & value() const
void load_ble_event(BLEEvent *event, esp_gap_ble_cb_event_t e, esp_ble_gap_cb_param_t *p)
@ BLE_COMPONENT_STATE_DISABLE
BLE should be disabled on next loop.
@ BLE_COMPONENT_STATE_OFF
Nothing has been initialized yet.
@ BLE_COMPONENT_STATE_ENABLE
BLE should be enabled on next loop.
@ BLE_COMPONENT_STATE_DISABLED
BLE is disabled.
@ BLE_COMPONENT_STATE_ACTIVE
BLE is active.
uint64_t ble_addr_to_uint64(const esp_bd_addr_t address)
void enqueue_ble_event(Args... args)
std::string format_mac_address_pretty(const uint8_t *mac)
void IRAM_ATTR HOT delay(uint32_t ms)
std::string get_mac_address()
Get the device MAC address as a string, in lowercase hex notation.
Application App
Global storage of Application pointer - only one Application can exist.