From bc5c2d4eb477c659ac84f0f9d7fb139b465a545e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 28 Nov 2022 18:16:25 -1000 Subject: [PATCH] Avoid parsing characteristics and descriptors to reduce memory pressure (#4109) --- .../bluetooth_proxy/bluetooth_connection.cpp | 4 -- .../esp32_ble_client/ble_client_base.cpp | 39 ++++++++++++++----- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/esphome/components/bluetooth_proxy/bluetooth_connection.cpp b/esphome/components/bluetooth_proxy/bluetooth_connection.cpp index 1fd6f08bb5..b14641fd86 100644 --- a/esphome/components/bluetooth_proxy/bluetooth_connection.cpp +++ b/esphome/components/bluetooth_proxy/bluetooth_connection.cpp @@ -105,8 +105,6 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga break; } case ESP_GATTC_UNREG_FOR_NOTIFY_EVT: { - if (this->get_characteristic(param->unreg_for_notify.handle) == nullptr) // No conn_id in this event - break; if (param->unreg_for_notify.status != ESP_GATT_OK) { ESP_LOGW(TAG, "[%d] [%s] Error unregistering notifications for handle 0x%2X, status=%d", this->connection_index_, this->address_str_.c_str(), param->unreg_for_notify.handle, @@ -122,8 +120,6 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga break; } case ESP_GATTC_REG_FOR_NOTIFY_EVT: { - if (this->get_characteristic(param->reg_for_notify.handle) == nullptr) // No conn_id in this event - break; if (param->reg_for_notify.status != ESP_GATT_OK) { ESP_LOGW(TAG, "[%d] [%s] Error registering notifications for handle 0x%2X, status=%d", this->connection_index_, this->address_str_.c_str(), param->reg_for_notify.handle, param->reg_for_notify.status); diff --git a/esphome/components/esp32_ble_client/ble_client_base.cpp b/esphome/components/esp32_ble_client/ble_client_base.cpp index c1e67108ca..065d56e5fb 100644 --- a/esphome/components/esp32_ble_client/ble_client_base.cpp +++ b/esphome/components/esp32_ble_client/ble_client_base.cpp @@ -9,6 +9,13 @@ namespace esphome { namespace esp32_ble_client { static const char *const TAG = "esp32_ble_client"; +static const esp_bt_uuid_t NOTIFY_DESC_UUID = { + .len = ESP_UUID_LEN_16, + .uuid = + { + .uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG, + }, +}; void BLEClientBase::setup() { static uint8_t connection_index = 0; @@ -173,21 +180,33 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_ break; } case ESP_GATTC_REG_FOR_NOTIFY_EVT: { - auto *descr = this->get_config_descriptor(param->reg_for_notify.handle); - if (descr->uuid.get_uuid().len != ESP_UUID_LEN_16 || - descr->uuid.get_uuid().uuid.uuid16 != ESP_GATT_UUID_CHAR_CLIENT_CONFIG) { - ESP_LOGW(TAG, "[%d] [%s] Handle 0x%x (uuid %s) is not a client config char uuid", this->connection_index_, - this->address_str_.c_str(), param->reg_for_notify.handle, descr->uuid.to_string().c_str()); + esp_gattc_descr_elem_t desc_result; + uint16_t count = 1; + esp_gatt_status_t descr_status = + esp_ble_gattc_get_descr_by_char_handle(this->gattc_if_, this->connection_index_, param->reg_for_notify.handle, + NOTIFY_DESC_UUID, &desc_result, &count); + if (descr_status != ESP_GATT_OK) { + ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_get_descr_by_char_handle error, status=%d", this->connection_index_, + this->address_str_.c_str(), descr_status); break; } + esp_gattc_char_elem_t char_result; + esp_gatt_status_t char_status = + esp_ble_gattc_get_all_char(this->gattc_if_, this->connection_index_, param->reg_for_notify.handle, + param->reg_for_notify.handle, &char_result, &count, 0); + if (char_status != ESP_GATT_OK) { + ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_get_all_char error, status=%d", this->connection_index_, + this->address_str_.c_str(), char_status); + break; + } + /* 1 = notify 2 = indicate */ - uint16_t notify_en = descr->characteristic->properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY ? 1 : 2; - - auto status = - esp_ble_gattc_write_char_descr(this->gattc_if_, this->conn_id_, descr->handle, sizeof(notify_en), + uint16_t notify_en = char_result.properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY ? 1 : 2; + esp_err_t status = + esp_ble_gattc_write_char_descr(this->gattc_if_, this->conn_id_, desc_result.handle, sizeof(notify_en), (uint8_t *) ¬ify_en, ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); if (status) { ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_write_char_descr error, status=%d", this->connection_index_, @@ -320,7 +339,7 @@ BLEDescriptor *BLEClientBase::get_config_descriptor(uint16_t handle) { if (!chr->parsed) chr->parse_descriptors(); for (auto &desc : chr->descriptors) { - if (desc->uuid.get_uuid().uuid.uuid16 == 0x2902) + if (desc->uuid.get_uuid().uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG) return desc; } }