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); }
/******************************************************************************* ** ** 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); }