ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
ble_descriptor.cpp
Go to the documentation of this file.
1#include "ble_descriptor.h"
3#include "ble_service.h"
4#include "esphome/core/log.h"
5
6#include <cstring>
7
8#ifdef USE_ESP32
9
11
12static const char *const TAG = "esp32_ble_server.descriptor";
13
14static RAMAllocator<uint8_t> descriptor_allocator{}; // NOLINT
15
16BLEDescriptor::BLEDescriptor(ESPBTUUID uuid, uint16_t max_len, bool read, bool write) {
17 this->uuid_ = uuid;
18 this->value_.attr_len = 0;
19 this->value_.attr_max_len = max_len;
20 this->value_.attr_value = descriptor_allocator.allocate(max_len);
21 if (read) {
22 this->permissions_ |= ESP_GATT_PERM_READ;
23 }
24 if (write) {
25 this->permissions_ |= ESP_GATT_PERM_WRITE;
26 }
27}
28
29BLEDescriptor::~BLEDescriptor() { free(this->value_.attr_value); } // NOLINT
30
32 this->characteristic_ = characteristic;
33 esp_attr_control_t control;
34 control.auto_rsp = ESP_GATT_AUTO_RSP;
35
36#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
37 char uuid_buf[esp32_ble::UUID_STR_LEN];
38 this->uuid_.to_str(uuid_buf);
39 ESP_LOGV(TAG, "Creating descriptor - %s", uuid_buf);
40#endif
41 esp_bt_uuid_t uuid = this->uuid_.get_uuid();
42 esp_err_t err = esp_ble_gatts_add_char_descr(this->characteristic_->get_service()->get_handle(), &uuid,
43 this->permissions_, &this->value_, &control);
44 if (err != ESP_OK) {
45 ESP_LOGE(TAG, "esp_ble_gatts_add_char_descr failed: %d", err);
46 this->state_ = FAILED;
47 return;
48 }
49 this->state_ = CREATING;
50}
51
52void BLEDescriptor::set_value(std::vector<uint8_t> &&buffer) { this->set_value_impl_(buffer.data(), buffer.size()); }
53
54void BLEDescriptor::set_value(std::initializer_list<uint8_t> data) { this->set_value_impl_(data.begin(), data.size()); }
55
56void BLEDescriptor::set_value_impl_(const uint8_t *data, size_t length) {
57 if (length > this->value_.attr_max_len) {
58 ESP_LOGE(TAG, "Size %d too large, must be no bigger than %d", length, this->value_.attr_max_len);
59 return;
60 }
61 this->value_.attr_len = length;
62 memcpy(this->value_.attr_value, data, length);
63}
64
65void BLEDescriptor::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
66 esp_ble_gatts_cb_param_t *param) {
67 switch (event) {
68 case ESP_GATTS_ADD_CHAR_DESCR_EVT: {
69 if (this->characteristic_ != nullptr && this->uuid_ == ESPBTUUID::from_uuid(param->add_char_descr.descr_uuid) &&
70 this->characteristic_->get_service()->get_handle() == param->add_char_descr.service_handle &&
71 this->characteristic_ == this->characteristic_->get_service()->get_last_created_characteristic()) {
72 this->handle_ = param->add_char_descr.attr_handle;
73 this->state_ = CREATED;
74 }
75 break;
76 }
77 case ESP_GATTS_WRITE_EVT: {
78 if (this->handle_ != param->write.handle)
79 break;
80 this->value_.attr_len = param->write.len;
81 memcpy(this->value_.attr_value, param->write.value, param->write.len);
82 if (this->on_write_callback_) {
83 (*this->on_write_callback_)(std::span<const uint8_t>(param->write.value, param->write.len),
84 param->write.conn_id);
85 }
86 break;
87 }
88 default:
89 break;
90 }
91}
92
93} // namespace esphome::esp32_ble_server
94
95#endif
static ESPBTUUID from_uuid(esp_bt_uuid_t uuid)
Definition ble_uuid.cpp:84
ESPDEPRECATED("Use to_str() instead. Removed in 2026.8.0", "2026.2.0") std const char * to_str(std::span< char, UUID_STR_LEN > output) const
Definition ble_uuid.cpp:146
esp_bt_uuid_t get_uuid() const
Definition ble_uuid.cpp:145
std::unique_ptr< std::function< void(std::span< const uint8_t >, uint16_t)> > on_write_callback_
void set_value(std::vector< uint8_t > &&buffer)
void set_value_impl_(const uint8_t *data, size_t length)
void do_create(BLECharacteristic *characteristic)
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
BLEDescriptor(ESPBTUUID uuid, uint16_t max_len=100, bool read=true, bool write=true)
uint16_t length
Definition tt21100.cpp:0