blob: d8eb192ea80ff51e76b10cb484c34e997eb2f82e [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
2 *
3 * Copyright (C) 2004-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 * This file contains action functions for advanced audio/video stream
22 * state machine. these functions are shared by both audio and video
23 * streams.
24 *
25 ******************************************************************************/
26
27#include "bt_target.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080028
Jack Hef2af1c42016-12-13 01:59:12 -080029#include <base/logging.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080030#include <string.h>
Pavlin Radoslavovd5f49602017-01-03 16:53:18 -080031#include <vector>
Anubhav Gupta6a277762014-11-13 19:58:09 +053032
The Android Open Source Project5738f832012-12-12 16:00:35 -080033#include "avdt_api.h"
Abhijit Adsule47b43102015-05-19 02:44:26 -050034#include "bt_utils.h"
Myles Watsoncd1fd072016-11-09 13:17:43 -080035#include "bta_av_int.h"
Pavlin Radoslavov3b8391c2017-05-12 01:16:10 -070036#include "btif/include/btif_av_co.h"
Pavlin Radoslavove91297a2017-06-19 12:44:11 -070037#include "btif/include/btif_storage.h"
38#include "device/include/interop.h"
Jakub Pawlowski3eb4a482016-02-24 10:39:46 -080039#include "l2c_api.h"
Myles Watsoncd1fd072016-11-09 13:17:43 -080040#include "l2cdefs.h"
Myles Watsond7ffd642016-10-27 10:27:36 -070041#include "osi/include/osi.h"
Jakub Pawlowski3eb4a482016-02-24 10:39:46 -080042#include "osi/include/properties.h"
43#include "utl.h"
Abhijit Adsule47b43102015-05-19 02:44:26 -050044
Marie Janssene9e58ce2016-06-17 14:12:17 -070045#if (BTA_AR_INCLUDED == TRUE)
The Android Open Source Project5738f832012-12-12 16:00:35 -080046#include "bta_ar_api.h"
47#endif
48
49/*****************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -080050 * Constants
51 ****************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -080052
53/* the delay time in milliseconds to start service discovery on AVRCP */
54#ifndef BTA_AV_RC_DISC_TIME_VAL
Myles Watsoncd1fd072016-11-09 13:17:43 -080055#define BTA_AV_RC_DISC_TIME_VAL 3500
The Android Open Source Project5738f832012-12-12 16:00:35 -080056#endif
57
Myles Watsoncd1fd072016-11-09 13:17:43 -080058/* the timer in milliseconds to guard against link busy and AVDT_CloseReq failed
59 * to be sent */
The Android Open Source Project5738f832012-12-12 16:00:35 -080060#ifndef BTA_AV_CLOSE_REQ_TIME_VAL
Myles Watsoncd1fd072016-11-09 13:17:43 -080061#define BTA_AV_CLOSE_REQ_TIME_VAL 4000
The Android Open Source Project5738f832012-12-12 16:00:35 -080062#endif
63
Myles Watsoncd1fd072016-11-09 13:17:43 -080064/* number to retry on reconfigure failure - some headsets requirs this number to
65 * be more than 1 */
The Android Open Source Project5738f832012-12-12 16:00:35 -080066#ifndef BTA_AV_RECONFIG_RETRY
Myles Watsoncd1fd072016-11-09 13:17:43 -080067#define BTA_AV_RECONFIG_RETRY 6
The Android Open Source Project5738f832012-12-12 16:00:35 -080068#endif
69
Abhijit Adsule47b43102015-05-19 02:44:26 -050070/* ACL quota we are letting FW use for A2DP Offload Tx. */
Myles Watsoncd1fd072016-11-09 13:17:43 -080071#define BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA 4
Abhijit Adsule47b43102015-05-19 02:44:26 -050072
Myles Watsoncd1fd072016-11-09 13:17:43 -080073static void bta_av_st_rc_timer(tBTA_AV_SCB* p_scb,
74 UNUSED_ATTR tBTA_AV_DATA* p_data);
Chris Mantond44d6402015-03-06 14:41:32 -080075
The Android Open Source Project5738f832012-12-12 16:00:35 -080076/* state machine states */
Myles Watsoncd1fd072016-11-09 13:17:43 -080077enum {
78 BTA_AV_INIT_SST,
79 BTA_AV_INCOMING_SST,
80 BTA_AV_OPENING_SST,
81 BTA_AV_OPEN_SST,
82 BTA_AV_RCFG_SST,
83 BTA_AV_CLOSING_SST
The Android Open Source Project5738f832012-12-12 16:00:35 -080084};
85
The Android Open Source Project5738f832012-12-12 16:00:35 -080086/* the call out functions for audio stream */
Myles Watsoncd1fd072016-11-09 13:17:43 -080087const tBTA_AV_CO_FUNCTS bta_av_a2dp_cos = {
88 bta_av_co_audio_init, bta_av_co_audio_disc_res,
89 bta_av_co_audio_getconfig, bta_av_co_audio_setconfig,
90 bta_av_co_audio_open, bta_av_co_audio_close,
91 bta_av_co_audio_start, bta_av_co_audio_stop,
Pavlin Radoslavov31d373b2017-02-14 12:18:44 -080092 bta_av_co_audio_src_data_path, bta_av_co_audio_delay,
93 bta_av_co_audio_update_mtu};
The Android Open Source Project5738f832012-12-12 16:00:35 -080094
95/* ssm action functions for audio stream */
Myles Watsoncd1fd072016-11-09 13:17:43 -080096const tBTA_AV_SACT bta_av_a2dp_action[] = {
Pavlin Radoslavovf66f4e92016-10-14 15:14:37 -070097 bta_av_do_disc_a2dp, /* BTA_AV_DO_DISC */
The Android Open Source Project5738f832012-12-12 16:00:35 -080098 bta_av_cleanup, /* BTA_AV_CLEANUP */
99 bta_av_free_sdb, /* BTA_AV_FREE_SDB */
100 bta_av_config_ind, /* BTA_AV_CONFIG_IND */
101 bta_av_disconnect_req, /* BTA_AV_DISCONNECT_REQ */
102 bta_av_security_req, /* BTA_AV_SECURITY_REQ */
103 bta_av_security_rsp, /* BTA_AV_SECURITY_RSP */
104 bta_av_setconfig_rsp, /* BTA_AV_SETCONFIG_RSP */
105 bta_av_st_rc_timer, /* BTA_AV_ST_RC_TIMER */
106 bta_av_str_opened, /* BTA_AV_STR_OPENED */
107 bta_av_security_ind, /* BTA_AV_SECURITY_IND */
108 bta_av_security_cfm, /* BTA_AV_SECURITY_CFM */
109 bta_av_do_close, /* BTA_AV_DO_CLOSE */
110 bta_av_connect_req, /* BTA_AV_CONNECT_REQ */
111 bta_av_sdp_failed, /* BTA_AV_SDP_FAILED */
112 bta_av_disc_results, /* BTA_AV_DISC_RESULTS */
113 bta_av_disc_res_as_acp, /* BTA_AV_DISC_RES_AS_ACP */
114 bta_av_open_failed, /* BTA_AV_OPEN_FAILED */
115 bta_av_getcap_results, /* BTA_AV_GETCAP_RESULTS */
116 bta_av_setconfig_rej, /* BTA_AV_SETCONFIG_REJ */
117 bta_av_discover_req, /* BTA_AV_DISCOVER_REQ */
118 bta_av_conn_failed, /* BTA_AV_CONN_FAILED */
119 bta_av_do_start, /* BTA_AV_DO_START */
120 bta_av_str_stopped, /* BTA_AV_STR_STOPPED */
121 bta_av_reconfig, /* BTA_AV_RECONFIG */
122 bta_av_data_path, /* BTA_AV_DATA_PATH */
123 bta_av_start_ok, /* BTA_AV_START_OK */
124 bta_av_start_failed, /* BTA_AV_START_FAILED */
125 bta_av_str_closed, /* BTA_AV_STR_CLOSED */
126 bta_av_clr_cong, /* BTA_AV_CLR_CONG */
127 bta_av_suspend_cfm, /* BTA_AV_SUSPEND_CFM */
128 bta_av_rcfg_str_ok, /* BTA_AV_RCFG_STR_OK */
129 bta_av_rcfg_failed, /* BTA_AV_RCFG_FAILED */
130 bta_av_rcfg_connect, /* BTA_AV_RCFG_CONNECT */
131 bta_av_rcfg_discntd, /* BTA_AV_RCFG_DISCNTD */
132 bta_av_suspend_cont, /* BTA_AV_SUSPEND_CONT */
133 bta_av_rcfg_cfm, /* BTA_AV_RCFG_CFM */
134 bta_av_rcfg_open, /* BTA_AV_RCFG_OPEN */
135 bta_av_security_rej, /* BTA_AV_SECURITY_REJ */
136 bta_av_open_rc, /* BTA_AV_OPEN_RC */
137 bta_av_chk_2nd_start, /* BTA_AV_CHK_2ND_START */
138 bta_av_save_caps, /* BTA_AV_SAVE_CAPS */
139 bta_av_set_use_rc, /* BTA_AV_SET_USE_RC */
140 bta_av_cco_close, /* BTA_AV_CCO_CLOSE */
141 bta_av_switch_role, /* BTA_AV_SWITCH_ROLE */
142 bta_av_role_res, /* BTA_AV_ROLE_RES */
143 bta_av_delay_co, /* BTA_AV_DELAY_CO */
144 bta_av_open_at_inc, /* BTA_AV_OPEN_AT_INC */
Abhijit Adsule47b43102015-05-19 02:44:26 -0500145 bta_av_offload_req, /* BTA_AV_OFFLOAD_REQ */
146 bta_av_offload_rsp, /* BTA_AV_OFFLOAD_RSP */
Myles Watsoncd1fd072016-11-09 13:17:43 -0800147 NULL};
The Android Open Source Project5738f832012-12-12 16:00:35 -0800148
149/* these tables translate AVDT events to SSM events */
Marie Janssene9e58ce2016-06-17 14:12:17 -0700150static const uint16_t bta_av_stream_evt_ok[] = {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800151 BTA_AV_STR_DISC_OK_EVT, /* AVDT_DISCOVER_CFM_EVT */
152 BTA_AV_STR_GETCAP_OK_EVT, /* AVDT_GETCAP_CFM_EVT */
153 BTA_AV_STR_OPEN_OK_EVT, /* AVDT_OPEN_CFM_EVT */
154 BTA_AV_STR_OPEN_OK_EVT, /* AVDT_OPEN_IND_EVT */
155 BTA_AV_STR_CONFIG_IND_EVT, /* AVDT_CONFIG_IND_EVT */
156 BTA_AV_STR_START_OK_EVT, /* AVDT_START_CFM_EVT */
157 BTA_AV_STR_START_OK_EVT, /* AVDT_START_IND_EVT */
158 BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_CFM_EVT */
159 BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_IND_EVT */
160 BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_CFM_EVT */
161 BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_IND_EVT */
162 BTA_AV_STR_RECONFIG_CFM_EVT, /* AVDT_RECONFIG_CFM_EVT */
163 0, /* AVDT_RECONFIG_IND_EVT */
164 BTA_AV_STR_SECURITY_CFM_EVT, /* AVDT_SECURITY_CFM_EVT */
165 BTA_AV_STR_SECURITY_IND_EVT, /* AVDT_SECURITY_IND_EVT */
166 BTA_AV_STR_WRITE_CFM_EVT, /* AVDT_WRITE_CFM_EVT */
167 BTA_AV_AVDT_CONNECT_EVT, /* AVDT_CONNECT_IND_EVT */
168 BTA_AV_AVDT_DISCONNECT_EVT, /* AVDT_DISCONNECT_IND_EVT */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800169#if (AVDT_REPORTING == TRUE)
Myles Watsoncd1fd072016-11-09 13:17:43 -0800170 BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_CONN_EVT */
171 BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_DISCONN_EVT */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800172#endif
Myles Watsoncd1fd072016-11-09 13:17:43 -0800173 BTA_AV_AVDT_DELAY_RPT_EVT, /* AVDT_DELAY_REPORT_EVT */
174 0 /* AVDT_DELAY_REPORT_CFM_EVT */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800175};
176
Marie Janssene9e58ce2016-06-17 14:12:17 -0700177static const uint16_t bta_av_stream_evt_fail[] = {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800178 BTA_AV_STR_DISC_FAIL_EVT, /* AVDT_DISCOVER_CFM_EVT */
179 BTA_AV_STR_GETCAP_FAIL_EVT, /* AVDT_GETCAP_CFM_EVT */
180 BTA_AV_STR_OPEN_FAIL_EVT, /* AVDT_OPEN_CFM_EVT */
181 BTA_AV_STR_OPEN_OK_EVT, /* AVDT_OPEN_IND_EVT */
182 BTA_AV_STR_CONFIG_IND_EVT, /* AVDT_CONFIG_IND_EVT */
183 BTA_AV_STR_START_FAIL_EVT, /* AVDT_START_CFM_EVT */
184 BTA_AV_STR_START_OK_EVT, /* AVDT_START_IND_EVT */
185 BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_CFM_EVT */
186 BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_IND_EVT */
187 BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_CFM_EVT */
188 BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_IND_EVT */
189 BTA_AV_STR_RECONFIG_CFM_EVT, /* AVDT_RECONFIG_CFM_EVT */
190 0, /* AVDT_RECONFIG_IND_EVT */
191 BTA_AV_STR_SECURITY_CFM_EVT, /* AVDT_SECURITY_CFM_EVT */
192 BTA_AV_STR_SECURITY_IND_EVT, /* AVDT_SECURITY_IND_EVT */
193 BTA_AV_STR_WRITE_CFM_EVT, /* AVDT_WRITE_CFM_EVT */
194 BTA_AV_AVDT_CONNECT_EVT, /* AVDT_CONNECT_IND_EVT */
195 BTA_AV_AVDT_DISCONNECT_EVT, /* AVDT_DISCONNECT_IND_EVT */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800196#if (AVDT_REPORTING == TRUE)
Myles Watsoncd1fd072016-11-09 13:17:43 -0800197 BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_CONN_EVT */
198 BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_DISCONN_EVT */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800199#endif
Myles Watsoncd1fd072016-11-09 13:17:43 -0800200 BTA_AV_AVDT_DELAY_RPT_EVT, /* AVDT_DELAY_REPORT_EVT */
201 0 /* AVDT_DELAY_REPORT_CFM_EVT */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800202};
203
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700204static void bta_av_stream0_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700205 uint8_t event, tAVDT_CTRL* p_data);
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700206static void bta_av_stream1_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700207 uint8_t event, tAVDT_CTRL* p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800208#if BTA_AV_NUM_STRS > 2
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700209static void bta_av_stream2_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700210 uint8_t event, tAVDT_CTRL* p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800211#endif
212#if BTA_AV_NUM_STRS > 3
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700213static void bta_av_stream3_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700214 uint8_t event, tAVDT_CTRL* p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800215#endif
216#if BTA_AV_NUM_STRS > 4
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700217static void bta_av_stream4_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700218 uint8_t event, tAVDT_CTRL* p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800219#endif
220#if BTA_AV_NUM_STRS > 5
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700221static void bta_av_stream5_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700222 uint8_t event, tAVDT_CTRL* p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800223#endif
Myles Watsoncd1fd072016-11-09 13:17:43 -0800224/* the array of callback functions to receive events from AVDT control channel
225 */
226tAVDT_CTRL_CBACK* const bta_av_dt_cback[] = {bta_av_stream0_cback,
227 bta_av_stream1_cback
The Android Open Source Project5738f832012-12-12 16:00:35 -0800228#if BTA_AV_NUM_STRS > 2
Myles Watsoncd1fd072016-11-09 13:17:43 -0800229 ,
230 bta_av_stream2_cback
The Android Open Source Project5738f832012-12-12 16:00:35 -0800231#endif
232#if BTA_AV_NUM_STRS > 3
Myles Watsoncd1fd072016-11-09 13:17:43 -0800233 ,
234 bta_av_stream3_cback
The Android Open Source Project5738f832012-12-12 16:00:35 -0800235#endif
236#if BTA_AV_NUM_STRS > 4
Myles Watsoncd1fd072016-11-09 13:17:43 -0800237 ,
238 bta_av_stream4_cback
The Android Open Source Project5738f832012-12-12 16:00:35 -0800239#endif
240#if BTA_AV_NUM_STRS > 5
Myles Watsoncd1fd072016-11-09 13:17:43 -0800241 ,
242 bta_av_stream5_cback
The Android Open Source Project5738f832012-12-12 16:00:35 -0800243#endif
244};
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530245/***********************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800246 *
247 * Function bta_get_scb_handle
248 *
249 * Description gives the registered AVDT handle.by checking with sep_type.
250 *
251 *
252 * Returns void
253 **********************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800254static uint8_t bta_av_get_scb_handle(tBTA_AV_SCB* p_scb, uint8_t local_sep) {
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -0800255 for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800256 if ((p_scb->seps[i].tsep == local_sep) &&
257 A2DP_CodecTypeEquals(p_scb->seps[i].codec_info,
258 p_scb->cfg.codec_info)) {
259 return (p_scb->seps[i].av_handle);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530260 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800261 }
262 APPL_TRACE_DEBUG("%s: local sep_type %d not found", __func__, local_sep)
263 return 0; /* return invalid handle */
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530264}
265
266/***********************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800267 *
268 * Function bta_av_get_scb_sep_type
269 *
270 * Description gives the sep type by cross-checking with AVDT handle
271 *
272 *
273 * Returns void
274 **********************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800275static uint8_t bta_av_get_scb_sep_type(tBTA_AV_SCB* p_scb,
276 uint8_t tavdt_handle) {
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -0800277 for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800278 if (p_scb->seps[i].av_handle == tavdt_handle) return (p_scb->seps[i].tsep);
279 }
280 APPL_TRACE_DEBUG("%s: handle %d not found", __func__, tavdt_handle)
281 return AVDT_TSEP_INVALID;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530282}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800283
284/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800285 *
286 * Function bta_av_save_addr
287 *
288 * Description copy the bd_addr and maybe reset the supported flags
289 *
290 *
291 * Returns void
292 *
293 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700294static void bta_av_save_addr(tBTA_AV_SCB* p_scb, const RawAddress& b) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800295 APPL_TRACE_DEBUG("%s: r:%d, s:%d", __func__, p_scb->recfg_sup,
296 p_scb->suspend_sup);
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700297 if (p_scb->peer_addr != b) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800298 APPL_TRACE_ERROR("%s: reset flags", __func__);
299 /* a new addr, reset the supported flags */
300 p_scb->recfg_sup = true;
301 p_scb->suspend_sup = true;
302 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800303
Myles Watsoncd1fd072016-11-09 13:17:43 -0800304 /* do this copy anyway, just in case the first addr matches
305 * the control block one by accident */
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700306 p_scb->peer_addr = b;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800307}
308
309/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800310 *
311 * Function notify_start_failed
312 *
313 * Description notify up-layer AV start failed
314 *
315 *
316 * Returns void
317 *
318 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800319static void notify_start_failed(tBTA_AV_SCB* p_scb) {
320 tBTA_AV_START start;
321 /* if start failed, clear role */
322 p_scb->role &= ~BTA_AV_ROLE_START_INT;
323 start.chnl = p_scb->chnl;
324 start.status = BTA_AV_FAIL;
325 start.initiator = true;
326 start.hndl = p_scb->hndl;
327 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
Zhihai Xu379743b2013-09-29 13:42:13 -0700328}
329
330/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800331 *
332 * Function bta_av_st_rc_timer
333 *
334 * Description start the AVRC timer if no RC connection & CT is supported &
335 * RC is used or
336 * as ACP (we do not really know if we want AVRC)
337 *
338 * Returns void
339 *
340 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800341static void bta_av_st_rc_timer(tBTA_AV_SCB* p_scb,
342 UNUSED_ATTR tBTA_AV_DATA* p_data) {
343 APPL_TRACE_DEBUG("%s: rc_handle:%d, use_rc: %d", __func__, p_scb->rc_handle,
344 p_scb->use_rc);
345 /* for outgoing RC connection as INT/CT */
346 if ((p_scb->rc_handle == BTA_AV_RC_HANDLE_NONE) &&
347 /* (bta_av_cb.features & BTA_AV_FEAT_RCCT) && */
348 (p_scb->use_rc == true || (p_scb->role & BTA_AV_ROLE_AD_ACP))) {
349 if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) == 0) {
350 bta_sys_start_timer(p_scb->avrc_ct_timer, BTA_AV_RC_DISC_TIME_VAL,
351 BTA_AV_AVRC_TIMER_EVT, p_scb->hndl);
352 } else {
353 p_scb->wait |= BTA_AV_WAIT_CHECK_RC;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800354 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800355 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800356}
357
358/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800359 *
360 * Function bta_av_next_getcap
361 *
362 * Description The function gets the capabilities of the next available
363 * stream found in the discovery results.
364 *
365 * Returns true if we sent request to AVDT, false otherwise.
366 *
367 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800368static bool bta_av_next_getcap(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
369 int i;
370 tAVDT_GETCAP_REQ* p_req;
371 bool sent_cmd = false;
372 uint16_t uuid_int = p_scb->uuid_int;
373 uint8_t sep_requested = 0;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530374
Myles Watsoncd1fd072016-11-09 13:17:43 -0800375 if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
376 sep_requested = AVDT_TSEP_SNK;
377 else if (uuid_int == UUID_SERVCLASS_AUDIO_SINK)
378 sep_requested = AVDT_TSEP_SRC;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800379
Myles Watsoncd1fd072016-11-09 13:17:43 -0800380 for (i = p_scb->sep_info_idx; i < p_scb->num_seps; i++) {
381 /* steam not in use, is a sink, and is the right media type (audio/video) */
382 if ((p_scb->sep_info[i].in_use == false) &&
383 (p_scb->sep_info[i].tsep == sep_requested) &&
384 (p_scb->sep_info[i].media_type == p_scb->media_type)) {
385 p_scb->sep_info_idx = i;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800386
Myles Watsoncd1fd072016-11-09 13:17:43 -0800387 /* we got a stream; get its capabilities */
388 if (p_scb->p_cap == NULL)
389 p_scb->p_cap = (tAVDT_CFG*)osi_malloc(sizeof(tAVDT_CFG));
390 if (p_scb->avdt_version >= AVDT_VERSION_SYNC) {
391 p_req = AVDT_GetAllCapReq;
392 } else {
393 p_req = AVDT_GetCapReq;
394 }
395 (*p_req)(p_scb->peer_addr, p_scb->sep_info[i].seid, p_scb->p_cap,
396 bta_av_dt_cback[p_scb->hdi]);
397 sent_cmd = true;
398 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800399 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800400 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800401
Myles Watsoncd1fd072016-11-09 13:17:43 -0800402 /* if no streams available then stream open fails */
403 if (!sent_cmd) {
404 bta_av_ssm_execute(p_scb, BTA_AV_STR_GETCAP_FAIL_EVT, p_data);
405 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800406
Myles Watsoncd1fd072016-11-09 13:17:43 -0800407 return sent_cmd;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800408}
409
410/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800411 *
412 * Function bta_av_proc_stream_evt
413 *
414 * Description Utility function to compose stream events.
415 *
416 * Returns void
417 *
418 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700419static void bta_av_proc_stream_evt(uint8_t handle, const RawAddress* bd_addr,
Myles Watsoncd1fd072016-11-09 13:17:43 -0800420 uint8_t event, tAVDT_CTRL* p_data,
421 int index) {
422 uint16_t sec_len = 0;
423 tBTA_AV_SCB* p_scb = bta_av_cb.p_scb[index];
The Android Open Source Project5738f832012-12-12 16:00:35 -0800424
Myles Watsoncd1fd072016-11-09 13:17:43 -0800425 if (p_data) {
426 if (event == AVDT_SECURITY_IND_EVT) {
427 sec_len = (p_data->security_ind.len < BTA_AV_SECURITY_MAX_LEN)
428 ? p_data->security_ind.len
429 : BTA_AV_SECURITY_MAX_LEN;
430 } else if (event == AVDT_SECURITY_CFM_EVT && p_data->hdr.err_code == 0) {
431 sec_len = (p_data->security_cfm.len < BTA_AV_SECURITY_MAX_LEN)
432 ? p_data->security_cfm.len
433 : BTA_AV_SECURITY_MAX_LEN;
434 }
435 }
436
437 if (p_scb) {
438 tBTA_AV_STR_MSG* p_msg =
439 (tBTA_AV_STR_MSG*)osi_malloc(sizeof(tBTA_AV_STR_MSG) + sec_len);
440
441 /* copy event data, bd addr, and handle to event message buffer */
442 p_msg->hdr.offset = 0;
443
444 if (bd_addr != NULL) {
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700445 p_msg->bd_addr = *bd_addr;
446 VLOG(1) << __func__ << ": bd_addr:" << bd_addr;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800447 }
448
Myles Watsoncd1fd072016-11-09 13:17:43 -0800449 if (p_data != NULL) {
450 memcpy(&p_msg->msg, p_data, sizeof(tAVDT_CTRL));
451 /* copy config params to event message buffer */
452 switch (event) {
453 case AVDT_RECONFIG_CFM_EVT:
Pavlin Radoslavove49ed4b2016-11-28 14:32:40 -0800454 if (p_msg->msg.hdr.err_code == 0) {
455 APPL_TRACE_DEBUG(
Myles Watson911d1ae2016-11-28 16:44:40 -0800456 "%s: reconfig cfm event codec info = 0x%06x-%06x-%06x-%02x",
457 __func__,
458 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[0] << 16) +
459 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[1] << 8) +
460 p_msg->msg.reconfig_cfm.p_cfg->codec_info[2],
461 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[3] << 16) +
462 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[4] << 8) +
463 p_msg->msg.reconfig_cfm.p_cfg->codec_info[5],
464 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[6] << 16) +
465 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[7] << 8) +
466 p_msg->msg.reconfig_cfm.p_cfg->codec_info[8],
467 p_msg->msg.reconfig_cfm.p_cfg->codec_info[9]);
Pavlin Radoslavove49ed4b2016-11-28 14:32:40 -0800468 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800469 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800470
Myles Watsoncd1fd072016-11-09 13:17:43 -0800471 case AVDT_CONFIG_IND_EVT:
472 /* We might have 2 SEP signallings(A2DP + VDP) with one peer device on
473 * one L2CAP.
474 * If we already have a signalling connection with the bd_addr and the
475 * streaming
476 * SST is at INIT state, change it to INCOMING state to handle the
477 * signalling
478 * from the 2nd SEP. */
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700479 if ((bta_av_find_lcb(*bd_addr, BTA_AV_LCB_FIND) != NULL) &&
Myles Watsoncd1fd072016-11-09 13:17:43 -0800480 (bta_av_is_scb_init(p_scb))) {
481 bta_av_set_scb_sst_incoming(p_scb);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800482
Myles Watsoncd1fd072016-11-09 13:17:43 -0800483 /* When ACP_CONNECT_EVT was received, we put first available scb to
484 * incoming state.
485 * Later when we receive AVDT_CONFIG_IND_EVT, we use a new p_scb and
486 * set its state to
487 * incoming which we do it above.
488 * We also have to set the old p_scb state to init to be used later
489 */
490 for (int i = 0; i < BTA_AV_NUM_STRS; i++) {
491 if ((bta_av_cb.p_scb[i]) && (i != index)) {
492 if (bta_av_cb.p_scb[i]->state == BTA_AV_INCOMING_SST) {
493 bta_av_cb.p_scb[i]->state = BTA_AV_INIT_SST;
494 bta_av_cb.p_scb[i]->coll_mask = 0;
495 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800496 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800497 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800498 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800499 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800500
Myles Watsoncd1fd072016-11-09 13:17:43 -0800501 memcpy(&p_msg->cfg, p_data->config_ind.p_cfg, sizeof(tAVDT_CFG));
502 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800503
Myles Watsoncd1fd072016-11-09 13:17:43 -0800504 case AVDT_SECURITY_IND_EVT:
505 p_msg->msg.security_ind.p_data = (uint8_t*)(p_msg + 1);
506 memcpy(p_msg->msg.security_ind.p_data, p_data->security_ind.p_data,
507 sec_len);
508 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800509
Myles Watsoncd1fd072016-11-09 13:17:43 -0800510 case AVDT_SECURITY_CFM_EVT:
511 p_msg->msg.security_cfm.p_data = (uint8_t*)(p_msg + 1);
512 if (p_data->hdr.err_code == 0) {
513 memcpy(p_msg->msg.security_cfm.p_data, p_data->security_cfm.p_data,
514 sec_len);
515 }
516 break;
Tsuyoshi Kamata24940c32015-03-04 12:09:26 +0900517
Myles Watsoncd1fd072016-11-09 13:17:43 -0800518 case AVDT_SUSPEND_IND_EVT:
519 p_msg->msg.hdr.err_code = 0;
520 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800521
Myles Watsoncd1fd072016-11-09 13:17:43 -0800522 case AVDT_CONNECT_IND_EVT:
523 p_scb->recfg_sup = true;
524 p_scb->suspend_sup = true;
525 break;
Tsuyoshi Kamata24940c32015-03-04 12:09:26 +0900526
Myles Watsoncd1fd072016-11-09 13:17:43 -0800527 default:
528 break;
529 }
530 } else
531 p_msg->msg.hdr.err_code = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800532
Myles Watsoncd1fd072016-11-09 13:17:43 -0800533 /* look up application event */
534 if ((p_data == NULL) || (p_data->hdr.err_code == 0)) {
535 p_msg->hdr.event = bta_av_stream_evt_ok[event];
536 } else {
537 p_msg->hdr.event = bta_av_stream_evt_fail[event];
The Android Open Source Project5738f832012-12-12 16:00:35 -0800538 }
539
Myles Watsoncd1fd072016-11-09 13:17:43 -0800540 p_msg->initiator = false;
541 if (event == AVDT_SUSPEND_CFM_EVT) p_msg->initiator = true;
542
543 APPL_TRACE_VERBOSE("%s: hndl:x%x", __func__, p_scb->hndl);
544 p_msg->hdr.layer_specific = p_scb->hndl;
545 p_msg->handle = handle;
546 p_msg->avdt_event = event;
547 bta_sys_sendmsg(p_msg);
548 }
549
Myles Watsoncd1fd072016-11-09 13:17:43 -0800550 if (p_data) {
551 bta_av_conn_cback(handle, bd_addr, event, p_data);
552 } else {
553 APPL_TRACE_ERROR("%s: p_data is null", __func__);
554 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800555}
556
557/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800558 *
559 * Function bta_av_sink_data_cback
560 *
561 * Description This is the AVDTP callback function for sink stream events.
562 *
563 * Returns void
564 *
565 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800566void bta_av_sink_data_cback(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp,
567 uint8_t m_pt) {
568 int index = 0;
569 tBTA_AV_SCB* p_scb;
570 APPL_TRACE_DEBUG(
571 "%s: avdt_handle: %d pkt_len=0x%x offset = 0x%x "
572 "number of frames 0x%x sequence number 0x%x",
573 __func__, handle, p_pkt->len, p_pkt->offset,
574 *((uint8_t*)(p_pkt + 1) + p_pkt->offset), p_pkt->layer_specific);
575 /* Get SCB and correct sep type */
576 for (index = 0; index < BTA_AV_NUM_STRS; index++) {
577 p_scb = bta_av_cb.p_scb[index];
578 if ((p_scb->avdt_handle == handle) &&
579 (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)) {
580 break;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530581 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800582 }
583 if (index == BTA_AV_NUM_STRS) {
584 /* cannot find correct handler */
Pavlin Radoslavov7aaf7c62016-08-23 12:24:03 -0700585 osi_free(p_pkt);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800586 return;
587 }
588 p_pkt->event = BTA_AV_SINK_MEDIA_DATA_EVT;
589 p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(BTA_AV_SINK_MEDIA_DATA_EVT,
590 (tBTA_AV_MEDIA*)p_pkt);
591 /* Free the buffer: a copy of the packet has been delivered */
592 osi_free(p_pkt);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530593}
594
595/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800596 *
597 * Function bta_av_stream0_cback
598 *
599 * Description This is the AVDTP callback function for stream events.
600 *
601 * Returns void
602 *
603 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700604static void bta_av_stream0_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700605 uint8_t event, tAVDT_CTRL* p_data) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800606 APPL_TRACE_VERBOSE("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
607 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 0);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800608}
609
610/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800611 *
612 * Function bta_av_stream1_cback
613 *
614 * Description This is the AVDTP callback function for stream events.
615 *
616 * Returns void
617 *
618 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700619static void bta_av_stream1_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700620 uint8_t event, tAVDT_CTRL* p_data) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800621 APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
622 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 1);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800623}
624
625#if BTA_AV_NUM_STRS > 2
626/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800627 *
628 * Function bta_av_stream2_cback
629 *
630 * Description This is the AVDTP callback function for stream events.
631 *
632 * Returns void
633 *
634 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700635static void bta_av_stream2_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700636 uint8_t event, tAVDT_CTRL* p_data) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800637 APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
638 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 2);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800639}
640#endif
641
642#if BTA_AV_NUM_STRS > 3
643/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800644 *
645 * Function bta_av_stream3_cback
646 *
647 * Description This is the AVDTP callback function for stream events.
648 *
649 * Returns void
650 *
651 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700652static void bta_av_stream3_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700653 uint8_t event, tAVDT_CTRL* p_data) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800654 APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
655 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 3);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800656}
657#endif
658
659/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800660 *
661 * Function bta_av_stream4_cback
662 *
663 * Description This is the AVDTP callback function for stream events.
664 *
665 * Returns void
666 *
667 ******************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -0800668#if BTA_AV_NUM_STRS > 4
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700669static void bta_av_stream4_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700670 uint8_t event, tAVDT_CTRL* p_data) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800671 APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
672 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 4);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800673}
674#endif
675
676/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800677 *
678 * Function bta_av_stream5_cback
679 *
680 * Description This is the AVDTP callback function for stream events.
681 *
682 * Returns void
683 *
684 ******************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -0800685#if BTA_AV_NUM_STRS > 5
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700686static void bta_av_stream5_cback(uint8_t handle, const RawAddress* bd_addr,
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700687 uint8_t event, tAVDT_CTRL* p_data) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800688 APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
689 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 5);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800690}
691#endif
692
693/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800694 *
695 * Function bta_av_a2dp_sdp_cback
696 *
697 * Description A2DP service discovery callback.
698 *
699 * Returns void
700 *
701 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800702static void bta_av_a2dp_sdp_cback(bool found, tA2DP_Service* p_service) {
703 tBTA_AV_SCB* p_scb = bta_av_hndl_to_scb(bta_av_cb.handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800704
Myles Watsoncd1fd072016-11-09 13:17:43 -0800705 if (p_scb == NULL) {
706 APPL_TRACE_ERROR("%s: no scb found for handle(0x%x)", __func__,
707 bta_av_cb.handle);
708 return;
709 }
Pavlin Radoslavov717a4a92016-02-06 08:36:06 -0800710
Myles Watsoncd1fd072016-11-09 13:17:43 -0800711 tBTA_AV_SDP_RES* p_msg =
712 (tBTA_AV_SDP_RES*)osi_malloc(sizeof(tBTA_AV_SDP_RES));
713 p_msg->hdr.event =
714 (found) ? BTA_AV_SDP_DISC_OK_EVT : BTA_AV_SDP_DISC_FAIL_EVT;
715 if (found && (p_service != NULL))
716 p_scb->avdt_version = p_service->avdt_version;
717 else
718 p_scb->avdt_version = 0x00;
719 p_msg->hdr.layer_specific = bta_av_cb.handle;
Pavlin Radoslavov717a4a92016-02-06 08:36:06 -0800720
Myles Watsoncd1fd072016-11-09 13:17:43 -0800721 bta_sys_sendmsg(p_msg);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800722}
723
724/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800725 *
726 * Function bta_av_adjust_seps_idx
727 *
728 * Description adjust the sep_idx
729 *
730 * Returns
731 *
732 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800733static void bta_av_adjust_seps_idx(tBTA_AV_SCB* p_scb, uint8_t avdt_handle) {
734 APPL_TRACE_DEBUG("%s: codec: %s", __func__,
735 A2DP_CodecName(p_scb->cfg.codec_info));
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -0800736 for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800737 APPL_TRACE_DEBUG("%s: av_handle: %d codec: %s", __func__,
738 p_scb->seps[i].av_handle,
739 A2DP_CodecName(p_scb->seps[i].codec_info));
740 if (p_scb->seps[i].av_handle && (p_scb->seps[i].av_handle == avdt_handle) &&
741 A2DP_CodecTypeEquals(p_scb->seps[i].codec_info,
742 p_scb->cfg.codec_info)) {
743 p_scb->sep_idx = i;
744 p_scb->avdt_handle = p_scb->seps[i].av_handle;
745 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800746 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800747 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800748}
749
750/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800751 *
752 * Function bta_av_switch_role
753 *
754 * Description Switch role was not started and a timer was started.
755 * another attempt to switch role now - still opening.
756 *
757 * Returns void
758 *
759 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800760void bta_av_switch_role(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
761 tBTA_AV_RS_RES switch_res = BTA_AV_RS_NONE;
762 tBTA_AV_API_OPEN* p_buf = &p_scb->q_info.open;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800763
Myles Watsoncd1fd072016-11-09 13:17:43 -0800764 APPL_TRACE_DEBUG("%s: wait:x%x", __func__, p_scb->wait);
765 if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_START)
766 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RETRY;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800767
Myles Watsoncd1fd072016-11-09 13:17:43 -0800768 /* clear the masks set when the timer is started */
769 p_scb->wait &=
770 ~(BTA_AV_WAIT_ROLE_SW_RES_OPEN | BTA_AV_WAIT_ROLE_SW_RES_START);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800771
Myles Watsoncd1fd072016-11-09 13:17:43 -0800772 if (p_scb->q_tag == BTA_AV_Q_TAG_OPEN) {
773 if (bta_av_switch_if_needed(p_scb) ||
774 !bta_av_link_role_ok(p_scb, A2DP_SET_MULTL_BIT)) {
775 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_OPEN;
776 } else {
777 /* this should not happen in theory. Just in case...
778 * continue to do_disc_a2dp */
779 switch_res = BTA_AV_RS_DONE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800780 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800781 } else {
782 /* report failure on OPEN */
783 switch_res = BTA_AV_RS_FAIL;
784 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800785
Myles Watsoncd1fd072016-11-09 13:17:43 -0800786 if (switch_res != BTA_AV_RS_NONE) {
787 if (bta_av_cb.rs_idx == (p_scb->hdi + 1)) {
788 bta_av_cb.rs_idx = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800789 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800790 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_RETRY;
791 p_scb->q_tag = 0;
792 p_buf->switch_res = switch_res;
793 bta_av_do_disc_a2dp(p_scb, (tBTA_AV_DATA*)p_buf);
794 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800795}
796
797/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800798 *
799 * Function bta_av_role_res
800 *
801 * Description Handle the role changed event
802 *
803 *
804 * Returns void
805 *
806 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800807void bta_av_role_res(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
808 bool initiator = false;
809 tBTA_AV_START start;
810 tBTA_AV_OPEN av_open;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800811
Myles Watsoncd1fd072016-11-09 13:17:43 -0800812 APPL_TRACE_DEBUG("%s: q_tag:%d, wait:x%x, role:x%x", __func__, p_scb->q_tag,
813 p_scb->wait, p_scb->role);
814 if (p_scb->role & BTA_AV_ROLE_START_INT) initiator = true;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800815
Myles Watsoncd1fd072016-11-09 13:17:43 -0800816 if (p_scb->q_tag == BTA_AV_Q_TAG_START) {
817 if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_STARTED) {
818 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
819 if (p_data->role_res.hci_status != HCI_SUCCESS) {
820 p_scb->role &= ~BTA_AV_ROLE_START_INT;
Jakub Pawlowskic752e132017-06-16 12:52:23 -0700821 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800822 /* start failed because of role switch. */
823 start.chnl = p_scb->chnl;
824 start.status = BTA_AV_FAIL_ROLE;
825 start.hndl = p_scb->hndl;
826 start.initiator = initiator;
827 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
828 } else {
829 bta_av_start_ok(p_scb, p_data);
830 }
831 } else if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_START)
832 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_FAILED;
833 } else if (p_scb->q_tag == BTA_AV_Q_TAG_OPEN) {
834 if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_OPEN) {
835 p_scb->role &= ~BTA_AV_ROLE_START_INT;
836 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
837
838 if (p_data->role_res.hci_status != HCI_SUCCESS) {
839 /* Open failed because of role switch. */
Jakub Pawlowski903c1662017-06-13 17:53:54 -0700840 av_open.bd_addr = p_scb->peer_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -0800841 av_open.chnl = p_scb->chnl;
842 av_open.hndl = p_scb->hndl;
843 start.status = BTA_AV_FAIL_ROLE;
844 if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC)
845 av_open.sep = AVDT_TSEP_SNK;
846 else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)
847 av_open.sep = AVDT_TSEP_SRC;
848 (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV*)&av_open);
849 } else {
850 /* Continue av open process */
851 p_scb->q_info.open.switch_res = BTA_AV_RS_DONE;
852 bta_av_do_disc_a2dp(p_scb, (tBTA_AV_DATA*)&(p_scb->q_info.open));
853 }
854 } else {
855 APPL_TRACE_WARNING(
856 "%s: unexpected role switch event: q_tag = %d wait = %d", __func__,
857 p_scb->q_tag, p_scb->wait);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800858 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800859 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800860
Myles Watsoncd1fd072016-11-09 13:17:43 -0800861 APPL_TRACE_DEBUG("%s: wait:x%x, role:x%x", __func__, p_scb->wait,
862 p_scb->role);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800863}
864
865/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800866 *
867 * Function bta_av_delay_co
868 *
869 * Description Call the delay call-out function to report the delay report
870 * from SNK
871 *
872 * Returns void
873 *
874 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800875void bta_av_delay_co(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
876 p_scb->p_cos->delay(p_scb->hndl, p_data->str_msg.msg.delay_rpt_cmd.delay);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800877}
878
879/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800880 *
881 * Function bta_av_do_disc_a2dp
882 *
883 * Description Do service discovery for A2DP.
884 *
885 * Returns void
886 *
887 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800888void bta_av_do_disc_a2dp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
889 bool ok_continue = false;
890 tA2DP_SDP_DB_PARAMS db_params;
891 uint16_t attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
892 ATTR_ID_PROTOCOL_DESC_LIST,
893 ATTR_ID_BT_PROFILE_DESC_LIST};
894 uint16_t sdp_uuid = 0; /* UUID for which SDP has to be done */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800895
Myles Watsoncd1fd072016-11-09 13:17:43 -0800896 APPL_TRACE_DEBUG("%s: use_rc: %d rs:%d, oc:%d", __func__,
897 p_data->api_open.use_rc, p_data->api_open.switch_res,
898 bta_av_cb.audio_open_cnt);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800899
Myles Watsoncd1fd072016-11-09 13:17:43 -0800900 memcpy(&(p_scb->open_api), &(p_data->api_open), sizeof(tBTA_AV_API_OPEN));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800901
Myles Watsoncd1fd072016-11-09 13:17:43 -0800902 switch (p_data->api_open.switch_res) {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800903 case BTA_AV_RS_NONE:
Myles Watsoncd1fd072016-11-09 13:17:43 -0800904 if (bta_av_switch_if_needed(p_scb) ||
905 !bta_av_link_role_ok(p_scb, A2DP_SET_MULTL_BIT)) {
906 /* waiting for role switch result. save the api to control block */
907 memcpy(&p_scb->q_info.open, &p_data->api_open,
908 sizeof(tBTA_AV_API_OPEN));
909 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_OPEN;
910 p_scb->q_tag = BTA_AV_Q_TAG_OPEN;
911 } else {
912 ok_continue = true;
913 }
914 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800915
916 case BTA_AV_RS_FAIL:
Myles Watsoncd1fd072016-11-09 13:17:43 -0800917 /* report a new failure event */
918 p_scb->open_status = BTA_AV_FAIL_ROLE;
919 bta_av_ssm_execute(p_scb, BTA_AV_SDP_DISC_FAIL_EVT, NULL);
920 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800921
922 case BTA_AV_RS_OK:
Myles Watsoncd1fd072016-11-09 13:17:43 -0800923 p_data = (tBTA_AV_DATA*)&p_scb->q_info.open;
924 /* continue to open if link role is ok */
925 if (bta_av_link_role_ok(p_scb, A2DP_SET_MULTL_BIT)) {
926 ok_continue = true;
927 } else {
928 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_OPEN;
929 }
930 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800931
932 case BTA_AV_RS_DONE:
Myles Watsoncd1fd072016-11-09 13:17:43 -0800933 ok_continue = true;
934 break;
935 }
936
937 APPL_TRACE_DEBUG("%s: ok_continue: %d wait:x%x, q_tag: %d", __func__,
938 ok_continue, p_scb->wait, p_scb->q_tag);
939 if (!ok_continue) return;
940
941 /* clear the role switch bits */
942 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
943
944 if (p_scb->wait & BTA_AV_WAIT_CHECK_RC) {
945 p_scb->wait &= ~BTA_AV_WAIT_CHECK_RC;
946 bta_sys_start_timer(p_scb->avrc_ct_timer, BTA_AV_RC_DISC_TIME_VAL,
947 BTA_AV_AVRC_TIMER_EVT, p_scb->hndl);
948 }
949
950 if (bta_av_cb.features & BTA_AV_FEAT_MASTER) {
951 L2CA_SetDesireRole(L2CAP_ROLE_DISALLOW_SWITCH);
952
953 if (bta_av_cb.audio_open_cnt == 1) {
954 /* there's already an A2DP connection. do not allow switch */
955 bta_sys_clear_default_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800956 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800957 }
958 /* store peer addr other parameters */
959 bta_av_save_addr(p_scb, p_data->api_open.bd_addr);
960 p_scb->sec_mask = p_data->api_open.sec_mask;
961 p_scb->use_rc = p_data->api_open.use_rc;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800962
Jakub Pawlowskic752e132017-06-16 12:52:23 -0700963 bta_sys_app_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800964
Myles Watsoncd1fd072016-11-09 13:17:43 -0800965 if (p_scb->skip_sdp == true) {
966 tA2DP_Service a2dp_ser;
967 a2dp_ser.avdt_version = AVDT_VERSION;
968 p_scb->skip_sdp = false;
969 p_scb->uuid_int = p_data->api_open.uuid;
Pavlin Radoslavovf66f4e92016-10-14 15:14:37 -0700970 /* only one A2DP find service is active at a time */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800971 bta_av_cb.handle = p_scb->hndl;
Myles Watsoncd1fd072016-11-09 13:17:43 -0800972 APPL_TRACE_WARNING("%s: Skip Sdp for incoming A2dp connection", __func__);
973 bta_av_a2dp_sdp_cback(true, &a2dp_ser);
974 return;
975 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800976
Myles Watsoncd1fd072016-11-09 13:17:43 -0800977 /* only one A2DP find service is active at a time */
978 bta_av_cb.handle = p_scb->hndl;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800979
Myles Watsoncd1fd072016-11-09 13:17:43 -0800980 /* set up parameters */
981 db_params.db_len = BTA_AV_DISC_BUF_SIZE;
982 db_params.num_attr = 3;
983 db_params.p_attrs = attr_list;
984 p_scb->uuid_int = p_data->api_open.uuid;
985 p_scb->sdp_discovery_started = true;
986 if (p_scb->uuid_int == UUID_SERVCLASS_AUDIO_SINK)
987 sdp_uuid = UUID_SERVCLASS_AUDIO_SOURCE;
988 else if (p_scb->uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
989 sdp_uuid = UUID_SERVCLASS_AUDIO_SINK;
Ayan Ghoshc90c0d42014-12-11 17:56:02 +0530990
Myles Watsoncd1fd072016-11-09 13:17:43 -0800991 APPL_TRACE_DEBUG("%s: uuid_int 0x%x, Doing SDP For 0x%x", __func__,
992 p_scb->uuid_int, sdp_uuid);
Jakub Pawlowski135b7f62017-06-16 10:00:46 -0700993 if (A2DP_FindService(sdp_uuid, p_scb->peer_addr, &db_params,
Myles Watsoncd1fd072016-11-09 13:17:43 -0800994 bta_av_a2dp_sdp_cback) == A2DP_SUCCESS)
995 return;
996
997 /* when the code reaches here, either the DB is NULL
998 * or A2DP_FindService is not successful */
999 bta_av_a2dp_sdp_cback(false, NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001000}
1001
1002/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001003 *
1004 * Function bta_av_cleanup
1005 *
1006 * Description cleanup AV stream control block.
1007 *
1008 * Returns void
1009 *
1010 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001011void bta_av_cleanup(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
1012 tBTA_AV_CONN_CHG msg;
1013 uint8_t role = BTA_AV_ROLE_AD_INT;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001014
Myles Watsoncd1fd072016-11-09 13:17:43 -08001015 APPL_TRACE_DEBUG("%s", __func__);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001016
Myles Watsoncd1fd072016-11-09 13:17:43 -08001017 /* free any buffers */
1018 osi_free_and_reset((void**)&p_scb->p_cap);
1019 p_scb->sdp_discovery_started = false;
1020 p_scb->avdt_version = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001021
Myles Watsoncd1fd072016-11-09 13:17:43 -08001022 /* initialize some control block variables */
1023 p_scb->open_status = BTA_AV_SUCCESS;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001024
Myles Watsoncd1fd072016-11-09 13:17:43 -08001025 /* if de-registering shut everything down */
1026 msg.hdr.layer_specific = p_scb->hndl;
1027 p_scb->started = false;
Pavlin Radoslavov3b8391c2017-05-12 01:16:10 -07001028 p_scb->current_codec = nullptr;
Myles Watsoncd1fd072016-11-09 13:17:43 -08001029 p_scb->cong = false;
1030 p_scb->role = role;
1031 p_scb->cur_psc_mask = 0;
1032 p_scb->wait = 0;
1033 p_scb->num_disc_snks = 0;
1034 alarm_cancel(p_scb->avrc_ct_timer);
Abhijit Adsule47b43102015-05-19 02:44:26 -05001035
Andre Eisenbach796523d2016-11-10 16:11:00 -08001036 /* TODO(eisenbach): RE-IMPLEMENT USING VSC OR HAL EXTENSION
1037 vendor_get_interface()->send_command(
1038 (vendor_opcode_t)BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
1039 if (p_scb->offload_start_pending) {
1040 tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
1041 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
1042 }
1043 */
1044
Myles Watsoncd1fd072016-11-09 13:17:43 -08001045 p_scb->offload_start_pending = false;
1046
1047 p_scb->skip_sdp = false;
1048 if (p_scb->deregistring) {
1049 /* remove stream */
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08001050 for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
Myles Watsoncd1fd072016-11-09 13:17:43 -08001051 if (p_scb->seps[i].av_handle) AVDT_RemoveStream(p_scb->seps[i].av_handle);
1052 p_scb->seps[i].av_handle = 0;
Abhijit Adsule47b43102015-05-19 02:44:26 -05001053 }
Abhijit Adsule47b43102015-05-19 02:44:26 -05001054
Myles Watsoncd1fd072016-11-09 13:17:43 -08001055 bta_av_dereg_comp((tBTA_AV_DATA*)&msg);
1056 } else {
1057 /* report stream closed to main SM */
1058 msg.is_up = false;
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001059 msg.peer_addr = p_scb->peer_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -08001060 bta_av_conn_chg((tBTA_AV_DATA*)&msg);
1061 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001062}
1063
1064/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001065 *
1066 * Function bta_av_free_sdb
1067 *
1068 * Description Free service discovery db buffer.
1069 *
1070 * Returns void
1071 *
1072 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001073void bta_av_free_sdb(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
1074 p_scb->sdp_discovery_started = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001075}
1076
1077/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001078 *
1079 * Function bta_av_config_ind
1080 *
1081 * Description Handle a stream configuration indication from the peer.
1082 *
1083 * Returns void
1084 *
1085 ******************************************************************************/
Pavlin Radoslavovcd02ce92016-11-04 17:18:51 -07001086void bta_av_config_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
Myles Watsoncd1fd072016-11-09 13:17:43 -08001087 tBTA_AV_CI_SETCONFIG setconfig;
1088 tAVDT_SEP_INFO* p_info;
1089 tAVDT_CFG* p_evt_cfg = &p_data->str_msg.cfg;
1090 uint8_t psc_mask = (p_evt_cfg->psc_mask | p_scb->cfg.psc_mask);
1091 uint8_t
1092 local_sep; /* sep type of local handle on which connection was received */
1093 tBTA_AV_STR_MSG* p_msg = (tBTA_AV_STR_MSG*)p_data;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001094
Myles Watsoncd1fd072016-11-09 13:17:43 -08001095 local_sep = bta_av_get_scb_sep_type(p_scb, p_msg->handle);
1096 p_scb->avdt_label = p_data->str_msg.msg.hdr.label;
1097 memcpy(p_scb->cfg.codec_info, p_evt_cfg->codec_info, AVDT_CODEC_SIZE);
1098 bta_av_save_addr(p_scb, p_data->str_msg.bd_addr);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001099
Myles Watsoncd1fd072016-11-09 13:17:43 -08001100 /* Clear collision mask */
1101 p_scb->coll_mask = 0;
1102 alarm_cancel(bta_av_cb.accept_signalling_timer);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001103
Myles Watsoncd1fd072016-11-09 13:17:43 -08001104 /* if no codec parameters in configuration, fail */
1105 if ((p_evt_cfg->num_codec == 0) ||
1106 /* or the peer requests for a service we do not support */
1107 ((psc_mask != p_scb->cfg.psc_mask) &&
1108 (psc_mask != (p_scb->cfg.psc_mask & ~AVDT_PSC_DELAY_RPT)))) {
1109 setconfig.hndl = p_scb->hndl; /* we may not need this */
1110 setconfig.err_code = AVDT_ERR_UNSUP_CFG;
1111 bta_av_ssm_execute(p_scb, BTA_AV_CI_SETCONFIG_FAIL_EVT,
1112 (tBTA_AV_DATA*)&setconfig);
1113 } else {
1114 p_info = &p_scb->sep_info[0];
1115 p_info->in_use = 0;
1116 p_info->media_type = p_scb->media_type;
1117 p_info->seid = p_data->str_msg.msg.config_ind.int_seid;
1118
1119 /* Sep type of Peer will be oppsite role to our local sep */
1120 if (local_sep == AVDT_TSEP_SRC)
1121 p_info->tsep = AVDT_TSEP_SNK;
1122 else if (local_sep == AVDT_TSEP_SNK)
1123 p_info->tsep = AVDT_TSEP_SRC;
1124
1125 p_scb->role |= BTA_AV_ROLE_AD_ACP;
1126 p_scb->cur_psc_mask = p_evt_cfg->psc_mask;
1127 if (bta_av_cb.features & BTA_AV_FEAT_RCTG)
1128 p_scb->use_rc = true;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001129 else
Myles Watsoncd1fd072016-11-09 13:17:43 -08001130 p_scb->use_rc = false;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301131
Myles Watsoncd1fd072016-11-09 13:17:43 -08001132 p_scb->num_seps = 1;
1133 p_scb->sep_info_idx = 0;
1134 APPL_TRACE_DEBUG("%s: SEID: %d use_rc: %d cur_psc_mask:0x%x", __func__,
1135 p_info->seid, p_scb->use_rc, p_scb->cur_psc_mask);
1136 /* in case of A2DP SINK this is the first time peer data is being sent to
1137 * co functions */
1138 if (local_sep == AVDT_TSEP_SNK) {
1139 p_scb->p_cos->setcfg(p_scb->hndl, p_evt_cfg->codec_info, p_info->seid,
1140 p_scb->peer_addr, p_evt_cfg->num_protect,
1141 p_evt_cfg->protect_info, AVDT_TSEP_SNK,
1142 p_msg->handle);
1143 } else {
1144 p_scb->p_cos->setcfg(p_scb->hndl, p_evt_cfg->codec_info, p_info->seid,
1145 p_scb->peer_addr, p_evt_cfg->num_protect,
1146 p_evt_cfg->protect_info, AVDT_TSEP_SRC,
1147 p_msg->handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001148 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08001149 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001150}
1151
1152/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001153 *
1154 * Function bta_av_disconnect_req
1155 *
1156 * Description Disconnect AVDTP connection.
1157 *
1158 * Returns void
1159 *
1160 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001161void bta_av_disconnect_req(tBTA_AV_SCB* p_scb,
1162 UNUSED_ATTR tBTA_AV_DATA* p_data) {
1163 tBTA_AV_RCB* p_rcb;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001164
Myles Watsoncd1fd072016-11-09 13:17:43 -08001165 APPL_TRACE_DEBUG("%s: conn_lcb: 0x%x", __func__, bta_av_cb.conn_lcb);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001166
Myles Watsoncd1fd072016-11-09 13:17:43 -08001167 alarm_cancel(bta_av_cb.link_signalling_timer);
1168 alarm_cancel(p_scb->avrc_ct_timer);
Pavlin Radoslavov78bcff72015-12-04 17:36:34 -08001169
Myles Watsoncd1fd072016-11-09 13:17:43 -08001170 if (bta_av_cb.conn_lcb) {
1171 p_rcb = bta_av_get_rcb_by_shdl((uint8_t)(p_scb->hdi + 1));
1172 if (p_rcb) bta_av_del_rc(p_rcb);
1173 AVDT_DisconnectReq(p_scb->peer_addr, bta_av_dt_cback[p_scb->hdi]);
1174 } else {
1175 bta_av_ssm_execute(p_scb, BTA_AV_AVDT_DISCONNECT_EVT, NULL);
1176 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001177}
1178
1179/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001180 *
1181 * Function bta_av_security_req
1182 *
1183 * Description Send an AVDTP security request.
1184 *
1185 * Returns void
1186 *
1187 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001188void bta_av_security_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1189 if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
1190 AVDT_SecurityReq(p_scb->avdt_handle, p_data->api_protect_req.p_data,
1191 p_data->api_protect_req.len);
1192 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001193}
1194
1195/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001196 *
1197 * Function bta_av_security_rsp
1198 *
1199 * Description Send an AVDTP security response.
1200 *
1201 * Returns void
1202 *
1203 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001204void bta_av_security_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1205 if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
1206 AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label,
1207 p_data->api_protect_rsp.error_code,
1208 p_data->api_protect_rsp.p_data,
1209 p_data->api_protect_rsp.len);
1210 } else {
1211 AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_NSC, NULL,
1212 0);
1213 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001214}
1215
1216/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001217 *
1218 * Function bta_av_setconfig_rsp
1219 *
1220 * Description setconfig is OK
1221 *
1222 * Returns void
1223 *
1224 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001225void bta_av_setconfig_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1226 uint8_t num = p_data->ci_setconfig.num_seid + 1;
1227 uint8_t avdt_handle = p_data->ci_setconfig.avdt_handle;
1228 uint8_t* p_seid = p_data->ci_setconfig.p_seid;
1229 int i;
1230 uint8_t local_sep;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001231
Myles Watsoncd1fd072016-11-09 13:17:43 -08001232 /* we like this codec_type. find the sep_idx */
1233 local_sep = bta_av_get_scb_sep_type(p_scb, avdt_handle);
1234 bta_av_adjust_seps_idx(p_scb, avdt_handle);
1235 APPL_TRACE_DEBUG("%s: sep_idx: %d cur_psc_mask:0x%x", __func__,
1236 p_scb->sep_idx, p_scb->cur_psc_mask);
Andre Eisenbach948bea02014-07-18 18:43:18 -07001237
Myles Watsoncd1fd072016-11-09 13:17:43 -08001238 if ((AVDT_TSEP_SNK == local_sep) &&
1239 (p_data->ci_setconfig.err_code == AVDT_SUCCESS) &&
1240 (p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback != NULL)) {
1241 tBTA_AV_MEDIA av_sink_codec_info;
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001242 av_sink_codec_info.avk_config.bd_addr = p_scb->peer_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -08001243 av_sink_codec_info.avk_config.codec_info = p_scb->cfg.codec_info;
1244 p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(BTA_AV_SINK_MEDIA_CFG_EVT,
1245 &av_sink_codec_info);
1246 }
1247
1248 AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label,
1249 p_data->ci_setconfig.err_code, p_data->ci_setconfig.category);
1250
1251 alarm_cancel(bta_av_cb.link_signalling_timer);
1252
1253 if (p_data->ci_setconfig.err_code == AVDT_SUCCESS) {
1254 p_scb->wait = BTA_AV_WAIT_ACP_CAPS_ON;
1255 if (p_data->ci_setconfig.recfg_needed)
1256 p_scb->role |= BTA_AV_ROLE_SUSPEND_OPT;
1257 APPL_TRACE_DEBUG("%s: recfg_needed:%d role:x%x num:%d", __func__,
1258 p_data->ci_setconfig.recfg_needed, p_scb->role, num);
1259 /* callout module tells BTA the number of "good" SEPs and their SEIDs.
1260 * getcap on these SEID */
1261 p_scb->num_seps = num;
1262
1263 if (p_scb->cur_psc_mask & AVDT_PSC_DELAY_RPT)
1264 p_scb->avdt_version = AVDT_VERSION_SYNC;
1265
1266 if (A2DP_GetCodecType(p_scb->cfg.codec_info) == A2DP_MEDIA_CT_SBC ||
1267 num > 1) {
1268 /* if SBC is used by the SNK as INT, discover req is not sent in
1269 * bta_av_config_ind.
Jakub Pawlowskic752e132017-06-16 12:52:23 -07001270 * call disc_res now */
Myles Watsoncd1fd072016-11-09 13:17:43 -08001271 /* this is called in A2DP SRC path only, In case of SINK we don't need it
1272 */
1273 if (local_sep == AVDT_TSEP_SRC)
1274 p_scb->p_cos->disc_res(p_scb->hndl, num, num, 0, p_scb->peer_addr,
1275 UUID_SERVCLASS_AUDIO_SOURCE);
1276 } else {
1277 /* we do not know the peer device and it is using non-SBC codec
1278 * we need to know all the SEPs on SNK */
1279 bta_av_discover_req(p_scb, NULL);
1280 return;
Anubhav Gupta6b84f292015-05-05 13:15:07 +05301281 }
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301282
Myles Watsoncd1fd072016-11-09 13:17:43 -08001283 for (i = 1; i < num; i++) {
1284 APPL_TRACE_DEBUG("%s: sep_info[%d] SEID: %d", __func__, i, p_seid[i - 1]);
1285 /* initialize the sep_info[] to get capabilities */
1286 p_scb->sep_info[i].in_use = false;
1287 p_scb->sep_info[i].tsep = AVDT_TSEP_SNK;
1288 p_scb->sep_info[i].media_type = p_scb->media_type;
1289 p_scb->sep_info[i].seid = p_seid[i - 1];
The Android Open Source Project5738f832012-12-12 16:00:35 -08001290 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08001291
1292 /* only in case of local sep as SRC we need to look for other SEPs, In case
1293 * of SINK we don't */
1294 if (local_sep == AVDT_TSEP_SRC) {
1295 /* Make sure UUID has been initialized... */
1296 if (p_scb->uuid_int == 0) p_scb->uuid_int = p_scb->open_api.uuid;
1297 bta_av_next_getcap(p_scb, p_data);
1298 }
1299 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001300}
1301
1302/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001303 *
1304 * Function bta_av_str_opened
1305 *
1306 * Description Stream opened OK (incoming/outgoing).
1307 *
1308 * Returns void
1309 *
1310 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001311void bta_av_str_opened(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1312 tBTA_AV_CONN_CHG msg;
1313 tBTA_AV_OPEN open;
1314 uint8_t* p;
1315 uint16_t mtu;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001316
Myles Watsoncd1fd072016-11-09 13:17:43 -08001317 msg.hdr.layer_specific = p_scb->hndl;
1318 msg.is_up = true;
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001319 msg.peer_addr = p_scb->peer_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -08001320 p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle);
1321 bta_av_conn_chg((tBTA_AV_DATA*)&msg);
1322 /* set the congestion flag, so AV would not send media packets by accident */
1323 p_scb->cong = true;
1324 p_scb->offload_start_pending = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001325
Myles Watsoncd1fd072016-11-09 13:17:43 -08001326 p_scb->stream_mtu =
1327 p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE;
1328 mtu = bta_av_chk_mtu(p_scb, p_scb->stream_mtu);
1329 APPL_TRACE_DEBUG("%s: l2c_cid: 0x%x stream_mtu: %d mtu: %d", __func__,
1330 p_scb->l2c_cid, p_scb->stream_mtu, mtu);
1331 if (mtu == 0 || mtu > p_scb->stream_mtu) mtu = p_scb->stream_mtu;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001332
Ben YoungTae Kim624ba682017-06-20 19:26:08 +05301333 /* Set the media channel as high priority */
1334 L2CA_SetTxPriority(p_scb->l2c_cid, L2CAP_CHNL_PRIORITY_HIGH);
Myles Watsoncd1fd072016-11-09 13:17:43 -08001335 L2CA_SetChnlFlushability(p_scb->l2c_cid, true);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001336
Jakub Pawlowskic752e132017-06-16 12:52:23 -07001337 bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08001338 memset(&p_scb->q_info, 0, sizeof(tBTA_AV_Q_INFO));
The Android Open Source Project5738f832012-12-12 16:00:35 -08001339
Myles Watsoncd1fd072016-11-09 13:17:43 -08001340 p_scb->l2c_bufs = 0;
Pavlin Radoslavovcd02ce92016-11-04 17:18:51 -07001341 p_scb->p_cos->open(p_scb->hndl, mtu);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001342
Myles Watsoncd1fd072016-11-09 13:17:43 -08001343 {
1344 /* TODO check if other audio channel is open.
1345 * If yes, check if reconfig is needed
1346 * Rigt now we do not do this kind of checking.
1347 * BTA-AV is INT for 2nd audio connection.
1348 * The application needs to make sure the current codec_info is proper.
1349 * If one audio connection is open and another SNK attempts to connect to
1350 * AV,
1351 * the connection will be rejected.
1352 */
1353 /* check if other audio channel is started. If yes, start */
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001354 open.bd_addr = p_scb->peer_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -08001355 open.chnl = p_scb->chnl;
1356 open.hndl = p_scb->hndl;
1357 open.status = BTA_AV_SUCCESS;
1358 open.starting = bta_av_chk_start(p_scb);
1359 open.edr = 0;
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001360 p = BTM_ReadRemoteFeatures(p_scb->peer_addr);
Marie Janssenf9c57522017-02-22 08:35:29 -08001361 if (p != NULL) {
Myles Watsoncd1fd072016-11-09 13:17:43 -08001362 if (HCI_EDR_ACL_2MPS_SUPPORTED(p)) open.edr |= BTA_AV_EDR_2MBPS;
1363 if (HCI_EDR_ACL_3MPS_SUPPORTED(p)) open.edr |= BTA_AV_EDR_3MBPS;
1364 }
Marie Janssene9e58ce2016-06-17 14:12:17 -07001365#if (BTA_AR_INCLUDED == TRUE)
Jakub Pawlowski78b81c62017-06-16 13:55:52 -07001366 bta_ar_avdt_conn(BTA_ID_AV, open.bd_addr);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001367#endif
Myles Watsoncd1fd072016-11-09 13:17:43 -08001368 if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC)
1369 open.sep = AVDT_TSEP_SNK;
1370 else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)
1371 open.sep = AVDT_TSEP_SRC;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301372
Myles Watsoncd1fd072016-11-09 13:17:43 -08001373 (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV*)&open);
1374 if (open.starting) {
1375 bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001376 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08001377 }
Anubhav Gupta6a277762014-11-13 19:58:09 +05301378
Myles Watsoncd1fd072016-11-09 13:17:43 -08001379 // This code is used to pass PTS TC for AVDTP ABORT
1380 char value[PROPERTY_VALUE_MAX] = {0};
1381 if ((osi_property_get("bluetooth.pts.force_a2dp_abort", value, "false")) &&
1382 (!strcmp(value, "true"))) {
1383 APPL_TRACE_ERROR("%s: Calling AVDT_AbortReq", __func__);
1384 AVDT_AbortReq(p_scb->avdt_handle);
1385 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001386}
1387
1388/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001389 *
1390 * Function bta_av_security_ind
1391 *
1392 * Description Handle an AVDTP security indication.
1393 *
1394 * Returns void
1395 *
1396 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001397void bta_av_security_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1398 tBTA_AV_PROTECT_REQ protect_req;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001399
Myles Watsoncd1fd072016-11-09 13:17:43 -08001400 p_scb->avdt_label = p_data->str_msg.msg.hdr.label;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001401
Myles Watsoncd1fd072016-11-09 13:17:43 -08001402 if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
1403 protect_req.chnl = p_scb->chnl;
1404 protect_req.hndl = p_scb->hndl;
1405 protect_req.p_data = p_data->str_msg.msg.security_ind.p_data;
1406 protect_req.len = p_data->str_msg.msg.security_ind.len;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001407
Myles Watsoncd1fd072016-11-09 13:17:43 -08001408 (*bta_av_cb.p_cback)(BTA_AV_PROTECT_REQ_EVT, (tBTA_AV*)&protect_req);
1409 }
1410 /* app doesn't support security indication; respond with failure */
1411 else {
1412 AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_NSC, NULL,
1413 0);
1414 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001415}
1416
1417/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001418 *
1419 * Function bta_av_security_cfm
1420 *
1421 * Description Handle an AVDTP security confirm.
1422 *
1423 * Returns void
1424 *
1425 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001426void bta_av_security_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1427 tBTA_AV_PROTECT_RSP protect_rsp;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001428
Myles Watsoncd1fd072016-11-09 13:17:43 -08001429 if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
1430 protect_rsp.chnl = p_scb->chnl;
1431 protect_rsp.hndl = p_scb->hndl;
1432 protect_rsp.p_data = p_data->str_msg.msg.security_cfm.p_data;
1433 protect_rsp.len = p_data->str_msg.msg.security_cfm.len;
1434 protect_rsp.err_code = p_data->str_msg.msg.hdr.err_code;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001435
Myles Watsoncd1fd072016-11-09 13:17:43 -08001436 (*bta_av_cb.p_cback)(BTA_AV_PROTECT_RSP_EVT, (tBTA_AV*)&protect_rsp);
1437 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001438}
1439
1440/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001441 *
1442 * Function bta_av_do_close
1443 *
1444 * Description Close stream.
1445 *
1446 * Returns void
1447 *
1448 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001449void bta_av_do_close(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
1450 /* stop stream if started */
1451 if (p_scb->co_started) {
1452 bta_av_str_stopped(p_scb, NULL);
1453 }
1454 alarm_cancel(bta_av_cb.link_signalling_timer);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001455
Myles Watsoncd1fd072016-11-09 13:17:43 -08001456 /* close stream */
1457 p_scb->started = false;
Pavlin Radoslavov3b8391c2017-05-12 01:16:10 -07001458 p_scb->current_codec = nullptr;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001459
Myles Watsoncd1fd072016-11-09 13:17:43 -08001460 /* drop the buffers queued in L2CAP */
1461 L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001462
Myles Watsoncd1fd072016-11-09 13:17:43 -08001463 AVDT_CloseReq(p_scb->avdt_handle);
1464 /* just in case that the link is congested, link is flow controled by peer or
1465 * for whatever reason the the close request can not be sent in time.
1466 * when this timer expires, AVDT_DisconnectReq will be called to disconnect
1467 * the link
1468 */
1469 bta_sys_start_timer(p_scb->avrc_ct_timer, BTA_AV_CLOSE_REQ_TIME_VAL,
1470 BTA_AV_API_CLOSE_EVT, p_scb->hndl);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001471}
1472
1473/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001474 *
1475 * Function bta_av_connect_req
1476 *
1477 * Description Connect AVDTP connection.
1478 *
1479 * Returns void
1480 *
1481 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001482void bta_av_connect_req(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
1483 p_scb->sdp_discovery_started = false;
1484 if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) {
1485 /* SNK initiated L2C connection while SRC was doing SDP. */
1486 /* Wait until timeout to check if SNK starts signalling. */
1487 APPL_TRACE_EVENT("%s: coll_mask = 0x%2X", __func__, p_scb->coll_mask);
1488 p_scb->coll_mask |= BTA_AV_COLL_API_CALLED;
1489 APPL_TRACE_EVENT("%s: updated coll_mask = 0x%2X", __func__,
1490 p_scb->coll_mask);
1491 return;
1492 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001493
Myles Watsoncd1fd072016-11-09 13:17:43 -08001494 AVDT_ConnectReq(p_scb->peer_addr, p_scb->sec_mask,
1495 bta_av_dt_cback[p_scb->hdi]);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001496}
1497
1498/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001499 *
1500 * Function bta_av_sdp_failed
1501 *
1502 * Description Service discovery failed.
1503 *
1504 * Returns void
1505 *
1506 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001507void bta_av_sdp_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1508 if (!p_scb->open_status) p_scb->open_status = BTA_AV_FAIL_SDP;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001509
Myles Watsoncd1fd072016-11-09 13:17:43 -08001510 p_scb->sdp_discovery_started = false;
1511 bta_av_str_closed(p_scb, p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001512}
1513
1514/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001515 *
1516 * Function bta_av_disc_results
1517 *
1518 * Description Handle the AVDTP discover results. Search through the
1519 * results and find the first available stream, and get
1520 * its capabilities.
1521 *
1522 * Returns void
1523 *
1524 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001525void bta_av_disc_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1526 uint8_t num_snks = 0, num_srcs = 0, i;
1527 /* our uuid in case we initiate connection */
1528 uint16_t uuid_int = p_scb->uuid_int;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001529
Myles Watsoncd1fd072016-11-09 13:17:43 -08001530 APPL_TRACE_DEBUG("%s: initiator UUID 0x%x", __func__, uuid_int);
1531 /* store number of stream endpoints returned */
1532 p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001533
Myles Watsoncd1fd072016-11-09 13:17:43 -08001534 for (i = 0; i < p_scb->num_seps; i++) {
1535 /* steam not in use, is a sink, and is audio */
1536 if ((p_scb->sep_info[i].in_use == false) &&
1537 (p_scb->sep_info[i].media_type == p_scb->media_type)) {
1538 if ((p_scb->sep_info[i].tsep == AVDT_TSEP_SNK) &&
1539 (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE))
1540 num_snks++;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301541
Myles Watsoncd1fd072016-11-09 13:17:43 -08001542 if ((p_scb->sep_info[i].tsep == AVDT_TSEP_SRC) &&
1543 (uuid_int == UUID_SERVCLASS_AUDIO_SINK))
1544 num_srcs++;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001545 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08001546 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001547
Myles Watsoncd1fd072016-11-09 13:17:43 -08001548 p_scb->p_cos->disc_res(p_scb->hndl, p_scb->num_seps, num_snks, num_srcs,
1549 p_scb->peer_addr, uuid_int);
1550 p_scb->num_disc_snks = num_snks;
1551 p_scb->num_disc_srcs = num_srcs;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001552
Myles Watsoncd1fd072016-11-09 13:17:43 -08001553 /* if we got any */
1554 if (p_scb->num_seps > 0) {
1555 /* initialize index into discovery results */
1556 p_scb->sep_info_idx = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001557
Myles Watsoncd1fd072016-11-09 13:17:43 -08001558 /* get the capabilities of the first available stream */
1559 bta_av_next_getcap(p_scb, p_data);
1560 }
1561 /* else we got discover response but with no streams; we're done */
1562 else {
1563 bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data);
1564 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001565}
1566
1567/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001568 *
1569 * Function bta_av_disc_res_as_acp
1570 *
1571 * Description Handle the AVDTP discover results. Search through the
1572 * results and find the first available stream, and get
1573 * its capabilities.
1574 *
1575 * Returns void
1576 *
1577 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001578void bta_av_disc_res_as_acp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1579 uint8_t num_snks = 0, i;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001580
Myles Watsoncd1fd072016-11-09 13:17:43 -08001581 /* store number of stream endpoints returned */
1582 p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001583
Myles Watsoncd1fd072016-11-09 13:17:43 -08001584 for (i = 0; i < p_scb->num_seps; i++) {
1585 /* steam is a sink, and is audio */
1586 if ((p_scb->sep_info[i].tsep == AVDT_TSEP_SNK) &&
1587 (p_scb->sep_info[i].media_type == p_scb->media_type)) {
1588 p_scb->sep_info[i].in_use = false;
1589 num_snks++;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001590 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08001591 }
1592 p_scb->p_cos->disc_res(p_scb->hndl, p_scb->num_seps, num_snks, 0,
1593 p_scb->peer_addr, UUID_SERVCLASS_AUDIO_SOURCE);
1594 p_scb->num_disc_snks = num_snks;
1595 p_scb->num_disc_srcs = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001596
Myles Watsoncd1fd072016-11-09 13:17:43 -08001597 /* if we got any */
1598 if (p_scb->num_seps > 0) {
1599 /* initialize index into discovery results */
1600 p_scb->sep_info_idx = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001601
Myles Watsoncd1fd072016-11-09 13:17:43 -08001602 /* get the capabilities of the first available stream */
1603 bta_av_next_getcap(p_scb, p_data);
1604 }
1605 /* else we got discover response but with no streams; we're done */
1606 else {
1607 bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data);
1608 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001609}
1610
1611/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001612 *
1613 * Function bta_av_save_caps
1614 *
1615 * Description report the SNK SEP capabilities to application
1616 *
1617 * Returns void
1618 *
1619 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001620void bta_av_save_caps(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1621 tAVDT_CFG cfg;
1622 tAVDT_SEP_INFO* p_info = &p_scb->sep_info[p_scb->sep_info_idx];
1623 uint8_t old_wait = p_scb->wait;
1624 bool getcap_done = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001625
Myles Watsoncd1fd072016-11-09 13:17:43 -08001626 APPL_TRACE_DEBUG("%s: num_seps:%d sep_info_idx:%d wait:x%x", __func__,
1627 p_scb->num_seps, p_scb->sep_info_idx, p_scb->wait);
1628 memcpy(&cfg, p_scb->p_cap, sizeof(tAVDT_CFG));
1629 /* let application know the capability of the SNK */
1630 p_scb->p_cos->getcfg(p_scb->hndl, cfg.codec_info, &p_scb->sep_info_idx,
1631 p_info->seid, &cfg.num_protect, cfg.protect_info);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001632
Myles Watsoncd1fd072016-11-09 13:17:43 -08001633 p_scb->sep_info_idx++;
1634 if (p_scb->num_seps > p_scb->sep_info_idx) {
1635 /* Some devices have seps at the end of the discover list, which is not */
1636 /* matching media type(video not audio). */
1637 /* In this case, we are done with getcap without sending another */
1638 /* request to AVDT. */
1639 if (!bta_av_next_getcap(p_scb, p_data)) getcap_done = true;
1640 } else
1641 getcap_done = true;
1642
1643 if (getcap_done) {
1644 /* we are done getting capabilities. restore the p_cb->sep_info_idx */
1645 p_scb->sep_info_idx = 0;
1646 p_scb->wait &= ~(BTA_AV_WAIT_ACP_CAPS_ON | BTA_AV_WAIT_ACP_CAPS_STARTED);
1647 if (old_wait & BTA_AV_WAIT_ACP_CAPS_STARTED) {
1648 bta_av_start_ok(p_scb, NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001649 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08001650 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001651}
1652
1653/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001654 *
1655 * Function bta_av_set_use_rc
1656 *
1657 * Description set to use AVRC for this stream control block.
1658 *
1659 * Returns void
1660 *
1661 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001662void bta_av_set_use_rc(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
1663 p_scb->use_rc = true;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001664}
1665
1666/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001667 *
1668 * Function bta_av_cco_close
1669 *
1670 * Description call close call-out function.
1671 *
1672 * Returns void
1673 *
1674 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001675void bta_av_cco_close(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
1676 uint16_t mtu;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001677
Myles Watsoncd1fd072016-11-09 13:17:43 -08001678 mtu = bta_av_chk_mtu(p_scb, BTA_AV_MAX_A2DP_MTU);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001679
Pavlin Radoslavovcd02ce92016-11-04 17:18:51 -07001680 p_scb->p_cos->close(p_scb->hndl);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001681}
1682
1683/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001684 *
1685 * Function bta_av_open_failed
1686 *
1687 * Description Failed to open an AVDT stream
1688 *
1689 * Returns void
1690 *
1691 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001692void bta_av_open_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1693 bool is_av_opened = false;
1694 tBTA_AV_SCB* p_opened_scb = NULL;
1695 uint8_t idx;
1696 tBTA_AV_OPEN open;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001697
Myles Watsoncd1fd072016-11-09 13:17:43 -08001698 APPL_TRACE_DEBUG("%s", __func__);
1699 p_scb->open_status = BTA_AV_FAIL_STREAM;
1700 bta_av_cco_close(p_scb, p_data);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001701
Myles Watsoncd1fd072016-11-09 13:17:43 -08001702 /* check whether there is already an opened audio or video connection with the
1703 * same device */
1704 for (idx = 0; (idx < BTA_AV_NUM_STRS) && (is_av_opened == false); idx++) {
1705 p_opened_scb = bta_av_cb.p_scb[idx];
1706 if (p_opened_scb && (p_opened_scb->state == BTA_AV_OPEN_SST) &&
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001707 (p_opened_scb->peer_addr == p_scb->peer_addr))
Myles Watsoncd1fd072016-11-09 13:17:43 -08001708 is_av_opened = true;
1709 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001710
Myles Watsoncd1fd072016-11-09 13:17:43 -08001711 /* if there is already an active AV connnection with the same bd_addr,
1712 don't send disconnect req, just report the open event with
1713 BTA_AV_FAIL_GET_CAP status */
1714 if (is_av_opened == true) {
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001715 open.bd_addr = p_scb->peer_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -08001716 open.chnl = p_scb->chnl;
1717 open.hndl = p_scb->hndl;
1718 open.status = BTA_AV_FAIL_GET_CAP;
1719 open.starting = bta_av_chk_start(p_scb);
1720 open.edr = 0;
1721 /* set the state back to initial state */
1722 bta_av_set_scb_sst_init(p_scb);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001723
Myles Watsoncd1fd072016-11-09 13:17:43 -08001724 if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC)
1725 open.sep = AVDT_TSEP_SNK;
1726 else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)
1727 open.sep = AVDT_TSEP_SRC;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001728
Myles Watsoncd1fd072016-11-09 13:17:43 -08001729 (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV*)&open);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001730
Myles Watsoncd1fd072016-11-09 13:17:43 -08001731 } else {
1732 AVDT_DisconnectReq(p_scb->peer_addr, bta_av_dt_cback[p_scb->hdi]);
1733 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001734}
1735
1736/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001737 *
1738 * Function bta_av_getcap_results
1739 *
1740 * Description Handle the AVDTP get capabilities results. Check the codec
1741 * type and see if it matches ours. If it does not, get the
1742 * capabilities of the next stream, if any.
1743 *
1744 * Returns void
1745 *
1746 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001747void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1748 tAVDT_CFG cfg;
1749 uint8_t media_type;
1750 tAVDT_SEP_INFO* p_info = &p_scb->sep_info[p_scb->sep_info_idx];
1751 uint16_t uuid_int; /* UUID for which connection was initiatied */
The Android Open Source Project5738f832012-12-12 16:00:35 -08001752
Myles Watsoncd1fd072016-11-09 13:17:43 -08001753 memcpy(&cfg, &p_scb->cfg, sizeof(tAVDT_CFG));
1754 cfg.num_codec = 1;
1755 cfg.num_protect = p_scb->p_cap->num_protect;
1756 memcpy(cfg.codec_info, p_scb->p_cap->codec_info, AVDT_CODEC_SIZE);
1757 memcpy(cfg.protect_info, p_scb->p_cap->protect_info, AVDT_PROTECT_SIZE);
1758 media_type = A2DP_GetMediaType(p_scb->p_cap->codec_info);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001759
Myles Watsoncd1fd072016-11-09 13:17:43 -08001760 APPL_TRACE_DEBUG("%s: num_codec %d", __func__, p_scb->p_cap->num_codec);
1761 APPL_TRACE_DEBUG("%s: media type x%x, x%x", __func__, media_type,
1762 p_scb->media_type);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001763
Myles Watsoncd1fd072016-11-09 13:17:43 -08001764 /* if codec present and we get a codec configuration */
1765 if ((p_scb->p_cap->num_codec != 0) && (media_type == p_scb->media_type) &&
1766 (p_scb->p_cos->getcfg(p_scb->hndl, cfg.codec_info, &p_scb->sep_info_idx,
1767 p_info->seid, &cfg.num_protect,
1768 cfg.protect_info) == A2DP_SUCCESS)) {
1769 /* save copy of codec configuration */
1770 memcpy(&p_scb->cfg, &cfg, sizeof(tAVDT_CFG));
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301771
Myles Watsoncd1fd072016-11-09 13:17:43 -08001772 uuid_int = p_scb->uuid_int;
1773 APPL_TRACE_DEBUG("%s: initiator UUID = 0x%x", __func__, uuid_int);
1774 if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
1775 bta_av_adjust_seps_idx(p_scb,
1776 bta_av_get_scb_handle(p_scb, AVDT_TSEP_SRC));
1777 else if (uuid_int == UUID_SERVCLASS_AUDIO_SINK)
1778 bta_av_adjust_seps_idx(p_scb,
1779 bta_av_get_scb_handle(p_scb, AVDT_TSEP_SNK));
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301780
Myles Watsoncd1fd072016-11-09 13:17:43 -08001781 /* use only the services peer supports */
1782 cfg.psc_mask &= p_scb->p_cap->psc_mask;
1783 p_scb->cur_psc_mask = cfg.psc_mask;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001784
Myles Watsoncd1fd072016-11-09 13:17:43 -08001785 if ((uuid_int == UUID_SERVCLASS_AUDIO_SINK) &&
1786 (p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback != NULL)) {
1787 APPL_TRACE_DEBUG("%s: configure decoder for Sink connection", __func__);
1788 tBTA_AV_MEDIA av_sink_codec_info;
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001789 av_sink_codec_info.avk_config.bd_addr = p_scb->peer_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -08001790 av_sink_codec_info.avk_config.codec_info = p_scb->cfg.codec_info;
1791 p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(
1792 BTA_AV_SINK_MEDIA_CFG_EVT, &av_sink_codec_info);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001793 }
1794
Myles Watsoncd1fd072016-11-09 13:17:43 -08001795 if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE) {
1796 A2DP_AdjustCodec(cfg.codec_info);
1797 }
1798
1799 /* open the stream */
1800 AVDT_OpenReq(p_scb->seps[p_scb->sep_idx].av_handle, p_scb->peer_addr,
1801 p_scb->sep_info[p_scb->sep_info_idx].seid, &cfg);
1802
1803 if (!bta_av_is_rcfg_sst(p_scb)) {
1804 /* free capabilities buffer */
1805 osi_free_and_reset((void**)&p_scb->p_cap);
1806 }
1807 } else {
1808 /* try the next stream, if any */
1809 p_scb->sep_info_idx++;
1810 bta_av_next_getcap(p_scb, p_data);
1811 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001812}
1813
1814/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001815 *
1816 * Function bta_av_setconfig_rej
1817 *
1818 * Description Send AVDTP set config reject.
1819 *
1820 * Returns void
1821 *
1822 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001823void bta_av_setconfig_rej(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1824 tBTA_AV_REJECT reject;
1825 uint8_t avdt_handle = p_data->ci_setconfig.avdt_handle;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001826
Myles Watsoncd1fd072016-11-09 13:17:43 -08001827 bta_av_adjust_seps_idx(p_scb, avdt_handle);
1828 APPL_TRACE_DEBUG("%s: sep_idx: %d", __func__, p_scb->sep_idx);
1829 AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_UNSUP_CFG, 0);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301830
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001831 reject.bd_addr = p_data->str_msg.bd_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -08001832 reject.hndl = p_scb->hndl;
1833 (*bta_av_cb.p_cback)(BTA_AV_REJECT_EVT, (tBTA_AV*)&reject);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001834}
1835
1836/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001837 *
1838 * Function bta_av_discover_req
1839 *
1840 * Description Send an AVDTP discover request to the peer.
1841 *
1842 * Returns void
1843 *
1844 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001845void bta_av_discover_req(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
1846 /* send avdtp discover request */
The Android Open Source Project5738f832012-12-12 16:00:35 -08001847
Myles Watsoncd1fd072016-11-09 13:17:43 -08001848 AVDT_DiscoverReq(p_scb->peer_addr, p_scb->sep_info, BTA_AV_NUM_SEPS,
1849 bta_av_dt_cback[p_scb->hdi]);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001850}
1851
1852/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001853 *
1854 * Function bta_av_conn_failed
1855 *
1856 * Description AVDTP connection failed.
1857 *
1858 * Returns void
1859 *
1860 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001861void bta_av_conn_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1862 p_scb->open_status = BTA_AV_FAIL_STREAM;
1863 bta_av_str_closed(p_scb, p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001864}
1865
1866/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001867 *
1868 * Function bta_av_do_start
1869 *
1870 * Description Start stream.
1871 *
1872 * Returns void
1873 *
1874 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001875void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1876 uint8_t policy = HCI_ENABLE_SNIFF_MODE;
1877 uint8_t cur_role;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001878
Myles Watsoncd1fd072016-11-09 13:17:43 -08001879 APPL_TRACE_DEBUG("%s: sco_occupied:%d, role:x%x, started:%d", __func__,
1880 bta_av_cb.sco_occupied, p_scb->role, p_scb->started);
1881 if (bta_av_cb.sco_occupied) {
1882 bta_av_start_failed(p_scb, p_data);
1883 return;
1884 }
1885
1886 /* disallow role switch during streaming, only if we are the master role
1887 * i.e. allow role switch, if we are slave.
1888 * It would not hurt us, if the peer device wants us to be master */
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001889 if ((BTM_GetRole(p_scb->peer_addr, &cur_role) == BTM_SUCCESS) &&
Myles Watsoncd1fd072016-11-09 13:17:43 -08001890 (cur_role == BTM_ROLE_MASTER)) {
1891 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
1892 }
1893
Jakub Pawlowskic752e132017-06-16 12:52:23 -07001894 bta_sys_clear_policy(BTA_ID_AV, policy, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08001895
1896 if ((p_scb->started == false) &&
1897 ((p_scb->role & BTA_AV_ROLE_START_INT) == 0)) {
1898 p_scb->role |= BTA_AV_ROLE_START_INT;
Jakub Pawlowskic752e132017-06-16 12:52:23 -07001899 bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08001900
1901 AVDT_StartReq(&p_scb->avdt_handle, 1);
1902 } else if (p_scb->started) {
1903 p_scb->role |= BTA_AV_ROLE_START_INT;
1904 if (p_scb->wait == 0) {
1905 if (p_scb->role & BTA_AV_ROLE_SUSPEND) {
1906 notify_start_failed(p_scb);
1907 } else {
1908 bta_av_start_ok(p_scb, NULL);
1909 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001910 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08001911 }
1912 APPL_TRACE_DEBUG("%s: started %d role:x%x", __func__, p_scb->started,
1913 p_scb->role);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001914}
1915
1916/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08001917 *
1918 * Function bta_av_str_stopped
1919 *
1920 * Description Stream stopped.
1921 *
1922 * Returns void
1923 *
1924 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08001925void bta_av_str_stopped(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
1926 tBTA_AV_SUSPEND suspend_rsp;
1927 uint8_t start = p_scb->started;
1928 bool sus_evt = true;
1929 BT_HDR* p_buf;
1930 uint8_t policy = HCI_ENABLE_SNIFF_MODE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001931
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08001932 APPL_TRACE_ERROR("%s: audio_open_cnt=%d, p_data %p", __func__,
Myles Watsoncd1fd072016-11-09 13:17:43 -08001933 bta_av_cb.audio_open_cnt, p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001934
Jakub Pawlowskic752e132017-06-16 12:52:23 -07001935 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08001936 if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 ||
1937 bta_av_cb.audio_open_cnt == 1)
1938 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
Jakub Pawlowskic752e132017-06-16 12:52:23 -07001939 bta_sys_set_policy(BTA_ID_AV, policy, p_scb->peer_addr);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001940
Myles Watsoncd1fd072016-11-09 13:17:43 -08001941 if (p_scb->co_started) {
Andre Eisenbach796523d2016-11-10 16:11:00 -08001942 /* TODO(eisenbach): RE-IMPLEMENT USING VSC OR HAL EXTENSION
Myles Watsoncd1fd072016-11-09 13:17:43 -08001943 vendor_get_interface()->send_command(
1944 (vendor_opcode_t)BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
1945 if (p_scb->offload_start_pending) {
1946 tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
1947 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001948 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08001949 p_scb->offload_start_pending = false;
Andre Eisenbach796523d2016-11-10 16:11:00 -08001950 */
The Android Open Source Project5738f832012-12-12 16:00:35 -08001951
Myles Watsoncd1fd072016-11-09 13:17:43 -08001952 bta_av_stream_chg(p_scb, false);
1953 p_scb->co_started = false;
1954
1955 p_scb->p_cos->stop(p_scb->hndl);
Jakub Pawlowski903c1662017-06-13 17:53:54 -07001956 L2CA_SetFlushTimeout(p_scb->peer_addr, L2CAP_DEFAULT_FLUSH_TO);
Myles Watsoncd1fd072016-11-09 13:17:43 -08001957 }
1958
1959 /* if q_info.a2dp_list is not empty, drop it now */
1960 if (BTA_AV_CHNL_AUDIO == p_scb->chnl) {
1961 while (!list_is_empty(p_scb->a2dp_list)) {
1962 p_buf = (BT_HDR*)list_front(p_scb->a2dp_list);
1963 list_remove(p_scb->a2dp_list, p_buf);
1964 osi_free(p_buf);
1965 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001966
1967 /* drop the audio buffers queued in L2CAP */
Myles Watsoncd1fd072016-11-09 13:17:43 -08001968 if (p_data && p_data->api_stop.flush)
1969 L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
1970 }
1971
1972 suspend_rsp.chnl = p_scb->chnl;
1973 suspend_rsp.hndl = p_scb->hndl;
1974
1975 if (p_data && p_data->api_stop.suspend) {
1976 APPL_TRACE_DEBUG("%s: suspending: %d, sup:%d", __func__, start,
1977 p_scb->suspend_sup);
1978 if ((start) && (p_scb->suspend_sup)) {
1979 sus_evt = false;
1980 p_scb->l2c_bufs = 0;
1981 AVDT_SuspendReq(&p_scb->avdt_handle, 1);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001982 }
1983
Myles Watsoncd1fd072016-11-09 13:17:43 -08001984 /* send SUSPEND_EVT event only if not in reconfiguring state and sus_evt is
1985 * true*/
1986 if ((sus_evt) && (p_scb->state != BTA_AV_RCFG_SST)) {
1987 suspend_rsp.status = BTA_AV_SUCCESS;
1988 suspend_rsp.initiator = true;
1989 (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, (tBTA_AV*)&suspend_rsp);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001990 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08001991 } else {
1992 suspend_rsp.status = BTA_AV_SUCCESS;
1993 suspend_rsp.initiator = true;
1994 APPL_TRACE_EVENT("%s: status %d", __func__, suspend_rsp.status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001995
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08001996 // Send STOP_EVT event only if not in reconfiguring state.
1997 // However, we should send STOP_EVT if we are reconfiguring when taking
1998 // the Close->Configure->Open->Start path.
1999 if (p_scb->state != BTA_AV_RCFG_SST ||
2000 (p_data && p_data->api_stop.reconfig_stop)) {
Myles Watsoncd1fd072016-11-09 13:17:43 -08002001 (*bta_av_cb.p_cback)(BTA_AV_STOP_EVT, (tBTA_AV*)&suspend_rsp);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002002 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002003 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002004}
2005
2006/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002007 *
2008 * Function bta_av_reconfig
2009 *
2010 * Description process the reconfigure request.
2011 * save the parameter in control block and
2012 * suspend, reconfigure or close the stream
2013 *
2014 * Returns void
2015 *
2016 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002017void bta_av_reconfig(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2018 tAVDT_CFG* p_cfg;
2019 tBTA_AV_API_STOP stop;
2020 tBTA_AV_API_RCFG* p_rcfg = &p_data->api_reconfig;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002021
Myles Watsoncd1fd072016-11-09 13:17:43 -08002022 APPL_TRACE_DEBUG("%s: r:%d, s:%d idx: %d (o:%d)", __func__, p_scb->recfg_sup,
2023 p_scb->suspend_sup, p_scb->rcfg_idx, p_scb->sep_info_idx);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002024
Myles Watsoncd1fd072016-11-09 13:17:43 -08002025 p_scb->num_recfg = 0;
2026 /* store the new configuration in control block */
2027 if (p_scb->p_cap == NULL)
2028 p_scb->p_cap = (tAVDT_CFG*)osi_malloc(sizeof(tAVDT_CFG));
2029 p_cfg = p_scb->p_cap;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002030
Myles Watsoncd1fd072016-11-09 13:17:43 -08002031 alarm_cancel(p_scb->avrc_ct_timer);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002032
Myles Watsoncd1fd072016-11-09 13:17:43 -08002033 memcpy(p_cfg, &p_scb->cfg, sizeof(tAVDT_CFG));
2034 p_cfg->num_protect = p_rcfg->num_protect;
2035 memcpy(p_cfg->codec_info, p_rcfg->codec_info, AVDT_CODEC_SIZE);
2036 memcpy(p_cfg->protect_info, p_rcfg->p_protect_info, p_rcfg->num_protect);
2037 p_scb->rcfg_idx = p_rcfg->sep_info_idx;
2038 p_scb->p_cap->psc_mask = p_scb->cur_psc_mask;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002039
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002040 // If the requested SEP index is same as the current one, then we
2041 // can Suspend->Reconfigure->Start.
2042 // Otherwise, we have to Close->Configure->Open->Start or
2043 // Close->Configure->Open for streams that are / are not started.
2044 if ((p_scb->rcfg_idx == p_scb->sep_info_idx) && p_rcfg->suspend &&
2045 p_scb->recfg_sup && p_scb->suspend_sup) {
Myles Watsoncd1fd072016-11-09 13:17:43 -08002046 if (p_scb->started) {
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002047 // Suspend->Reconfigure->Start
Myles Watsoncd1fd072016-11-09 13:17:43 -08002048 stop.flush = false;
2049 stop.suspend = true;
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002050 stop.reconfig_stop = false;
Myles Watsoncd1fd072016-11-09 13:17:43 -08002051 bta_av_str_stopped(p_scb, (tBTA_AV_DATA*)&stop);
2052 } else {
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002053 // Reconfigure
Myles Watsoncd1fd072016-11-09 13:17:43 -08002054 APPL_TRACE_DEBUG("%s: reconfig", __func__);
2055 AVDT_ReconfigReq(p_scb->avdt_handle, p_scb->p_cap);
2056 p_scb->p_cap->psc_mask = p_scb->cur_psc_mask;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002057 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002058 } else {
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002059 // Close the stream first, and then Configure it
2060 APPL_TRACE_DEBUG("%s: Close/Open started: %d state: %d num_protect: %d",
2061 __func__, p_scb->started, p_scb->state,
Myles Watsoncd1fd072016-11-09 13:17:43 -08002062 p_cfg->num_protect);
2063 if (p_scb->started) {
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002064 // Close->Configure->Open->Start
2065 if ((p_scb->rcfg_idx != p_scb->sep_info_idx) && p_scb->recfg_sup) {
2066 // Make sure we trigger STOP_EVT when taking the longer road to
2067 // reconfiguration, otherwise we don't call Start.
2068 stop.flush = false;
2069 stop.suspend = false;
2070 stop.reconfig_stop = true;
2071 bta_av_str_stopped(p_scb, (tBTA_AV_DATA*)&stop);
2072 } else {
2073 bta_av_str_stopped(p_scb, NULL);
2074 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002075 p_scb->started = false;
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002076 } else {
2077 // Close->Configure->Open
2078 bta_av_str_stopped(p_scb, NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002079 }
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002080 // Drop the buffers queued in L2CAP
2081 L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
2082 AVDT_CloseReq(p_scb->avdt_handle);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002083 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002084}
2085
2086/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002087 *
2088 * Function bta_av_data_path
2089 *
2090 * Description Handle stream data path.
2091 *
2092 * Returns void
2093 *
2094 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002095void bta_av_data_path(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
2096 BT_HDR* p_buf = NULL;
2097 uint32_t timestamp;
2098 bool new_buf = false;
Pavlin Radoslavov3b8391c2017-05-12 01:16:10 -07002099 uint8_t m_pt = 0x60;
Myles Watsoncd1fd072016-11-09 13:17:43 -08002100 tAVDT_DATA_OPT_MASK opt;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002101
Myles Watsoncd1fd072016-11-09 13:17:43 -08002102 if (p_scb->cong) return;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002103
Pavlin Radoslavov3b8391c2017-05-12 01:16:10 -07002104 if (p_scb->current_codec->useRtpHeaderMarkerBit()) {
2105 m_pt |= AVDT_MARKER_SET;
2106 }
2107
Myles Watsoncd1fd072016-11-09 13:17:43 -08002108 // Always get the current number of bufs que'd up
2109 p_scb->l2c_bufs =
2110 (uint8_t)L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_GET);
Chris Mantond44d6402015-03-06 14:41:32 -08002111
Myles Watsoncd1fd072016-11-09 13:17:43 -08002112 if (!list_is_empty(p_scb->a2dp_list)) {
2113 p_buf = (BT_HDR*)list_front(p_scb->a2dp_list);
2114 list_remove(p_scb->a2dp_list, p_buf);
2115 /* use q_info.a2dp data, read the timestamp */
2116 timestamp = *(uint32_t*)(p_buf + 1);
2117 } else {
2118 new_buf = true;
2119 /* A2DP_list empty, call co_data, dup data to other channels */
2120 p_buf = (BT_HDR*)p_scb->p_cos->data(p_scb->cfg.codec_info, &timestamp);
2121
2122 if (p_buf) {
2123 /* use the offset area for the time stamp */
2124 *(uint32_t*)(p_buf + 1) = timestamp;
2125
2126 /* dup the data to other channels */
2127 bta_av_dup_audio_buf(p_scb, p_buf);
Chris Mantond44d6402015-03-06 14:41:32 -08002128 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002129 }
Chris Mantond44d6402015-03-06 14:41:32 -08002130
Myles Watsoncd1fd072016-11-09 13:17:43 -08002131 if (p_buf) {
2132 if (p_scb->l2c_bufs < (BTA_AV_QUEUE_DATA_CHK_NUM)) {
2133 /* There's a buffer, just queue it to L2CAP.
2134 * There's no need to increment it here, it is always read from
2135 * L2CAP (see above).
2136 */
Chris Mantond44d6402015-03-06 14:41:32 -08002137
Myles Watsoncd1fd072016-11-09 13:17:43 -08002138 /* opt is a bit mask, it could have several options set */
2139 opt = AVDT_DATA_OPT_NONE;
2140 if (p_scb->no_rtp_hdr) {
2141 opt |= AVDT_DATA_OPT_NO_RTP;
2142 }
2143
Pavlin Radoslavovd5f49602017-01-03 16:53:18 -08002144 //
2145 // Fragment the payload if larger than the MTU.
2146 // NOTE: The fragmentation is RTP-compatibie.
2147 //
2148 size_t extra_fragments_n = 0;
2149 if (p_buf->len > 0) {
2150 extra_fragments_n = (p_buf->len / p_scb->stream_mtu) +
2151 ((p_buf->len % p_scb->stream_mtu) ? 1 : 0) - 1;
2152 }
2153 std::vector<BT_HDR*> extra_fragments;
2154 extra_fragments.reserve(extra_fragments_n);
2155
2156 uint8_t* data_begin = (uint8_t*)(p_buf + 1) + p_buf->offset;
2157 uint8_t* data_end = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len;
2158 while (extra_fragments_n-- > 0) {
2159 data_begin += p_scb->stream_mtu;
2160 size_t fragment_len = data_end - data_begin;
2161 if (fragment_len > p_scb->stream_mtu) fragment_len = p_scb->stream_mtu;
2162
2163 BT_HDR* p_buf2 = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
2164 p_buf2->offset = p_buf->offset;
2165 p_buf2->len = 0;
2166 p_buf2->layer_specific = 0;
2167 uint8_t* packet2 =
2168 (uint8_t*)(p_buf2 + 1) + p_buf2->offset + p_buf2->len;
2169 memcpy(packet2, data_begin, fragment_len);
2170 p_buf2->len += fragment_len;
2171 extra_fragments.push_back(p_buf2);
2172 p_buf->len -= fragment_len;
2173 }
2174
2175 if (!extra_fragments.empty()) {
2176 // Reset the RTP Marker bit for all fragments except the last one
2177 m_pt &= ~AVDT_MARKER_SET;
2178 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002179 AVDT_WriteReqOpt(p_scb->avdt_handle, p_buf, timestamp, m_pt, opt);
Pavlin Radoslavovd5f49602017-01-03 16:53:18 -08002180 for (size_t i = 0; i < extra_fragments.size(); i++) {
2181 if (i + 1 == extra_fragments.size()) {
2182 // Set the RTP Marker bit for the last fragment
2183 m_pt |= AVDT_MARKER_SET;
2184 }
2185 BT_HDR* p_buf2 = extra_fragments[i];
2186 AVDT_WriteReqOpt(p_scb->avdt_handle, p_buf2, timestamp, m_pt, opt);
2187 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002188 p_scb->cong = true;
2189 } else {
2190 /* there's a buffer, but L2CAP does not seem to be moving data */
2191 if (new_buf) {
2192 /* just got this buffer from co_data,
2193 * put it in queue */
2194 list_append(p_scb->a2dp_list, p_buf);
2195 } else {
2196 /* just dequeue it from the a2dp_list */
2197 if (list_length(p_scb->a2dp_list) < 3) {
2198 /* put it back to the queue */
2199 list_prepend(p_scb->a2dp_list, p_buf);
2200 } else {
2201 /* too many buffers in a2dp_list, drop it. */
2202 bta_av_co_audio_drop(p_scb->hndl);
2203 osi_free(p_buf);
Chris Mantond44d6402015-03-06 14:41:32 -08002204 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002205 }
Chris Mantond44d6402015-03-06 14:41:32 -08002206 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002207 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002208}
2209
2210/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002211 *
2212 * Function bta_av_start_ok
2213 *
2214 * Description Stream started.
2215 *
2216 * Returns void
2217 *
2218 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002219void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2220 tBTA_AV_START start;
Myles Watsoncd1fd072016-11-09 13:17:43 -08002221 bool initiator = false;
2222 bool suspend = false;
2223 uint16_t flush_to;
2224 uint8_t new_role = p_scb->role;
2225 BT_HDR hdr;
2226 uint8_t policy = HCI_ENABLE_SNIFF_MODE;
2227 uint8_t cur_role;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002228
Myles Watsoncd1fd072016-11-09 13:17:43 -08002229 APPL_TRACE_DEBUG("%s: wait:x%x, role:x%x", __func__, p_scb->wait,
2230 p_scb->role);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002231
Myles Watsoncd1fd072016-11-09 13:17:43 -08002232 p_scb->started = true;
Pavlin Radoslavov3b8391c2017-05-12 01:16:10 -07002233 p_scb->current_codec = bta_av_get_a2dp_current_codec();
2234
Myles Watsoncd1fd072016-11-09 13:17:43 -08002235 if (p_scb->sco_suspend) {
2236 p_scb->sco_suspend = false;
2237 }
2238
2239 if (new_role & BTA_AV_ROLE_START_INT) initiator = true;
2240
2241 /* for A2DP SINK we do not send get_caps */
2242 if ((p_scb->avdt_handle == p_scb->seps[p_scb->sep_idx].av_handle) &&
2243 (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)) {
2244 p_scb->wait &= ~(BTA_AV_WAIT_ACP_CAPS_ON);
2245 APPL_TRACE_DEBUG("%s: local SEP type is SNK new wait is 0x%x", __func__,
2246 p_scb->wait);
2247 }
2248 if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_FAILED) {
2249 /* role switch has failed */
2250 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_FAILED;
2251 p_data = (tBTA_AV_DATA*)&hdr;
2252 hdr.offset = BTA_AV_RS_FAIL;
2253 }
2254 APPL_TRACE_DEBUG("%s: wait:x%x", __func__, p_scb->wait);
2255
2256 if (p_data && (p_data->hdr.offset != BTA_AV_RS_NONE)) {
2257 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
2258 if (p_data->hdr.offset == BTA_AV_RS_FAIL) {
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002259 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002260 start.chnl = p_scb->chnl;
2261 start.status = BTA_AV_FAIL_ROLE;
2262 start.hndl = p_scb->hndl;
2263 start.initiator = initiator;
2264 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
2265 return;
2266 }
2267 }
2268
2269 if (!bta_av_link_role_ok(p_scb, A2DP_SET_ONE_BIT))
2270 p_scb->q_tag = BTA_AV_Q_TAG_START;
2271 else {
2272 /* The wait flag may be set here while we are already master on the link */
2273 /* this could happen if a role switch complete event occurred during
2274 * reconfig */
2275 /* if we are now master on the link, there is no need to wait for the role
2276 * switch, */
2277 /* complete anymore so we can clear the wait for role switch flag */
2278 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
2279 }
2280
2281 if (p_scb->wait &
2282 (BTA_AV_WAIT_ROLE_SW_RES_OPEN | BTA_AV_WAIT_ROLE_SW_RES_START)) {
2283 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_STARTED;
2284 p_scb->q_tag = BTA_AV_Q_TAG_START;
2285 }
2286
2287 if (p_scb->wait) {
2288 APPL_TRACE_ERROR("%s: wait:x%x q_tag:%d- not started", __func__,
2289 p_scb->wait, p_scb->q_tag);
2290 /* Clear first bit of p_scb->wait and not to return from this point else
2291 * HAL layer gets blocked. And if there is delay in Get Capability response
2292 * as
2293 * first bit of p_scb->wait is cleared hence it ensures bt_av_start_ok is
2294 * not called
2295 * again from bta_av_save_caps.
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002296 */
Myles Watsoncd1fd072016-11-09 13:17:43 -08002297 p_scb->wait &= ~BTA_AV_WAIT_ACP_CAPS_ON;
2298 }
2299
2300 /* tell role manager to check M/S role */
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002301 bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002302
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002303 bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002304
2305 if (p_scb->media_type == AVDT_MEDIA_TYPE_AUDIO) {
2306 /* in normal logic, conns should be bta_av_cb.audio_count - 1,
2307 * However, bta_av_stream_chg is not called to increase
2308 * bta_av_cb.audio_count yet.
2309 * If the code were to be re-arranged for some reasons, this number may need
2310 * to be changed
2311 */
2312 p_scb->co_started = bta_av_cb.audio_open_cnt;
2313 flush_to = p_bta_av_cfg->p_audio_flush_to[p_scb->co_started - 1];
2314 } else {
2315 flush_to = p_bta_av_cfg->video_flush_to;
2316 }
Jakub Pawlowski903c1662017-06-13 17:53:54 -07002317 L2CA_SetFlushTimeout(p_scb->peer_addr, flush_to);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002318
2319 /* clear the congestion flag */
2320 p_scb->cong = false;
2321
2322 if (new_role & BTA_AV_ROLE_START_INT) {
2323 new_role &= ~BTA_AV_ROLE_START_INT;
2324 } else if ((new_role & BTA_AV_ROLE_AD_ACP) &&
2325 (new_role & BTA_AV_ROLE_SUSPEND_OPT)) {
2326 suspend = true;
2327 }
2328
2329 if (!suspend) {
2330 p_scb->q_tag = BTA_AV_Q_TAG_STREAM;
2331 bta_av_stream_chg(p_scb, true);
2332 }
2333
2334 {
2335 /* If sink starts stream, disable sniff mode here */
2336 if (!initiator) {
2337 /* If souce is the master role, disable role switch during streaming.
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002338 * Otherwise allow role switch, if source is slave.
2339 * Because it would not hurt source, if the peer device wants source to be
2340 * master */
Jakub Pawlowski903c1662017-06-13 17:53:54 -07002341 if ((BTM_GetRole(p_scb->peer_addr, &cur_role) == BTM_SUCCESS) &&
Myles Watsoncd1fd072016-11-09 13:17:43 -08002342 (cur_role == BTM_ROLE_MASTER)) {
2343 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
2344 }
2345
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002346 bta_sys_clear_policy(BTA_ID_AV, policy, p_scb->peer_addr);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002347 }
2348
Myles Watsoncd1fd072016-11-09 13:17:43 -08002349 p_scb->role = new_role;
2350 p_scb->role &= ~BTA_AV_ROLE_AD_ACP;
2351 p_scb->role &= ~BTA_AV_ROLE_SUSPEND_OPT;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002352
Myles Watsoncd1fd072016-11-09 13:17:43 -08002353 p_scb->no_rtp_hdr = false;
2354 p_scb->p_cos->start(p_scb->hndl, p_scb->cfg.codec_info, &p_scb->no_rtp_hdr);
2355 p_scb->co_started = true;
2356
2357 APPL_TRACE_DEBUG("%s: suspending: %d, role:x%x, init %d", __func__, suspend,
2358 p_scb->role, initiator);
2359
2360 start.suspending = suspend;
2361 start.initiator = initiator;
2362 start.chnl = p_scb->chnl;
2363 start.status = BTA_AV_SUCCESS;
2364 start.hndl = p_scb->hndl;
2365 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
2366
2367 if (suspend) {
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002368 tBTA_AV_API_STOP stop;
Myles Watsoncd1fd072016-11-09 13:17:43 -08002369 p_scb->role |= BTA_AV_ROLE_SUSPEND;
2370 p_scb->cong = true; /* do not allow the media data to go through */
2371 /* do not duplicate the media packets to this channel */
2372 p_scb->p_cos->stop(p_scb->hndl);
2373 p_scb->co_started = false;
2374 stop.flush = false;
2375 stop.suspend = true;
Pavlin Radoslavov5ce01162016-12-05 13:02:26 -08002376 stop.reconfig_stop = false;
Myles Watsoncd1fd072016-11-09 13:17:43 -08002377 bta_av_ssm_execute(p_scb, BTA_AV_AP_STOP_EVT, (tBTA_AV_DATA*)&stop);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302378 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002379 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002380}
2381
2382/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002383 *
2384 * Function bta_av_start_failed
2385 *
2386 * Description Stream start failed.
2387 *
2388 * Returns void
2389 *
2390 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002391void bta_av_start_failed(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
2392 if (p_scb->started == false && p_scb->co_started == false) {
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002393 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002394 notify_start_failed(p_scb);
2395 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002396
Myles Watsoncd1fd072016-11-09 13:17:43 -08002397 bta_sys_set_policy(BTA_ID_AV,
2398 (HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_MASTER_SLAVE_SWITCH),
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002399 p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002400 p_scb->sco_suspend = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002401}
2402
2403/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002404 *
2405 * Function bta_av_str_closed
2406 *
2407 * Description Stream closed.
2408 *
2409 * Returns void
2410 *
2411 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002412void bta_av_str_closed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2413 tBTA_AV data;
2414 tBTA_AV_EVT event;
Myles Watsoncd1fd072016-11-09 13:17:43 -08002415 uint8_t policy = HCI_ENABLE_SNIFF_MODE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002416
Myles Watsoncd1fd072016-11-09 13:17:43 -08002417 if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 ||
2418 bta_av_cb.audio_open_cnt == 1)
2419 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002420 bta_sys_set_policy(BTA_ID_AV, policy, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002421 if (bta_av_cb.audio_open_cnt <= 1) {
2422 /* last connection - restore the allow switch flag */
2423 L2CA_SetDesireRole(L2CAP_ROLE_ALLOW_SWITCH);
2424 }
2425
2426 if (p_scb->open_status) {
2427 /* must be failure when opening the stream */
Jakub Pawlowski903c1662017-06-13 17:53:54 -07002428 data.open.bd_addr = p_scb->peer_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -08002429 data.open.status = p_scb->open_status;
2430 data.open.chnl = p_scb->chnl;
2431 data.open.hndl = p_scb->hndl;
2432
2433 if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC)
2434 data.open.sep = AVDT_TSEP_SNK;
2435 else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)
2436 data.open.sep = AVDT_TSEP_SRC;
2437
2438 event = BTA_AV_OPEN_EVT;
2439 p_scb->open_status = BTA_AV_SUCCESS;
2440
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002441 bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002442 bta_av_cleanup(p_scb, p_data);
2443 (*bta_av_cb.p_cback)(event, &data);
2444 } else {
2445 /* do stop if we were started */
2446 if (p_scb->co_started) {
2447 bta_av_str_stopped(p_scb, NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002448 }
2449
The Android Open Source Project5738f832012-12-12 16:00:35 -08002450 {
Pavlin Radoslavovcd02ce92016-11-04 17:18:51 -07002451 p_scb->p_cos->close(p_scb->hndl);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002452 data.close.chnl = p_scb->chnl;
2453 data.close.hndl = p_scb->hndl;
2454 event = BTA_AV_CLOSE_EVT;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302455
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002456 bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002457 bta_av_cleanup(p_scb, p_data);
2458 (*bta_av_cb.p_cback)(event, &data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002459 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002460 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002461}
2462
2463/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002464 *
2465 * Function bta_av_clr_cong
2466 *
2467 * Description Clear stream congestion flag.
2468 *
2469 * Returns void
2470 *
2471 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002472void bta_av_clr_cong(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
2473 if (p_scb->co_started) p_scb->cong = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002474}
2475
2476/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002477 *
2478 * Function bta_av_suspend_cfm
2479 *
2480 * Description process the suspend response
2481 *
2482 * Returns void
2483 *
2484 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002485void bta_av_suspend_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2486 tBTA_AV_SUSPEND suspend_rsp;
2487 uint8_t err_code = p_data->str_msg.msg.hdr.err_code;
2488 uint8_t policy = HCI_ENABLE_SNIFF_MODE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002489
Myles Watsoncd1fd072016-11-09 13:17:43 -08002490 APPL_TRACE_DEBUG("%s: audio_open_cnt = %d, err_code = %d", __func__,
2491 bta_av_cb.audio_open_cnt, err_code);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002492
Myles Watsoncd1fd072016-11-09 13:17:43 -08002493 if (p_scb->started == false) {
2494 /* handle the condition where there is a collision of SUSPEND req from
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002495 *either side
2496 ** Second SUSPEND req could be rejected. Do not treat this as a failure
2497 */
Myles Watsoncd1fd072016-11-09 13:17:43 -08002498 APPL_TRACE_WARNING("%s: already suspended, ignore, err_code %d", __func__,
2499 err_code);
2500 return;
2501 }
2502
2503 suspend_rsp.status = BTA_AV_SUCCESS;
2504 if (err_code && (err_code != AVDT_ERR_BAD_STATE)) {
2505 /* Disable suspend feature only with explicit rejection(not with timeout) */
2506 if (err_code != AVDT_ERR_TIMEOUT) {
2507 p_scb->suspend_sup = false;
Zhihai Xu5ae72cf2013-05-15 17:29:44 -07002508 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002509 suspend_rsp.status = BTA_AV_FAIL;
Zhihai Xu5ae72cf2013-05-15 17:29:44 -07002510
Myles Watsoncd1fd072016-11-09 13:17:43 -08002511 APPL_TRACE_ERROR("%s: suspend failed, closing connection", __func__);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002512
Myles Watsoncd1fd072016-11-09 13:17:43 -08002513 /* SUSPEND failed. Close connection. */
2514 bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, NULL);
2515 } else {
2516 /* only set started to false when suspend is successful */
2517 p_scb->started = false;
2518 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002519
Myles Watsoncd1fd072016-11-09 13:17:43 -08002520 if (p_scb->role & BTA_AV_ROLE_SUSPEND) {
2521 p_scb->role &= ~BTA_AV_ROLE_SUSPEND;
2522 p_scb->cong = false;
2523 }
2524
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002525 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002526 if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 ||
2527 bta_av_cb.audio_open_cnt == 1)
2528 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
Jakub Pawlowskic752e132017-06-16 12:52:23 -07002529 bta_sys_set_policy(BTA_ID_AV, policy, p_scb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002530
2531 /* in case that we received suspend_ind, we may need to call co_stop here */
2532 if (p_scb->co_started) {
Andre Eisenbach796523d2016-11-10 16:11:00 -08002533 /* TODO(eisenbach): RE-IMPLEMENT USING VSC OR HAL EXTENSION
Myles Watsoncd1fd072016-11-09 13:17:43 -08002534 vendor_get_interface()->send_command(
2535 (vendor_opcode_t)BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
2536 if (p_scb->offload_start_pending) {
2537 tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
2538 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002539 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002540 p_scb->offload_start_pending = false;
Andre Eisenbach796523d2016-11-10 16:11:00 -08002541 */
The Android Open Source Project5738f832012-12-12 16:00:35 -08002542
Myles Watsoncd1fd072016-11-09 13:17:43 -08002543 bta_av_stream_chg(p_scb, false);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002544
2545 {
Myles Watsoncd1fd072016-11-09 13:17:43 -08002546 p_scb->co_started = false;
2547 p_scb->p_cos->stop(p_scb->hndl);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002548 }
Jakub Pawlowski903c1662017-06-13 17:53:54 -07002549 L2CA_SetFlushTimeout(p_scb->peer_addr, L2CAP_DEFAULT_FLUSH_TO);
Myles Watsoncd1fd072016-11-09 13:17:43 -08002550 }
2551
2552 {
2553 suspend_rsp.chnl = p_scb->chnl;
2554 suspend_rsp.hndl = p_scb->hndl;
2555 suspend_rsp.initiator = p_data->str_msg.initiator;
2556 (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, (tBTA_AV*)&suspend_rsp);
2557 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002558}
2559
2560/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002561 *
2562 * Function bta_av_rcfg_str_ok
2563 *
2564 * Description report reconfigure successful
2565 *
2566 * Returns void
2567 *
2568 ******************************************************************************/
Pavlin Radoslavov31d373b2017-02-14 12:18:44 -08002569void bta_av_rcfg_str_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
Myles Watsoncd1fd072016-11-09 13:17:43 -08002570 tBTA_AV_RECONFIG evt;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002571
Myles Watsoncd1fd072016-11-09 13:17:43 -08002572 p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle);
2573 APPL_TRACE_DEBUG("%s: l2c_cid: %d", __func__, p_scb->l2c_cid);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002574
Pavlin Radoslavovc9cff562017-02-14 17:38:19 -08002575 if (p_data != NULL) {
2576 // p_data could be NULL if the reconfig was triggered by the local device
2577 p_scb->stream_mtu =
2578 p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE;
2579 uint16_t mtu = bta_av_chk_mtu(p_scb, p_scb->stream_mtu);
2580 APPL_TRACE_DEBUG("%s: l2c_cid: 0x%x stream_mtu: %d mtu: %d", __func__,
2581 p_scb->l2c_cid, p_scb->stream_mtu, mtu);
2582 if (mtu == 0 || mtu > p_scb->stream_mtu) mtu = p_scb->stream_mtu;
2583 p_scb->p_cos->update_mtu(p_scb->hndl, mtu);
2584 }
Pavlin Radoslavov31d373b2017-02-14 12:18:44 -08002585
Myles Watsoncd1fd072016-11-09 13:17:43 -08002586 /* rc listen */
2587 bta_av_st_rc_timer(p_scb, NULL);
2588 osi_free_and_reset((void**)&p_scb->p_cap);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002589
Myles Watsoncd1fd072016-11-09 13:17:43 -08002590 /* No need to keep the role bits once reconfig is done. */
2591 p_scb->role &= ~BTA_AV_ROLE_AD_ACP;
2592 p_scb->role &= ~BTA_AV_ROLE_SUSPEND_OPT;
2593 p_scb->role &= ~BTA_AV_ROLE_START_INT;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002594
Myles Watsoncd1fd072016-11-09 13:17:43 -08002595 {
2596 /* reconfigure success */
2597 evt.status = BTA_AV_SUCCESS;
2598 evt.chnl = p_scb->chnl;
2599 evt.hndl = p_scb->hndl;
2600 (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV*)&evt);
2601 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002602}
2603
2604/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002605 *
2606 * Function bta_av_rcfg_failed
2607 *
2608 * Description process reconfigure failed
2609 *
2610 * Returns void
2611 *
2612 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002613void bta_av_rcfg_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2614 tBTA_AV_RECONFIG evt;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002615
Myles Watsoncd1fd072016-11-09 13:17:43 -08002616 APPL_TRACE_DEBUG("%s: num_recfg: %d, conn_lcb:0x%x", __func__,
2617 p_scb->num_recfg, bta_av_cb.conn_lcb);
2618 if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) {
2619 bta_av_cco_close(p_scb, p_data);
2620 /* report failure */
2621 evt.status = BTA_AV_FAIL_STREAM;
2622 evt.chnl = p_scb->chnl;
2623 evt.hndl = p_scb->hndl;
2624 (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV*)&evt);
2625 /* go to closing state */
2626 bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, NULL);
2627 } else {
2628 /* open failed. try again */
2629 p_scb->num_recfg++;
2630 if (bta_av_cb.conn_lcb) {
2631 AVDT_DisconnectReq(p_scb->peer_addr, bta_av_dt_cback[p_scb->hdi]);
2632 } else {
2633 bta_av_connect_req(p_scb, NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002634 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002635 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002636}
2637
2638/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002639 *
2640 * Function bta_av_rcfg_connect
2641 *
2642 * Description stream closed. reconnect the stream
2643 *
2644 * Returns void
2645 *
2646 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002647void bta_av_rcfg_connect(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
2648 p_scb->cong = false;
2649 p_scb->num_recfg++;
2650 APPL_TRACE_DEBUG("%s: num_recfg: %d", __func__, p_scb->num_recfg);
2651 if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) {
2652 /* let bta_av_rcfg_failed report fail */
2653 bta_av_rcfg_failed(p_scb, NULL);
2654 } else
2655 AVDT_ConnectReq(p_scb->peer_addr, p_scb->sec_mask,
2656 bta_av_dt_cback[p_scb->hdi]);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002657}
2658
2659/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002660 *
2661 * Function bta_av_rcfg_discntd
2662 *
2663 * Description AVDT disconnected. reconnect the stream
2664 *
2665 * Returns void
2666 *
2667 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002668void bta_av_rcfg_discntd(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
2669 tBTA_AV_RECONFIG evt;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002670
Myles Watsoncd1fd072016-11-09 13:17:43 -08002671 APPL_TRACE_DEBUG("%s: num_recfg: %d", __func__, p_scb->num_recfg);
2672 p_scb->num_recfg++;
2673 if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) {
2674 /* report failure */
2675 evt.status = BTA_AV_FAIL_STREAM;
2676 evt.chnl = p_scb->chnl;
2677 evt.hndl = p_scb->hndl;
2678 (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV*)&evt);
2679 /* report close event & go to init state */
2680 bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, NULL);
2681 } else
2682 AVDT_ConnectReq(p_scb->peer_addr, p_scb->sec_mask,
2683 bta_av_dt_cback[p_scb->hdi]);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002684}
2685
2686/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002687 *
2688 * Function bta_av_suspend_cont
2689 *
2690 * Description received the suspend response.
2691 * continue to reconfigure the stream
2692 *
2693 * Returns void
2694 *
2695 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002696void bta_av_suspend_cont(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2697 uint8_t err_code = p_data->str_msg.msg.hdr.err_code;
2698 tBTA_AV_RECONFIG evt;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002699
Myles Watsoncd1fd072016-11-09 13:17:43 -08002700 p_scb->started = false;
2701 p_scb->cong = false;
2702 if (err_code) {
2703 if (AVDT_ERR_CONNECT == err_code) {
2704 /* report failure */
2705 evt.status = BTA_AV_FAIL;
2706 (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV*)&evt);
2707 bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, NULL);
2708 } else {
2709 APPL_TRACE_ERROR("%s: suspend rejected, try close", __func__);
2710 /* Disable suspend feature only with explicit rejection(not with timeout)
2711 */
2712 if (err_code != AVDT_ERR_TIMEOUT) {
2713 p_scb->suspend_sup = false;
2714 }
2715 /* drop the buffers queued in L2CAP */
2716 L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002717
Myles Watsoncd1fd072016-11-09 13:17:43 -08002718 AVDT_CloseReq(p_scb->avdt_handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002719 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002720 } else {
2721 APPL_TRACE_DEBUG("%s: calling AVDT_ReconfigReq", __func__);
2722 /* reconfig the stream */
The Android Open Source Project5738f832012-12-12 16:00:35 -08002723
Myles Watsoncd1fd072016-11-09 13:17:43 -08002724 AVDT_ReconfigReq(p_scb->avdt_handle, p_scb->p_cap);
2725 p_scb->p_cap->psc_mask = p_scb->cur_psc_mask;
2726 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002727}
2728
2729/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002730 *
2731 * Function bta_av_rcfg_cfm
2732 *
2733 * Description if reconfigure is successful, report the event
2734 * otherwise, close the stream.
2735 *
2736 * Returns void
2737 *
2738 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002739void bta_av_rcfg_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2740 uint8_t err_code = p_data->str_msg.msg.hdr.err_code;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002741
Myles Watsoncd1fd072016-11-09 13:17:43 -08002742 APPL_TRACE_DEBUG("%s: err_code = %d", __func__, err_code);
Pavlin Radoslavove91297a2017-06-19 12:44:11 -07002743
2744 // Disable AVDTP RECONFIGURE for blacklisted devices
2745 bool disable_avdtp_reconfigure = false;
2746 {
2747 char remote_name[BTM_MAX_REM_BD_NAME_LEN] = "";
Jakub Pawlowski04801862017-06-19 19:41:06 -07002748 if (btif_storage_get_stored_remote_name(p_scb->peer_addr, remote_name)) {
Pavlin Radoslavove91297a2017-06-19 12:44:11 -07002749 if (interop_match_name(INTEROP_DISABLE_AVDTP_RECONFIGURE, remote_name) ||
2750 interop_match_addr(INTEROP_DISABLE_AVDTP_RECONFIGURE,
Jakub Pawlowskia484a882017-06-24 17:30:18 -07002751 (const RawAddress*)&p_scb->peer_addr)) {
Jakub Pawlowski04801862017-06-19 19:41:06 -07002752 VLOG(1) << __func__ << ": disable AVDTP RECONFIGURE: interop matched "
2753 "name "
2754 << remote_name << " address " << p_scb->peer_addr;
Pavlin Radoslavove91297a2017-06-19 12:44:11 -07002755 disable_avdtp_reconfigure = true;
2756 }
2757 }
2758 }
2759
2760 if ((err_code != 0) || disable_avdtp_reconfigure) {
Myles Watsoncd1fd072016-11-09 13:17:43 -08002761 APPL_TRACE_ERROR("%s: reconfig rejected, try close", __func__);
2762 /* Disable reconfiguration feature only with explicit rejection(not with
2763 * timeout) */
Pavlin Radoslavove91297a2017-06-19 12:44:11 -07002764 if ((err_code != AVDT_ERR_TIMEOUT) || disable_avdtp_reconfigure) {
Myles Watsoncd1fd072016-11-09 13:17:43 -08002765 p_scb->recfg_sup = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002766 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002767 /* started flag is false when reconfigure command is sent */
2768 /* drop the buffers queued in L2CAP */
2769 L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
2770 AVDT_CloseReq(p_scb->avdt_handle);
2771 } else {
2772 /* update the codec info after rcfg cfm */
2773 APPL_TRACE_DEBUG(
2774 "%s: updating from codec %s to codec %s", __func__,
2775 A2DP_CodecName(p_scb->cfg.codec_info),
2776 A2DP_CodecName(p_data->str_msg.msg.reconfig_cfm.p_cfg->codec_info));
2777 memcpy(p_scb->cfg.codec_info,
2778 p_data->str_msg.msg.reconfig_cfm.p_cfg->codec_info, AVDT_CODEC_SIZE);
2779 /* take the SSM back to OPEN state */
2780 bta_av_ssm_execute(p_scb, BTA_AV_STR_OPEN_OK_EVT, NULL);
2781 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002782}
2783
2784/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002785 *
2786 * Function bta_av_rcfg_open
2787 *
Myles Watsoncd1fd072016-11-09 13:17:43 -08002788 * Description AVDT is connected. open the stream with the new
Myles Watson1baaae32016-11-09 14:25:23 -08002789 * configuration
Myles Watson8af480e2016-11-09 10:40:23 -08002790 *
2791 * Returns void
2792 *
2793 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002794void bta_av_rcfg_open(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
2795 APPL_TRACE_DEBUG("%s: num_disc_snks = %d", __func__, p_scb->num_disc_snks);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002796
Myles Watsoncd1fd072016-11-09 13:17:43 -08002797 if (p_scb->num_disc_snks == 0) {
2798 /* Need to update call-out module so that it will be ready for discover */
2799 p_scb->p_cos->stop(p_scb->hndl);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002800
Myles Watsoncd1fd072016-11-09 13:17:43 -08002801 /* send avdtp discover request */
2802 AVDT_DiscoverReq(p_scb->peer_addr, p_scb->sep_info, BTA_AV_NUM_SEPS,
2803 bta_av_dt_cback[p_scb->hdi]);
2804 } else {
2805 memcpy(p_scb->cfg.codec_info, p_scb->p_cap->codec_info, AVDT_CODEC_SIZE);
2806 /* we may choose to use a different SEP at reconfig.
2807 * adjust the sep_idx now */
2808 bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SRC));
The Android Open Source Project5738f832012-12-12 16:00:35 -08002809
Myles Watsoncd1fd072016-11-09 13:17:43 -08002810 /* open the stream with the new config */
2811 p_scb->sep_info_idx = p_scb->rcfg_idx;
2812 AVDT_OpenReq(p_scb->avdt_handle, p_scb->peer_addr,
2813 p_scb->sep_info[p_scb->sep_info_idx].seid, p_scb->p_cap);
2814 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002815}
2816
2817/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002818 *
2819 * Function bta_av_security_rej
2820 *
2821 * Description Send an AVDTP security reject.
2822 *
2823 * Returns void
2824 *
2825 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002826void bta_av_security_rej(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
2827 AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_BAD_STATE,
2828 NULL, 0);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002829}
2830
2831/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002832 *
2833 * Function bta_av_chk_2nd_start
2834 *
2835 * Description check if this is 2nd stream and if it needs to be started.
Myles Watsoncd1fd072016-11-09 13:17:43 -08002836 * This function needs to be kept very similar to
Myles Watson1baaae32016-11-09 14:25:23 -08002837 * bta_av_chk_start
Myles Watson8af480e2016-11-09 10:40:23 -08002838 *
2839 * Returns void
2840 *
2841 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002842void bta_av_chk_2nd_start(tBTA_AV_SCB* p_scb,
2843 UNUSED_ATTR tBTA_AV_DATA* p_data) {
2844 tBTA_AV_SCB* p_scbi;
2845 int i;
2846 bool new_started = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002847
Myles Watsoncd1fd072016-11-09 13:17:43 -08002848 if ((p_scb->chnl == BTA_AV_CHNL_AUDIO) && (bta_av_cb.audio_open_cnt >= 2)) {
2849 /* more than one audio channel is connected */
2850 if (!(p_scb->role & BTA_AV_ROLE_SUSPEND_OPT)) {
2851 /* this channel does not need to be reconfigured.
2852 * if there is other channel streaming, start the stream now */
2853 for (i = 0; i < BTA_AV_NUM_STRS; i++) {
2854 p_scbi = bta_av_cb.p_scb[i];
2855 if (p_scbi && p_scbi->chnl == BTA_AV_CHNL_AUDIO && p_scbi->co_started) {
2856 if (!new_started) {
2857 /* start the new stream */
2858 new_started = true;
2859 bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
2860 }
2861 /* may need to update the flush timeout of this already started stream
2862 */
2863 if (p_scbi->co_started != bta_av_cb.audio_open_cnt) {
2864 p_scbi->co_started = bta_av_cb.audio_open_cnt;
2865 L2CA_SetFlushTimeout(
Jakub Pawlowski903c1662017-06-13 17:53:54 -07002866 p_scbi->peer_addr,
Myles Watsoncd1fd072016-11-09 13:17:43 -08002867 p_bta_av_cfg->p_audio_flush_to[p_scbi->co_started - 1]);
2868 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002869 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002870 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002871 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002872 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002873}
2874
2875/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002876 *
2877 * Function bta_av_open_rc
2878 *
2879 * Description Send a message to main SM to open RC channel.
2880 *
2881 * Returns void
2882 *
2883 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002884void bta_av_open_rc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2885 tBTA_AV_START start;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002886
Myles Watsoncd1fd072016-11-09 13:17:43 -08002887 APPL_TRACE_DEBUG("%s: use_rc: %d, wait: x%x role:x%x", __func__,
2888 p_scb->use_rc, p_scb->wait, p_scb->role);
2889 if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) &&
2890 (p_scb->q_tag == BTA_AV_Q_TAG_START)) {
2891 /* waiting for role switch for some reason & the timer expires */
2892 if (!bta_av_link_role_ok(p_scb, A2DP_SET_ONE_BIT)) {
2893 APPL_TRACE_ERROR(
2894 "%s: failed to start streaming for role management reasons!!",
2895 __func__);
2896 alarm_cancel(p_scb->avrc_ct_timer);
2897 start.chnl = p_scb->chnl;
2898 start.status = BTA_AV_FAIL_ROLE;
2899 start.initiator = true;
2900 start.hndl = p_scb->hndl;
2901 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
2902 bta_av_cb.rs_idx = 0;
2903 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
2904 } else {
2905 /* role switch is done. continue to start streaming */
2906 bta_av_cb.rs_idx = 0;
2907 p_data->hdr.offset = BTA_AV_RS_OK;
2908 bta_av_start_ok(p_scb, p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002909 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002910 return;
2911 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002912
Myles Watsoncd1fd072016-11-09 13:17:43 -08002913 if (p_scb->use_rc == true || (p_scb->role & BTA_AV_ROLE_AD_ACP)) {
2914 if (bta_av_cb.disc) {
2915 /* AVRC discover db is in use */
2916 if (p_scb->rc_handle == BTA_AV_RC_HANDLE_NONE) {
2917 /* AVRC channel is not connected. delay a little bit */
2918 if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) == 0) {
2919 bta_sys_start_timer(p_scb->avrc_ct_timer, BTA_AV_RC_DISC_TIME_VAL,
2920 BTA_AV_AVRC_TIMER_EVT, p_scb->hndl);
2921 } else {
2922 p_scb->wait |= BTA_AV_WAIT_CHECK_RC;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002923 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002924 }
2925 } else {
2926 /* use main SM for AVRC SDP activities */
2927 bta_av_rc_disc((uint8_t)(p_scb->hdi + 1));
The Android Open Source Project5738f832012-12-12 16:00:35 -08002928 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002929 } else {
2930 if (BTA_AV_RC_HANDLE_NONE != p_scb->rc_handle) {
2931 /* the open API said that this handle does not want a RC connection.
2932 * disconnect it now */
2933 AVRC_Close(p_scb->rc_handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002934 }
Myles Watsoncd1fd072016-11-09 13:17:43 -08002935 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002936}
2937
2938/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002939 *
2940 * Function bta_av_open_at_inc
2941 *
2942 * Description This function is called if API open is called by application
2943 * while state-machine is at incoming state.
2944 *
2945 * Returns void
2946 *
2947 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002948void bta_av_open_at_inc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2949 memcpy(&(p_scb->open_api), &(p_data->api_open), sizeof(tBTA_AV_API_OPEN));
The Android Open Source Project5738f832012-12-12 16:00:35 -08002950
Myles Watsoncd1fd072016-11-09 13:17:43 -08002951 if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) {
2952 p_scb->coll_mask |= BTA_AV_COLL_API_CALLED;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002953
Myles Watsoncd1fd072016-11-09 13:17:43 -08002954 /* API open will be handled at timeout if SNK did not start signalling. */
2955 /* API open will be ignored if SNK starts signalling. */
2956 } else {
2957 /* SNK did not start signalling, API was called N seconds timeout. */
2958 /* We need to switch to INIT state and start opening connection. */
2959 p_scb->coll_mask = 0;
2960 bta_av_set_scb_sst_init(p_scb);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002961
Myles Watsoncd1fd072016-11-09 13:17:43 -08002962 tBTA_AV_API_OPEN* p_buf =
2963 (tBTA_AV_API_OPEN*)osi_malloc(sizeof(tBTA_AV_API_OPEN));
2964 memcpy(p_buf, &(p_scb->open_api), sizeof(tBTA_AV_API_OPEN));
2965 p_scb->skip_sdp = true;
2966 bta_sys_sendmsg(p_buf);
2967 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002968}
2969
Abhijit Adsule47b43102015-05-19 02:44:26 -05002970/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08002971 *
2972 * Function bta_av_offload_req
2973 *
2974 * Description This function is called if application requests offload of
2975 * a2dp audio.
2976 *
2977 * Returns void
2978 *
2979 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08002980void bta_av_offload_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
2981 tBTA_AV_STATUS status = BTA_AV_FAIL_RESOURCES;
Abhijit Adsule47b43102015-05-19 02:44:26 -05002982
Myles Watsoncd1fd072016-11-09 13:17:43 -08002983 APPL_TRACE_DEBUG("%s: stream %s, audio channels open %d", __func__,
2984 p_scb->started ? "STARTED" : "STOPPED",
2985 bta_av_cb.audio_open_cnt);
Abhijit Adsule47b43102015-05-19 02:44:26 -05002986
Myles Watsoncd1fd072016-11-09 13:17:43 -08002987 /* Check if stream has already been started. */
2988 /* Support offload if only one audio source stream is open. */
2989 if (p_scb->started != true) {
2990 status = BTA_AV_FAIL_STREAM;
Myles Watsoncd1fd072016-11-09 13:17:43 -08002991 }
Abhijit Adsule47b43102015-05-19 02:44:26 -05002992
Andre Eisenbach796523d2016-11-10 16:11:00 -08002993 /* TODO(eisenbach): RE-IMPLEMENT USING VSC OR HAL EXTENSION
2994 uint16_t mtu = bta_av_chk_mtu(p_scb, p_scb->stream_mtu);
2995 else if (bta_av_cb.audio_open_cnt == 1 &&
2996 p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC &&
2997 p_scb->chnl == BTA_AV_CHNL_AUDIO) {
2998 bt_vendor_op_a2dp_offload_t a2dp_offload_start;
2999
3000 if (L2CA_GetConnectionConfig(
3001 p_scb->l2c_cid, &a2dp_offload_start.acl_data_size,
3002 &a2dp_offload_start.remote_cid, &a2dp_offload_start.lm_handle)) {
3003 APPL_TRACE_DEBUG("%s: l2cmtu %d lcid 0x%02X rcid 0x%02X lm_handle
3004 0x%02X",
3005 __func__, a2dp_offload_start.acl_data_size,
3006 p_scb->l2c_cid, a2dp_offload_start.remote_cid,
3007 a2dp_offload_start.lm_handle);
3008
3009 a2dp_offload_start.bta_av_handle = p_scb->hndl;
3010 a2dp_offload_start.xmit_quota = BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA;
3011 a2dp_offload_start.stream_mtu =
3012 (mtu < p_scb->stream_mtu) ? mtu : p_scb->stream_mtu;
3013 a2dp_offload_start.local_cid = p_scb->l2c_cid;
3014 a2dp_offload_start.is_flushable = true;
3015 a2dp_offload_start.stream_source =
3016 ((uint32_t)(p_scb->cfg.codec_info[1] | p_scb->cfg.codec_info[2]));
3017
3018 memcpy(a2dp_offload_start.codec_info, p_scb->cfg.codec_info,
3019 sizeof(a2dp_offload_start.codec_info));
3020
3021 if (!vendor_get_interface()->send_command(
3022 (vendor_opcode_t)BT_VND_OP_A2DP_OFFLOAD_START,
3023 &a2dp_offload_start)) {
3024 status = BTA_AV_SUCCESS;
3025 p_scb->offload_start_pending = true;
3026 }
3027 }
3028 }
3029 */
Myles Watsoncd1fd072016-11-09 13:17:43 -08003030 if (status != BTA_AV_SUCCESS)
3031 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
Abhijit Adsule47b43102015-05-19 02:44:26 -05003032}
3033
3034/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -08003035 *
3036 * Function bta_av_offload_rsp
3037 *
3038 * Description This function is called when the vendor lib responds to
3039 * BT_VND_OP_A2DP_OFFLOAD_START.
3040 *
3041 * Returns void
3042 *
3043 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -08003044void bta_av_offload_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
3045 tBTA_AV_STATUS status = p_data->api_status_rsp.status;
Abhijit Adsule47b43102015-05-19 02:44:26 -05003046
Myles Watsoncd1fd072016-11-09 13:17:43 -08003047 APPL_TRACE_DEBUG("%s: stream %s status %s", __func__,
3048 p_scb->started ? "STARTED" : "STOPPED",
3049 status ? "FAIL" : "SUCCESS");
Abhijit Adsule47b43102015-05-19 02:44:26 -05003050
Myles Watsoncd1fd072016-11-09 13:17:43 -08003051 /* Check if stream has already been started. */
3052 if (status == BTA_AV_SUCCESS && p_scb->started != true) {
3053 status = BTA_AV_FAIL_STREAM;
3054 }
Abhijit Adsule47b43102015-05-19 02:44:26 -05003055
Myles Watsoncd1fd072016-11-09 13:17:43 -08003056 p_scb->offload_start_pending = false;
3057 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
Abhijit Adsule47b43102015-05-19 02:44:26 -05003058}