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();
95 esp_err_t err = nvs_flash_init();
97 ESP_LOGE(TAG,
"nvs_flash_init failed: %d", err);
103#ifdef USE_ESP32_BLE_ADVERTISING
105 if (this->advertising_ !=
nullptr)
107 this->advertising_ =
new BLEAdvertising(this->advertising_cycle_time_);
119 ESP_LOGE(TAG,
"btStart failed: %d", esp_bt_controller_get_status());
123 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
125 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE) {
126 esp_bt_controller_config_t cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
127 err = esp_bt_controller_init(&cfg);
129 ESP_LOGE(TAG,
"esp_bt_controller_init failed: %s", esp_err_to_name(err));
132 while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE)
135 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED) {
136 err = esp_bt_controller_enable(ESP_BT_MODE_BLE);
138 ESP_LOGE(TAG,
"esp_bt_controller_enable failed: %s", esp_err_to_name(err));
142 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
143 ESP_LOGE(TAG,
"esp bt controller enable failed");
149 esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
151 err = esp_bluedroid_init();
153 ESP_LOGE(TAG,
"esp_bluedroid_init failed: %d", err);
156 err = esp_bluedroid_enable();
158 ESP_LOGE(TAG,
"esp_bluedroid_enable failed: %d", err);
162 if (!this->gap_event_handlers_.empty()) {
165 ESP_LOGE(TAG,
"esp_ble_gap_register_callback failed: %d", err);
170 if (!this->gatts_event_handlers_.empty()) {
173 ESP_LOGE(TAG,
"esp_ble_gatts_register_callback failed: %d", err);
178 if (!this->gattc_event_handlers_.empty()) {
181 ESP_LOGE(TAG,
"esp_ble_gattc_register_callback failed: %d", err);
188 name = this->name_.
value();
194 if (name.length() > 20) {
196 name.erase(name.begin() + 13, name.end() - 7);
198 name = name.substr(0, 20);
203 err = esp_ble_gap_set_device_name(name.c_str());
205 ESP_LOGE(TAG,
"esp_ble_gap_set_device_name failed: %d", err);
209 err = esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &(this->io_cap_),
sizeof(uint8_t));
211 ESP_LOGE(TAG,
"esp_ble_gap_set_security_param failed: %d", err);
222 esp_err_t err = esp_bluedroid_disable();
224 ESP_LOGE(TAG,
"esp_bluedroid_disable failed: %d", err);
227 err = esp_bluedroid_deinit();
229 ESP_LOGE(TAG,
"esp_bluedroid_deinit failed: %d", err);
235 ESP_LOGE(TAG,
"btStop failed: %d", esp_bt_controller_get_status());
239 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
241 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED) {
242 err = esp_bt_controller_disable();
244 ESP_LOGE(TAG,
"esp_bt_controller_disable failed: %s", esp_err_to_name(err));
247 while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED)
250 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED) {
251 err = esp_bt_controller_deinit();
253 ESP_LOGE(TAG,
"esp_bt_controller_deinit failed: %s", esp_err_to_name(err));
257 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
258 ESP_LOGE(TAG,
"esp bt controller disable failed");
267 switch (this->state_) {
272 ESP_LOGD(TAG,
"Disabling");
274 for (
auto *ble_event_handler : this->ble_status_event_handlers_) {
275 ble_event_handler->ble_before_disabled_event_handler();
279 ESP_LOGE(TAG,
"Could not be dismantled");
287 ESP_LOGD(TAG,
"Enabling");
291 ESP_LOGE(TAG,
"Could not be set up");
303 BLEEvent *ble_event = this->ble_events_.pop();
304 while (ble_event !=
nullptr) {
305 switch (ble_event->
type_) {
307 esp_gatts_cb_event_t
event = ble_event->
event_.
gatts.gatts_event;
308 esp_gatt_if_t gatts_if = ble_event->
event_.
gatts.gatts_if;
309 esp_ble_gatts_cb_param_t *param = ble_event->
event_.
gatts.gatts_param;
310 ESP_LOGV(TAG,
"gatts_event [esp_gatt_if: %d] - %d", gatts_if, event);
311 for (
auto *gatts_handler : this->gatts_event_handlers_) {
312 gatts_handler->gatts_event_handler(event, gatts_if, param);
317 esp_gattc_cb_event_t
event = ble_event->
event_.
gattc.gattc_event;
318 esp_gatt_if_t gattc_if = ble_event->
event_.
gattc.gattc_if;
319 esp_ble_gattc_cb_param_t *param = ble_event->
event_.
gattc.gattc_param;
320 ESP_LOGV(TAG,
"gattc_event [esp_gatt_if: %d] - %d", gattc_if, event);
321 for (
auto *gattc_handler : this->gattc_event_handlers_) {
322 gattc_handler->gattc_event_handler(event, gattc_if, param);
327 esp_gap_ble_cb_event_t gap_event = ble_event->
event_.
gap.gap_event;
329 case ESP_GAP_BLE_SCAN_RESULT_EVT:
331 for (
auto *scan_handler : this->gap_scan_event_handlers_) {
332 scan_handler->gap_scan_event_handler(ble_event->
scan_result());
337 case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
338 case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
339 case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
344 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
345 for (
auto *gap_handler : this->gap_event_handlers_) {
346 gap_handler->gap_event_handler(
347 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.scan_complete));
352 case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
353 case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
354 case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
355 case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
356 case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
358 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
359 for (
auto *gap_handler : this->gap_event_handlers_) {
360 gap_handler->gap_event_handler(
361 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.adv_complete));
366 case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT:
367 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
368 for (
auto *gap_handler : this->gap_event_handlers_) {
369 gap_handler->gap_event_handler(
370 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.read_rssi_complete));
375 case ESP_GAP_BLE_AUTH_CMPL_EVT:
376 case ESP_GAP_BLE_SEC_REQ_EVT:
377 case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
378 case ESP_GAP_BLE_PASSKEY_REQ_EVT:
379 case ESP_GAP_BLE_NC_REQ_EVT:
380 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
381 for (
auto *gap_handler : this->gap_event_handlers_) {
382 gap_handler->gap_event_handler(
383 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.security));
389 ESP_LOGW(TAG,
"Unhandled GAP event type in loop: %d", gap_event);
398 this->ble_event_pool_.release(ble_event);
399 ble_event = this->ble_events_.pop();
401#ifdef USE_ESP32_BLE_ADVERTISING
402 if (this->advertising_ !=
nullptr) {
403 this->advertising_->
loop();
408 uint16_t dropped = this->ble_events_.get_and_reset_dropped_count();
410 ESP_LOGW(TAG,
"Dropped %u BLE events due to buffer overflow", dropped);
416 event->load_gap_event(e, p);
420 event->load_gattc_event(e, i, p);
424 event->load_gatts_event(e, i, p);
430 if (event ==
nullptr) {
432 global_ble->ble_events_.increment_dropped_count();
446template void enqueue_ble_event(esp_gatts_cb_event_t, esp_gatt_if_t, esp_ble_gatts_cb_param_t *);
447template void enqueue_ble_event(esp_gattc_cb_event_t, esp_gatt_if_t, esp_ble_gattc_cb_param_t *);
453 case ESP_GAP_BLE_SCAN_RESULT_EVT:
454 case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
455 case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
456 case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
458 case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
459 case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
460 case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
461 case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
462 case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
464 case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT:
466 case ESP_GAP_BLE_AUTH_CMPL_EVT:
467 case ESP_GAP_BLE_SEC_REQ_EVT:
468 case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
469 case ESP_GAP_BLE_PASSKEY_REQ_EVT:
470 case ESP_GAP_BLE_NC_REQ_EVT:
475 case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
476 case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT:
477 case ESP_GAP_BLE_PHY_UPDATE_COMPLETE_EVT:
478 case ESP_GAP_BLE_CHANNEL_SELECT_ALGORITHM_EVT:
484 ESP_LOGW(TAG,
"Ignoring unexpected GAP event type: %d", event);
488 esp_ble_gatts_cb_param_t *param) {
493 esp_ble_gattc_cb_param_t *param) {
500 const uint8_t *mac_address = esp_bt_dev_get_address();
502 const char *io_capability_s;
503 switch (this->io_cap_) {
505 io_capability_s =
"display_only";
508 io_capability_s =
"display_yes_no";
511 io_capability_s =
"keyboard_only";
513 case ESP_IO_CAP_NONE:
514 io_capability_s =
"none";
516 case ESP_IO_CAP_KBDISP:
517 io_capability_s =
"keyboard_display";
520 io_capability_s =
"invalid";
526 " IO Capability: %s",
529 ESP_LOGCONFIG(TAG,
"Bluetooth stack is not enabled");
535 u |= uint64_t(
address[0] & 0xFF) << 40;
536 u |= uint64_t(
address[1] & 0xFF) << 32;
537 u |= uint64_t(
address[2] & 0xFF) << 24;
538 u |= uint64_t(
address[3] & 0xFF) << 16;
539 u |= uint64_t(
address[4] & 0xFF) << 8;
540 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_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)
struct esphome::esp32_ble::BLEEvent::@77::gattc_event gattc
struct esphome::esp32_ble::BLEEvent::@77::gap_event gap
BLEScanResult scan_result
struct esphome::esp32_ble::BLEEvent::@77::gatts_event gatts
union esphome::esp32_ble::BLEEvent::@77 event_
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_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.