mirror of
https://github.com/esphome/esphome.git
synced 2024-11-29 18:24:13 +01:00
Make parse_characteristics and parse_descriptors lazy to reduce memory pressure (#4063)
This commit is contained in:
parent
c5f59fad62
commit
53e0af18fb
6 changed files with 30 additions and 2 deletions
|
@ -72,11 +72,15 @@ void BluetoothProxy::loop() {
|
||||||
api::BluetoothGATTService service_resp;
|
api::BluetoothGATTService service_resp;
|
||||||
service_resp.uuid = {service->uuid.get_128bit_high(), service->uuid.get_128bit_low()};
|
service_resp.uuid = {service->uuid.get_128bit_high(), service->uuid.get_128bit_low()};
|
||||||
service_resp.handle = service->start_handle;
|
service_resp.handle = service->start_handle;
|
||||||
|
if (!service->parsed)
|
||||||
|
service->parse_characteristics();
|
||||||
for (auto &characteristic : service->characteristics) {
|
for (auto &characteristic : service->characteristics) {
|
||||||
api::BluetoothGATTCharacteristic characteristic_resp;
|
api::BluetoothGATTCharacteristic characteristic_resp;
|
||||||
characteristic_resp.uuid = {characteristic->uuid.get_128bit_high(), characteristic->uuid.get_128bit_low()};
|
characteristic_resp.uuid = {characteristic->uuid.get_128bit_high(), characteristic->uuid.get_128bit_low()};
|
||||||
characteristic_resp.handle = characteristic->handle;
|
characteristic_resp.handle = characteristic->handle;
|
||||||
characteristic_resp.properties = characteristic->properties;
|
characteristic_resp.properties = characteristic->properties;
|
||||||
|
if (!characteristic->parsed)
|
||||||
|
characteristic->parse_descriptors();
|
||||||
for (auto &descriptor : characteristic->descriptors) {
|
for (auto &descriptor : characteristic->descriptors) {
|
||||||
api::BluetoothGATTDescriptor descriptor_resp;
|
api::BluetoothGATTDescriptor descriptor_resp;
|
||||||
descriptor_resp.uuid = {descriptor->uuid.get_128bit_high(), descriptor->uuid.get_128bit_low()};
|
descriptor_resp.uuid = {descriptor->uuid.get_128bit_high(), descriptor->uuid.get_128bit_low()};
|
||||||
|
@ -87,6 +91,13 @@ void BluetoothProxy::loop() {
|
||||||
}
|
}
|
||||||
resp.services.push_back(std::move(service_resp));
|
resp.services.push_back(std::move(service_resp));
|
||||||
api::global_api_server->send_bluetooth_gatt_services(resp);
|
api::global_api_server->send_bluetooth_gatt_services(resp);
|
||||||
|
// Descriptors are rarely used and can be quite large so we clear them
|
||||||
|
// after sending them to save memory. If something actually needs them
|
||||||
|
// it can parse them again.
|
||||||
|
for (auto &characteristic : service->characteristics) {
|
||||||
|
characteristic->parsed = false;
|
||||||
|
characteristic->descriptors.clear();
|
||||||
|
}
|
||||||
connection->send_service_++;
|
connection->send_service_++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ BLECharacteristic::~BLECharacteristic() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BLECharacteristic::parse_descriptors() {
|
void BLECharacteristic::parse_descriptors() {
|
||||||
|
this->parsed = true;
|
||||||
uint16_t offset = 0;
|
uint16_t offset = 0;
|
||||||
esp_gattc_descr_elem_t result;
|
esp_gattc_descr_elem_t result;
|
||||||
|
|
||||||
|
@ -49,6 +50,8 @@ void BLECharacteristic::parse_descriptors() {
|
||||||
}
|
}
|
||||||
|
|
||||||
BLEDescriptor *BLECharacteristic::get_descriptor(espbt::ESPBTUUID uuid) {
|
BLEDescriptor *BLECharacteristic::get_descriptor(espbt::ESPBTUUID uuid) {
|
||||||
|
if (!this->parsed)
|
||||||
|
this->parse_descriptors();
|
||||||
for (auto &desc : this->descriptors) {
|
for (auto &desc : this->descriptors) {
|
||||||
if (desc->uuid == uuid)
|
if (desc->uuid == uuid)
|
||||||
return desc;
|
return desc;
|
||||||
|
@ -59,6 +62,8 @@ BLEDescriptor *BLECharacteristic::get_descriptor(uint16_t uuid) {
|
||||||
return this->get_descriptor(espbt::ESPBTUUID::from_uint16(uuid));
|
return this->get_descriptor(espbt::ESPBTUUID::from_uint16(uuid));
|
||||||
}
|
}
|
||||||
BLEDescriptor *BLECharacteristic::get_descriptor_by_handle(uint16_t handle) {
|
BLEDescriptor *BLECharacteristic::get_descriptor_by_handle(uint16_t handle) {
|
||||||
|
if (!this->parsed)
|
||||||
|
this->parse_descriptors();
|
||||||
for (auto &desc : this->descriptors) {
|
for (auto &desc : this->descriptors) {
|
||||||
if (desc->handle == handle)
|
if (desc->handle == handle)
|
||||||
return desc;
|
return desc;
|
||||||
|
|
|
@ -18,6 +18,7 @@ class BLEService;
|
||||||
class BLECharacteristic {
|
class BLECharacteristic {
|
||||||
public:
|
public:
|
||||||
~BLECharacteristic();
|
~BLECharacteristic();
|
||||||
|
bool parsed = false;
|
||||||
espbt::ESPBTUUID uuid;
|
espbt::ESPBTUUID uuid;
|
||||||
uint16_t handle;
|
uint16_t handle;
|
||||||
esp_gatt_char_prop_t properties;
|
esp_gatt_char_prop_t properties;
|
||||||
|
|
|
@ -135,6 +135,7 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||||
for (auto &svc : this->services_)
|
for (auto &svc : this->services_)
|
||||||
delete svc; // NOLINT(cppcoreguidelines-owning-memory)
|
delete svc; // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
this->services_.clear();
|
this->services_.clear();
|
||||||
|
esp_ble_gattc_cache_clean(this->remote_bda_);
|
||||||
this->set_state(espbt::ClientState::IDLE);
|
this->set_state(espbt::ClientState::IDLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +155,6 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||||
svc->uuid.to_string().c_str());
|
svc->uuid.to_string().c_str());
|
||||||
ESP_LOGI(TAG, "[%d] [%s] start_handle: 0x%x end_handle: 0x%x", this->connection_index_,
|
ESP_LOGI(TAG, "[%d] [%s] start_handle: 0x%x end_handle: 0x%x", this->connection_index_,
|
||||||
this->address_str_.c_str(), svc->start_handle, svc->end_handle);
|
this->address_str_.c_str(), svc->start_handle, svc->end_handle);
|
||||||
svc->parse_characteristics();
|
|
||||||
}
|
}
|
||||||
this->set_state(espbt::ClientState::CONNECTED);
|
this->set_state(espbt::ClientState::CONNECTED);
|
||||||
this->state_ = espbt::ClientState::ESTABLISHED;
|
this->state_ = espbt::ClientState::ESTABLISHED;
|
||||||
|
@ -287,6 +287,8 @@ BLECharacteristic *BLEClientBase::get_characteristic(uint16_t service, uint16_t
|
||||||
|
|
||||||
BLECharacteristic *BLEClientBase::get_characteristic(uint16_t handle) {
|
BLECharacteristic *BLEClientBase::get_characteristic(uint16_t handle) {
|
||||||
for (auto *svc : this->services_) {
|
for (auto *svc : this->services_) {
|
||||||
|
if (!svc->parsed)
|
||||||
|
svc->parse_characteristics();
|
||||||
for (auto *chr : svc->characteristics) {
|
for (auto *chr : svc->characteristics) {
|
||||||
if (chr->handle == handle)
|
if (chr->handle == handle)
|
||||||
return chr;
|
return chr;
|
||||||
|
@ -298,6 +300,8 @@ BLECharacteristic *BLEClientBase::get_characteristic(uint16_t handle) {
|
||||||
BLEDescriptor *BLEClientBase::get_config_descriptor(uint16_t handle) {
|
BLEDescriptor *BLEClientBase::get_config_descriptor(uint16_t handle) {
|
||||||
auto *chr = this->get_characteristic(handle);
|
auto *chr = this->get_characteristic(handle);
|
||||||
if (chr != nullptr) {
|
if (chr != nullptr) {
|
||||||
|
if (!chr->parsed)
|
||||||
|
chr->parse_descriptors();
|
||||||
for (auto &desc : chr->descriptors) {
|
for (auto &desc : chr->descriptors) {
|
||||||
if (desc->uuid.get_uuid().uuid.uuid16 == 0x2902)
|
if (desc->uuid.get_uuid().uuid.uuid16 == 0x2902)
|
||||||
return desc;
|
return desc;
|
||||||
|
@ -323,7 +327,11 @@ BLEDescriptor *BLEClientBase::get_descriptor(uint16_t service, uint16_t chr, uin
|
||||||
|
|
||||||
BLEDescriptor *BLEClientBase::get_descriptor(uint16_t handle) {
|
BLEDescriptor *BLEClientBase::get_descriptor(uint16_t handle) {
|
||||||
for (auto *svc : this->services_) {
|
for (auto *svc : this->services_) {
|
||||||
|
if (!svc->parsed)
|
||||||
|
svc->parse_characteristics();
|
||||||
for (auto *chr : svc->characteristics) {
|
for (auto *chr : svc->characteristics) {
|
||||||
|
if (!chr->parsed)
|
||||||
|
chr->parse_descriptors();
|
||||||
for (auto *desc : chr->descriptors) {
|
for (auto *desc : chr->descriptors) {
|
||||||
if (desc->handle == handle)
|
if (desc->handle == handle)
|
||||||
return desc;
|
return desc;
|
||||||
|
|
|
@ -11,6 +11,8 @@ namespace esp32_ble_client {
|
||||||
static const char *const TAG = "esp32_ble_client";
|
static const char *const TAG = "esp32_ble_client";
|
||||||
|
|
||||||
BLECharacteristic *BLEService::get_characteristic(espbt::ESPBTUUID uuid) {
|
BLECharacteristic *BLEService::get_characteristic(espbt::ESPBTUUID uuid) {
|
||||||
|
if (!this->parsed)
|
||||||
|
this->parse_characteristics();
|
||||||
for (auto &chr : this->characteristics) {
|
for (auto &chr : this->characteristics) {
|
||||||
if (chr->uuid == uuid)
|
if (chr->uuid == uuid)
|
||||||
return chr;
|
return chr;
|
||||||
|
@ -28,6 +30,7 @@ BLEService::~BLEService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BLEService::parse_characteristics() {
|
void BLEService::parse_characteristics() {
|
||||||
|
this->parsed = true;
|
||||||
uint16_t offset = 0;
|
uint16_t offset = 0;
|
||||||
esp_gattc_char_elem_t result;
|
esp_gattc_char_elem_t result;
|
||||||
|
|
||||||
|
@ -57,7 +60,6 @@ void BLEService::parse_characteristics() {
|
||||||
ESP_LOGI(TAG, "[%d] [%s] characteristic %s, handle 0x%x, properties 0x%x", this->client->get_connection_index(),
|
ESP_LOGI(TAG, "[%d] [%s] characteristic %s, handle 0x%x, properties 0x%x", this->client->get_connection_index(),
|
||||||
this->client->address_str().c_str(), characteristic->uuid.to_string().c_str(), characteristic->handle,
|
this->client->address_str().c_str(), characteristic->uuid.to_string().c_str(), characteristic->handle,
|
||||||
characteristic->properties);
|
characteristic->properties);
|
||||||
characteristic->parse_descriptors();
|
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ class BLEClientBase;
|
||||||
class BLEService {
|
class BLEService {
|
||||||
public:
|
public:
|
||||||
~BLEService();
|
~BLEService();
|
||||||
|
bool parsed = false;
|
||||||
espbt::ESPBTUUID uuid;
|
espbt::ESPBTUUID uuid;
|
||||||
uint16_t start_handle;
|
uint16_t start_handle;
|
||||||
uint16_t end_handle;
|
uint16_t end_handle;
|
||||||
|
|
Loading…
Reference in a new issue