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

Commit 64b4a645 authored by Jack He's avatar Jack He Committed by android-build-merger
Browse files

HFP: Add support for Multi-HFP (2/2) am: e1ddc3c2 am: 7bd384ce

am: 25bdbc20

Change-Id: I404e225a5c7bbd8a51153b8b3c7e6896abc8252d
parents b86f5cac 25bdbc20
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -422,7 +422,7 @@ void bta_ag_rfc_close(tBTA_AG_SCB* p_scb,
    bta_ag_sco_shutdown(p_scb, tBTA_AG_DATA::kEmpty);

    /* Check if all the SLCs are down */
    for (i = 0; i < BTA_AG_NUM_SCB; i++) {
    for (i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++) {
      if (bta_ag_cb.scb[i].in_use && bta_ag_cb.scb[i].svc_conn)
        num_active_conn++;
    }
@@ -512,7 +512,8 @@ void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
  }

  /* Collision Handling */
  for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, ag_scb++) {
  for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_MAX_NUM_CLIENTS;
       i++, ag_scb++) {
    if (ag_scb->in_use && alarm_is_scheduled(ag_scb->collision_timer)) {
      alarm_cancel(ag_scb->collision_timer);

+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
 ****************************************************************************/

static const tBTA_SYS_REG bta_ag_reg = {bta_ag_hdl_event, BTA_AgDisable};
const tBTA_AG_RES_DATA tBTA_AG_RES_DATA::kEmpty = {};

/*******************************************************************************
 *
+10 −3
Original line number Diff line number Diff line
@@ -958,7 +958,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
          ** Application will set it back to 1
          ** callheld indicator will be sent across to the peer. */
          if (val.str[0] == '2') {
            for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB;
            for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_MAX_NUM_CLIENTS;
                 i++, ag_scb++) {
              if (ag_scb->in_use) {
                if ((ag_scb->call_ind == BTA_AG_CALL_ACTIVE) &&
@@ -1099,7 +1099,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
      if (p_scb->features & BTA_AG_FEAT_BTRH) {
        /* If set command; send response and notify app */
        if (arg_type == BTA_AG_AT_SET) {
          for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB;
          for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_MAX_NUM_CLIENTS;
               i++, ag_scb++) {
            if (ag_scb->in_use) {
              bta_ag_send_result(ag_scb, BTA_AG_BTRH_RES, nullptr, int_arg);
@@ -1243,6 +1243,12 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
      break;
    }
    case BTA_AG_LOCAL_EVT_BCC: {
      if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) {
        LOG(WARNING) << __func__ << ": AT+BCC rejected as " << p_scb->peer_addr
                     << " is not the active device";
        bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_ALLOWED);
        break;
      }
      bta_ag_send_ok(p_scb);
      bta_ag_sco_open(p_scb, tBTA_AG_DATA::kEmpty);
      break;
@@ -1435,7 +1441,8 @@ void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, const tBTA_AG_API_RESULT& result) {

        /* if sco already opened or no inband ring send ring now */
        if (bta_ag_sco_is_open(p_scb) || !bta_ag_inband_enabled(p_scb) ||
            (p_scb->features & BTA_AG_FEAT_NOSCO)) {
            (p_scb->features & BTA_AG_FEAT_NOSCO) ||
            (result.data.audio_handle != bta_ag_scb_to_idx(p_scb))) {
          bta_ag_send_ring(p_scb, tBTA_AG_DATA::kEmpty);
        } else {
          /* else open sco, send ring after sco opened */
+2 −6
Original line number Diff line number Diff line
@@ -32,11 +32,6 @@
/*****************************************************************************
 *  Constants
 ****************************************************************************/
/* Number of SCBs (AG service instances that can be registered) */
#ifndef BTA_AG_NUM_SCB
#define BTA_AG_NUM_SCB 2
#endif

/* Time to wait for retry in case of collision */
#ifndef BTA_AG_COLLISION_TIMEOUT_MS
#define BTA_AG_COLLISION_TIMEOUT_MS (2 * 1000) /* 2 seconds */
@@ -265,7 +260,7 @@ typedef struct {

/* type for AG control block */
typedef struct {
  tBTA_AG_SCB scb[BTA_AG_NUM_SCB];         /* service control blocks */
  tBTA_AG_SCB scb[BTA_AG_MAX_NUM_CLIENTS]; /* service control blocks */
  tBTA_AG_PROFILE profile[BTA_AG_NUM_IDX]; /* profile-specific data */
  tBTA_AG_SCO_CB sco;                      /* SCO data */
  tBTA_AG_CBACK* p_cback;                  /* application callback */
@@ -340,6 +335,7 @@ extern void bta_ag_rfc_do_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
extern void bta_ag_rfc_do_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);

/* SCO functions */
extern bool bta_ag_sco_is_active_device(const RawAddress& bd_addr);
extern bool bta_ag_sco_is_open(tBTA_AG_SCB* p_scb);
extern bool bta_ag_sco_is_opening(tBTA_AG_SCB* p_scb);
extern void bta_ag_sco_conn_rsp(tBTA_AG_SCB* p_scb,
+38 −39
Original line number Diff line number Diff line
@@ -300,7 +300,7 @@ static tBTA_AG_SCB* bta_ag_scb_alloc(void) {
  tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
  int i;

  for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
  for (i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
    if (!p_scb->in_use) {
      /* initialize variables */
      p_scb->in_use = true;
@@ -321,7 +321,7 @@ static tBTA_AG_SCB* bta_ag_scb_alloc(void) {
    }
  }

  if (i == BTA_AG_NUM_SCB) {
  if (i == BTA_AG_MAX_NUM_CLIENTS) {
    /* out of scbs */
    p_scb = nullptr;
    APPL_TRACE_WARNING("%s: Out of scbs", __func__);
@@ -356,7 +356,7 @@ void bta_ag_scb_dealloc(tBTA_AG_SCB* p_scb) {

  /* If all scbs are deallocated, callback with disable event */
  if (!bta_sys_is_register(BTA_ID_AG)) {
    for (idx = 0; idx < BTA_AG_NUM_SCB; idx++) {
    for (idx = 0; idx < BTA_AG_MAX_NUM_CLIENTS; idx++) {
      if (bta_ag_cb.scb[idx].in_use) {
        allocated = true;
        break;
@@ -398,7 +398,7 @@ tBTA_AG_SCB* bta_ag_scb_by_idx(uint16_t idx) {
  tBTA_AG_SCB* p_scb;

  /* verify index */
  if (idx > 0 && idx <= BTA_AG_NUM_SCB) {
  if (idx > 0 && idx <= BTA_AG_MAX_NUM_CLIENTS) {
    p_scb = &bta_ag_cb.scb[idx - 1];
    if (!p_scb->in_use) {
      p_scb = nullptr;
@@ -442,7 +442,7 @@ uint8_t bta_ag_service_to_idx(tBTA_SERVICE_MASK services) {
uint16_t bta_ag_idx_by_bdaddr(const RawAddress* peer_addr) {
  tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
  if (peer_addr != nullptr) {
    for (uint16_t i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
    for (uint16_t i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
      if (p_scb->in_use && *peer_addr == p_scb->peer_addr) {
        return (i + 1);
      }
@@ -466,7 +466,7 @@ uint16_t bta_ag_idx_by_bdaddr(const RawAddress* peer_addr) {
 ******************************************************************************/
bool bta_ag_other_scb_open(tBTA_AG_SCB* p_curr_scb) {
  tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
  for (int i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
  for (int i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
    if (p_scb->in_use && p_scb != p_curr_scb &&
        p_scb->state == BTA_AG_OPEN_ST) {
      return true;
@@ -506,7 +506,7 @@ tBTA_AG_SCB* bta_ag_get_other_idle_scb(tBTA_AG_SCB* p_curr_scb) {
  tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
  uint8_t xx;

  for (xx = 0; xx < BTA_AG_NUM_SCB; xx++, p_scb++) {
  for (xx = 0; xx < BTA_AG_MAX_NUM_CLIENTS; xx++, p_scb++) {
    if (p_scb->in_use && (p_scb != p_curr_scb) &&
        (p_scb->state == BTA_AG_INIT_ST)) {
      return p_scb;
@@ -551,36 +551,35 @@ static void bta_ag_collision_timer_cback(void* data) {
void bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, uint8_t id,
                            UNUSED_ATTR uint8_t app_id,
                            const RawAddress& peer_addr) {
  uint16_t handle;
  tBTA_AG_SCB* p_scb;

  /* Check if we have opening scb for the peer device. */
  handle = bta_ag_idx_by_bdaddr(&peer_addr);
  p_scb = bta_ag_scb_by_idx(handle);
  uint16_t handle = bta_ag_idx_by_bdaddr(&peer_addr);
  tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(handle);

  if (p_scb && (p_scb->state == BTA_AG_OPENING_ST)) {
    if (id == BTA_ID_SYS) {
      /* ACL collision */
      APPL_TRACE_WARNING("AG found collision (ACL) ...");
      LOG(WARNING) << __func__ << "AG found collision (ACL) for handle "
                   << unsigned(handle) << " device " << peer_addr;
    } else if (id == BTA_ID_AG) {
      /* RFCOMM collision */
      APPL_TRACE_WARNING("AG found collision (RFCOMM) ...");
      LOG(WARNING) << __func__ << "AG found collision (RFCOMM) for handle "
                   << unsigned(handle) << " device " << peer_addr;
    } else {
      APPL_TRACE_WARNING("AG found collision (\?\?\?) ...");
      LOG(WARNING) << __func__ << "AG found collision (UNKNOWN) for handle "
                   << unsigned(handle) << " device " << peer_addr;
    }

    p_scb->state = BTA_AG_INIT_ST;

    /* Cancel SDP if it had been started. */
    if (p_scb->p_disc_db) {
      (void)SDP_CancelServiceSearch(p_scb->p_disc_db);
      SDP_CancelServiceSearch(p_scb->p_disc_db);
      bta_ag_free_db(p_scb, tBTA_AG_DATA::kEmpty);
    }

    /* reopen registered servers */
    /* Collision may be detected before or after we close servers. */
    if (bta_ag_is_server_closed(p_scb))
    if (bta_ag_is_server_closed(p_scb)) {
      bta_ag_start_servers(p_scb, p_scb->reg_services);
    }

    /* Start timer to han */
    alarm_set_on_mloop(p_scb->collision_timer, BTA_AG_COLLISION_TIMEOUT_MS,
@@ -600,16 +599,19 @@ void bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, uint8_t id,
 ******************************************************************************/
void bta_ag_resume_open(tBTA_AG_SCB* p_scb) {
  if (p_scb) {
    APPL_TRACE_DEBUG("bta_ag_resume_open, Handle(%d)",
                     bta_ag_scb_to_idx(p_scb));

    APPL_TRACE_DEBUG("%s: handle=%d, bd_addr=%s", __func__,
                     bta_ag_scb_to_idx(p_scb),
                     p_scb->peer_addr.ToString().c_str());
    /* resume opening process.  */
    if (p_scb->state == BTA_AG_INIT_ST) {
      LOG(WARNING) << __func__
                   << ": handle=" << unsigned(bta_ag_scb_to_idx(p_scb))
                   << ", bd_addr=" << p_scb->peer_addr;
      p_scb->state = BTA_AG_OPENING_ST;
      bta_ag_start_open(p_scb, tBTA_AG_DATA::kEmpty);
    }
  } else {
    APPL_TRACE_ERROR("bta_ag_resume_open, Null p_scb");
    LOG(ERROR) << __func__ << ": null p_scb";
  }
}

@@ -668,7 +670,7 @@ void bta_ag_api_disable() {
  /* De-register with BTA system manager */
  bta_sys_deregister(BTA_ID_AG);

  for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
  for (i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
    if (p_scb->in_use) {
      bta_ag_sm_execute(p_scb, BTA_AG_API_DEREGISTER_EVT, tBTA_AG_DATA::kEmpty);
      do_dereg = true;
@@ -746,7 +748,8 @@ void bta_ag_api_result(uint16_t handle, tBTA_AG_RES result,
    }
  } else {
    int i;
    for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, p_scb++) {
    for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_MAX_NUM_CLIENTS;
         i++, p_scb++) {
      if (p_scb->in_use && p_scb->svc_conn) {
        APPL_TRACE_DEBUG("bta_ag_api_result p_scb 0x%08x ", p_scb);
        bta_ag_sm_execute(p_scb, static_cast<uint16_t>(BTA_AG_API_RESULT_EVT),
@@ -774,17 +777,12 @@ void bta_ag_sm_execute(tBTA_AG_SCB* p_scb, uint16_t event,
  uint16_t previous_event = event;
  uint8_t previous_state = p_scb->state;

  /* Ignore displaying of AT results when not connected (Ignored in state
   * machine) */
  if (previous_event != BTA_AG_API_RESULT_EVT ||
      p_scb->state == BTA_AG_OPEN_ST) {
  APPL_TRACE_EVENT(
        "%s: handle=0x%04x, state=%s(0x%02x), event=%s(0x%04x), "
        "result=%s(0x%02x)",
        __func__, bta_ag_scb_to_idx(p_scb), bta_ag_state_str(p_scb->state),
        p_scb->state, bta_ag_evt_str(event), event,
        bta_ag_res_str(data.api_result.result), data.api_result.result);
  }
      "%s: handle=0x%04x, bd_addr=%s, state=%s(0x%02x), "
      "event=%s(0x%04x), result=%s(0x%02x)",
      __func__, bta_ag_scb_to_idx(p_scb), p_scb->peer_addr.ToString().c_str(),
      bta_ag_state_str(p_scb->state), p_scb->state, bta_ag_evt_str(event),
      event, bta_ag_res_str(data.api_result.result), data.api_result.result);

  event &= 0x00FF;
  if (event >= (BTA_AG_MAX_EVT & 0x00FF)) {
@@ -809,9 +807,10 @@ void bta_ag_sm_execute(tBTA_AG_SCB* p_scb, uint16_t event,
  }
  if (p_scb->state != previous_state) {
    APPL_TRACE_EVENT(
        "%s: state_change[%s(0x%02x)]->[%s(0x%02x)], "
        "%s: handle=0x%04x, bd_addr=%s, state_change[%s(0x%02x)]->[%s(0x%02x)],"
        " event[%s(0x%04x)], result[%s(0x%02x)]",
        __func__, bta_ag_state_str(previous_state), previous_state,
        __func__, bta_ag_scb_to_idx(p_scb), p_scb->peer_addr.ToString().c_str(),
        bta_ag_state_str(previous_state), previous_state,
        bta_ag_state_str(p_scb->state), p_scb->state,
        bta_ag_evt_str(previous_event), previous_event,
        bta_ag_res_str(data.api_result.result), data.api_result.result);
Loading