ESPHome  2022.9.1
ble.cpp
Go to the documentation of this file.
1 #ifdef USE_ESP32
2 
3 #include "ble.h"
5 #include "esphome/core/log.h"
6 
7 #include <nvs_flash.h>
8 #include <freertos/FreeRTOSConfig.h>
9 #include <esp_bt_main.h>
10 #include <esp_bt.h>
11 #include <freertos/FreeRTOS.h>
12 #include <freertos/task.h>
13 #include <esp_gap_ble_api.h>
14 
15 #ifdef USE_ARDUINO
16 #include <esp32-hal-bt.h>
17 #endif
18 
19 namespace esphome {
20 namespace esp32_ble {
21 
22 static const char *const TAG = "esp32_ble";
23 
25  global_ble = this;
26  ESP_LOGCONFIG(TAG, "Setting up BLE...");
27 
28  if (!ble_setup_()) {
29  ESP_LOGE(TAG, "BLE could not be set up");
30  this->mark_failed();
31  return;
32  }
33 
34  this->advertising_ = new BLEAdvertising(); // NOLINT(cppcoreguidelines-owning-memory)
35 
36  this->advertising_->set_scan_response(true);
38  this->advertising_->start();
39 
40  ESP_LOGD(TAG, "BLE setup complete");
41 }
42 
45 #ifdef USE_ESP32_BLE_SERVER
46  if (this->server_ != nullptr) {
47  this->server_->mark_failed();
48  }
49 #endif
50 }
51 
53  esp_err_t err = nvs_flash_init();
54  if (err != ESP_OK) {
55  ESP_LOGE(TAG, "nvs_flash_init failed: %d", err);
56  return false;
57  }
58 
59 #ifdef USE_ARDUINO
60  if (!btStart()) {
61  ESP_LOGE(TAG, "btStart failed: %d", esp_bt_controller_get_status());
62  return false;
63  }
64 #else
65  if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
66  // start bt controller
67  if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE) {
68  esp_bt_controller_config_t cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
69  err = esp_bt_controller_init(&cfg);
70  if (err != ESP_OK) {
71  ESP_LOGE(TAG, "esp_bt_controller_init failed: %s", esp_err_to_name(err));
72  return false;
73  }
74  while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE)
75  ;
76  }
77  if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED) {
78  err = esp_bt_controller_enable(ESP_BT_MODE_BLE);
79  if (err != ESP_OK) {
80  ESP_LOGE(TAG, "esp_bt_controller_enable failed: %s", esp_err_to_name(err));
81  return false;
82  }
83  }
84  if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
85  ESP_LOGE(TAG, "esp bt controller enable failed");
86  return false;
87  }
88  }
89 #endif
90 
91  esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
92 
93  err = esp_bluedroid_init();
94  if (err != ESP_OK) {
95  ESP_LOGE(TAG, "esp_bluedroid_init failed: %d", err);
96  return false;
97  }
98  err = esp_bluedroid_enable();
99  if (err != ESP_OK) {
100  ESP_LOGE(TAG, "esp_bluedroid_enable failed: %d", err);
101  return false;
102  }
103  err = esp_ble_gap_register_callback(ESP32BLE::gap_event_handler);
104  if (err != ESP_OK) {
105  ESP_LOGE(TAG, "esp_ble_gap_register_callback failed: %d", err);
106  return false;
107  }
108 
109  if (this->has_server()) {
110  err = esp_ble_gatts_register_callback(ESP32BLE::gatts_event_handler);
111  if (err != ESP_OK) {
112  ESP_LOGE(TAG, "esp_ble_gatts_register_callback failed: %d", err);
113  return false;
114  }
115  }
116 
117  if (this->has_client()) {
118  err = esp_ble_gattc_register_callback(ESP32BLE::gattc_event_handler);
119  if (err != ESP_OK) {
120  ESP_LOGE(TAG, "esp_ble_gattc_register_callback failed: %d", err);
121  return false;
122  }
123  }
124 
125  std::string name = App.get_name();
126  if (name.length() > 20) {
128  name.erase(name.begin() + 13, name.end() - 7); // Remove characters between 13 and the mac address
129  } else {
130  name = name.substr(0, 20);
131  }
132  }
133 
134  err = esp_ble_gap_set_device_name(name.c_str());
135  if (err != ESP_OK) {
136  ESP_LOGE(TAG, "esp_ble_gap_set_device_name failed: %d", err);
137  return false;
138  }
139 
140  esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE;
141  err = esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
142  if (err != ESP_OK) {
143  ESP_LOGE(TAG, "esp_ble_gap_set_security_param failed: %d", err);
144  return false;
145  }
146 
147  // BLE takes some time to be fully set up, 200ms should be more than enough
148  delay(200); // NOLINT
149 
150  return true;
151 }
152 
154  BLEEvent *ble_event = this->ble_events_.pop();
155  while (ble_event != nullptr) {
156  switch (ble_event->type_) {
157  case BLEEvent::GATTS:
158  this->real_gatts_event_handler_(ble_event->event_.gatts.gatts_event, ble_event->event_.gatts.gatts_if,
159  &ble_event->event_.gatts.gatts_param);
160  break;
161  case BLEEvent::GAP:
162  this->real_gap_event_handler_(ble_event->event_.gap.gap_event, &ble_event->event_.gap.gap_param);
163  break;
164  default:
165  break;
166  }
167  delete ble_event; // NOLINT(cppcoreguidelines-owning-memory)
168  ble_event = this->ble_events_.pop();
169  }
170 }
171 
172 void ESP32BLE::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
173  BLEEvent *new_event = new BLEEvent(event, param); // NOLINT(cppcoreguidelines-owning-memory)
174  global_ble->ble_events_.push(new_event);
175 } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
176 
177 void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
178  ESP_LOGV(TAG, "(BLE) gap_event_handler - %d", event);
179  switch (event) {
180  default:
181  break;
182  }
183 }
184 
185 void ESP32BLE::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
186  esp_ble_gatts_cb_param_t *param) {
187  BLEEvent *new_event = new BLEEvent(event, gatts_if, param); // NOLINT(cppcoreguidelines-owning-memory)
188  global_ble->ble_events_.push(new_event);
189 } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
190 
191 void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
192  esp_ble_gatts_cb_param_t *param) {
193  ESP_LOGV(TAG, "(BLE) gatts_event [esp_gatt_if: %d] - %d", gatts_if, event);
194 #ifdef USE_ESP32_BLE_SERVER
195  this->server_->gatts_event_handler(event, gatts_if, param);
196 #endif
197 }
198 
199 void ESP32BLE::real_gattc_event_handler_(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
200  esp_ble_gattc_cb_param_t *param) {
201  // this->client_->gattc_event_handler(event, gattc_if, param);
202 }
203 
205 
206 void ESP32BLE::dump_config() { ESP_LOGCONFIG(TAG, "ESP32 BLE:"); }
207 
208 ESP32BLE *global_ble = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
209 
210 } // namespace esp32_ble
211 } // namespace esphome
212 
213 #endif
esp32_ble_server::BLEServer * server_
Definition: ble.h:63
const char * name
Definition: stm32flash.h:78
void set_min_preferred_interval(uint16_t interval)
ESP32BLE * global_ble
Definition: ble.cpp:208
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
Definition: ble.cpp:185
struct esphome::esp32_ble::BLEEvent::@59::gap_event gap
Queue< BLEEvent > ble_events_
Definition: ble.h:65
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
Definition: ble.cpp:172
void real_gattc_event_handler_(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
Definition: ble.cpp:199
float get_setup_priority() const override
Definition: ble.cpp:204
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
Definition: ble_server.cpp:122
void real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
Definition: ble.cpp:191
void setup() override
Definition: ble.cpp:24
void mark_failed() override
Definition: ble.cpp:43
Application App
Global storage of Application pointer - only one Application can exist.
enum esphome::esp32_ble::BLEEvent::ble_event_t type_
const std::string & get_name() const
Get the name of this Application set by set_name().
Definition: application.h:135
bool is_name_add_mac_suffix_enabled() const
Definition: application.h:137
struct esphome::esp32_ble::BLEEvent::@59::gatts_event gatts
void dump_config() override
Definition: ble.cpp:206
void loop() override
Definition: ble.cpp:153
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:111
void real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
Definition: ble.cpp:177
union esphome::esp32_ble::BLEEvent::@59 event_
static void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
Definition: a4988.cpp:4
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:27
BLEAdvertising * advertising_
Definition: ble.h:66
void set_scan_response(bool scan_response)