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

Commit 5dc3c45e authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Gerrit Code Review
Browse files

Merge changes from topic "bt-char-ext-prop"

* changes:
  Fall back to Read Request when reading Characteristic Extended Properties
  Server support for Characteristic Extended Properties
  Client support for Characteristic Extended Properties
parents e32c5acc 1cefd0cb
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -965,14 +965,6 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
  }
}

/** operation completed */
void bta_gattc_ignore_op_cmpl(UNUSED_ATTR tBTA_GATTC_CLCB* p_clcb,
                              tBTA_GATTC_DATA* p_data) {
  /* receive op complete when discovery is started, ignore the response,
      and wait for discovery finish and resent */
  VLOG(1) << __func__ << ": op = " << +p_data->hdr.layer_specific;
}

/** start a search in the local server cache */
void bta_gattc_search(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
  tGATT_STATUS status = GATT_INTERNAL_ERROR;
+111 −7
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@
#include "sdpdefs.h"
#include "utl.h"

#include <base/strings/string_number_conversions.h>

using base::StringPrintf;
using bluetooth::Uuid;
using gatt::Characteristic;
@@ -70,7 +72,7 @@ static void bta_gattc_explore_srvc_finished(uint16_t conn_id,
#define BTA_GATT_SDP_DB_SIZE 4096

#define GATT_CACHE_PREFIX "/data/misc/bluetooth/gatt_cache_"
#define GATT_CACHE_VERSION 5
#define GATT_CACHE_VERSION 6

static void bta_gattc_generate_cache_file_name(char* buffer, size_t buffer_len,
                                               const RawAddress& bda) {
@@ -153,16 +155,52 @@ static void bta_gattc_explore_next_service(uint16_t conn_id,
    return;
  }

  if (!p_srvc_cb->pending_discovery.StartNextServiceExploration()) {
    bta_gattc_explore_srvc_finished(conn_id, p_srvc_cb);
    return;
  }

  const auto& service = p_srvc_cb->pending_discovery.CurrentlyExploredService();
  if (p_srvc_cb->pending_discovery.StartNextServiceExploration()) {
    const auto& service =
        p_srvc_cb->pending_discovery.CurrentlyExploredService();
    VLOG(1) << "Start service discovery";

    /* start discovering included services */
    GATTC_Discover(conn_id, GATT_DISC_INC_SRVC, service.first, service.second);
    return;
  }
  // No more services to discover

  // As part of service discovery, read the values of "Characteristic Extended
  // Properties" descriptor
  const auto& descriptors =
      p_srvc_cb->pending_discovery.DescriptorHandlesToRead();
  if (!descriptors.empty()) {
    if (p_srvc_cb->read_multiple_not_supported) {
      tGATT_READ_PARAM read_param{
          .by_handle = {.handle = descriptors.front(),
                        .auth_req = GATT_AUTH_REQ_NONE}};
      GATTC_Read(conn_id, GATT_READ_BY_HANDLE, &read_param);
      // asynchronous continuation in bta_gattc_op_cmpl_during_discovery
      return;
    }

    // TODO(jpawlowski): as a limit we should use MTU/2 rather than
    // GATT_MAX_READ_MULTI_HANDLES
    /* each descriptor contains just 2 bytes, so response size is same as
     * request size */
    size_t num_handles =
        std::min(descriptors.size(), (size_t)GATT_MAX_READ_MULTI_HANDLES);

    tGATT_READ_PARAM read_param;
    memset(&read_param, 0, sizeof(tGATT_READ_PARAM));

    read_param.read_multiple.num_handles = num_handles;
    read_param.read_multiple.auth_req = GATT_AUTH_REQ_NONE;
    memcpy(&read_param.read_multiple.handles, descriptors.data(),
           sizeof(uint16_t) * num_handles);
    GATTC_Read(conn_id, GATT_READ_MULTIPLE, &read_param);

    // asynchronous continuation in bta_gattc_op_cmpl_during_discovery
    return;
  }

  bta_gattc_explore_srvc_finished(conn_id, p_srvc_cb);
}

static void bta_gattc_explore_srvc_finished(uint16_t conn_id,
@@ -315,6 +353,66 @@ static tGATT_STATUS bta_gattc_sdp_service_disc(uint16_t conn_id,
  return GATT_SUCCESS;
}

/** operation completed */
void bta_gattc_op_cmpl_during_discovery(UNUSED_ATTR tBTA_GATTC_CLCB* p_clcb,
                                        tBTA_GATTC_DATA* p_data) {
  uint8_t op = (uint8_t)p_data->op_cmpl.op_code;

  if (op != GATTC_OPTYPE_READ) {
    /* receive op complete when discovery is started, ignore the response,
       and wait for discovery finish and resent */
    VLOG(1) << __func__ << ": op = " << +p_data->hdr.layer_specific;
    return;
  }
  // our read operation is finished.
  // TODO: check if we can get here when any other read operation i.e. initiated
  // by upper layer apps, can get us there.

  tBTA_GATTC_SERV* p_srvc_cb = p_clcb->p_srcb;
  const uint8_t status = p_data->op_cmpl.status;

  if (status == GATT_REQ_NOT_SUPPORTED &&
      !p_srvc_cb->read_multiple_not_supported) {
    // can't do "read multiple request", fall back to "read request"
    p_srvc_cb->read_multiple_not_supported = true;
    bta_gattc_explore_next_service(p_clcb->bta_conn_id, p_srvc_cb);
    return;
  }

  if (status != GATT_SUCCESS) {
    LOG(WARNING) << "Discovery on server failed: " << loghex(status);
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
  }

  const tGATT_VALUE& att_value = p_data->op_cmpl.p_cmpl->att_value;
  if (!p_srvc_cb->read_multiple_not_supported && att_value.len != 2) {
    // Just one Characteristic Extended Properties value at a time in Read
    // Response
    LOG(WARNING) << __func__ << " Read Response should be just 2 bytes!";
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
  }

  // Parsing is same for "Read Multiple Response", and for "Read Response"
  const uint8_t* p = att_value.value;
  std::vector<uint16_t> value_of_descriptors;
  while (p < att_value.value + att_value.len) {
    uint16_t extended_properties;
    STREAM_TO_UINT16(extended_properties, p);
    value_of_descriptors.push_back(extended_properties);
  }

  bool ret =
      p_srvc_cb->pending_discovery.SetValueOfDescriptors(value_of_descriptors);
  if (!ret) {
    LOG(WARNING) << __func__
                 << " Problem setting Extended Properties descriptors values";
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
  }

  // Continue service discovery
  bta_gattc_explore_next_service(p_clcb->bta_conn_id, p_srvc_cb);
}

/** callback function to GATT client stack */
void bta_gattc_disc_res_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
                              tGATT_DISC_RES* p_data) {
@@ -633,12 +731,18 @@ static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV* p_srvc_cb,
                                charac.value_handle, 0 /* s_handle */,
                                0 /* e_handle */, charac.value_handle,
                                charac.uuid, charac.properties);
      btgatt_db_element_t* characteristic = curr_db_attr;
      curr_db_attr++;

      for (const Descriptor& desc : charac.descriptors) {
        bta_gattc_fill_gatt_db_el(
            curr_db_attr, BTGATT_DB_DESCRIPTOR, desc.handle, 0 /* s_handle */,
            0 /* e_handle */, desc.handle, desc.uuid, 0 /* property */);

        if (desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_EXT_PROP)) {
          characteristic->extended_properties =
              desc.characteristic_extended_properties;
        }
        curr_db_attr++;
      }
    }
+6 −2
Original line number Diff line number Diff line
@@ -214,6 +214,10 @@ typedef struct {

  gatt::DatabaseBuilder pending_discovery;

  /* used only during service discovery, when reading Extended Characteristic
   * Properties */
  bool read_multiple_not_supported;

  uint8_t srvc_hdl_chg; /* service handle change indication pending */
  uint16_t attr_index;  /* cahce NV saving/loading attribute index */

@@ -363,7 +367,7 @@ extern void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb,
extern void bta_gattc_ci_open(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data);
extern void bta_gattc_ci_close(tBTA_GATTC_CLCB* p_clcb,
                               tBTA_GATTC_DATA* p_data);
extern void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB* p_clcb,
extern void bta_gattc_op_cmpl_during_discovery(tBTA_GATTC_CLCB* p_clcb,
                                               tBTA_GATTC_DATA* p_data);
extern void bta_gattc_restart_discover(tBTA_GATTC_CLCB* p_clcb,
                                       tBTA_GATTC_DATA* p_msg);
+26 −26
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ enum {
  BTA_GATTC_CONFIRM,
  BTA_GATTC_EXEC,
  BTA_GATTC_READ_MULTI,
  BTA_GATTC_IGNORE_OP_CMPL,
  BTA_GATTC_OP_CMPL_DURING_DISCOVERY,
  BTA_GATTC_DISC_CLOSE,
  BTA_GATTC_RESTART_DISCOVER,
  BTA_GATTC_CFG_MTU,
@@ -90,7 +90,7 @@ const tBTA_GATTC_ACTION bta_gattc_action[] = {
    bta_gattc_confirm,                  /* BTA_GATTC_CONFIRM */
    bta_gattc_execute,                  /* BTA_GATTC_EXEC */
    bta_gattc_read_multi,               /* BTA_GATTC_READ_MULTI */
    bta_gattc_ignore_op_cmpl,    /* BTA_GATTC_IGNORE_OP_CMPL */
    bta_gattc_op_cmpl_during_discovery, /* BTA_GATTC_OP_CMPL_DURING_DISCOVERY */
    bta_gattc_disc_close,               /* BTA_GATTC_DISC_CLOSE */
    bta_gattc_restart_discover,         /* BTA_GATTC_RESTART_DISCOVER */
    bta_gattc_cfg_mtu                   /* BTA_GATTC_CFG_MTU */
@@ -256,7 +256,7 @@ static const uint8_t bta_gattc_st_discover[][BTA_GATTC_NUM_COLS] = {
                                            BTA_GATTC_DISCOVER_ST},
    /* BTA_GATTC_DISCOVER_CMPL_EVT      */ {BTA_GATTC_DISC_CMPL,
                                            BTA_GATTC_CONN_ST},
    /* BTA_GATTC_OP_CMPL_EVT            */ {BTA_GATTC_IGNORE_OP_CMPL,
    /* BTA_GATTC_OP_CMPL_EVT            */ {BTA_GATTC_OP_CMPL_DURING_DISCOVERY,
                                            BTA_GATTC_DISCOVER_ST},
    /* BTA_GATTC_INT_DISCONN_EVT        */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},

+21 −3
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ const Uuid PRIMARY_SERVICE = Uuid::From16Bit(GATT_UUID_PRI_SERVICE);
const Uuid SECONDARY_SERVICE = Uuid::From16Bit(GATT_UUID_SEC_SERVICE);
const Uuid INCLUDE = Uuid::From16Bit(GATT_UUID_INCLUDE_SERVICE);
const Uuid CHARACTERISTIC = Uuid::From16Bit(GATT_UUID_CHAR_DECLARE);
const Uuid CHARACTERISTIC_EXTENDED_PROPERTIES =
    Uuid::From16Bit(GATT_UUID_CHAR_EXT_PROP);

bool HandleInRange(const Service& svc, uint16_t handle) {
  return handle >= svc.handle && handle <= svc.end_handle;
@@ -116,10 +118,17 @@ std::vector<StoredAttribute> Database::Serialize() const {
                               .uuid = charac.uuid}}});

      for (const Descriptor& desc : charac.descriptors) {
        if (desc.uuid == CHARACTERISTIC_EXTENDED_PROPERTIES) {
          nv_attr.push_back({desc.handle,
                             desc.uuid,
                             {.characteristic_extended_properties =
                                  desc.characteristic_extended_properties}});
        } else {
          nv_attr.push_back({desc.handle, desc.uuid, {}});
        }
      }
    }
  }

  return nv_attr;
}
@@ -182,11 +191,20 @@ Database Database::Deserialize(const std::vector<StoredAttribute>& nv_attr,
          .properties = attr.value.characteristic.properties,
      });

    } else {
      if (attr.type == CHARACTERISTIC_EXTENDED_PROPERTIES) {
        current_service_it->characteristics.back().descriptors.emplace_back(
            Descriptor{.handle = attr.handle,
                       .uuid = attr.type,
                       .characteristic_extended_properties =
                           attr.value.characteristic_extended_properties});

      } else {
        current_service_it->characteristics.back().descriptors.emplace_back(
            Descriptor{.handle = attr.handle, .uuid = attr.type});
      }
    }
  }
  *success = true;
  return result;
}
Loading