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();
221 if (name.length() > 20) {
224 name.erase(13, name.length() - 20);
231 err = esp_ble_gap_set_device_name(name.c_str());
233 ESP_LOGE(TAG,
"esp_ble_gap_set_device_name failed: %d", err);
237 err = esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &(this->io_cap_),
sizeof(uint8_t));
239 ESP_LOGE(TAG,
"esp_ble_gap_set_security_param failed: %d", err);
250 esp_err_t err = esp_bluedroid_disable();
252 ESP_LOGE(TAG,
"esp_bluedroid_disable failed: %d", err);
255 err = esp_bluedroid_deinit();
257 ESP_LOGE(TAG,
"esp_bluedroid_deinit failed: %d", err);
263 ESP_LOGE(TAG,
"btStop failed: %d", esp_bt_controller_get_status());
267 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
269 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED) {
270 err = esp_bt_controller_disable();
272 ESP_LOGE(TAG,
"esp_bt_controller_disable failed: %s", esp_err_to_name(err));
275 while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED)
278 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED) {
279 err = esp_bt_controller_deinit();
281 ESP_LOGE(TAG,
"esp_bt_controller_deinit failed: %s", esp_err_to_name(err));
285 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
286 ESP_LOGE(TAG,
"esp bt controller disable failed");
295 switch (this->state_) {
300 ESP_LOGD(TAG,
"Disabling");
302 for (
auto *ble_event_handler : this->ble_status_event_handlers_) {
303 ble_event_handler->ble_before_disabled_event_handler();
307 ESP_LOGE(TAG,
"Could not be dismantled");
315 ESP_LOGD(TAG,
"Enabling");
319 ESP_LOGE(TAG,
"Could not be set up");
331 BLEEvent *ble_event = this->ble_events_.pop();
332 while (ble_event !=
nullptr) {
333 switch (ble_event->
type_) {
334#ifdef USE_ESP32_BLE_SERVER
336 esp_gatts_cb_event_t
event = ble_event->
event_.
gatts.gatts_event;
337 esp_gatt_if_t gatts_if = ble_event->
event_.
gatts.gatts_if;
338 esp_ble_gatts_cb_param_t *param = &ble_event->
event_.
gatts.gatts_param;
339 ESP_LOGV(TAG,
"gatts_event [esp_gatt_if: %d] - %d", gatts_if, event);
340 for (
auto *gatts_handler : this->gatts_event_handlers_) {
341 gatts_handler->gatts_event_handler(event, gatts_if, param);
346#ifdef USE_ESP32_BLE_CLIENT
348 esp_gattc_cb_event_t
event = ble_event->
event_.
gattc.gattc_event;
349 esp_gatt_if_t gattc_if = ble_event->
event_.
gattc.gattc_if;
350 esp_ble_gattc_cb_param_t *param = &ble_event->
event_.
gattc.gattc_param;
351 ESP_LOGV(TAG,
"gattc_event [esp_gatt_if: %d] - %d", gattc_if, event);
352 for (
auto *gattc_handler : this->gattc_event_handlers_) {
353 gattc_handler->gattc_event_handler(event, gattc_if, param);
359 esp_gap_ble_cb_event_t gap_event = ble_event->
event_.
gap.gap_event;
361 case ESP_GAP_BLE_SCAN_RESULT_EVT:
363 for (
auto *scan_handler : this->gap_scan_event_handlers_) {
364 scan_handler->gap_scan_event_handler(ble_event->
scan_result());
369 case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
370 case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
371 case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
376 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
377 for (
auto *gap_handler : this->gap_event_handlers_) {
378 gap_handler->gap_event_handler(
379 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.scan_complete));
384 case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
385 case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
386 case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
387 case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
388 case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
390 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
391 for (
auto *gap_handler : this->gap_event_handlers_) {
392 gap_handler->gap_event_handler(
393 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.adv_complete));
398 case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT:
399 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
400 for (
auto *gap_handler : this->gap_event_handlers_) {
401 gap_handler->gap_event_handler(
402 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.read_rssi_complete));
407 case ESP_GAP_BLE_AUTH_CMPL_EVT:
408 case ESP_GAP_BLE_SEC_REQ_EVT:
409 case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
410 case ESP_GAP_BLE_PASSKEY_REQ_EVT:
411 case ESP_GAP_BLE_NC_REQ_EVT:
412 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
413 for (
auto *gap_handler : this->gap_event_handlers_) {
414 gap_handler->gap_event_handler(
415 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.security));
421 ESP_LOGW(TAG,
"Unhandled GAP event type in loop: %d", gap_event);
430 this->ble_event_pool_.release(ble_event);
431 ble_event = this->ble_events_.pop();
433#ifdef USE_ESP32_BLE_ADVERTISING
434 if (this->advertising_ !=
nullptr) {
435 this->advertising_->
loop();
440 uint16_t dropped = this->ble_events_.get_and_reset_dropped_count();
442 ESP_LOGW(TAG,
"Dropped %u BLE events due to buffer overflow", dropped);
448 event->load_gap_event(e, p);
451#ifdef USE_ESP32_BLE_CLIENT
453 event->load_gattc_event(e, i, p);
457#ifdef USE_ESP32_BLE_SERVER
459 event->load_gatts_event(e, i, p);
466 if (event ==
nullptr) {
468 global_ble->ble_events_.increment_dropped_count();
482#ifdef USE_ESP32_BLE_SERVER
483template void enqueue_ble_event(esp_gatts_cb_event_t, esp_gatt_if_t, esp_ble_gatts_cb_param_t *);
485#ifdef USE_ESP32_BLE_CLIENT
486template void enqueue_ble_event(esp_gattc_cb_event_t, esp_gatt_if_t, esp_ble_gattc_cb_param_t *);
493 case ESP_GAP_BLE_SCAN_RESULT_EVT:
494 case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
495 case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
496 case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
498 case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
499 case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
500 case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
501 case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
502 case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
504 case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT:
506 case ESP_GAP_BLE_AUTH_CMPL_EVT:
507 case ESP_GAP_BLE_SEC_REQ_EVT:
508 case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
509 case ESP_GAP_BLE_PASSKEY_REQ_EVT:
510 case ESP_GAP_BLE_NC_REQ_EVT:
515 case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
516 case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT:
517 case ESP_GAP_BLE_PHY_UPDATE_COMPLETE_EVT:
518 case ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT:
524 ESP_LOGW(TAG,
"Ignoring unexpected GAP event type: %d", event);
527#ifdef USE_ESP32_BLE_SERVER
529 esp_ble_gatts_cb_param_t *param) {
534#ifdef USE_ESP32_BLE_CLIENT
536 esp_ble_gattc_cb_param_t *param) {
544 const uint8_t *mac_address = esp_bt_dev_get_address();
546 const char *io_capability_s;
547 switch (this->io_cap_) {
549 io_capability_s =
"display_only";
552 io_capability_s =
"display_yes_no";
555 io_capability_s =
"keyboard_only";
557 case ESP_IO_CAP_NONE:
558 io_capability_s =
"none";
560 case ESP_IO_CAP_KBDISP:
561 io_capability_s =
"keyboard_display";
564 io_capability_s =
"invalid";
570 " IO Capability: %s",
573 ESP_LOGCONFIG(TAG,
"Bluetooth stack is not enabled");
579 u |= uint64_t(
address[0] & 0xFF) << 40;
580 u |= uint64_t(
address[1] & 0xFF) << 32;
581 u |= uint64_t(
address[2] & 0xFF) << 24;
582 u |= uint64_t(
address[3] & 0xFF) << 16;
583 u |= uint64_t(
address[4] & 0xFF) << 8;
584 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.