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

Commit 34465601 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Myles Watson
Browse files

gatt: Add CID for sending notification confirmation

This patch fixes a regression after

commit 13c39b9b
stack/gatt: Extend calls with CID

Notification confirmation was not taken into account.
For notification function attp_send_cl_msg() is called with p_clcb NULL
which leads to a crash in the following line:

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

This patch introduces a new function:  attp_send_cl_confirmation_msg()

which is used only for sending confirmation.
Also this patch makes sure that cid is provided to the GATT client so it
can be used in the confirmation call.
Note: handle was removed from the confirmation call as it is redundant.

The only missing part in this patch is handling timers per each
indication and this will be fixed in following patches which will add
eatt support.

Tag: #feature
Bug: 159786353
Sponsor: jpawlowski@
Test: compile & manual

Change-Id: I8bdb38ec673e11744d670223e5416be01666e1a6
parent a50f4d8a
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -824,11 +824,11 @@ void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {

/** send handle value confirmation */
void bta_gattc_confirm(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
  uint16_t handle = p_data->api_confirm.handle;
  uint16_t cid = p_data->api_confirm.cid;

  if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific,
                                   handle) != GATT_SUCCESS) {
    LOG(ERROR) << __func__ << ": to handle=" << loghex(handle) << " failed";
                                   cid) != GATT_SUCCESS) {
    LOG(ERROR) << __func__ << ": to cid=" << loghex(cid) << " failed";
  } else {
    /* if over BR_EDR, inform PM for mode change */
    if (p_clcb->transport == BT_TRANSPORT_BR_EDR) {
@@ -1162,7 +1162,7 @@ bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, tBTA_GATTC_RCB* p_clrcb,
      }
    }
    /* send confirmation here if this is an indication, it should always be */
    GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
    GATTC_SendHandleValueConfirm(conn_id, p_notify->cid);

    /* if connection available, refresh cache by doing discovery now */
    if (p_clcb) bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
@@ -1213,7 +1213,7 @@ void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op,
  if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
    LOG(ERROR) << __func__ << ": indication/notif for unknown app";
    if (op == GATTC_OPTYPE_INDICATION)
      GATTC_SendHandleValueConfirm(conn_id, handle);
      GATTC_SendHandleValueConfirm(conn_id, p_data->cid);
    return;
  }

@@ -1221,7 +1221,7 @@ void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op,
  if (p_clrcb == NULL) {
    LOG(ERROR) << __func__ << ": indication/notif for unregistered app";
    if (op == GATTC_OPTYPE_INDICATION)
      GATTC_SendHandleValueConfirm(conn_id, handle);
      GATTC_SendHandleValueConfirm(conn_id, p_data->cid);
    return;
  }

@@ -1229,13 +1229,14 @@ void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op,
  if (p_srcb == NULL) {
    LOG(ERROR) << __func__ << ": indication/notif for unknown device, ignore";
    if (op == GATTC_OPTYPE_INDICATION)
      GATTC_SendHandleValueConfirm(conn_id, handle);
      GATTC_SendHandleValueConfirm(conn_id, p_data->cid);
    return;
  }

  tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);

  notify.handle = handle;
  notify.cid = p_data->cid;

  /* if service change indication/notification, don't forward to application */
  if (bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, &notify,
@@ -1265,7 +1266,7 @@ void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op,
  /* no one intersted and need ack? */
  else if (op == GATTC_OPTYPE_INDICATION) {
    VLOG(1) << __func__ << " no one interested, ack now";
    GATTC_SendHandleValueConfirm(conn_id, handle);
    GATTC_SendHandleValueConfirm(conn_id, p_data->cid);
  }
}

+5 −5
Original line number Diff line number Diff line
@@ -599,21 +599,21 @@ void BTA_GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) {
 * Description      This function is called to send handle value confirmation.
 *
 * Parameters       conn_id - connection ID.
 *                    p_char_id - characteristic ID to confirm.
 *                  cid
 *
 * Returns          None
 *
 ******************************************************************************/
void BTA_GATTC_SendIndConfirm(uint16_t conn_id, uint16_t handle) {
void BTA_GATTC_SendIndConfirm(uint16_t conn_id, uint16_t cid) {
  tBTA_GATTC_API_CONFIRM* p_buf =
      (tBTA_GATTC_API_CONFIRM*)osi_calloc(sizeof(tBTA_GATTC_API_CONFIRM));

  VLOG(1) << __func__ << ": conn_id=" << +conn_id << " handle=0x" << std::hex
          << +handle;
  VLOG(1) << __func__ << ": conn_id=" << +conn_id << " cid=0x" << std::hex
          << +cid;

  p_buf->hdr.event = BTA_GATTC_API_CONFIRM_EVT;
  p_buf->hdr.layer_specific = conn_id;
  p_buf->handle = handle;
  p_buf->cid = cid;

  bta_sys_sendmsg(p_buf);
}
+1 −1
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ typedef struct {

typedef struct {
  BT_HDR hdr;
  uint16_t handle;
  uint16_t cid;
} tBTA_GATTC_API_CONFIRM;

typedef tGATT_CL_COMPLETE tBTA_GATTC_CMPL;
+3 −2
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ typedef struct {
  uint16_t len;
  uint8_t value[GATT_MAX_ATTR_LEN];
  bool is_notify;
  uint16_t cid;
} tBTA_GATTC_NOTIFY;

typedef struct {
@@ -643,12 +644,12 @@ void BTA_GATTC_WriteCharDescr(uint16_t conn_id, uint16_t handle,
 * Description      This function is called to send handle value confirmation.
 *
 * Parameters       conn_id - connection ID.
 *                  handle - characteristic handle to confirm.
 *                  cid - channel id
 *
 * Returns          None
 *
 ******************************************************************************/
extern void BTA_GATTC_SendIndConfirm(uint16_t conn_id, uint16_t handle);
extern void BTA_GATTC_SendIndConfirm(uint16_t conn_id, uint16_t cid);

/*******************************************************************************
 *
+1 −1
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ static void btif_test_command_complete_cback(uint16_t conn_id, tGATTC_OPTYPE op,
      break;

    case GATTC_OPTYPE_INDICATION:
      GATTC_SendHandleValueConfirm(conn_id, p_data->handle);
      GATTC_SendHandleValueConfirm(conn_id, p_data->cid);
      break;

    default:
Loading