ESPHome  2024.4.0
ble_service.cpp
Go to the documentation of this file.
1 #include "ble_service.h"
2 #include "ble_server.h"
3 #include "esphome/core/log.h"
4 
5 #ifdef USE_ESP32
6 
7 namespace esphome {
8 namespace esp32_ble_server {
9 
10 static const char *const TAG = "esp32_ble_server.service";
11 
12 BLEService::BLEService(ESPBTUUID uuid, uint16_t num_handles, uint8_t inst_id, bool advertise)
13  : uuid_(uuid), num_handles_(num_handles), inst_id_(inst_id), advertise_(advertise) {}
14 
16  for (auto &chr : this->characteristics_)
17  delete chr; // NOLINT(cppcoreguidelines-owning-memory)
18 }
19 
21  for (auto *chr : this->characteristics_) {
22  if (chr->get_uuid() == uuid)
23  return chr;
24  }
25  return nullptr;
26 }
27 
29  return this->get_characteristic(ESPBTUUID::from_uint16(uuid));
30 }
31 BLECharacteristic *BLEService::create_characteristic(uint16_t uuid, esp_gatt_char_prop_t properties) {
32  return create_characteristic(ESPBTUUID::from_uint16(uuid), properties);
33 }
34 BLECharacteristic *BLEService::create_characteristic(const std::string &uuid, esp_gatt_char_prop_t properties) {
35  return create_characteristic(ESPBTUUID::from_raw(uuid), properties);
36 }
37 BLECharacteristic *BLEService::create_characteristic(ESPBTUUID uuid, esp_gatt_char_prop_t properties) {
38  // NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
39  BLECharacteristic *characteristic = new BLECharacteristic(uuid, properties);
40  this->characteristics_.push_back(characteristic);
41  return characteristic;
42 }
43 
45  this->server_ = server;
46 
47  esp_gatt_srvc_id_t srvc_id;
48  srvc_id.is_primary = true;
49  srvc_id.id.inst_id = this->inst_id_;
50  srvc_id.id.uuid = this->uuid_.get_uuid();
51 
52  esp_err_t err = esp_ble_gatts_create_service(server->get_gatts_if(), &srvc_id, this->num_handles_);
53  if (err != ESP_OK) {
54  ESP_LOGE(TAG, "esp_ble_gatts_create_service failed: %d", err);
55  this->init_state_ = FAILED;
56  return;
57  }
58  this->init_state_ = CREATING;
59 }
60 
62  if (this->init_state_ == DELETING || this->init_state_ == DELETED)
63  return;
64  this->init_state_ = DELETING;
66  this->last_created_characteristic_ = nullptr;
67  this->stop_();
68  esp_err_t err = esp_ble_gatts_delete_service(this->handle_);
69  if (err != ESP_OK) {
70  ESP_LOGE(TAG, "esp_ble_gatts_delete_service failed: %d", err);
71  return;
72  }
73 }
74 
76  if (this->created_characteristic_count_ >= this->characteristics_.size() &&
78  return false; // Signifies there are no characteristics, or they are all finished being created.
79 
81  return true; // Signifies that the previous characteristic is still being created.
82 
83  auto *characteristic = this->characteristics_[this->created_characteristic_count_++];
84  this->last_created_characteristic_ = characteristic;
85  characteristic->do_create(this);
86  return true;
87 }
88 
90  if (this->do_create_characteristics_())
91  return;
92  should_start_ = true;
93 
94  esp_err_t err = esp_ble_gatts_start_service(this->handle_);
95  if (err != ESP_OK) {
96  ESP_LOGE(TAG, "esp_ble_gatts_start_service failed: %d", err);
97  return;
98  }
99  if (this->advertise_)
101  this->running_state_ = STARTING;
102 }
103 
105  should_start_ = false;
106  this->stop_();
107 }
108 
110  if (this->running_state_ == STOPPING || this->running_state_ == STOPPED)
111  return;
112  this->running_state_ = STOPPING;
113  esp_err_t err = esp_ble_gatts_stop_service(this->handle_);
114  if (err != ESP_OK) {
115  ESP_LOGE(TAG, "esp_ble_gatts_stop_service failed: %d", err);
116  return;
117  }
118  if (this->advertise_)
120 }
121 
122 bool BLEService::is_created() { return this->init_state_ == CREATED; }
124  if (this->init_state_ == FAILED)
125  return true;
126  bool failed = false;
127  for (auto *characteristic : this->characteristics_)
128  failed |= characteristic->is_failed();
129 
130  if (failed)
131  this->init_state_ = FAILED;
132  return this->init_state_ == FAILED;
133 }
134 
135 void BLEService::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
136  esp_ble_gatts_cb_param_t *param) {
137  switch (event) {
138  case ESP_GATTS_CREATE_EVT: {
139  if (this->uuid_ == ESPBTUUID::from_uuid(param->create.service_id.id.uuid) &&
140  this->inst_id_ == param->create.service_id.id.inst_id) {
141  this->handle_ = param->create.service_handle;
142  this->init_state_ = CREATED;
143  if (this->should_start_)
144  this->start();
145  }
146  break;
147  }
148  case ESP_GATTS_DELETE_EVT:
149  if (param->del.service_handle == this->handle_) {
150  this->init_state_ = DELETED;
151  }
152  break;
153  case ESP_GATTS_START_EVT: {
154  if (param->start.service_handle == this->handle_) {
155  this->running_state_ = RUNNING;
156  }
157  break;
158  }
159  case ESP_GATTS_STOP_EVT: {
160  if (param->start.service_handle == this->handle_) {
161  this->running_state_ = STOPPED;
162  }
163  break;
164  }
165  default:
166  break;
167  }
168 
169  for (auto *characteristic : this->characteristics_) {
170  characteristic->gatts_event_handler(event, gatts_if, param);
171  }
172 }
173 
174 } // namespace esp32_ble_server
175 } // namespace esphome
176 
177 #endif
ESP32BLE * global_ble
Definition: ble.cpp:394
BLECharacteristic * last_created_characteristic_
Definition: ble_service.h:56
void advertising_remove_service_uuid(ESPBTUUID uuid)
Definition: ble.cpp:82
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
BLEService(ESPBTUUID uuid, uint16_t num_handles, uint8_t inst_id, bool advertise)
Definition: ble_service.cpp:12
static ESPBTUUID from_uuid(esp_bt_uuid_t uuid)
Definition: ble_uuid.cpp:91
static ESPBTUUID from_uint16(uint16_t uuid)
Definition: ble_uuid.cpp:16
void do_create(BLEServer *server)
Definition: ble_service.cpp:44
std::vector< BLECharacteristic * > characteristics_
Definition: ble_service.h:55
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
static ESPBTUUID from_raw(const uint8_t *data)
Definition: ble_uuid.cpp:28
BLECharacteristic * get_characteristic(ESPBTUUID uuid)
Definition: ble_service.cpp:20
BLECharacteristic * create_characteristic(const std::string &uuid, esp_gatt_char_prop_t properties)
Definition: ble_service.cpp:34
void advertising_add_service_uuid(ESPBTUUID uuid)
Definition: ble.cpp:76
esp_bt_uuid_t get_uuid() const
Definition: ble_uuid.cpp:164
enum esphome::esp32_ble_server::BLEService::RunningState STOPPED