ESPHome  2022.11.3
ble_server.cpp
Go to the documentation of this file.
1 #include "ble_server.h"
2 
4 #include "esphome/core/log.h"
6 #include "esphome/core/version.h"
7 
8 #ifdef USE_ESP32
9 
10 #include <nvs_flash.h>
11 #include <freertos/FreeRTOSConfig.h>
12 #include <esp_bt_main.h>
13 #include <esp_bt.h>
14 #include <freertos/task.h>
15 #include <esp_gap_ble_api.h>
16 
17 namespace esphome {
18 namespace esp32_ble_server {
19 
20 static const char *const TAG = "esp32_ble_server";
21 
22 static const uint16_t DEVICE_INFORMATION_SERVICE_UUID = 0x180A;
23 static const uint16_t MODEL_UUID = 0x2A24;
24 static const uint16_t VERSION_UUID = 0x2A26;
25 static const uint16_t MANUFACTURER_UUID = 0x2A29;
26 
28  if (this->is_failed()) {
29  ESP_LOGE(TAG, "BLE Server was marked failed by ESP32BLE");
30  return;
31  }
32 
33  ESP_LOGD(TAG, "Setting up BLE Server...");
34 
35  global_ble_server = this;
36 }
37 
39  switch (this->state_) {
40  case RUNNING:
41  return;
42 
43  case INIT: {
44  esp_err_t err = esp_ble_gatts_app_register(0);
45  if (err != ESP_OK) {
46  ESP_LOGE(TAG, "esp_ble_gatts_app_register failed: %d", err);
47  this->mark_failed();
48  return;
49  }
50  this->state_ = REGISTERING;
51  break;
52  }
53  case REGISTERING: {
54  if (this->registered_) {
55  this->device_information_service_ = this->create_service(DEVICE_INFORMATION_SERVICE_UUID);
56 
58 
59  this->state_ = STARTING_SERVICE;
60  }
61  break;
62  }
63  case STARTING_SERVICE: {
64  if (!this->device_information_service_->is_created()) {
65  break;
66  }
67  if (this->device_information_service_->is_running()) {
68  this->state_ = RUNNING;
69  this->can_proceed_ = true;
70  ESP_LOGD(TAG, "BLE server setup successfully");
71  } else if (!this->device_information_service_->is_starting()) {
72  this->device_information_service_->start();
73  }
74  break;
75  }
76  }
77 }
78 
80  if (this->model_.has_value()) {
81  BLECharacteristic *model =
82  this->device_information_service_->create_characteristic(MODEL_UUID, BLECharacteristic::PROPERTY_READ);
83  model->set_value(this->model_.value());
84  } else {
85  BLECharacteristic *model =
86  this->device_information_service_->create_characteristic(MODEL_UUID, BLECharacteristic::PROPERTY_READ);
87  model->set_value(ESPHOME_BOARD);
88  }
89 
91  this->device_information_service_->create_characteristic(VERSION_UUID, BLECharacteristic::PROPERTY_READ);
92  version->set_value("ESPHome " ESPHOME_VERSION);
93 
94  BLECharacteristic *manufacturer =
95  this->device_information_service_->create_characteristic(MANUFACTURER_UUID, BLECharacteristic::PROPERTY_READ);
96  manufacturer->set_value(this->manufacturer_);
97 
98  return true;
99 }
100 
101 std::shared_ptr<BLEService> BLEServer::create_service(const uint8_t *uuid, bool advertise) {
102  return this->create_service(ESPBTUUID::from_raw(uuid), advertise);
103 }
104 std::shared_ptr<BLEService> BLEServer::create_service(uint16_t uuid, bool advertise) {
105  return this->create_service(ESPBTUUID::from_uint16(uuid), advertise);
106 }
107 std::shared_ptr<BLEService> BLEServer::create_service(const std::string &uuid, bool advertise) {
108  return this->create_service(ESPBTUUID::from_raw(uuid), advertise);
109 }
110 std::shared_ptr<BLEService> BLEServer::create_service(ESPBTUUID uuid, bool advertise, uint16_t num_handles,
111  uint8_t inst_id) {
112  ESP_LOGV(TAG, "Creating service - %s", uuid.to_string().c_str());
113  std::shared_ptr<BLEService> service = std::make_shared<BLEService>(uuid, num_handles, inst_id);
114  this->services_.emplace_back(service);
115  if (advertise) {
117  }
118  service->do_create(this);
119  return service;
120 }
121 
122 void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
123  esp_ble_gatts_cb_param_t *param) {
124  switch (event) {
125  case ESP_GATTS_CONNECT_EVT: {
126  ESP_LOGD(TAG, "BLE Client connected");
127  this->add_client_(param->connect.conn_id, (void *) this);
128  this->connected_clients_++;
129  for (auto *component : this->service_components_) {
130  component->on_client_connect();
131  }
132  break;
133  }
134  case ESP_GATTS_DISCONNECT_EVT: {
135  ESP_LOGD(TAG, "BLE Client disconnected");
136  if (this->remove_client_(param->disconnect.conn_id))
137  this->connected_clients_--;
139  for (auto *component : this->service_components_) {
140  component->on_client_disconnect();
141  }
142  break;
143  }
144  case ESP_GATTS_REG_EVT: {
145  this->gatts_if_ = gatts_if;
146  this->registered_ = true;
147  break;
148  }
149  default:
150  break;
151  }
152 
153  for (const auto &service : this->services_) {
154  service->gatts_event_handler(event, gatts_if, param);
155  }
156 }
157 
159 
160 void BLEServer::dump_config() { ESP_LOGCONFIG(TAG, "ESP32 BLE Server:"); }
161 
162 BLEServer *global_ble_server = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
163 
164 } // namespace esp32_ble_server
165 } // namespace esphome
166 
167 #endif
value_type const & value() const
Definition: optional.h:89
bool remove_client_(uint16_t conn_id)
Definition: ble_server.h:67
ESP32BLE * global_ble
Definition: ble.cpp:208
float get_setup_priority() const override
Definition: ble_server.cpp:158
void set_value(const uint8_t *data, size_t length)
bool has_value() const
Definition: optional.h:87
std::shared_ptr< BLEService > create_service(const uint8_t *uuid, bool advertise=false)
Definition: ble_server.cpp:101
std::shared_ptr< BLEService > device_information_service_
Definition: ble_server.h:80
const float AFTER_BLUETOOTH
Definition: component.cpp:21
optional< std::string > model_
Definition: ble_server.h:72
void add_client_(uint16_t conn_id, void *client)
Definition: ble_server.h:64
std::vector< BLEServiceComponent * > service_components_
Definition: ble_server.h:82
enum esphome::esp32_ble_server::BLEServer::State INIT
static ESPBTUUID from_uint16(uint16_t uuid)
Definition: ble_uuid.cpp:15
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
std::vector< std::shared_ptr< BLEService > > services_
Definition: ble_server.h:79
BLEAdvertising * get_advertising()
Definition: ble.h:46
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:112
Definition: a4988.cpp:4
static ESPBTUUID from_raw(const uint8_t *data)
Definition: ble_uuid.cpp:27