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

Commit 5fa2d0d9 authored by Jayden Kim's avatar Jayden Kim Committed by Automerger Merge Worker
Browse files

Add helper functions to get LE L2CAP channel and ACL handle information am:...

Add helper functions to get LE L2CAP channel and ACL handle information am: 762667bd am: f4fb16a7

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/3367197



Change-Id: I93220b1c46269707ed26d787dd213099cea1953f
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents d580d34c f4fb16a7
Loading
Loading
Loading
Loading
+79 −15
Original line number Diff line number Diff line
@@ -55,7 +55,9 @@ typedef struct {

  uint8_t service_id;     /* Used by BTM */
  uint16_t gap_handle;    /* GAP handle */
  uint16_t connection_id; /* L2CAP CID */
  uint16_t local_cid;     /* Local L2CAP CID */
  uint16_t remote_cid;    /* Remote L2CAP CID */
  uint16_t acl_handle;    /* ACL handle */
  bool rem_addr_specified;
  uint8_t chan_mode_mask; /* Supported channel modes (FCR) */
  RawAddress rem_dev_address;
@@ -284,7 +286,7 @@ uint16_t GAP_ConnOpen(const char* /* p_serv_name */, uint8_t service_id, bool is
      cid = stack::l2cap::get_interface().L2CA_ConnectReqWithSecurity(p_ccb->psm, *p_rem_bda,
                                                                      security);
      if (cid != 0) {
        p_ccb->connection_id = cid;
        p_ccb->local_cid = cid;
        return p_ccb->gap_handle;
      }
      log::warn("Unable to initiate connection peer:{} psm:{} transport:{}", *p_rem_bda, p_ccb->psm,
@@ -295,7 +297,7 @@ uint16_t GAP_ConnOpen(const char* /* p_serv_name */, uint8_t service_id, bool is
      cid = stack::l2cap::get_interface().L2CA_ConnectLECocReq(p_ccb->psm, *p_rem_bda,
                                                               &p_ccb->local_coc_cfg, security);
      if (cid != 0) {
        p_ccb->connection_id = cid;
        p_ccb->local_cid = cid;
        return p_ccb->gap_handle;
      }
      log::warn("Unable to initiate connection peer:{} psm:{} transport:{}", *p_rem_bda, p_ccb->psm,
@@ -329,14 +331,14 @@ uint16_t GAP_ConnClose(uint16_t gap_handle) {
  /* Check if we have a connection ID */
  if (p_ccb->con_state != GAP_CCB_STATE_LISTENING) {
    if (p_ccb->transport == BT_TRANSPORT_LE) {
      if (!stack::l2cap::get_interface().L2CA_DisconnectLECocReq(p_ccb->connection_id)) {
      if (!stack::l2cap::get_interface().L2CA_DisconnectLECocReq(p_ccb->local_cid)) {
        log::warn("Unable to request L2CAP disconnect le_coc peer:{} cid:{}",
                  p_ccb->rem_dev_address, p_ccb->connection_id);
                  p_ccb->rem_dev_address, p_ccb->local_cid);
      }
    } else {
      if (!stack::l2cap::get_interface().L2CA_DisconnectReq(p_ccb->connection_id)) {
      if (!stack::l2cap::get_interface().L2CA_DisconnectReq(p_ccb->local_cid)) {
        log::warn("Unable to request L2CAP disconnect peer:{} cid:{}", p_ccb->rem_dev_address,
                  p_ccb->connection_id);
                  p_ccb->local_cid);
      }
    }
  }
@@ -451,9 +453,9 @@ static bool gap_try_write_queued_data(tGAP_CCB* p_ccb) {
  while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->tx_queue)) != NULL) {
    tL2CAP_DW_RESULT status;
    if (p_ccb->transport == BT_TRANSPORT_LE) {
      status = stack::l2cap::get_interface().L2CA_LECocDataWrite(p_ccb->connection_id, p_buf);
      status = stack::l2cap::get_interface().L2CA_LECocDataWrite(p_ccb->local_cid, p_buf);
    } else {
      status = stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_buf);
      status = stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->local_cid, p_buf);
    }

    if (status == tL2CAP_DW_RESULT::CONGESTED) {
@@ -576,7 +578,67 @@ uint16_t GAP_ConnGetL2CAPCid(uint16_t gap_handle) {
    return 0;
  }

  return p_ccb->connection_id;
  return p_ccb->local_cid;
}

/*******************************************************************************
 *
 * Function         GAP_GetLeChannelInfo
 *
 * Description      This function is called to get LE L2CAP channel information
 *                  by the gap handle. All OUT parameters must NOT be nullptr.
 *
 * Parameters:      handle        - Handle of the port returned in the Open
 *                  remote_mtu    - OUT remote L2CAP MTU
 *                  local_mps     - OUT local L2CAP COC MPS
 *                  remote_mps    - OUT remote L2CAP COC MPS
 *                  local_credit  - OUT local L2CAP COC credit
 *                  remote_credit - OUT remote L2CAP COC credit
 *                  local_cid     - OUT local L2CAP CID
 *                  remote_cid    - OUT remote L2CAP CID
 *                  acl_handle    - OUT ACL handle
 *
 * Returns          true if request accepted
 *
 ******************************************************************************/
bool GAP_GetLeChannelInfo(uint16_t gap_handle, uint16_t* remote_mtu, uint16_t* local_mps,
                          uint16_t* remote_mps, uint16_t* local_credit, uint16_t* remote_credit,
                          uint16_t* local_cid, uint16_t* remote_cid, uint16_t* acl_handle) {
  tGAP_CCB* p_ccb = gap_find_ccb_by_handle(gap_handle);
  if (p_ccb == NULL || p_ccb->transport != BT_TRANSPORT_LE ||
      p_ccb->con_state != GAP_CCB_STATE_CONNECTED) {
    return false;
  }

  *remote_mtu = p_ccb->peer_coc_cfg.mtu;
  *local_mps = p_ccb->local_coc_cfg.mps;
  *remote_mps = p_ccb->peer_coc_cfg.mps;
  *local_credit = p_ccb->local_coc_cfg.credits;
  *remote_credit = p_ccb->peer_coc_cfg.credits;
  *local_cid = p_ccb->local_cid;
  *remote_cid = p_ccb->remote_cid;
  *acl_handle = p_ccb->acl_handle;
  return true;
}

/*******************************************************************************
 *
 * Function         GAP_IsTransportLe
 *
 * Description      This function returns if the transport is LE by the gap handle.
 *
 * Parameters:      handle        - Handle of the port returned in the Open
 *
 * Returns          true if transport is LE, else false
 *
 ******************************************************************************/
bool GAP_IsTransportLe(uint16_t gap_handle) {
  tGAP_CCB* p_ccb = gap_find_ccb_by_handle(gap_handle);
  if (p_ccb == NULL || p_ccb->transport != BT_TRANSPORT_LE ||
      p_ccb->con_state != GAP_CCB_STATE_CONNECTED) {
    return false;
  }
  return true;
}

/*******************************************************************************
@@ -649,7 +711,7 @@ static void gap_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid, uint1

  /* Save the BD Address and Channel ID. */
  p_ccb->rem_dev_address = bd_addr;
  p_ccb->connection_id = l2cap_cid;
  p_ccb->local_cid = l2cap_cid;

  if (p_ccb->transport == BT_TRANSPORT_LE) {
    /* get the remote coc configuration */
@@ -683,12 +745,14 @@ static void gap_checks_con_flags(tGAP_CCB* p_ccb) {
    tGAP_CB_DATA cb_data;
    uint16_t l2cap_remote_cid;
    if (com::android::bluetooth::flags::bt_socket_api_l2cap_cid() &&
        stack::l2cap::get_interface().L2CA_GetRemoteChannelId(p_ccb->connection_id,
        stack::l2cap::get_interface().L2CA_GetRemoteChannelId(p_ccb->local_cid,
                                                              &l2cap_remote_cid)) {
      cb_data.l2cap_cids.local_cid = p_ccb->connection_id;
      cb_data.l2cap_cids.local_cid = p_ccb->local_cid;
      cb_data.l2cap_cids.remote_cid = l2cap_remote_cid;
      cb_data_ptr = &cb_data;
    }
    stack::l2cap::get_interface().L2CA_GetRemoteChannelId(p_ccb->local_cid, &p_ccb->remote_cid);
    stack::l2cap::get_interface().L2CA_GetAclHandle(p_ccb->local_cid, &p_ccb->acl_handle);
    p_ccb->con_state = GAP_CCB_STATE_CONNECTED;

    p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_OPENED, cb_data_ptr);
@@ -926,7 +990,7 @@ static void gap_congestion_ind(uint16_t lcid, bool is_congested) {
 * Function         gap_find_ccb_by_cid
 *
 * Description      This function searches the CCB table for an entry with the
 *                  passed CID.
 *                  passed local CID.
 *
 * Returns          the CCB address, or NULL if not found.
 *
@@ -937,7 +1001,7 @@ static tGAP_CCB* gap_find_ccb_by_cid(uint16_t cid) {

  /* Look through each connection control block */
  for (xx = 0, p_ccb = conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) {
    if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->connection_id == cid)) {
    if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->local_cid == cid)) {
      return p_ccb;
    }
  }
+37 −0
Original line number Diff line number Diff line
@@ -224,6 +224,43 @@ uint16_t GAP_ConnGetRemMtuSize(uint16_t gap_handle);
 ******************************************************************************/
uint16_t GAP_ConnGetL2CAPCid(uint16_t gap_handle);

/*******************************************************************************
 *
 * Function         GAP_GetLeChannelInfo
 *
 * Description      This function is called to get LE L2CAP channel information
 *                  by the gap handle. All OUT parameters must NOT be nullptr.
 *
 * Parameters:      handle        - Handle of the port returned in the Open
 *                  remote_mtu    - OUT remote L2CAP MTU
 *                  local_mps     - OUT local L2CAP COC MPS
 *                  remote_mps    - OUT remote L2CAP COC MPS
 *                  local_credit  - OUT local L2CAP COC credit
 *                  remote_credit - OUT remote L2CAP COC credit
 *                  local_cid     - OUT local L2CAP CID
 *                  remote_cid    - OUT remote L2CAP CID
 *                  acl_handle    - OUT ACL handle
 *
 * Returns          true if request accepted
 *
 ******************************************************************************/
bool GAP_GetLeChannelInfo(uint16_t gap_handle, uint16_t* remote_mtu, uint16_t* local_mps,
                          uint16_t* remote_mps, uint16_t* local_credit, uint16_t* remote_credit,
                          uint16_t* local_cid, uint16_t* remote_cid, uint16_t* acl_handle);

/*******************************************************************************
 *
 * Function         GAP_IsTransportLe
 *
 * Description      This function returns if the transport is LE by the gap handle.
 *
 * Parameters:      handle        - Handle of the port returned in the Open
 *
 * Returns          true if transport is LE, else false
 *
 ******************************************************************************/
bool GAP_IsTransportLe(uint16_t gap_handle);

/*******************************************************************************
 *
 * Function         GAP_Init
+17 −0
Original line number Diff line number Diff line
@@ -916,6 +916,23 @@ public:
   **
   *******************************************************************************/
  virtual bool L2CA_isMediaChannel(uint16_t handle, uint16_t channel_id, bool is_local_cid) = 0;

  /*******************************************************************************
   **
   ** Function         L2CA_GetAclHandle
   **
   ** Description      Given a local channel identifier, |lcid|, this function
   **                  returns the handle of the corresponding ACL connection, |acl_handle|. If
   **                  |lcid| is not known or is invalid, this function returns false and does not
   **                  modify the value pointed at by |acl_handle|.
   **
   ** Parameters:      lcid: Local CID
   **                  acl_handle: Pointer to ACL handle must NOT be nullptr
   **
   ** Returns          true if acl_handle lookup was successful
   **
   ******************************************************************************/
  virtual bool L2CA_GetAclHandle(uint16_t lcid, uint16_t* acl_handle) = 0;
};

Interface& get_interface();
+17 −0
Original line number Diff line number Diff line
@@ -777,3 +777,20 @@ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status);
**
*******************************************************************************/
[[nodiscard]] bool L2CA_isMediaChannel(uint16_t handle, uint16_t channel_id, bool is_local_cid);

/*******************************************************************************
**
** Function         L2CA_GetAclHandle
**
** Description      Given a local channel identifier, |lcid|, this function
**                  returns the handle of the corresponding ACL connection, |acl_handle|. If
**                  |lcid| is not known or is invalid, this function returns false and does not
**                  modify the value pointed at by |acl_handle|.
**
** Parameters:      lcid: Local CID
**                  acl_handle: Pointer to ACL handle must NOT be nullptr
**
** Returns          true if acl_handle lookup was successful
**
******************************************************************************/
[[nodiscard]] bool L2CA_GetAclHandle(uint16_t lcid, uint16_t* acl_handle);
+32 −0
Original line number Diff line number Diff line
@@ -1731,6 +1731,38 @@ bool L2CA_isMediaChannel(uint16_t handle, uint16_t channel_id, bool is_local_cid
  return ret;
}

/*******************************************************************************
 *
 *  Function        L2CA_GetAclHandle
 *
 *  Description     Given a local channel identifier, |lcid|, this function
 *                  returns the bound ACL handle, |acl_handle|. If |acl_handle|
 *                  is not known or is invalid, this function returns false and
 *                  does not modify the value pointed at by |acl_handle|.
 *
 *  Parameters:     lcid: Local CID
 *                  rcid: Pointer to ACL handle must NOT be nullptr
 *
 *  Return value:   true if acl_handle lookup was successful
 *
 ******************************************************************************/
bool L2CA_GetAclHandle(uint16_t lcid, uint16_t* acl_handle) {
  log::assert_that(acl_handle != nullptr, "assert failed: acl_handle != nullptr");

  tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(nullptr, lcid);
  if (p_ccb == nullptr) {
    log::error("No CCB for CID:0x{:04x}", lcid);
    return false;
  }
  uint16_t handle = p_ccb->p_lcb->Handle();
  if (handle == HCI_INVALID_HANDLE) {
    log::error("Invalid ACL handle");
    return false;
  }
  *acl_handle = handle;
  return true;
}

using namespace bluetooth;

#define DUMPSYS_TAG "shim::legacy::l2cap"
Loading