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

Commit 7eacee8b authored by Sanket Agarwal's avatar Sanket Agarwal
Browse files

Incoming HF connection: CB interaction between BTA <-> BTIF

For incoming connections we are not storing the handles in BTIF which
implies that BTIF ignores the message (and so does jni -> java). This is
fixed by sending the handle as part of BTA message on incoming accept.

Other bugs include connection from remote (incoming) and disconnecting
from host. They also depended on not storing the handle properly in
first place.

Bug: b/33555377
Bug: b/30984220

Test: Manual testing of incoming connections
Change-Id: I84950d42aba2d2c975ea86cc8217fd0129cc90e9
parent 5fcb584d
Loading
Loading
Loading
Loading
+1 −45
Original line number Diff line number Diff line
@@ -119,28 +119,6 @@ void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) {
  bta_hf_client_do_disc(client_cb);
}

/*******************************************************************************
 *
 * Function         bta_hf_client_cback_open
 *
 * Description      Send open callback event to application.
 *
 *
 * Returns          void
 *
 ******************************************************************************/
static void bta_hf_client_cback_open(tBTA_HF_CLIENT_CB* client_cb,
                                     tBTA_HF_CLIENT_STATUS status) {
  tBTA_HF_CLIENT evt;

  memset(&evt, 0, sizeof(evt));

  /* call app callback with open event */
  evt.open.status = status;
  bdcpy(evt.open.bd_addr, client_cb->peer_addr);
  bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt);
}

/*******************************************************************************
 *
 * Function         bta_hf_client_rfc_open
@@ -163,8 +141,6 @@ void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) {

  bta_sys_conn_open(BTA_ID_HS, 1, client_cb->peer_addr);

  bta_hf_client_cback_open(client_cb, BTA_HF_CLIENT_SUCCESS);

  /* start SLC procedure */
  bta_hf_client_slc_seq(client_cb, false);
}
@@ -256,9 +232,6 @@ void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA* p_data) {
  client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;

  bta_hf_client_at_reset(client_cb);

  /* call open cback w. failure */
  bta_hf_client_cback_open(client_cb, BTA_HF_CLIENT_FAIL_RFCOMM);
}

/*******************************************************************************
@@ -279,9 +252,6 @@ void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) {
                     p_data->hdr.layer_specific);
    return;
  }

  /* call open cback w. failure */
  bta_hf_client_cback_open(client_cb, BTA_HF_CLIENT_FAIL_SDP);
}

/*******************************************************************************
@@ -302,9 +272,6 @@ void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) {
                     p_data->hdr.layer_specific);
    return;
  }

  /* call open cback w. failure */
  bta_hf_client_cback_open(client_cb, BTA_HF_CLIENT_FAIL_RESOURCES);
}

/*******************************************************************************
@@ -326,14 +293,6 @@ void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data) {
    return;
  }

  /* reinitialize stuff */
  client_cb->peer_features = 0;
  client_cb->chld_features = 0;
  client_cb->role = BTA_HF_CLIENT_ACP;
  client_cb->svc_conn = false;
  client_cb->send_at_reply = false;
  client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;

  bta_hf_client_at_reset(client_cb);

  bta_sys_conn_close(BTA_ID_HS, 1, client_cb->peer_addr);
@@ -342,13 +301,9 @@ void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data) {
  tBTA_HF_CLIENT evt;
  memset(&evt, 0, sizeof(evt));
  bdcpy(evt.conn.bd_addr, client_cb->peer_addr);
  bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt);

  /* if not deregistering reopen server */
  if (bta_hf_client_cb_arr.deregister == false) {
    /* Clear peer bd_addr so instance can be reused */
    bdcpy(client_cb->peer_addr, bd_addr_null);

    /* Make sure SCO is shutdown */
    bta_hf_client_sco_shutdown(client_cb);

@@ -481,6 +436,7 @@ void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) {
 *
 ******************************************************************************/
void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
  APPL_TRACE_DEBUG("%s", __func__);
  tBTA_HF_CLIENT_CB* client_cb =
      bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
  if (client_cb == NULL) {
+49 −12
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright (c) 2014 The Android Open Source Project
 *  Copyright (c) 2016 The Android Open Source Project
 *  Copyright (C) 2003-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,6 +34,7 @@ extern fixed_queue_t* btu_bta_alarm_queue;

static const char* bta_hf_client_evt_str(uint16_t event);
static const char* bta_hf_client_state_str(uint8_t state);
void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle);

/* state machine states */
enum {
@@ -279,8 +280,8 @@ void bta_hf_client_cb_arr_init() {
  // reset the handles and make the CBs non-allocated
  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    // Allocate the handles in increasing order of indices
    bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
    bta_hf_client_cb_arr.cb[i].handle = BTA_HF_CLIENT_CB_FIRST_HANDLE + i;
    bta_hf_client_cb_arr.cb[i].is_allocated = false;
  }
}

@@ -288,19 +289,26 @@ void bta_hf_client_cb_arr_init() {
*
* Function         bta_hf_client_cb_init
*
* Description      Initialize an HF_Client service control block.
* Description      Initialize an HF_Client service control block. Assign the
*                  handle to cb->handle.
*
*
*
* Returns          void
*
******************************************************************************/
void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb) {
void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) {
  APPL_TRACE_DEBUG("%s", __func__);

  // Free any memory we need to explicity release
  alarm_free(client_cb->collision_timer);
  client_cb->collision_timer = NULL;

  // Memset the rest of the block
  memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));

  // Re allocate any variables required
  client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer");
  client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
  client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
  client_cb->handle = handle;
}

/*******************************************************************************
@@ -587,12 +595,15 @@ bool bta_hf_client_allocate_handle(const BD_ADDR bd_addr, uint16_t* p_handle) {
      continue;
    }

    // Reset the client control block
    bta_hf_client_cb_init(client_cb, client_cb->handle);

    *p_handle = client_cb->handle;
    APPL_TRACE_DEBUG("%s: marking CB handle %d to true", __func__,
                     client_cb->handle);

    client_cb->is_allocated = true;
    bdcpy(client_cb->peer_addr, bd_addr);

    // Reset the handle for use (i.e. reset timers etc)
    bta_hf_client_cb_init(client_cb);
    bta_hf_client_at_init(client_cb);
    return true;
  }
@@ -647,7 +658,7 @@ void bta_hf_client_api_disable() {
  /* reinit the control block */
  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    if (bta_hf_client_cb_arr.cb[i].is_allocated) {
      bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]));
      bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
    }
  }

@@ -729,8 +740,30 @@ void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) {
    }
  }

  /* If the state has changed then notify the app of the corresponding change */
  if (in_state != client_cb->state) {
    APPL_TRACE_DEBUG(
        "%s: notifying state change to %d -> %d "
        "device %02x:%02x:%02x:%02x:%02x:%02x",
        __func__, in_state, client_cb->state, client_cb->peer_addr[0],
        client_cb->peer_addr[1], client_cb->peer_addr[2],
        client_cb->peer_addr[3], client_cb->peer_addr[4],
        client_cb->peer_addr[5]);
    tBTA_HF_CLIENT evt;
    memset(&evt, 0, sizeof(evt));
    bdcpy(evt.bd_addr, client_cb->peer_addr);
    if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
      bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt);
    } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
      evt.open.handle = client_cb->handle;
      bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt);
    }
  }

  /* if the next state is INIT then release the cb for future use */
  if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
    APPL_TRACE_DEBUG("%s: marking CB handle %d to false", __func__,
                     client_cb->handle);
    client_cb->is_allocated = false;
  }

@@ -781,7 +814,11 @@ void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) {
    return;
  }

  if (client_cb->svc_conn) return;
  if (client_cb->svc_conn) {
    APPL_TRACE_WARNING("%s: SLC already connected for CB handle %d", __func__,
                       client_cb->handle);
    return;
  }

  switch (client_cb->at_cb.current_cmd) {
    case BTA_HF_CLIENT_AT_NONE:
+12 −9
Original line number Diff line number Diff line
@@ -74,8 +74,8 @@ static void bta_hf_client_mgmt_cback(uint32_t code, uint16_t port_handle) {
  tBTA_HF_CLIENT_CB* client_cb =
      bta_hf_client_find_cb_by_rfc_handle(port_handle);

  APPL_TRACE_DEBUG("%s: code = %d, port_handle = %d", __func__, code,
                   port_handle);
  APPL_TRACE_DEBUG("%s: code = %d, port_handle = %d serv = %d", __func__, code,
                   port_handle, bta_hf_client_cb_arr.serv_handle);

  /* ignore close event for port handles other than connected handle */
  if (code != PORT_SUCCESS && client_cb != NULL &&
@@ -114,9 +114,6 @@ static void bta_hf_client_mgmt_cback(uint32_t code, uint16_t port_handle) {
        // Set the connection fields for this new CB
        client_cb->conn_handle = port_handle;

        // Copy the BDADDR
        bdcpy(client_cb->peer_addr, peer_addr);

        // Since we have accepted an incoming RFCOMM connection:
        // a) Release the current server from it duties
        // b) Start a new server for more new incoming connection
@@ -124,13 +121,19 @@ static void bta_hf_client_mgmt_cback(uint32_t code, uint16_t port_handle) {
        bta_hf_client_start_server();
      }
    } else {
      APPL_TRACE_ERROR(
          "bta_hf_client_mgmt_cback: PORT_SUCCESS, ignoring handle = %d",
      APPL_TRACE_ERROR("%s: PORT_SUCCESS, ignoring handle = %d", __func__,
                       port_handle);
      return;
    }
  } else if (client_cb != NULL &&
             port_handle == client_cb->conn_handle) { /* code != PORT_SUC */
    APPL_TRACE_ERROR(
        "%s: closing port handle %d "
        "dev %02x:%02x:%02x:%02x:%02x:%02x",
        __func__, port_handle, client_cb->peer_addr[0], client_cb->peer_addr[1],
        client_cb->peer_addr[2], client_cb->peer_addr[3],
        client_cb->peer_addr[4], client_cb->peer_addr[5]);

    RFCOMM_RemoveServer(port_handle);
    p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
  }
@@ -261,7 +264,7 @@ void bta_hf_client_rfc_do_open(tBTA_HF_CLIENT_DATA* p_data) {
 * Returns          void
 *
 ******************************************************************************/
void bta_hf_client_rfc_do_close(UNUSED_ATTR tBTA_HF_CLIENT_DATA* p_data) {
void bta_hf_client_rfc_do_close(tBTA_HF_CLIENT_DATA* p_data) {
  tBTA_HF_CLIENT_CB* client_cb =
      bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
  if (client_cb == NULL) {
+1 −0
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ typedef struct {
/* data associated with BTA_HF_CLIENT_OPEN_EVT */
typedef struct {
  BD_ADDR bd_addr;
  uint16_t handle;  // Handle for client control block
  tBTA_HF_CLIENT_STATUS status;
} tBTA_HF_CLIENT_OPEN;

+4 −1
Original line number Diff line number Diff line
@@ -60,7 +60,10 @@ void* BtifAvrcpAudioTrackCreate(int trackFreq, int channelType) {
}

void BtifAvrcpAudioTrackStart(void* handle) {
  CHECK(handle != NULL);
  if (handle == NULL) {
    LOG_ERROR(LOG_TAG, "%s: handle is null!", __func__);
    return;
  }
  BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
  CHECK(trackHolder != NULL);
  CHECK(trackHolder->track != NULL);
Loading