217 lines
8.7 KiB
C++
217 lines
8.7 KiB
C++
|
|
/* Copyright Statement:
|
||
|
|
* *
|
||
|
|
* * This software/firmware and related documentation ("MediaTek Software") are
|
||
|
|
* * protected under relevant copyright laws. The information contained herein
|
||
|
|
* * is confidential and proprietary to MediaTek Inc. and/or its licensors.
|
||
|
|
* * Without the prior written permission of MediaTek inc. and/or its licensors,
|
||
|
|
* * any reproduction, modification, use or disclosure of MediaTek Software,
|
||
|
|
* * and information contained herein, in whole or in part, shall be strictly prohibited.
|
||
|
|
* *
|
||
|
|
* * MediaTek Inc. (C) 2016. All rights reserved.
|
||
|
|
* *
|
||
|
|
* * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
|
||
|
|
* * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
|
||
|
|
* * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
|
||
|
|
* * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
|
||
|
|
* * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
|
||
|
|
* * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
|
||
|
|
* * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
|
||
|
|
* * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
|
||
|
|
* * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
|
||
|
|
* * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
|
||
|
|
* * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
|
||
|
|
* * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
|
||
|
|
* * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
|
||
|
|
* * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
|
||
|
|
* * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
|
||
|
|
* * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
|
||
|
|
* * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
|
||
|
|
* * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
|
||
|
|
* *
|
||
|
|
* * The following software/firmware and/or related documentation ("MediaTek Software")
|
||
|
|
* * have been modified by MediaTek Inc. All revisions are subject to any receiver's
|
||
|
|
* * applicable license agreements with MediaTek Inc.
|
||
|
|
* */
|
||
|
|
|
||
|
|
#include "bta_dm_api.h"
|
||
|
|
#include "bta/ag/bta_ag_int.h"
|
||
|
|
#include "stack/btm/btm_int_types.h"
|
||
|
|
#include "stack/btm/btm_sco.h"
|
||
|
|
#include "stack/include/btm_api.h"
|
||
|
|
#include "mediatek/stack/include/mtk_btm_int.h"
|
||
|
|
#include "stack/include/acl_api.h"
|
||
|
|
|
||
|
|
extern tBTM_CB btm_cb;
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/* L O C A L D A T A D E F I N I T I O N S */
|
||
|
|
/******************************************************************************/
|
||
|
|
|
||
|
|
|
||
|
|
/*******************************************************************************
|
||
|
|
*
|
||
|
|
* Function btm_is_sco_active_or_establishing_by_bdaddr
|
||
|
|
*
|
||
|
|
* Description This function is called to see if a SCO connection is active
|
||
|
|
* or establisting for a bd address.
|
||
|
|
*
|
||
|
|
* Returns bool
|
||
|
|
*
|
||
|
|
******************************************************************************/
|
||
|
|
bool btm_is_sco_active_or_establishing_by_bdaddr(const RawAddress& remote_bda) {
|
||
|
|
#if (BTM_MAX_SCO_LINKS > 0)
|
||
|
|
uint8_t xx;
|
||
|
|
tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
|
||
|
|
|
||
|
|
/* If any SCO is being established or establishing to the remote BD address, refuse this */
|
||
|
|
for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
|
||
|
|
if (p->esco.data.bd_addr == remote_bda &&
|
||
|
|
(p->state != SCO_ST_UNUSED && p->state != SCO_ST_LISTENING)) {
|
||
|
|
return (true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
return (false);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*******************************************************************************
|
||
|
|
*
|
||
|
|
* Function btm_sco_preemption_conn_req
|
||
|
|
*
|
||
|
|
* Description Send preemption connection request to hfp stack
|
||
|
|
*
|
||
|
|
*
|
||
|
|
* Returns void
|
||
|
|
*
|
||
|
|
******************************************************************************/
|
||
|
|
void btm_sco_preemption_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class, uint8_t
|
||
|
|
link_type,uint16_t sco_index,tBTM_ESCO_CBACK* p_esco_cback)
|
||
|
|
{
|
||
|
|
tBTM_ESCO_CONN_REQ_EVT_DATA evt_data = {};
|
||
|
|
|
||
|
|
/* Notify upper layer of connect indication */
|
||
|
|
evt_data.bd_addr = bda;
|
||
|
|
memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
|
||
|
|
evt_data.link_type = link_type;
|
||
|
|
evt_data.sco_inx = sco_index;
|
||
|
|
tBTM_ESCO_EVT_DATA btm_esco_evt_data = {};
|
||
|
|
btm_esco_evt_data.conn_evt = evt_data;
|
||
|
|
p_esco_cback(BTM_ESCO_CONN_REQ_EVT, &btm_esco_evt_data);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*******************************************************************************
|
||
|
|
*
|
||
|
|
* Function btm_is_any_sco_active
|
||
|
|
*
|
||
|
|
* Description This function is called to see if any SCO is already in use.
|
||
|
|
*
|
||
|
|
*
|
||
|
|
* Returns bool
|
||
|
|
*
|
||
|
|
******************************************************************************/
|
||
|
|
bool btm_is_any_sco_active(void) {
|
||
|
|
#if (BTM_MAX_SCO_LINKS > 0)
|
||
|
|
uint16_t xx;
|
||
|
|
tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
|
||
|
|
|
||
|
|
for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
|
||
|
|
if (p->state == SCO_ST_CONNECTED) return (true);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
return (false);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*******************************************************************************
|
||
|
|
*
|
||
|
|
* Function btm_find_sco_idx_by_addr
|
||
|
|
*
|
||
|
|
* Description This function return the sco idx by request bd address.
|
||
|
|
*
|
||
|
|
*
|
||
|
|
* Returns uint16_t
|
||
|
|
*
|
||
|
|
******************************************************************************/
|
||
|
|
uint16_t btm_find_sco_idx_by_addr(const RawAddress& bda) {
|
||
|
|
#if (BTM_MAX_SCO_LINKS > 0)
|
||
|
|
uint16_t xx;
|
||
|
|
tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
|
||
|
|
|
||
|
|
for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
|
||
|
|
if(p->esco.data.bd_addr == bda) return xx;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
return BTM_MAX_SCO_LINKS;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*******************************************************************************
|
||
|
|
*
|
||
|
|
* Function BTM_RegForEScoCback
|
||
|
|
*
|
||
|
|
* Description This function registers a SCO event callback with the
|
||
|
|
* specified instance. It should be used to received
|
||
|
|
* connection indication events and change of link parameter
|
||
|
|
* events.
|
||
|
|
*
|
||
|
|
* Returns BTM_SUCCESS if the successful.
|
||
|
|
* BTM_ILLEGAL_VALUE if there is an illegal sco_inx
|
||
|
|
*
|
||
|
|
******************************************************************************/
|
||
|
|
tBTM_STATUS BTM_RegForEScoCback(uint16_t sco_inx,const RawAddress& bda,bool is_orig,
|
||
|
|
tBTM_SCO_CB* p_conn_cb,tBTM_SCO_CB* p_disc_cb) {
|
||
|
|
#if (BTM_MAX_SCO_LINKS > 0)
|
||
|
|
tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
|
||
|
|
BTM_TRACE_DEBUG("%s: sco_inx = %x,pre is_orig %x,is_orig %x,pre p_conn_cb %x,pre p_disc_cb %x,p_conn_cb %x,p_disc_cb %x", __func__,sco_inx,p->is_orig ,is_orig,p->p_conn_cb,p->p_disc_cb,p_conn_cb,p_disc_cb);
|
||
|
|
p->hci_handle = BTM_INVALID_SCO_INDEX;
|
||
|
|
p->is_orig = is_orig;
|
||
|
|
p->p_conn_cb = p_conn_cb;
|
||
|
|
p->p_disc_cb = p_disc_cb;
|
||
|
|
p->esco.data.bd_addr = bda;
|
||
|
|
p->rem_bd_known = true;
|
||
|
|
return (BTM_SUCCESS);
|
||
|
|
#else
|
||
|
|
return (BTM_MODE_UNSUPPORTED);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
/*******************************************************************************
|
||
|
|
*
|
||
|
|
* Function btm_sco_chk_pend_unpark
|
||
|
|
*
|
||
|
|
* Description This function is called by BTIF when there is a mode change
|
||
|
|
* event to see if there are SCO commands waiting for the
|
||
|
|
* unpark.
|
||
|
|
*
|
||
|
|
* Returns void
|
||
|
|
*
|
||
|
|
******************************************************************************/
|
||
|
|
void btm_sco_chk_pend_unpark(uint8_t hci_status, uint16_t hci_handle, tBTM_PM_STATE state) {
|
||
|
|
#if (BTM_MAX_SCO_LINKS > 0)
|
||
|
|
tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
|
||
|
|
for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
|
||
|
|
uint16_t acl_handle =
|
||
|
|
BTM_GetHCIConnHandle(p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR);
|
||
|
|
if ((p->state == SCO_ST_PEND_UNPARK) && (acl_handle == hci_handle)) {
|
||
|
|
if (state == BTM_PM_ST_ACTIVE) {
|
||
|
|
LOG(INFO) << __func__ << ": " << p->esco.data.bd_addr
|
||
|
|
<< " unparked, sending connection request, acl_handle="
|
||
|
|
<< unsigned(acl_handle)
|
||
|
|
<< ", hci_status=" << unsigned(hci_status);
|
||
|
|
if (btm_send_connect_request(acl_handle, &p->esco.setup) ==
|
||
|
|
BTM_CMD_STARTED) {
|
||
|
|
p->state = SCO_ST_CONNECTING;
|
||
|
|
} else {
|
||
|
|
LOG(ERROR) << __func__ << ": failed to send connection request for "
|
||
|
|
<< p->esco.data.bd_addr;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(bta_ag_idx_by_bdaddr(&p->esco.data.bd_addr));
|
||
|
|
if( p_scb != nullptr){
|
||
|
|
LOG(ERROR) << __func__ << ": We need to switch to active mode before creating SCO for"
|
||
|
|
<< p->esco.data.bd_addr;
|
||
|
|
bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif // BTM_MAX_SCO_LINKS
|
||
|
|
}
|