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

Commit 87916c16 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

gatt_attr: Read GATT Server supported features in a sequence

With this patch Android reads Server Supported Features and writes
Client supported featuers after discovery.

From now on, Eatt will not trigger GATT read if Server Supported Feature
value is already known.

This helps to pass GATT/CL/GAN/BV-02-C
Bug: 236083555
Test: atest Bluetooth InstrumentationTests
Tag: #stability

Change-Id: I41f027a768a57c4885e057d4086236a45d20f573
parent 1cb0d917
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -681,7 +681,15 @@ struct eatt_impl {
      eatt_device* eatt_dev = add_eatt_device(bd_addr);
      connect_eatt(eatt_dev);
    } else {
      /* For new device, first read GATT server supported features. */
      if (gatt_profile_get_eatt_support(bd_addr)) {
        LOG_DEBUG("Eatt is supported for device %s",
                  bd_addr.ToString().c_str());
        supported_features_cb(role, bd_addr,
                              BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK);
        return;
      }

      /* If we don't know yet, read GATT server supported features. */
      if (gatt_cl_read_sr_supp_feat_req(
              bd_addr, base::BindOnce(&eatt_impl::supported_features_cb,
                                      base::Unretained(this), role)) == false) {
+56 −22
Original line number Diff line number Diff line
@@ -81,6 +81,9 @@ static void gatt_cl_start_config_ccc(tGATT_PROFILE_CLCB* p_clcb);

static bool gatt_sr_is_robust_caching_enabled();

static bool read_sr_supported_feat_req(
    uint16_t conn_id, base::OnceCallback<void(const RawAddress&, uint8_t)> cb);

static tGATT_STATUS gatt_sr_read_db_hash(uint16_t conn_id,
                                         tGATT_VALUE* p_value);
static tGATT_STATUS gatt_sr_read_cl_supp_feat(uint16_t conn_id,
@@ -567,10 +570,15 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op,
          << " status: " << status
          << " conn id: " << loghex(static_cast<uint8_t>(conn_id));

  if (op != GATTC_OPTYPE_READ) return;
  if (op != GATTC_OPTYPE_READ && op != GATTC_OPTYPE_WRITE) {
    LOG_DEBUG("Not interested in opcode %d", op);
    return;
  }

  if (iter == OngoingOps.end()) {
    LOG(ERROR) << __func__ << " Unexpected read complete";
    /* If OngoingOps is empty it means we are not interested in the result here.
     */
    LOG_DEBUG("Unexpected read complete");
    return;
  }

@@ -578,6 +586,20 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op,
  uint16_t cl_op_uuid = operation_callback_data->op_uuid;
  operation_callback_data->op_uuid = 0;

  if (op == GATTC_OPTYPE_WRITE) {
    if (cl_op_uuid == GATT_UUID_GATT_SRV_CHGD) {
      LOG_DEBUG("Write response from Service Changed CCC");
      OngoingOps.erase(iter);
      /* Read server supported features here supported */
      read_sr_supported_feat_req(
          conn_id, base::BindOnce([](const RawAddress& bdaddr,
                                     uint8_t support) { return; }));
    } else {
      LOG_DEBUG("Not interested in that write response");
    }
    return;
  }

  uint8_t* pp = p_data->att_value.value;

  VLOG(1) << __func__ << " cl_op_uuid " << loghex(cl_op_uuid);
@@ -666,6 +688,13 @@ static void gatt_cl_start_config_ccc(tGATT_PROFILE_CLCB* p_clcb) {
      ccc_value.len = 2;
      ccc_value.value[0] = GATT_CLT_CONFIG_INDICATION;
      GATTC_Write(p_clcb->conn_id, GATT_WRITE, &ccc_value);

      gatt_op_cb_data cb_data;
      cb_data.cb = base::BindOnce(
          [](const RawAddress& bdaddr, uint8_t support) { return; });
      cb_data.op_uuid = GATT_UUID_GATT_SRV_CHGD;
      OngoingOps[p_clcb->conn_id] = std::move(cb_data);

      break;
    }
  }
@@ -723,6 +752,30 @@ void gatt_cl_init_sr_status(tGATT_TCB& tcb) {
    bluetooth::eatt::EattExtension::AddFromStorage(tcb.peer_bda);
}

static bool read_sr_supported_feat_req(
    uint16_t conn_id, base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
  tGATT_READ_PARAM param = {};

  param.service.s_handle = 1;
  param.service.e_handle = 0xFFFF;
  param.service.auth_req = 0;

  param.service.uuid = bluetooth::Uuid::From16Bit(GATT_UUID_SERVER_SUP_FEAT);

  if (GATTC_Read(conn_id, GATT_READ_BY_TYPE, &param) != GATT_SUCCESS) {
    LOG_ERROR("Read GATT Support features GATT_Read Failed");
    return false;
  }

  gatt_op_cb_data cb_data;

  cb_data.cb = std::move(cb);
  cb_data.op_uuid = GATT_UUID_SERVER_SUP_FEAT;
  OngoingOps[conn_id] = std::move(cb_data);

  return true;
}

/*******************************************************************************
 *
 * Function         gatt_cl_read_sr_supp_feat_req
@@ -736,7 +789,6 @@ bool gatt_cl_read_sr_supp_feat_req(
    const RawAddress& peer_bda,
    base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
  tGATT_PROFILE_CLCB* p_clcb;
  tGATT_READ_PARAM param;
  uint16_t conn_id;

  if (!cb) return false;
@@ -765,25 +817,7 @@ bool gatt_cl_read_sr_supp_feat_req(
    return false;
  }

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

  param.service.s_handle = 1;
  param.service.e_handle = 0xFFFF;
  param.service.auth_req = 0;

  param.service.uuid = bluetooth::Uuid::From16Bit(GATT_UUID_SERVER_SUP_FEAT);

  if (GATTC_Read(conn_id, GATT_READ_BY_TYPE, &param) != GATT_SUCCESS) {
    LOG(ERROR) << __func__ << " Read GATT Support features GATT_Read Failed";
    return false;
  }

  gatt_op_cb_data cb_data;
  cb_data.cb = std::move(cb);
  cb_data.op_uuid = GATT_UUID_SERVER_SUP_FEAT;
  OngoingOps[conn_id] = std::move(cb_data);

  return true;
  return read_sr_supported_feat_req(conn_id, std::move(cb));
}

/*******************************************************************************