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

Commit a9e2a90a authored by Venkata Jagadeesh Garaga's avatar Venkata Jagadeesh Garaga Committed by Automerger Merge Worker
Browse files

SDP: Serialize sdp connections from profiles/BT APP am: 29d72cab

parents a42d5604 29d72cab
Loading
Loading
Loading
Loading
+37 −2
Original line number Diff line number Diff line
@@ -257,6 +257,16 @@ static void sdp_disconnect_ind(uint16_t l2cap_cid, bool ack_needed) {
    return;
  }

  if (ack_needed) {
    sdpu_process_pend_ccb(p_ccb->connection_id, false);
  } else {
    SDP_TRACE_WARNING(
        "SDP - Rcvd L2CAP disc, "
        "ACL disc clear pend sdp ccb: 0x%x",
        l2cap_cid);
    sdpu_clear_pend_ccb(p_ccb->connection_id);
  }

  SDP_TRACE_EVENT("SDP - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid);
  /* Tell the user if there is a callback */
  if (p_ccb->p_cb)
@@ -345,7 +355,17 @@ tCONN_CB* sdp_conn_originate(const RawAddress& p_bd_addr) {
   */
  p_ccb->con_state = SDP_STATE_CONN_SETUP;

  // Look for any active sdp connection on the remote device
  cid = sdpu_get_active_ccb_cid(p_bd_addr);

  if (cid == 0) {
    p_ccb->con_state = SDP_STATE_CONN_SETUP;
    cid = L2CA_ConnectReq2(BT_PSM_SDP, p_bd_addr, BTM_SEC_NONE);
  } else {
    p_ccb->con_state = SDP_STATE_CONN_PEND;
    SDP_TRACE_WARNING("SDP already active for peer %s. cid=%#0x",
                      p_bd_addr.ToString().c_str(), cid);
  }

  /* Check if L2CAP started the connection process */
  if (cid == 0) {
@@ -372,8 +392,20 @@ void sdp_disconnect(tCONN_CB* p_ccb, tSDP_REASON reason) {

  /* Check if we have a connection ID */
  if (p_ccb->connection_id != 0) {
    L2CA_DisconnectReq(p_ccb->connection_id);
    p_ccb->disconnect_reason = reason;
    if (SDP_SUCCESS == reason &&
        (true == sdpu_process_pend_ccb(p_ccb->connection_id, true))) {
      /* Tell the user if he has a callback */
      if (p_ccb->p_cb)
        (*p_ccb->p_cb)(static_cast<tSDP_STATUS>(p_ccb->disconnect_reason));
      else if (p_ccb->p_cb2)
        (*p_ccb->p_cb2)(static_cast<tSDP_STATUS>(p_ccb->disconnect_reason),
                        p_ccb->user_data);
      sdpu_release_ccb(p_ccb);
      return;
    } else {
      L2CA_DisconnectReq(p_ccb->connection_id);
    }
  }

  /* If at setup state, we may not get callback ind from L2CAP */
@@ -412,6 +444,7 @@ static void sdp_disconnect_cfm(uint16_t l2cap_cid,

  SDP_TRACE_EVENT("SDP - Rcvd L2CAP disc cfm, CID: 0x%x", l2cap_cid);

  sdpu_process_pend_ccb(p_ccb->connection_id, false);
  /* Tell the user if there is a callback */
  if (p_ccb->p_cb)
    (*p_ccb->p_cb)(static_cast<tSDP_STATUS>(p_ccb->disconnect_reason));
@@ -439,6 +472,8 @@ void sdp_conn_timer_timeout(void* data) {
                  p_ccb->connection_id);

  L2CA_DisconnectReq(p_ccb->connection_id);
  sdpu_clear_pend_ccb(p_ccb->connection_id);

  /* Tell the user if there is a callback */
  if (p_ccb->p_cb)
    (*p_ccb->p_cb)(SDP_CONN_FAILED);
+128 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include "stack/include/avrc_api.h"
#include "stack/include/avrc_defs.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/btm_api_types.h"
#include "stack/include/sdp_api.h"
#include "stack/include/sdpdefs.h"
#include "stack/include/stack_metrics_logging.h"
@@ -320,9 +321,12 @@ tCONN_CB* sdpu_find_ccb_by_cid(uint16_t cid) {

  /* Look through each connection control block */
  for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
    if ((p_ccb->con_state != SDP_STATE_IDLE) && (p_ccb->connection_id == cid))
    if ((p_ccb->con_state != SDP_STATE_IDLE) &&
        (p_ccb->con_state != SDP_STATE_CONN_PEND) &&
        (p_ccb->connection_id == cid)) {
      return (p_ccb);
    }
  }

  /* If here, not found */
  return (NULL);
@@ -402,6 +406,129 @@ void sdpu_release_ccb(tCONN_CB* p_ccb) {
  osi_free_and_reset((void**)&p_ccb->rsp_list);
}

/*******************************************************************************
 *
 * Function         sdpu_get_active_ccb_cid
 *
 * Description      This function checks if any sdp connecting is there for
 *                  same remote and returns cid if its available
 *
 *                  RawAddress : Remote address
 *
 * Returns          returns cid if any active sdp connection, else 0.
 *
 ******************************************************************************/
uint16_t sdpu_get_active_ccb_cid(const RawAddress& remote_bd_addr) {
  uint16_t xx;
  tCONN_CB* p_ccb;

  // Look through each connection control block for active sdp on given remote
  for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
    if ((p_ccb->con_state == SDP_STATE_CONN_SETUP) ||
        (p_ccb->con_state == SDP_STATE_CFG_SETUP) ||
        (p_ccb->con_state == SDP_STATE_CONNECTED)) {
      if (p_ccb->con_flags & SDP_FLAGS_IS_ORIG &&
          p_ccb->device_address == remote_bd_addr) {
        return p_ccb->connection_id;
      }
    }
  }

  // No active sdp channel for this remote
  return 0;
}

/*******************************************************************************
 *
 * Function         sdpu_process_pend_ccb
 *
 * Description      This function process if any sdp ccb pending for connection
 *
 *                  uint16_t : Remote CID
 *                  bool: if true will reuse current channel else will create a
 *                         new L2CAP connection
 *
 * Returns          returns true if any pending ccb, else false.
 *
 ******************************************************************************/
bool sdpu_process_pend_ccb(uint16_t cid, bool use_cur_chnl) {
  uint16_t xx;
  tCONN_CB* p_ccb;

  if (use_cur_chnl) {
    // Look through each connection control block for active sdp on given remote
    for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
      if ((p_ccb->con_state == SDP_STATE_CONN_PEND) &&
          (p_ccb->connection_id == cid) &&
          (p_ccb->con_flags & SDP_FLAGS_IS_ORIG)) {
        p_ccb->con_state = SDP_STATE_CONNECTED;
        sdp_disc_connected(p_ccb);
        return true;
      }
    }
    // No pending SDP channel for this remote
    return false;
  }

  uint16_t new_cid = 0;
  bool new_conn = false;
  for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
    if ((p_ccb->con_state == SDP_STATE_CONN_PEND) &&
        (p_ccb->connection_id == cid) &&
        (p_ccb->con_flags & SDP_FLAGS_IS_ORIG)) {
      if (!new_conn) {
        p_ccb->con_state = SDP_STATE_CONN_SETUP;
        new_cid =
            L2CA_ConnectReq2(BT_PSM_SDP, p_ccb->device_address, BTM_SEC_NONE);
        new_conn = true;
      }
      // Check if L2CAP started the connection process
      if (new_cid != 0) {
        p_ccb->connection_id = new_cid;
      } else {
        // Tell the user if he has a callback
        if (p_ccb->p_cb)
          (*p_ccb->p_cb)(SDP_CONN_FAILED);
        else if (p_ccb->p_cb2)
          (*p_ccb->p_cb2)(SDP_CONN_FAILED, p_ccb->user_data);
        sdpu_release_ccb(p_ccb);
      }
    }
  }
  return new_conn && new_cid != 0;
}

/*******************************************************************************
 *
 * Function         sdpu_clear_pend_ccb
 *
 * Description      This function releases if any sdp ccb pending for connection
 *
 *                  uint16_t : Remote CID
 *
 * Returns          returns none.
 *
 ******************************************************************************/
void sdpu_clear_pend_ccb(uint16_t cid) {
  uint16_t xx;
  tCONN_CB* p_ccb;

  // Look through each connection control block for active sdp on given remote
  for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
    if ((p_ccb->con_state == SDP_STATE_CONN_PEND) &&
        (p_ccb->connection_id == cid) &&
        (p_ccb->con_flags & SDP_FLAGS_IS_ORIG)) {
      // Tell the user if he has a callback
      if (p_ccb->p_cb)
        (*p_ccb->p_cb)(SDP_CONN_FAILED);
      else if (p_ccb->p_cb2)
        (*p_ccb->p_cb2)(SDP_CONN_FAILED, p_ccb->user_data);
      sdpu_release_ccb(p_ccb);
    }
  }
  return;
}

/*******************************************************************************
 *
 * Function         sdpu_build_attrib_seq
+4 −0
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ typedef struct {
#define SDP_STATE_CONN_SETUP 1
#define SDP_STATE_CFG_SETUP 2
#define SDP_STATE_CONNECTED 3
#define SDP_STATE_CONN_PEND 4
  uint8_t con_state;

#define SDP_FLAGS_IS_ORIG 0x01
@@ -236,6 +237,9 @@ extern bool sdpu_is_service_id_avrc_target(const tSDP_ATTRIBUTE* p_attr);
extern bool spdu_is_avrcp_version_valid(const uint16_t version);
extern void sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE* p_attr,
                                         const RawAddress* bdaddr);
extern uint16_t sdpu_get_active_ccb_cid(const RawAddress& remote_bd_addr);
extern bool sdpu_process_pend_ccb(uint16_t cid, bool use_cur_chnl);
extern void sdpu_clear_pend_ccb(uint16_t cid);

/* Functions provided by sdp_db.cc
 */