コード例 #1
0
static void connection_request_cb(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *data) {
  assert(data != NULL);

  // Don't care about change of link parameters, only connection requests.
  if (event != BTM_ESCO_CONN_REQ_EVT)
    return;

  pthread_mutex_lock(&lock);

  const tBTM_ESCO_CONN_REQ_EVT_DATA *conn_data = &data->conn_evt;
  sco_socket_t *sco_socket = sco_socket_find_locked(conn_data->sco_inx);
  int client_fd = INVALID_FD;

  if (!sco_socket) {
    LOG_ERROR(LOG_TAG, "%s unable to find sco_socket for handle: %hu", __func__, conn_data->sco_inx);
    goto error;
  }

  if (sco_socket != listen_sco_socket) {
    LOG_ERROR(LOG_TAG, "%s received connection request on non-listening socket handle: %hu", __func__, conn_data->sco_inx);
    goto error;
  }

  sco_socket_t *new_sco_socket = sco_socket_establish_locked(true, NULL, &client_fd);
  if (!new_sco_socket) {
    LOG_ERROR(LOG_TAG, "%s unable to allocate new sco_socket.", __func__);
    goto error;
  }

  // Swap socket->sco_handle and new_socket->sco_handle
  uint16_t temp = sco_socket->sco_handle;
  sco_socket->sco_handle = new_sco_socket->sco_handle;
  new_sco_socket->sco_handle = temp;

  sock_connect_signal_t connect_signal;
  connect_signal.size = sizeof(connect_signal);
  memcpy(&connect_signal.bd_addr, conn_data->bd_addr, sizeof(bt_bdaddr_t));
  connect_signal.channel = 0;
  connect_signal.status = 0;

  if (socket_write_and_transfer_fd(sco_socket->socket, &connect_signal, sizeof(connect_signal), client_fd) != sizeof(connect_signal)) {
    LOG_ERROR(LOG_TAG, "%s unable to send new file descriptor to listening socket.", __func__);
    goto error;
  }

  BTM_RegForEScoEvts(listen_sco_socket->sco_handle, connection_request_cb);
  BTM_EScoConnRsp(conn_data->sco_inx, HCI_SUCCESS, NULL);

  pthread_mutex_unlock(&lock);
  return;

error:;
  pthread_mutex_unlock(&lock);

  if (client_fd != INVALID_FD)
    close(client_fd);
  BTM_EScoConnRsp(conn_data->sco_inx, HCI_ERR_HOST_REJECT_RESOURCES, NULL);
}
コード例 #2
0
/*******************************************************************************
**
** Function         bta_hf_client_sco_conn_rsp
**
** Description      Process the SCO connection request
**
**
** Returns          void
**
*******************************************************************************/
static void bta_hf_client_sco_conn_rsp(tBTM_ESCO_CONN_REQ_EVT_DATA *p_data)
{
    tBTM_ESCO_PARAMS    resp;
    UINT8               hci_status = HCI_SUCCESS;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_LISTEN_ST)
    {
        if (p_data->link_type == BTM_LINK_TYPE_SCO)
        {
            resp = bta_hf_client_esco_params[0];
        }
        else
        {
            resp = bta_hf_client_esco_params[bta_hf_client_cb.scb.negotiated_codec];
        }

        /* tell sys to stop av if any */
        bta_sys_sco_use(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
    }
    else
    {
        hci_status = HCI_ERR_HOST_REJECT_DEVICE;
    }

    BTM_EScoConnRsp(p_data->sco_inx, hci_status, &resp);
}