Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d3cb118 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

GATT database refactor

Move logic and data responsible for GATT Discovery into separate class.
Create clean representation of GATT database, and attributes for
storage.
Minor service discovery improvements:
* don't send requests to explore services with start handle equal to end handle.
* don't try to discover characteristic if only one handle is left at end
  of service - it uses two handles, one for definition, one for value
* if secondary service is defined before service that includes it, it
  should now be properly discovered.

Test: Added DatabaseBuilderTest, manual tests with LE HID devices, Daydream
      Controller and Clips camera.
Bug: 67057055
Change-Id: I511f4ee7c56c8fa65f012de0b6d1291321840d11
parent dc5bf162
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ cc_library_static {
        "gatt/bta_gatts_api.cc",
        "gatt/bta_gatts_main.cc",
        "gatt/bta_gatts_utils.cc",
        "gatt/database.cc",
        "gatt/database_builder.cc",
        "hearing_aid/hearing_aid.cc",
        "hearing_aid/hearing_aid_audio_source.cc",
        "hf_client/bta_hf_client_act.cc",
@@ -127,7 +129,9 @@ cc_test {
    defaults: ["fluoride_bta_defaults"],
    srcs: [
        "test/bta_hf_client_test.cc",
        "test/gatt_cache_file_test.cc",
        "test/gatt/database_builder_test.cc",
        "test/gatt/database_builder_sample_device_test.cc",
        "test/gatt/database_test.cc",
    ],
    shared_libs: [
        "liblog",
+11 −15
Original line number Diff line number Diff line
@@ -473,7 +473,7 @@ void bta_gattc_conn(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
  if (p_clcb->p_srcb->mtu == 0) p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE;

  /* start database cache if needed */
  if (p_clcb->p_srcb->srvc_cache.empty() ||
  if (p_clcb->p_srcb->gatt_database.IsEmpty() ||
      p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
    if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
      p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
@@ -654,11 +654,9 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb,
      /* set all srcb related clcb into discovery ST */
      bta_gattc_set_discover_st(p_clcb->p_srcb);

      p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb);
      if (p_clcb->status == GATT_SUCCESS) {
      bta_gattc_init_cache(p_clcb->p_srcb);
      p_clcb->status = bta_gattc_discover_pri_service(
          p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
      }
      if (p_clcb->status != GATT_SUCCESS) {
        LOG(ERROR) << "discovery on server failed";
        bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
@@ -692,16 +690,15 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb,
  if (p_clcb->status != GATT_SUCCESS) {
    /* clean up cache */
    if (p_clcb->p_srcb) {
      // clear reallocating
      std::vector<tBTA_GATTC_SERVICE>().swap(p_clcb->p_srcb->srvc_cache);
      p_clcb->p_srcb->gatt_database.Clear();
    }

    /* used to reset cache in application */
    bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
  }

  if (p_clcb->p_srcb) {
    /* release pending attribute list buffer */
    p_clcb->p_srcb->pending_discovery.clear();
    p_clcb->p_srcb->pending_discovery.Clear();
  }

  if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
@@ -981,7 +978,7 @@ void bta_gattc_search(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
  tGATT_STATUS status = GATT_INTERNAL_ERROR;
  tBTA_GATTC cb_data;
  VLOG(1) << __func__ << ": conn_id=" << +p_clcb->bta_conn_id;
  if (p_clcb->p_srcb && !p_clcb->p_srcb->srvc_cache.empty()) {
  if (p_clcb->p_srcb && !p_clcb->p_srcb->gatt_database.IsEmpty()) {
    status = GATT_SUCCESS;
    /* search the local cache of a server device */
    bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
@@ -1105,8 +1102,7 @@ void bta_gattc_process_api_refresh(const RawAddress& remote_bda) {
    }
    /* in all other cases, mark it and delete the cache */

    // clear reallocating
    std::vector<tBTA_GATTC_SERVICE>().swap(p_srvc_cb->srvc_cache);
    p_srvc_cb->gatt_database.Clear();
  }

  /* used to reset cache in application */
@@ -1123,10 +1119,10 @@ bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, tBTA_GATTC_RCB* p_clrcb,
  Uuid gattp_uuid = Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER);
  Uuid srvc_chg_uuid = Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD);

  const tBTA_GATTC_CHARACTERISTIC* p_char =
  const gatt::Characteristic* p_char =
      bta_gattc_get_characteristic_srcb(p_srcb, p_notify->handle);
  if (!p_char) return false;
  const tBTA_GATTC_SERVICE* p_svc =
  const gatt::Service* p_svc =
      bta_gattc_get_service_for_handle_srcb(p_srcb, p_char->value_handle);
  if (!p_svc || p_svc->uuid != gattp_uuid || p_char->uuid != srvc_chg_uuid) {
    return false;
+12 −12
Original line number Diff line number Diff line
@@ -266,10 +266,10 @@ void BTA_GATTC_DiscoverServiceByUuid(uint16_t conn_id,
 *
 * Parameters       conn_id: connection ID which identify the server.
 *
 * Returns          returns list of tBTA_GATTC_SERVICE or NULL.
 * Returns          returns list of gatt::Service or NULL.
 *
 ******************************************************************************/
const std::vector<tBTA_GATTC_SERVICE>* BTA_GATTC_GetServices(uint16_t conn_id) {
const std::vector<gatt::Service>* BTA_GATTC_GetServices(uint16_t conn_id) {
  return bta_gattc_get_services(conn_id);
}

@@ -283,10 +283,10 @@ const std::vector<tBTA_GATTC_SERVICE>* BTA_GATTC_GetServices(uint16_t conn_id) {
 * Parameters       conn_id - connection ID which identify the server.
 *                  handle - characteristic handle
 *
 * Returns          returns pointer to tBTA_GATTC_CHARACTERISTIC or NULL.
 * Returns          returns pointer to gatt::Characteristic or NULL.
 *
 ******************************************************************************/
const tBTA_GATTC_CHARACTERISTIC* BTA_GATTC_GetCharacteristic(uint16_t conn_id,
const gatt::Characteristic* BTA_GATTC_GetCharacteristic(uint16_t conn_id,
                                                        uint16_t handle) {
  return bta_gattc_get_characteristic(conn_id, handle);
}
@@ -301,24 +301,24 @@ const tBTA_GATTC_CHARACTERISTIC* BTA_GATTC_GetCharacteristic(uint16_t conn_id,
 * Parameters       conn_id - connection ID which identify the server.
 *                  handle - descriptor handle
 *
 * Returns          returns pointer to tBTA_GATTC_DESCRIPTOR or NULL.
 * Returns          returns pointer to gatt::Descriptor or NULL.
 *
 ******************************************************************************/
const tBTA_GATTC_DESCRIPTOR* BTA_GATTC_GetDescriptor(uint16_t conn_id,
const gatt::Descriptor* BTA_GATTC_GetDescriptor(uint16_t conn_id,
                                                uint16_t handle) {
  return bta_gattc_get_descriptor(conn_id, handle);
}

/* Return characteristic that owns descriptor with handle equal to |handle|, or
 * NULL */
const tBTA_GATTC_CHARACTERISTIC* BTA_GATTC_GetOwningCharacteristic(
    uint16_t conn_id, uint16_t handle) {
const gatt::Characteristic* BTA_GATTC_GetOwningCharacteristic(uint16_t conn_id,
                                                              uint16_t handle) {
  return bta_gattc_get_owning_characteristic(conn_id, handle);
}

/* Return service that owns descriptor or characteristic with handle equal to
 * |handle|, or NULL */
const tBTA_GATTC_SERVICE* BTA_GATTC_GetOwningService(uint16_t conn_id,
const gatt::Service* BTA_GATTC_GetOwningService(uint16_t conn_id,
                                                uint16_t handle) {
  return bta_gattc_get_service_for_handle(conn_id, handle);
}
+211 −493

File changed.

Preview size limit exceeded, changes collapsed.

+14 −18
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

#include "bta_gatt_api.h"
#include "bta_sys.h"
#include "database_builder.h"
#include "osi/include/fixed_queue.h"

#include "bt_common.h"
@@ -206,13 +207,11 @@ typedef struct {

  uint8_t state;

  std::vector<tBTA_GATTC_SERVICE> srvc_cache;
  gatt::Database gatt_database;
  uint8_t update_count; /* indication received */
  uint8_t num_clcb;     /* number of associated CLCB */

  std::vector<tBTA_GATTC_SERVICE> pending_discovery;
  std::vector<tBTA_GATTC_SERVICE>::iterator pending_service;
  std::vector<tBTA_GATTC_CHARACTERISTIC>::iterator pending_char;
  gatt::DatabaseBuilder pending_discovery;

  uint8_t srvc_hdl_chg; /* service handle change indication pending */
  uint16_t attr_index;  /* cahce NV saving/loading attribute index */
@@ -427,27 +426,24 @@ extern tGATT_STATUS bta_gattc_discover_pri_service(uint16_t conn_id,
                                                   uint8_t disc_type);
extern void bta_gattc_search_service(tBTA_GATTC_CLCB* p_clcb,
                                     bluetooth::Uuid* p_uuid);
extern std::vector<tBTA_GATTC_SERVICE>* bta_gattc_get_services(
extern const std::vector<gatt::Service>* bta_gattc_get_services(
    uint16_t conn_id);
extern const tBTA_GATTC_SERVICE* bta_gattc_get_service_for_handle(
    uint16_t conn_id, uint16_t handle);
tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic_srcb(
extern const gatt::Service* bta_gattc_get_service_for_handle(uint16_t conn_id,
                                                             uint16_t handle);
const gatt::Characteristic* bta_gattc_get_characteristic_srcb(
    tBTA_GATTC_SERV* p_srcb, uint16_t handle);
extern tBTA_GATTC_SERVICE* bta_gattc_get_service_for_handle_srcb(
extern const gatt::Service* bta_gattc_get_service_for_handle_srcb(
    tBTA_GATTC_SERV* p_srcb, uint16_t handle);
extern tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic(uint16_t conn_id,
                                                               uint16_t handle);
extern const tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor(uint16_t conn_id,
extern const gatt::Characteristic* bta_gattc_get_characteristic(
    uint16_t conn_id, uint16_t handle);
extern const gatt::Descriptor* bta_gattc_get_descriptor(uint16_t conn_id,
                                                        uint16_t handle);
extern const tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_owning_characteristic(
extern const gatt::Characteristic* bta_gattc_get_owning_characteristic(
    uint16_t conn_id, uint16_t handle);
extern void bta_gattc_get_gatt_db(uint16_t conn_id, uint16_t start_handle,
                                  uint16_t end_handle, btgatt_db_element_t** db,
                                  int* count);
extern tGATT_STATUS bta_gattc_init_cache(tBTA_GATTC_SERV* p_srvc_cb);
extern void bta_gattc_rebuild_cache(tBTA_GATTC_SERV* p_srcv, uint16_t num_attr,
                                    tBTA_GATTC_NV_ATTR* attr);
extern void bta_gattc_cache_save(tBTA_GATTC_SERV* p_srvc_cb, uint16_t conn_id);
extern void bta_gattc_init_cache(tBTA_GATTC_SERV* p_srvc_cb);
extern void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb,
                                        tGATT_STATUS status);

Loading