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>
25static const char *
const TAG =
"esp32_ble";
29 ESP_LOGCONFIG(TAG,
"Running setup");
32 ESP_LOGE(TAG,
"BLE could not be prepared for configuration");
38 if (this->enable_on_boot_) {
63 this->advertising_->
start();
96 esp_err_t err = nvs_flash_init();
98 ESP_LOGE(TAG,
"nvs_flash_init failed: %d", err);
105 if (this->advertising_ !=
nullptr)
107 this->advertising_ =
new BLEAdvertising(this->advertising_cycle_time_);
118 ESP_LOGE(TAG,
"btStart failed: %d", esp_bt_controller_get_status());
122 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
124 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE) {
125 esp_bt_controller_config_t cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
126 err = esp_bt_controller_init(&cfg);
128 ESP_LOGE(TAG,
"esp_bt_controller_init failed: %s", esp_err_to_name(err));
131 while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE)
134 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED) {
135 err = esp_bt_controller_enable(ESP_BT_MODE_BLE);
137 ESP_LOGE(TAG,
"esp_bt_controller_enable failed: %s", esp_err_to_name(err));
141 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
142 ESP_LOGE(TAG,
"esp bt controller enable failed");
148 esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
150 err = esp_bluedroid_init();
152 ESP_LOGE(TAG,
"esp_bluedroid_init failed: %d", err);
155 err = esp_bluedroid_enable();
157 ESP_LOGE(TAG,
"esp_bluedroid_enable failed: %d", err);
161 if (!this->gap_event_handlers_.empty()) {
164 ESP_LOGE(TAG,
"esp_ble_gap_register_callback failed: %d", err);
169 if (!this->gatts_event_handlers_.empty()) {
172 ESP_LOGE(TAG,
"esp_ble_gatts_register_callback failed: %d", err);
177 if (!this->gattc_event_handlers_.empty()) {
180 ESP_LOGE(TAG,
"esp_ble_gattc_register_callback failed: %d", err);
187 name = this->name_.
value();
193 if (name.length() > 20) {
195 name.erase(name.begin() + 13, name.end() - 7);
197 name = name.substr(0, 20);
202 err = esp_ble_gap_set_device_name(name.c_str());
204 ESP_LOGE(TAG,
"esp_ble_gap_set_device_name failed: %d", err);
208 err = esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &(this->io_cap_),
sizeof(uint8_t));
210 ESP_LOGE(TAG,
"esp_ble_gap_set_security_param failed: %d", err);
221 esp_err_t err = esp_bluedroid_disable();
223 ESP_LOGE(TAG,
"esp_bluedroid_disable failed: %d", err);
226 err = esp_bluedroid_deinit();
228 ESP_LOGE(TAG,
"esp_bluedroid_deinit failed: %d", err);
234 ESP_LOGE(TAG,
"btStop failed: %d", esp_bt_controller_get_status());
238 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
240 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED) {
241 err = esp_bt_controller_disable();
243 ESP_LOGE(TAG,
"esp_bt_controller_disable failed: %s", esp_err_to_name(err));
246 while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED)
249 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED) {
250 err = esp_bt_controller_deinit();
252 ESP_LOGE(TAG,
"esp_bt_controller_deinit failed: %s", esp_err_to_name(err));
256 if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
257 ESP_LOGE(TAG,
"esp bt controller disable failed");
266 switch (this->state_) {
271 ESP_LOGD(TAG,
"Disabling");
273 for (
auto *ble_event_handler : this->ble_status_event_handlers_) {
274 ble_event_handler->ble_before_disabled_event_handler();
278 ESP_LOGE(TAG,
"Could not be dismantled");
286 ESP_LOGD(TAG,
"Enabling");
290 ESP_LOGE(TAG,
"Could not be set up");
302 BLEEvent *ble_event = this->ble_events_.pop();
303 while (ble_event !=
nullptr) {
304 switch (ble_event->
type_) {
306 esp_gatts_cb_event_t
event = ble_event->
event_.
gatts.gatts_event;
307 esp_gatt_if_t gatts_if = ble_event->
event_.
gatts.gatts_if;
308 esp_ble_gatts_cb_param_t *param = ble_event->
event_.
gatts.gatts_param;
309 ESP_LOGV(TAG,
"gatts_event [esp_gatt_if: %d] - %d", gatts_if, event);
310 for (
auto *gatts_handler : this->gatts_event_handlers_) {
311 gatts_handler->gatts_event_handler(event, gatts_if, param);
316 esp_gattc_cb_event_t
event = ble_event->
event_.
gattc.gattc_event;
317 esp_gatt_if_t gattc_if = ble_event->
event_.
gattc.gattc_if;
318 esp_ble_gattc_cb_param_t *param = ble_event->
event_.
gattc.gattc_param;
319 ESP_LOGV(TAG,
"gattc_event [esp_gatt_if: %d] - %d", gattc_if, event);
320 for (
auto *gattc_handler : this->gattc_event_handlers_) {
321 gattc_handler->gattc_event_handler(event, gattc_if, param);
326 esp_gap_ble_cb_event_t gap_event = ble_event->
event_.
gap.gap_event;
328 case ESP_GAP_BLE_SCAN_RESULT_EVT:
330 for (
auto *scan_handler : this->gap_scan_event_handlers_) {
331 scan_handler->gap_scan_event_handler(ble_event->
scan_result());
336 case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
337 case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
338 case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
343 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
344 for (
auto *gap_handler : this->gap_event_handlers_) {
345 gap_handler->gap_event_handler(
346 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.scan_complete));
351 case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
352 case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
353 case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
354 case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
355 case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
357 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
358 for (
auto *gap_handler : this->gap_event_handlers_) {
359 gap_handler->gap_event_handler(
360 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.adv_complete));
365 case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT:
366 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
367 for (
auto *gap_handler : this->gap_event_handlers_) {
368 gap_handler->gap_event_handler(
369 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.read_rssi_complete));
374 case ESP_GAP_BLE_AUTH_CMPL_EVT:
375 case ESP_GAP_BLE_SEC_REQ_EVT:
376 case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
377 case ESP_GAP_BLE_PASSKEY_REQ_EVT:
378 case ESP_GAP_BLE_NC_REQ_EVT:
379 ESP_LOGV(TAG,
"gap_event_handler - %d", gap_event);
380 for (
auto *gap_handler : this->gap_event_handlers_) {
381 gap_handler->gap_event_handler(
382 gap_event,
reinterpret_cast<esp_ble_gap_cb_param_t *
>(&ble_event->
event_.
gap.security));
388 ESP_LOGW(TAG,
"Unhandled GAP event type in loop: %d", gap_event);
397 this->ble_event_pool_.
release(ble_event);
398 ble_event = this->ble_events_.pop();
400 if (this->advertising_ !=
nullptr) {
401 this->advertising_->
loop();
405 uint16_t dropped = this->ble_events_.get_and_reset_dropped_count();
407 ESP_LOGW(TAG,
"Dropped %u BLE events due to buffer overflow", dropped);
413 event->load_gap_event(e, p);
417 event->load_gattc_event(e, i, p);
421 event->load_gatts_event(e, i, p);
427 if (event ==
nullptr) {
429 global_ble->ble_events_.increment_dropped_count();
443template void enqueue_ble_event(esp_gatts_cb_event_t, esp_gatt_if_t, esp_ble_gatts_cb_param_t *);
444template void enqueue_ble_event(esp_gattc_cb_event_t, esp_gatt_if_t, esp_ble_gattc_cb_param_t *);
450 case ESP_GAP_BLE_SCAN_RESULT_EVT:
451 case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
452 case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
453 case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
455 case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
456 case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
457 case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
458 case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
459 case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
461 case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT:
463 case ESP_GAP_BLE_AUTH_CMPL_EVT:
464 case ESP_GAP_BLE_SEC_REQ_EVT:
465 case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
466 case ESP_GAP_BLE_PASSKEY_REQ_EVT:
467 case ESP_GAP_BLE_NC_REQ_EVT:
472 case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
473 case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT:
479 ESP_LOGW(TAG,
"Ignoring unexpected GAP event type: %d", event);
483 esp_ble_gatts_cb_param_t *param) {
488 esp_ble_gattc_cb_param_t *param) {
495 const uint8_t *mac_address = esp_bt_dev_get_address();
497 const char *io_capability_s;
498 switch (this->io_cap_) {
500 io_capability_s =
"display_only";
503 io_capability_s =
"display_yes_no";
506 io_capability_s =
"keyboard_only";
508 case ESP_IO_CAP_NONE:
509 io_capability_s =
"none";
511 case ESP_IO_CAP_KBDISP:
512 io_capability_s =
"keyboard_display";
515 io_capability_s =
"invalid";
520 " MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n"
521 " IO Capability: %s",
522 mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5],
525 ESP_LOGCONFIG(TAG,
"ESP32 BLE: bluetooth stack is not enabled");
531 u |= uint64_t(
address[0] & 0xFF) << 40;
532 u |= uint64_t(
address[1] & 0xFF) << 32;
533 u |= uint64_t(
address[2] & 0xFF) << 24;
534 u |= uint64_t(
address[3] & 0xFF) << 16;
535 u |= uint64_t(
address[4] & 0xFF) << 8;
536 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 release(BLEEvent *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)
uint64_t ble_addr_to_uint64(const esp_bd_addr_t address)
void enqueue_ble_event(Args... args)
@ 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.
Providing packet encoding functions for exchanging data with a remote host.
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.