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

Commit 13c39b9b authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Jakub Pawlowski
Browse files

stack/gatt: Extend calls with CID

This is preparation for EATT

Tag: #feature
Bug: 159786353
Sponsor: jpawlowski@
Test: atest net_test_stack
Change-Id: Ie209b705f6cc458286e9566919280ed5e2de60c9
parent fcc85925
Loading
Loading
Loading
Loading
+17 −13
Original line number Diff line number Diff line
@@ -322,13 +322,14 @@ BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code,
 * Description      Send message to L2CAP.
 *
 ******************************************************************************/
tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, BT_HDR* p_toL2CAP) {
tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, uint16_t lcid,
                                    BT_HDR* p_toL2CAP) {
  uint16_t l2cap_ret;

  if (tcb.att_lcid == L2CAP_ATT_CID)
    l2cap_ret = L2CA_SendFixedChnlData(L2CAP_ATT_CID, tcb.peer_bda, p_toL2CAP);
  if (lcid == L2CAP_ATT_CID)
    l2cap_ret = L2CA_SendFixedChnlData(lcid, tcb.peer_bda, p_toL2CAP);
  else
    l2cap_ret = (uint16_t)L2CA_DataWrite(tcb.att_lcid, p_toL2CAP);
    l2cap_ret = (uint16_t)L2CA_DataWrite(lcid, p_toL2CAP);

  if (l2cap_ret == L2CAP_DW_FAILED) {
    LOG(ERROR) << __func__ << ": failed to write data to L2CAP";
@@ -394,11 +395,11 @@ BT_HDR* attp_build_sr_msg(tGATT_TCB& tcb, uint8_t op_code,
 *
 *
 ******************************************************************************/
tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, BT_HDR* p_msg) {
tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_msg) {
  if (p_msg == NULL) return GATT_NO_RESOURCES;

  p_msg->offset = L2CAP_MIN_OFFSET;
  return attp_send_msg_to_l2cap(tcb, p_msg);
  return attp_send_msg_to_l2cap(tcb, cid, p_msg);
}

/*******************************************************************************
@@ -417,13 +418,14 @@ tGATT_STATUS attp_cl_send_cmd(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
                              uint8_t cmd_code, BT_HDR* p_cmd) {
  cmd_code &= ~GATT_AUTH_SIGN_MASK;

  if (!tcb.cl_cmd_q.empty() && cmd_code != GATT_HANDLE_VALUE_CONF) {
  if (gatt_tcb_is_cid_busy(tcb, p_clcb->cid) &&
      cmd_code != GATT_HANDLE_VALUE_CONF) {
    gatt_cmd_enq(tcb, p_clcb, true, cmd_code, p_cmd);
    return GATT_CMD_STARTED;
  }

  /* no pending request or value confirmation */
  tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, p_cmd);
  tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, p_clcb->cid, p_cmd);
  if (att_ret != GATT_CONGESTED && att_ret != GATT_SUCCESS) {
    return GATT_INTERNAL_ERROR;
  }
@@ -458,6 +460,8 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
                              uint8_t op_code, tGATT_CL_MSG* p_msg) {
  BT_HDR* p_cmd = NULL;
  uint16_t offset = 0, handle;
  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, p_clcb->cid);

  switch (op_code) {
    case GATT_REQ_MTU:
      if (p_msg->mtu > GATT_MAX_MTU_SIZE) return GATT_ILLEGAL_PARAMETER;
@@ -504,7 +508,7 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
        return GATT_ILLEGAL_PARAMETER;

      p_cmd = attp_build_value_cmd(
          tcb.payload_size, op_code, p_msg->attr_value.handle, offset,
          payload_size, op_code, p_msg->attr_value.handle, offset,
          p_msg->attr_value.len, p_msg->attr_value.value);
      break;

@@ -513,13 +517,13 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
      break;

    case GATT_REQ_FIND_TYPE_VALUE:
      p_cmd = attp_build_read_by_type_value_cmd(tcb.payload_size,
      p_cmd = attp_build_read_by_type_value_cmd(payload_size,
                                                &p_msg->find_type_value);
      break;

    case GATT_REQ_READ_MULTI:
      p_cmd = attp_build_read_multi_cmd(tcb.payload_size,
                                        p_msg->read_multi.num_handles,
      p_cmd =
          attp_build_read_multi_cmd(payload_size, p_msg->read_multi.num_handles,
                                    p_msg->read_multi.handles);
      break;

+22 −12
Original line number Diff line number Diff line
@@ -431,7 +431,11 @@ tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle,
  memcpy(indication.value, p_val, val_len);
  indication.auth_req = GATT_AUTH_REQ_NONE;

  if (GATT_HANDLE_IS_VALID(p_tcb->indicate_handle)) {
  uint16_t* indicate_handle_p = NULL;
  uint16_t cid;

  if (!gatt_tcb_get_cid_available_for_indication(p_tcb, p_reg->eatt_support,
                                                 &indicate_handle_p, &cid)) {
    VLOG(1) << "Add a pending indication";
    gatt_add_pending_ind(p_tcb, &indication);
    return GATT_SUCCESS;
@@ -443,9 +447,9 @@ tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle,
      attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_IND, &gatt_sr_msg);
  if (!p_msg) return GATT_NO_RESOURCES;

  tGATT_STATUS cmd_status = attp_send_sr_msg(*p_tcb, p_msg);
  tGATT_STATUS cmd_status = attp_send_sr_msg(*p_tcb, cid, p_msg);
  if (cmd_status == GATT_SUCCESS || cmd_status == GATT_CONGESTED) {
    p_tcb->indicate_handle = indication.handle;
    *indicate_handle_p = indication.handle;
    gatt_start_conf_timer(p_tcb);
  }
  return cmd_status;
@@ -494,10 +498,13 @@ tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id,
  tGATT_STATUS cmd_sent;
  tGATT_SR_MSG gatt_sr_msg;
  gatt_sr_msg.attr_value = notif;

  uint16_t cid = gatt_tcb_get_att_cid(*p_tcb);

  BT_HDR* p_buf =
      attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_NOTIF, &gatt_sr_msg);
  if (p_buf != NULL) {
    cmd_sent = attp_send_sr_msg(*p_tcb, p_buf);
    cmd_sent = attp_send_sr_msg(*p_tcb, cid, p_buf);
  } else
    cmd_sent = GATT_NO_RESOURCES;
  return cmd_sent;
@@ -519,7 +526,6 @@ tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id,
 ******************************************************************************/
tGATT_STATUS GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id,
                           tGATT_STATUS status, tGATTS_RSP* p_msg) {
  tGATT_STATUS cmd_sent = GATT_ILLEGAL_PARAMETER;
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
@@ -533,16 +539,17 @@ tGATT_STATUS GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id,
    return (tGATT_STATUS)GATT_INVALID_CONN_ID;
  }

  if (p_tcb->sr_cmd.trans_id != trans_id) {
  tGATT_SR_CMD* sr_res_p = gatt_sr_get_cmd_by_trans_id(p_tcb, trans_id);

  if (!sr_res_p) {
    LOG(ERROR) << "conn_id=" << loghex(conn_id)
               << " waiting for op_code=" << loghex(p_tcb->sr_cmd.op_code);
               << " waiting for other op_code ";
    return (GATT_WRONG_STATE);
  }
  /* Process App response */
  cmd_sent = gatt_sr_process_app_rsp(*p_tcb, gatt_if, trans_id,
                                     p_tcb->sr_cmd.op_code, status, p_msg);

  return cmd_sent;
  /* Process App response */
  return gatt_sr_process_app_rsp(*p_tcb, gatt_if, trans_id, sr_res_p->op_code,
                                 status, p_msg, sr_res_p);
}

/******************************************************************************/
@@ -593,6 +600,8 @@ tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) {
  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
  if (!p_clcb) return GATT_NO_RESOURCES;

  /* For this request only ATT CID is valid */
  p_clcb->cid = L2CAP_ATT_CID;
  p_clcb->p_tcb->payload_size = mtu;
  p_clcb->operation = GATTC_OPTYPE_CONFIG;
  tGATT_CL_MSG gatt_cl_msg;
@@ -709,7 +718,8 @@ tGATT_STATUS GATTC_Read(uint16_t conn_id, tGATT_READ_TYPE type,
  p_clcb->op_subtype = type;
  p_clcb->auth_req = p_read->by_handle.auth_req;
  p_clcb->counter = 0;
  p_clcb->read_req_current_mtu = p_tcb->payload_size;
  p_clcb->read_req_current_mtu =
      gatt_tcb_get_payload_size_tx(*p_tcb, p_clcb->cid);

  switch (type) {
    case GATT_READ_BY_TYPE:
+2 −2
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ static bool gatt_sign_data(tGATT_CLCB* p_clcb) {
 * Returns
 *
 ******************************************************************************/
void gatt_verify_signature(tGATT_TCB& tcb, BT_HDR* p_buf) {
void gatt_verify_signature(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf) {
  uint16_t cmd_len;
  uint8_t op_code;
  uint8_t *p, *p_orig = (uint8_t*)(p_buf + 1) + p_buf->offset;
@@ -116,7 +116,7 @@ void gatt_verify_signature(tGATT_TCB& tcb, BT_HDR* p_buf) {
  }

  STREAM_TO_UINT8(op_code, p_orig);
  gatt_server_handle_client_req(tcb, op_code, (uint16_t)(p_buf->len - 1),
  gatt_server_handle_client_req(tcb, cid, op_code, (uint16_t)(p_buf->len - 1),
                                p_orig);
}
/*******************************************************************************
+46 −26
Original line number Diff line number Diff line
@@ -22,10 +22,10 @@
 *
 ******************************************************************************/

#include "bt_target.h"

#include <string.h>

#include "bt_common.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "gatt_int.h"
#include "l2c_api.h"
@@ -213,6 +213,8 @@ void gatt_act_write(tGATT_CLCB* p_clcb, uint8_t sec_act) {
  CHECK(p_clcb->p_attr_buf);
  tGATT_VALUE& attr = *((tGATT_VALUE*)p_clcb->p_attr_buf);

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, p_clcb->cid);

  switch (p_clcb->op_subtype) {
    case GATT_WRITE_NO_RSP: {
      p_clcb->s_handle = attr.handle;
@@ -231,7 +233,7 @@ void gatt_act_write(tGATT_CLCB* p_clcb, uint8_t sec_act) {
    }

    case GATT_WRITE: {
      if (attr.len <= (tcb.payload_size - GATT_HDR_SIZE)) {
      if (attr.len <= (payload_size - GATT_HDR_SIZE)) {
        p_clcb->s_handle = attr.handle;

        uint8_t rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_WRITE,
@@ -332,9 +334,10 @@ void gatt_send_prepare_write(tGATT_TCB& tcb, tGATT_CLCB* p_clcb) {
  VLOG(1) << __func__ << StringPrintf(" type=0x%x", type);
  uint16_t to_send = p_attr->len - p_attr->offset;

  if (to_send > (tcb.payload_size -
  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, p_clcb->cid);
  if (to_send > (payload_size -
                 GATT_WRITE_LONG_HDR_SIZE)) /* 2 = uint16_t offset bytes  */
    to_send = tcb.payload_size - GATT_WRITE_LONG_HDR_SIZE;
    to_send = payload_size - GATT_WRITE_LONG_HDR_SIZE;

  p_clcb->s_handle = p_attr->handle;

@@ -716,8 +719,8 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
  }

  STREAM_TO_UINT8(value_len, p);

  if ((value_len > (tcb.payload_size - 2)) || (value_len > (len - 1))) {
  uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, p_clcb->cid);
  if ((value_len > (payload_size - 2)) || (value_len > (len - 1))) {
    /* this is an error case that server's response containing a value length
       which is larger than MTU-2
       or value_len > message total length -1 */
@@ -725,7 +728,7 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
               << StringPrintf(
                      ": Discard response op_code=%d "
                      "vale_len=%d > (MTU-2=%d or msg_len-1=%d)",
                      op_code, value_len, (tcb.payload_size - 2), (len - 1));
                      op_code, value_len, (payload_size - 2), (len - 1));
    gatt_end_operation(p_clcb, GATT_ERROR, NULL);
    return;
  }
@@ -808,7 +811,7 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
             p_clcb->op_subtype == GATT_READ_BY_TYPE) {
      p_clcb->counter = len - 2;
      p_clcb->s_handle = handle;
      if (p_clcb->counter == (p_clcb->p_tcb->payload_size - 4)) {
      if (p_clcb->counter == (payload_size - 4)) {
        p_clcb->op_subtype = GATT_READ_BY_HANDLE;
        if (!p_clcb->p_attr_buf)
          p_clcb->p_attr_buf = (uint8_t*)osi_malloc(GATT_MAX_ATTR_LEN);
@@ -895,6 +898,8 @@ void gatt_process_read_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
  uint16_t offset = p_clcb->counter;
  uint8_t* p = p_data;

  uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, p_clcb->cid);

  if (p_clcb->operation == GATTC_OPTYPE_READ) {
    if (p_clcb->op_subtype != GATT_READ_BY_HANDLE) {
      p_clcb->counter = len;
@@ -915,12 +920,12 @@ void gatt_process_read_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,

        /* full packet for read or read blob rsp */
        bool packet_is_full;
        if (tcb.payload_size == p_clcb->read_req_current_mtu) {
          packet_is_full = (len == (tcb.payload_size - 1));
        if (payload_size == p_clcb->read_req_current_mtu) {
          packet_is_full = (len == (payload_size - 1));
        } else {
          packet_is_full = (len == (p_clcb->read_req_current_mtu - 1) ||
                            len == (tcb.payload_size - 1));
          p_clcb->read_req_current_mtu = tcb.payload_size;
                            len == (payload_size - 1));
          p_clcb->read_req_current_mtu = payload_size;
        }

        /* send next request if needed  */
@@ -1026,14 +1031,24 @@ uint8_t gatt_cmd_to_rsp_code(uint8_t cmd_code) {

/** Find next command in queue and sent to server */
bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) {
  std::queue<tGATT_CMD_Q>* cl_cmd_q;

  while (!tcb.cl_cmd_q.empty()) {
    tGATT_CMD_Q& cmd = tcb.cl_cmd_q.front();
    if (!cmd.to_send || cmd.p_cmd == NULL) return false;
    if (!tcb.cl_cmd_q.empty()) {
      cl_cmd_q = &tcb.cl_cmd_q;
    }

    tGATT_CMD_Q& cmd = cl_cmd_q->front();
    if (!cmd.to_send || cmd.p_cmd == NULL) {
      return false;
    }

    tGATT_STATUS att_ret;
    att_ret = attp_send_msg_to_l2cap(tcb, cmd.cid, cmd.p_cmd);

    tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, cmd.p_cmd);
    if (att_ret != GATT_SUCCESS && att_ret != GATT_CONGESTED) {
      LOG(ERROR) << __func__ << ": L2CAP sent error";
      tcb.cl_cmd_q.pop();
      cl_cmd_q->pop();
      continue;
    }

@@ -1043,7 +1058,7 @@ bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) {
    if (cmd.op_code == GATT_CMD_WRITE || cmd.op_code == GATT_SIGN_CMD_WRITE) {
      /* dequeue the request if is write command or sign write */
      uint8_t rsp_code;
      tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, &rsp_code);
      tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, cmd.cid, &rsp_code);

      /* send command complete callback here */
      gatt_end_operation(p_clcb, att_ret, NULL);
@@ -1062,13 +1077,18 @@ bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) {
}

/** This function is called to handle the server response to client */
void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint8_t op_code,
                                   uint16_t len, uint8_t* p_data) {
void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid,
                                   uint8_t op_code, uint16_t len,
                                   uint8_t* p_data) {
  VLOG(1) << __func__ << " opcode: " << loghex(op_code);

  uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, cid);

  if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF) {
    if (len >= tcb.payload_size) {
    if (len >= payload_size) {
      LOG(ERROR) << StringPrintf(
          "%s: invalid indicate pkt size: %d, PDU size: %d", __func__, len + 1,
          tcb.payload_size);
          payload_size);
      return;
    }

@@ -1077,7 +1097,7 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint8_t op_code,
  }

  uint8_t cmd_code = 0;
  tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, &cmd_code);
  tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, cid, &cmd_code);
  uint8_t rsp_code = gatt_cmd_to_rsp_code(cmd_code);
  if (!p_clcb || (rsp_code != op_code && op_code != GATT_RSP_ERROR)) {
    LOG(WARNING) << StringPrintf(
@@ -1092,16 +1112,16 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint8_t op_code,
    return;
  }

  alarm_cancel(p_clcb->gatt_rsp_timer_ent);
  gatt_stop_rsp_timer(p_clcb);
  p_clcb->retry_count = 0;

  /* the size of the message may not be bigger than the local max PDU size*/
  /* The message has to be smaller than the agreed MTU, len does not count
   * op_code */
  if (len >= tcb.payload_size) {
  if (len >= payload_size) {
    LOG(ERROR) << StringPrintf(
        "%s: invalid response pkt size: %d, PDU size: %d", __func__, len + 1,
        tcb.payload_size);
        payload_size);
    gatt_end_operation(p_clcb, GATT_ERROR, NULL);
  } else {
    switch (op_code) {
+18 −17
Original line number Diff line number Diff line
@@ -45,8 +45,8 @@ using bluetooth::Uuid;
static tGATT_ATTR& allocate_attr_in_db(tGATT_SVC_DB& db, const Uuid& uuid,
                                       tGATT_PERM perm);
static tGATT_STATUS gatts_send_app_read_request(
    tGATT_TCB& tcb, uint8_t op_code, uint16_t handle, uint16_t offset,
    uint32_t trans_id, bt_gatt_db_attribute_type_t gatt_type);
    tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t handle,
    uint16_t offset, uint32_t trans_id, bt_gatt_db_attribute_type_t gatt_type);

/**
 * Initialize a memory space to be a service database.
@@ -254,10 +254,10 @@ static tGATT_STATUS read_attr_value(tGATT_ATTR& attr16, uint16_t offset,
 *
 ******************************************************************************/
tGATT_STATUS gatts_db_read_attr_value_by_type(
    tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, BT_HDR* p_rsp,
    uint16_t s_handle, uint16_t e_handle, const Uuid& type, uint16_t* p_len,
    tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id,
    uint16_t* p_cur_handle) {
    tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
    BT_HDR* p_rsp, uint16_t s_handle, uint16_t e_handle, const Uuid& type,
    uint16_t* p_len, tGATT_SEC_FLAG sec_flag, uint8_t key_size,
    uint32_t trans_id, uint16_t* p_cur_handle) {
  tGATT_STATUS status = GATT_NOT_FOUND;
  uint16_t len = 0;
  uint8_t* p = (uint8_t*)(p_rsp + 1) + p_rsp->len + L2CAP_MIN_OFFSET;
@@ -276,8 +276,8 @@ tGATT_STATUS gatts_db_read_attr_value_by_type(
                                 &len, sec_flag, key_size);

        if (status == GATT_PENDING) {
          status = gatts_send_app_read_request(tcb, op_code, attr.handle, 0,
                                               trans_id, attr.gatt_type);
          status = gatts_send_app_read_request(tcb, cid, op_code, attr.handle,
                                               0, trans_id, attr.gatt_type);

          /* one callback at a time */
          break;
@@ -442,9 +442,10 @@ tGATT_ATTR* find_attr_by_handle(tGATT_SVC_DB* p_db, uint16_t handle) {
 *
 ******************************************************************************/
tGATT_STATUS gatts_read_attr_value_by_handle(
    tGATT_TCB& tcb, tGATT_SVC_DB* p_db, uint8_t op_code, uint16_t handle,
    uint16_t offset, uint8_t* p_value, uint16_t* p_len, uint16_t mtu,
    tGATT_SEC_FLAG sec_flag, uint8_t key_size, uint32_t trans_id) {
    tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db, uint8_t op_code,
    uint16_t handle, uint16_t offset, uint8_t* p_value, uint16_t* p_len,
    uint16_t mtu, tGATT_SEC_FLAG sec_flag, uint8_t key_size,
    uint32_t trans_id) {
  tGATT_ATTR* p_attr = find_attr_by_handle(p_db, handle);
  if (!p_attr) return GATT_NOT_FOUND;

@@ -454,8 +455,8 @@ tGATT_STATUS gatts_read_attr_value_by_handle(
                                        mtu, p_len, sec_flag, key_size);

  if (status == GATT_PENDING) {
    status = gatts_send_app_read_request(tcb, op_code, p_attr->handle, offset,
                                         trans_id, p_attr->gatt_type);
    status = gatts_send_app_read_request(tcb, cid, op_code, p_attr->handle,
                                         offset, trans_id, p_attr->gatt_type);
  }
  return status;
}
@@ -678,14 +679,14 @@ static tGATT_ATTR& allocate_attr_in_db(tGATT_SVC_DB& db, const Uuid& uuid,
 *
 ******************************************************************************/
static tGATT_STATUS gatts_send_app_read_request(
    tGATT_TCB& tcb, uint8_t op_code, uint16_t handle, uint16_t offset,
    uint32_t trans_id, bt_gatt_db_attribute_type_t gatt_type) {
    tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t handle,
    uint16_t offset, uint32_t trans_id, bt_gatt_db_attribute_type_t gatt_type) {
  tGATT_SRV_LIST_ELEM& el = *gatt_sr_find_i_rcb_by_handle(handle);
  uint16_t conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, el.gatt_if);

  if (trans_id == 0) {
    trans_id = gatt_sr_enqueue_cmd(tcb, op_code, handle);
    gatt_sr_update_cback_cnt(tcb, el.gatt_if, true, true);
    trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, handle);
    gatt_sr_update_cback_cnt(tcb, cid, el.gatt_if, true, true);
  }

  if (trans_id != 0) {
Loading