Reduce memory needed to send the services list (#4110)

This commit is contained in:
J. Nick Koston 2022-11-28 18:14:29 -10:00 committed by GitHub
parent ad0d6f6337
commit d5ff8f6117
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -86,31 +86,59 @@ void BluetoothProxy::loop() {
api::BluetoothGATTService service_resp;
service_resp.uuid = {service->uuid.get_128bit_high(), service->uuid.get_128bit_low()};
service_resp.handle = service->start_handle;
if (!service->parsed)
service->parse_characteristics();
for (auto &characteristic : service->characteristics) {
uint16_t char_offset = 0;
esp_gattc_char_elem_t char_result;
while (true) { // characteristics
uint16_t char_count = 1;
esp_gatt_status_t char_status =
esp_ble_gattc_get_all_char(connection->get_gattc_if(), connection->get_conn_id(), service->start_handle,
service->end_handle, &char_result, &char_count, char_offset);
if (char_status == ESP_GATT_INVALID_OFFSET || char_status == ESP_GATT_NOT_FOUND) {
break;
}
if (char_status != ESP_GATT_OK) {
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_get_all_char error, status=%d", connection->get_connection_index(),
connection->address_str().c_str(), char_status);
break;
}
if (char_count == 0) {
break;
}
api::BluetoothGATTCharacteristic characteristic_resp;
characteristic_resp.uuid = {characteristic->uuid.get_128bit_high(), characteristic->uuid.get_128bit_low()};
characteristic_resp.handle = characteristic->handle;
characteristic_resp.properties = characteristic->properties;
if (!characteristic->parsed)
characteristic->parse_descriptors();
for (auto &descriptor : characteristic->descriptors) {
auto char_uuid = espbt::ESPBTUUID::from_uuid(char_result.uuid);
characteristic_resp.uuid = {char_uuid.get_128bit_high(), char_uuid.get_128bit_low()};
characteristic_resp.handle = char_result.char_handle;
characteristic_resp.properties = char_result.properties;
char_offset++;
uint16_t desc_offset = 0;
esp_gattc_descr_elem_t desc_result;
while (true) { // descriptors
uint16_t desc_count = 1;
esp_gatt_status_t desc_status =
esp_ble_gattc_get_all_descr(connection->get_gattc_if(), connection->get_conn_id(),
char_result.char_handle, &desc_result, &desc_count, desc_offset);
if (desc_status == ESP_GATT_INVALID_OFFSET || desc_status == ESP_GATT_NOT_FOUND) {
break;
}
if (desc_status != ESP_GATT_OK) {
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gattc_get_all_descr error, status=%d", connection->get_connection_index(),
connection->address_str().c_str(), desc_status);
break;
}
if (desc_count == 0) {
break;
}
api::BluetoothGATTDescriptor descriptor_resp;
descriptor_resp.uuid = {descriptor->uuid.get_128bit_high(), descriptor->uuid.get_128bit_low()};
descriptor_resp.handle = descriptor->handle;
auto desc_uuid = espbt::ESPBTUUID::from_uuid(desc_result.uuid);
descriptor_resp.uuid = {desc_uuid.get_128bit_high(), desc_uuid.get_128bit_low()};
descriptor_resp.handle = desc_result.handle;
characteristic_resp.descriptors.push_back(std::move(descriptor_resp));
desc_offset++;
}
service_resp.characteristics.push_back(std::move(characteristic_resp));
}
resp.services.push_back(std::move(service_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->release_descriptors();
}
connection->send_service_++;
}
}