blob: d4e2e579a2768b91355f748a99c0f4faa3190840 [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"
28#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
29
Chris Mantond44d6402015-03-06 14:41:32 -080030#include <assert.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080031#include <string.h>
Anubhav Gupta6a277762014-11-13 19:58:09 +053032
33#include <cutils/properties.h>
34
The Android Open Source Project5738f832012-12-12 16:00:35 -080035#include "bta_av_int.h"
36#include "avdt_api.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080037#include "utl.h"
38#include "l2c_api.h"
39#include "l2cdefs.h"
Abhijit Adsule47b43102015-05-19 02:44:26 -050040#include "bt_utils.h"
41#include "vendor.h"
42
The Android Open Source Project5738f832012-12-12 16:00:35 -080043#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
44#include "bta_ar_api.h"
45#endif
46
47/*****************************************************************************
48** Constants
49*****************************************************************************/
50
51/* the delay time in milliseconds to start service discovery on AVRCP */
52#ifndef BTA_AV_RC_DISC_TIME_VAL
53#define BTA_AV_RC_DISC_TIME_VAL 3500
54#endif
55
56/* the timer in milliseconds to guard against link busy and AVDT_CloseReq failed to be sent */
57#ifndef BTA_AV_CLOSE_REQ_TIME_VAL
58#define BTA_AV_CLOSE_REQ_TIME_VAL 4000
59#endif
60
61/* number to retry on reconfigure failure - some headsets requirs this number to be more than 1 */
62#ifndef BTA_AV_RECONFIG_RETRY
63#define BTA_AV_RECONFIG_RETRY 6
64#endif
65
Abhijit Adsule47b43102015-05-19 02:44:26 -050066/* ACL quota we are letting FW use for A2DP Offload Tx. */
67#define BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA 4
68
Chris Mantond44d6402015-03-06 14:41:32 -080069static void bta_av_st_rc_timer(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
70
The Android Open Source Project5738f832012-12-12 16:00:35 -080071/* state machine states */
72enum
73{
74 BTA_AV_INIT_SST,
75 BTA_AV_INCOMING_SST,
76 BTA_AV_OPENING_SST,
77 BTA_AV_OPEN_SST,
78 BTA_AV_RCFG_SST,
79 BTA_AV_CLOSING_SST
80};
81
82
83/* the call out functions for audio stream */
84const tBTA_AV_CO_FUNCTS bta_av_a2d_cos =
85{
86 bta_av_co_audio_init,
87 bta_av_co_audio_disc_res,
88 bta_av_co_audio_getconfig,
89 bta_av_co_audio_setconfig,
90 bta_av_co_audio_open,
91 bta_av_co_audio_close,
92 bta_av_co_audio_start,
93 bta_av_co_audio_stop,
94 bta_av_co_audio_src_data_path,
95 bta_av_co_audio_delay
96};
97
98/* ssm action functions for audio stream */
99const tBTA_AV_SACT bta_av_a2d_action[] =
100{
101 bta_av_do_disc_a2d, /* BTA_AV_DO_DISC */
102 bta_av_cleanup, /* BTA_AV_CLEANUP */
103 bta_av_free_sdb, /* BTA_AV_FREE_SDB */
104 bta_av_config_ind, /* BTA_AV_CONFIG_IND */
105 bta_av_disconnect_req, /* BTA_AV_DISCONNECT_REQ */
106 bta_av_security_req, /* BTA_AV_SECURITY_REQ */
107 bta_av_security_rsp, /* BTA_AV_SECURITY_RSP */
108 bta_av_setconfig_rsp, /* BTA_AV_SETCONFIG_RSP */
109 bta_av_st_rc_timer, /* BTA_AV_ST_RC_TIMER */
110 bta_av_str_opened, /* BTA_AV_STR_OPENED */
111 bta_av_security_ind, /* BTA_AV_SECURITY_IND */
112 bta_av_security_cfm, /* BTA_AV_SECURITY_CFM */
113 bta_av_do_close, /* BTA_AV_DO_CLOSE */
114 bta_av_connect_req, /* BTA_AV_CONNECT_REQ */
115 bta_av_sdp_failed, /* BTA_AV_SDP_FAILED */
116 bta_av_disc_results, /* BTA_AV_DISC_RESULTS */
117 bta_av_disc_res_as_acp, /* BTA_AV_DISC_RES_AS_ACP */
118 bta_av_open_failed, /* BTA_AV_OPEN_FAILED */
119 bta_av_getcap_results, /* BTA_AV_GETCAP_RESULTS */
120 bta_av_setconfig_rej, /* BTA_AV_SETCONFIG_REJ */
121 bta_av_discover_req, /* BTA_AV_DISCOVER_REQ */
122 bta_av_conn_failed, /* BTA_AV_CONN_FAILED */
123 bta_av_do_start, /* BTA_AV_DO_START */
124 bta_av_str_stopped, /* BTA_AV_STR_STOPPED */
125 bta_av_reconfig, /* BTA_AV_RECONFIG */
126 bta_av_data_path, /* BTA_AV_DATA_PATH */
127 bta_av_start_ok, /* BTA_AV_START_OK */
128 bta_av_start_failed, /* BTA_AV_START_FAILED */
129 bta_av_str_closed, /* BTA_AV_STR_CLOSED */
130 bta_av_clr_cong, /* BTA_AV_CLR_CONG */
131 bta_av_suspend_cfm, /* BTA_AV_SUSPEND_CFM */
132 bta_av_rcfg_str_ok, /* BTA_AV_RCFG_STR_OK */
133 bta_av_rcfg_failed, /* BTA_AV_RCFG_FAILED */
134 bta_av_rcfg_connect, /* BTA_AV_RCFG_CONNECT */
135 bta_av_rcfg_discntd, /* BTA_AV_RCFG_DISCNTD */
136 bta_av_suspend_cont, /* BTA_AV_SUSPEND_CONT */
137 bta_av_rcfg_cfm, /* BTA_AV_RCFG_CFM */
138 bta_av_rcfg_open, /* BTA_AV_RCFG_OPEN */
139 bta_av_security_rej, /* BTA_AV_SECURITY_REJ */
140 bta_av_open_rc, /* BTA_AV_OPEN_RC */
141 bta_av_chk_2nd_start, /* BTA_AV_CHK_2ND_START */
142 bta_av_save_caps, /* BTA_AV_SAVE_CAPS */
143 bta_av_set_use_rc, /* BTA_AV_SET_USE_RC */
144 bta_av_cco_close, /* BTA_AV_CCO_CLOSE */
145 bta_av_switch_role, /* BTA_AV_SWITCH_ROLE */
146 bta_av_role_res, /* BTA_AV_ROLE_RES */
147 bta_av_delay_co, /* BTA_AV_DELAY_CO */
148 bta_av_open_at_inc, /* BTA_AV_OPEN_AT_INC */
Abhijit Adsule47b43102015-05-19 02:44:26 -0500149 bta_av_offload_req, /* BTA_AV_OFFLOAD_REQ */
150 bta_av_offload_rsp, /* BTA_AV_OFFLOAD_RSP */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800151 NULL
152};
153
154/* these tables translate AVDT events to SSM events */
155static const UINT16 bta_av_stream_evt_ok[] = {
156 BTA_AV_STR_DISC_OK_EVT, /* AVDT_DISCOVER_CFM_EVT */
157 BTA_AV_STR_GETCAP_OK_EVT, /* AVDT_GETCAP_CFM_EVT */
158 BTA_AV_STR_OPEN_OK_EVT, /* AVDT_OPEN_CFM_EVT */
159 BTA_AV_STR_OPEN_OK_EVT, /* AVDT_OPEN_IND_EVT */
160 BTA_AV_STR_CONFIG_IND_EVT, /* AVDT_CONFIG_IND_EVT */
161 BTA_AV_STR_START_OK_EVT, /* AVDT_START_CFM_EVT */
162 BTA_AV_STR_START_OK_EVT, /* AVDT_START_IND_EVT */
163 BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_CFM_EVT */
164 BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_IND_EVT */
165 BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_CFM_EVT */
166 BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_IND_EVT */
167 BTA_AV_STR_RECONFIG_CFM_EVT, /* AVDT_RECONFIG_CFM_EVT */
168 0, /* AVDT_RECONFIG_IND_EVT */
169 BTA_AV_STR_SECURITY_CFM_EVT, /* AVDT_SECURITY_CFM_EVT */
170 BTA_AV_STR_SECURITY_IND_EVT, /* AVDT_SECURITY_IND_EVT */
171 BTA_AV_STR_WRITE_CFM_EVT, /* AVDT_WRITE_CFM_EVT */
172 BTA_AV_AVDT_CONNECT_EVT, /* AVDT_CONNECT_IND_EVT */
173 BTA_AV_AVDT_DISCONNECT_EVT, /* AVDT_DISCONNECT_IND_EVT */
174#if (AVDT_REPORTING == TRUE)
175 BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_CONN_EVT */
176 BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_DISCONN_EVT */
177#endif
178 BTA_AV_AVDT_DELAY_RPT_EVT, /* AVDT_DELAY_REPORT_EVT */
179 0 /* AVDT_DELAY_REPORT_CFM_EVT */
180};
181
182static const UINT16 bta_av_stream_evt_fail[] = {
183 BTA_AV_STR_DISC_FAIL_EVT, /* AVDT_DISCOVER_CFM_EVT */
184 BTA_AV_STR_GETCAP_FAIL_EVT, /* AVDT_GETCAP_CFM_EVT */
185 BTA_AV_STR_OPEN_FAIL_EVT, /* AVDT_OPEN_CFM_EVT */
186 BTA_AV_STR_OPEN_OK_EVT, /* AVDT_OPEN_IND_EVT */
187 BTA_AV_STR_CONFIG_IND_EVT, /* AVDT_CONFIG_IND_EVT */
188 BTA_AV_STR_START_FAIL_EVT, /* AVDT_START_CFM_EVT */
189 BTA_AV_STR_START_OK_EVT, /* AVDT_START_IND_EVT */
190 BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_CFM_EVT */
191 BTA_AV_STR_SUSPEND_CFM_EVT, /* AVDT_SUSPEND_IND_EVT */
192 BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_CFM_EVT */
193 BTA_AV_STR_CLOSE_EVT, /* AVDT_CLOSE_IND_EVT */
194 BTA_AV_STR_RECONFIG_CFM_EVT, /* AVDT_RECONFIG_CFM_EVT */
195 0, /* AVDT_RECONFIG_IND_EVT */
196 BTA_AV_STR_SECURITY_CFM_EVT, /* AVDT_SECURITY_CFM_EVT */
197 BTA_AV_STR_SECURITY_IND_EVT, /* AVDT_SECURITY_IND_EVT */
198 BTA_AV_STR_WRITE_CFM_EVT, /* AVDT_WRITE_CFM_EVT */
199 BTA_AV_AVDT_CONNECT_EVT, /* AVDT_CONNECT_IND_EVT */
200 BTA_AV_AVDT_DISCONNECT_EVT, /* AVDT_DISCONNECT_IND_EVT */
201#if (AVDT_REPORTING == TRUE)
202 BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_CONN_EVT */
203 BTA_AV_AVDT_RPT_CONN_EVT, /* AVDT_REPORT_DISCONN_EVT */
204#endif
205 BTA_AV_AVDT_DELAY_RPT_EVT, /* AVDT_DELAY_REPORT_EVT */
206 0 /* AVDT_DELAY_REPORT_CFM_EVT */
207};
208
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530209void bta_av_stream_data_cback(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800210static void bta_av_stream0_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
211static void bta_av_stream1_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
212#if BTA_AV_NUM_STRS > 2
213static void bta_av_stream2_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
214#endif
215#if BTA_AV_NUM_STRS > 3
216static void bta_av_stream3_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
217#endif
218#if BTA_AV_NUM_STRS > 4
219static void bta_av_stream4_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
220#endif
221#if BTA_AV_NUM_STRS > 5
222static void bta_av_stream5_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
223#endif
224/* the array of callback functions to receive events from AVDT control channel */
225tAVDT_CTRL_CBACK * const bta_av_dt_cback[] =
226{
227 bta_av_stream0_cback
228 ,bta_av_stream1_cback
229#if BTA_AV_NUM_STRS > 2
230 ,bta_av_stream2_cback
231#endif
232#if BTA_AV_NUM_STRS > 3
233 ,bta_av_stream3_cback
234#endif
235#if BTA_AV_NUM_STRS > 4
236 ,bta_av_stream4_cback
237#endif
238#if BTA_AV_NUM_STRS > 5
239 ,bta_av_stream5_cback
240#endif
241};
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530242/***********************************************
243**
244** Function bta_get_scb_handle
245**
246** Description gives the registered AVDT handle.by checking with sep_type.
247**
248**
249** Returns void
250***********************************************/
Chris Mantond44d6402015-03-06 14:41:32 -0800251static UINT8 bta_av_get_scb_handle(tBTA_AV_SCB *p_scb, UINT8 local_sep)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530252{
253 UINT8 xx =0;
254 for (xx = 0; xx<BTA_AV_MAX_SEPS; xx++)
255 {
256 if ((p_scb->seps[xx].tsep == local_sep) &&
257 (p_scb->seps[xx].codec_type == p_scb->codec_type))
258 return (p_scb->seps[xx].av_handle);
259 }
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700260 APPL_TRACE_DEBUG(" bta_av_get_scb_handle appropiate sep_type not found")
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530261 return 0; /* return invalid handle */
262}
263
264/***********************************************
265**
266** Function bta_av_get_scb_sep_type
267**
268** Description gives the sep type by cross-checking with AVDT handle
269**
270**
271** Returns void
272***********************************************/
Chris Mantond44d6402015-03-06 14:41:32 -0800273static UINT8 bta_av_get_scb_sep_type(tBTA_AV_SCB *p_scb, UINT8 tavdt_handle)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530274{
275 UINT8 xx =0;
276 for (xx = 0; xx<BTA_AV_MAX_SEPS; xx++)
277 {
278 if (p_scb->seps[xx].av_handle == tavdt_handle)
279 return (p_scb->seps[xx].tsep);
280 }
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700281 APPL_TRACE_DEBUG(" bta_av_get_scb_sep_type appropiate handle not found")
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530282 return 3; /* return invalid sep type */
283}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800284
285/*******************************************************************************
286**
287** Function bta_av_save_addr
288**
289** Description copy the bd_addr and maybe reset the supported flags
290**
291**
292** Returns void
293**
294*******************************************************************************/
295static void bta_av_save_addr(tBTA_AV_SCB *p_scb, const BD_ADDR b)
296{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700297 APPL_TRACE_DEBUG("bta_av_save_addr r:%d, s:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800298 p_scb->recfg_sup, p_scb->suspend_sup);
299 if(bdcmp(p_scb->peer_addr, b) != 0)
300 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700301 APPL_TRACE_ERROR("reset flags");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800302 /* a new addr, reset the supported flags */
303 p_scb->recfg_sup = TRUE;
304 p_scb->suspend_sup = TRUE;
305 }
306
307 /* do this copy anyway, just in case the first addr matches
308 * the control block one by accident */
309 bdcpy(p_scb->peer_addr, b);
310}
311
312/*******************************************************************************
313**
Zhihai Xu379743b2013-09-29 13:42:13 -0700314** Function notify_start_failed
315**
316** Description notify up-layer AV start failed
317**
318**
319** Returns void
320**
321*******************************************************************************/
322static void notify_start_failed(tBTA_AV_SCB *p_scb)
323{
324 tBTA_AV_START start;
325 /* if start failed, clear role */
326 p_scb->role &= ~BTA_AV_ROLE_START_INT;
327 start.chnl = p_scb->chnl;
328 start.status = BTA_AV_FAIL;
329 start.initiator = TRUE;
330 start.hndl = p_scb->hndl;
331 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV *) &start);
332}
333
334/*******************************************************************************
335**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800336** Function bta_av_st_rc_timer
337**
338** Description start the AVRC timer if no RC connection & CT is supported &
339** RC is used or
340** as ACP (we do not really know if we want AVRC)
341**
342** Returns void
343**
344*******************************************************************************/
Chris Mantond44d6402015-03-06 14:41:32 -0800345static void bta_av_st_rc_timer(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800346{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800347 UNUSED(p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800348
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700349 APPL_TRACE_DEBUG("bta_av_st_rc_timer rc_handle:%d, use_rc: %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800350 p_scb->rc_handle, p_scb->use_rc);
351 /* for outgoing RC connection as INT/CT */
352 if( (p_scb->rc_handle == BTA_AV_RC_HANDLE_NONE) &&
353 /*(bta_av_cb.features & BTA_AV_FEAT_RCCT) &&*/
354 (p_scb->use_rc == TRUE || (p_scb->role & BTA_AV_ROLE_AD_ACP)) )
355 {
356 if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) == 0)
357 bta_sys_start_timer(&p_scb->timer, BTA_AV_AVRC_TIMER_EVT, BTA_AV_RC_DISC_TIME_VAL);
358 else
359 p_scb->wait |= BTA_AV_WAIT_CHECK_RC;
360 }
361
362}
363
364/*******************************************************************************
365**
366** Function bta_av_next_getcap
367**
368** Description The function gets the capabilities of the next available
369** stream found in the discovery results.
370**
371** Returns TRUE if we sent request to AVDT, FALSE otherwise.
372**
373*******************************************************************************/
374static BOOLEAN bta_av_next_getcap(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
375{
376 int i;
377 tAVDT_GETCAP_REQ *p_req;
378 BOOLEAN sent_cmd = FALSE;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530379 UINT16 uuid_int = p_scb->uuid_int;
380 UINT8 sep_requested = 0;
381
382 if(uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
383 sep_requested = AVDT_TSEP_SNK;
384 else if(uuid_int == UUID_SERVCLASS_AUDIO_SINK)
385 sep_requested = AVDT_TSEP_SRC;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800386
387 for (i = p_scb->sep_info_idx; i < p_scb->num_seps; i++)
388 {
389 /* steam not in use, is a sink, and is the right media type (audio/video) */
390 if ((p_scb->sep_info[i].in_use == FALSE) &&
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530391 (p_scb->sep_info[i].tsep == sep_requested) &&
The Android Open Source Project5738f832012-12-12 16:00:35 -0800392 (p_scb->sep_info[i].media_type == p_scb->media_type))
393 {
394 p_scb->sep_info_idx = i;
395
396 /* we got a stream; get its capabilities */
397 if (p_scb->p_cap == NULL)
398 {
Pavlin Radoslavov258c2532015-09-27 20:59:05 -0700399 p_scb->p_cap = (tAVDT_CFG *) osi_getbuf(sizeof(tAVDT_CFG));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800400 }
401 if (p_scb->p_cap == NULL)
402 {
403 i = p_scb->num_seps;
404 break;
405 }
406 if (p_scb->avdt_version >= AVDT_VERSION_SYNC)
407 {
408 p_req = AVDT_GetAllCapReq;
409 }
410 else
411 {
412 p_req = AVDT_GetCapReq;
413 }
414 (*p_req)(p_scb->peer_addr,
415 p_scb->sep_info[i].seid,
416 p_scb->p_cap, bta_av_dt_cback[p_scb->hdi]);
417 sent_cmd = TRUE;
418 break;
419 }
420 }
421
422 /* if no streams available then stream open fails */
423 if (!sent_cmd)
424 {
425 bta_av_ssm_execute(p_scb, BTA_AV_STR_GETCAP_FAIL_EVT, p_data);
426 }
427
428 return sent_cmd;
429
430}
431
432/*******************************************************************************
433**
434** Function bta_av_proc_stream_evt
435**
436** Description Utility function to compose stream events.
437**
438** Returns void
439**
440*******************************************************************************/
Chris Mantond44d6402015-03-06 14:41:32 -0800441static void bta_av_proc_stream_evt(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data, int index)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800442{
443 tBTA_AV_STR_MSG *p_msg;
444 UINT16 sec_len = 0;
445 tBTA_AV_SCB *p_scb = bta_av_cb.p_scb[index];
446 int xx;
447
448 if (p_data)
449 {
450 if (event == AVDT_SECURITY_IND_EVT)
451 {
452 sec_len = (p_data->security_ind.len < BTA_AV_SECURITY_MAX_LEN) ?
453 p_data->security_ind.len : BTA_AV_SECURITY_MAX_LEN;
454 }
455 else if (event == AVDT_SECURITY_CFM_EVT && p_data->hdr.err_code == 0)
456 {
457 sec_len = (p_data->security_cfm.len < BTA_AV_SECURITY_MAX_LEN) ?
458 p_data->security_cfm.len : BTA_AV_SECURITY_MAX_LEN;
459 }
460 }
461
Pavlin Radoslavov258c2532015-09-27 20:59:05 -0700462 if (p_scb && (p_msg = (tBTA_AV_STR_MSG *) osi_getbuf((UINT16) (sizeof(tBTA_AV_STR_MSG) + sec_len))) != NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800463 {
464
465 /* copy event data, bd addr, and handle to event message buffer */
466 p_msg->hdr.offset = 0;
467
468 if (bd_addr != NULL)
469 {
470 bdcpy(p_msg->bd_addr, bd_addr);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700471 APPL_TRACE_DEBUG(" bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800472 bd_addr[0], bd_addr[1],
473 bd_addr[2], bd_addr[3],
474 bd_addr[4], bd_addr[5]);
475 }
476
477 if (p_data != NULL)
478 {
479 memcpy(&p_msg->msg, p_data, sizeof (tAVDT_CTRL));
480 /* copy config params to event message buffer */
481 switch (event)
482 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800483 case AVDT_RECONFIG_CFM_EVT:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700484 APPL_TRACE_DEBUG("reconfig cfm event codec info = 0x%06x-%06x-%06x-%02x",
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800485 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[0]<<16)+(p_msg->msg.reconfig_cfm.p_cfg->codec_info[1]<<8)+p_msg->msg.reconfig_cfm.p_cfg->codec_info[2],
486 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[3]<<16)+(p_msg->msg.reconfig_cfm.p_cfg->codec_info[4]<<8)+p_msg->msg.reconfig_cfm.p_cfg->codec_info[5],
487 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[6]<<16)+(p_msg->msg.reconfig_cfm.p_cfg->codec_info[7]<<8)+p_msg->msg.reconfig_cfm.p_cfg->codec_info[8],
488 p_msg->msg.reconfig_cfm.p_cfg->codec_info[9]);
489 break;
490
491
492
The Android Open Source Project5738f832012-12-12 16:00:35 -0800493 case AVDT_CONFIG_IND_EVT:
494 /* We might have 2 SEP signallings(A2DP + VDP) with one peer device on one L2CAP.
495 * If we already have a signalling connection with the bd_addr and the streaming
496 * SST is at INIT state, change it to INCOMING state to handle the signalling
497 * from the 2nd SEP. */
498 if ((bta_av_find_lcb(bd_addr, BTA_AV_LCB_FIND) != NULL) && (bta_av_is_scb_init(p_scb)))
499 {
500 bta_av_set_scb_sst_incoming (p_scb);
501
502 /* When ACP_CONNECT_EVT was received, we put first available scb to incoming state.
503 * Later when we receive AVDT_CONFIG_IND_EVT, we use a new p_scb and set its state to
504 * incoming which we do it above.
505 * We also have to set the old p_scb state to init to be used later */
506 for (xx = 0; xx < BTA_AV_NUM_STRS; xx++)
507 {
508 if ((bta_av_cb.p_scb[xx]) && (xx != index))
509 {
510 if (bta_av_cb.p_scb[xx]->state == BTA_AV_INCOMING_SST)
511 {
512 bta_av_cb.p_scb[xx]->state = BTA_AV_INIT_SST;
513 bta_av_cb.p_scb[xx]->coll_mask = 0;
514 break;
515 }
516 }
517 }
518 }
519
520 memcpy(&p_msg->cfg, p_data->config_ind.p_cfg, sizeof(tAVDT_CFG));
521 break;
522
523 case AVDT_SECURITY_IND_EVT:
524 p_msg->msg.security_ind.p_data = (UINT8 *) (p_msg + 1);
525 memcpy(p_msg->msg.security_ind.p_data, p_data->security_ind.p_data, sec_len);
526 break;
527
528 case AVDT_SECURITY_CFM_EVT:
529 p_msg->msg.security_cfm.p_data = (UINT8 *) (p_msg + 1);
530 if (p_data->hdr.err_code == 0)
531 {
532 memcpy(p_msg->msg.security_cfm.p_data, p_data->security_cfm.p_data, sec_len);
533 }
534 break;
535 case AVDT_SUSPEND_IND_EVT:
536 p_msg->msg.hdr.err_code = 0;
537 break;
538
539 default:
540 break;
541 }
542 }
543 else
544 p_msg->msg.hdr.err_code = 0;
545
546 /* look up application event */
547 if ((p_data == NULL) || (p_data->hdr.err_code == 0))
548 {
549 p_msg->hdr.event = bta_av_stream_evt_ok[event];
550 }
551 else
552 {
553 p_msg->hdr.event = bta_av_stream_evt_fail[event];
554 }
555
556 p_msg->initiator = FALSE;
557 if (event == AVDT_SUSPEND_CFM_EVT)
558 p_msg->initiator = TRUE;
559
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700560 APPL_TRACE_VERBOSE("hndl:x%x", p_scb->hndl);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800561 p_msg->hdr.layer_specific = p_scb->hndl;
562 p_msg->handle = handle;
563 p_msg->avdt_event = event;
564 bta_sys_sendmsg(p_msg);
565 }
566
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800567/* coverity[var_deref_model] */
568/* false-positive: bta_av_conn_cback only processes AVDT_CONNECT_IND_EVT and AVDT_DISCONNECT_IND_EVT event
569 * these 2 events always have associated p_data */
Mallikarjuna GB46d706a2014-11-07 16:52:25 +0530570 if (p_data)
571 {
572 bta_av_conn_cback(handle, bd_addr, event, p_data);
573 }
574 else
575 {
576 APPL_TRACE_ERROR("%s: p_data is null", __func__);
577 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800578}
579
580/*******************************************************************************
581**
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530582** Function bta_av_stream_data_cback
583**
584** Description This is the AVDTP callback function for stream events.
585**
586** Returns void
587**
588*******************************************************************************/
589void bta_av_stream_data_cback(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt)
590{
591 int index = 0;
592 tBTA_AV_SCB *p_scb ;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700593 APPL_TRACE_DEBUG("bta_av_stream_data_cback avdt_handle: %d pkt_len=0x%x ofst = 0x%x", handle,p_pkt->len,p_pkt->offset);
594 APPL_TRACE_DEBUG(" Number of frames 0x%x",*((UINT8*)(p_pkt + 1) + p_pkt->offset));
595 APPL_TRACE_DEBUG("Sequence Number 0x%x",p_pkt->layer_specific);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530596 /* Get SCB and correct sep type*/
597 for(index = 0; index < BTA_AV_NUM_STRS;index ++ )
598 {
599 p_scb = bta_av_cb.p_scb[index];
600 if((p_scb->avdt_handle == handle)&&(p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK))
601 break;
602 }
603 if(index == BTA_AV_NUM_STRS) /* cannot find correct handler */
604 {
Pavlin Radoslavov258c2532015-09-27 20:59:05 -0700605 osi_freebuf(p_pkt);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530606 return;
607 }
608 p_pkt->event = BTA_AV_MEDIA_DATA_EVT;
609 p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_DATA_EVT, (tBTA_AV_MEDIA*)p_pkt);
Pavlin Radoslavov258c2532015-09-27 20:59:05 -0700610 osi_freebuf(p_pkt); /* a copy of packet had been delivered, we free this buffer */
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530611}
612
613/*******************************************************************************
614**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800615** Function bta_av_stream0_cback
616**
617** Description This is the AVDTP callback function for stream events.
618**
619** Returns void
620**
621*******************************************************************************/
622static void bta_av_stream0_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
623{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700624 APPL_TRACE_VERBOSE("bta_av_stream0_cback avdt_handle: %d event=0x%x", handle, event);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800625 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 0);
626}
627
628/*******************************************************************************
629**
630** Function bta_av_stream1_cback
631**
632** Description This is the AVDTP callback function for stream events.
633**
634** Returns void
635**
636*******************************************************************************/
637static void bta_av_stream1_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
638{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700639 APPL_TRACE_EVENT("bta_av_stream1_cback avdt_handle: %d event=0x%x", handle, event);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800640 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 1);
641}
642
643#if BTA_AV_NUM_STRS > 2
644/*******************************************************************************
645**
646** Function bta_av_stream2_cback
647**
648** Description This is the AVDTP callback function for stream events.
649**
650** Returns void
651**
652*******************************************************************************/
653static void bta_av_stream2_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
654{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700655 APPL_TRACE_EVENT("bta_av_stream2_cback avdt_handle: %d event=0x%x", handle, event);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800656 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 2);
657}
658#endif
659
660#if BTA_AV_NUM_STRS > 3
661/*******************************************************************************
662**
663** Function bta_av_stream3_cback
664**
665** Description This is the AVDTP callback function for stream events.
666**
667** Returns void
668**
669*******************************************************************************/
670static void bta_av_stream3_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
671{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700672 APPL_TRACE_EVENT("bta_av_stream3_cback avdt_handle: %d event=0x%x", handle, event);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800673 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 3);
674}
675#endif
676
677/*******************************************************************************
678**
679** Function bta_av_stream4_cback
680**
681** Description This is the AVDTP callback function for stream events.
682**
683** Returns void
684**
685*******************************************************************************/
686#if BTA_AV_NUM_STRS > 4
687static void bta_av_stream4_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
688{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700689 APPL_TRACE_EVENT("bta_av_stream4_cback avdt_handle: %d event=0x%x", handle, event);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800690 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 4);
691}
692#endif
693
694/*******************************************************************************
695**
696** Function bta_av_stream5_cback
697**
698** Description This is the AVDTP callback function for stream events.
699**
700** Returns void
701**
702*******************************************************************************/
703#if BTA_AV_NUM_STRS > 5
704static void bta_av_stream5_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
705{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700706 APPL_TRACE_EVENT("bta_av_stream5_cback avdt_handle: %d event=0x%x", handle, event);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800707 bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 5);
708}
709#endif
710
711/*******************************************************************************
712**
713** Function bta_av_a2d_sdp_cback
714**
715** Description A2DP service discovery callback.
716**
717** Returns void
718**
719*******************************************************************************/
720static void bta_av_a2d_sdp_cback(BOOLEAN found, tA2D_Service *p_service)
721{
722 tBTA_AV_SDP_RES *p_msg;
723 tBTA_AV_SCB *p_scb;
724
Pavlin Radoslavov258c2532015-09-27 20:59:05 -0700725 if ((p_msg = (tBTA_AV_SDP_RES *) osi_getbuf(sizeof(tBTA_AV_SDP_RES))) != NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800726 {
727 p_msg->hdr.event = (found) ? BTA_AV_SDP_DISC_OK_EVT : BTA_AV_SDP_DISC_FAIL_EVT;
728
729 p_scb = bta_av_hndl_to_scb(bta_av_cb.handle);
730 if (p_scb)
731 {
732 if (found && (p_service != NULL))
733 p_scb->avdt_version = p_service->avdt_version;
734 else
735 p_scb->avdt_version = 0x00;
736
737 p_msg->hdr.layer_specific = bta_av_cb.handle;
738 bta_sys_sendmsg(p_msg);
739 }
740 else
741 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700742 APPL_TRACE_ERROR ("bta_av_a2d_sdp_cback, no scb found for handle(0x%x)", bta_av_cb.handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800743 }
744 }
745}
746
747/*******************************************************************************
748**
749** Function bta_av_adjust_seps_idx
750**
751** Description adjust the sep_idx
752**
753** Returns
754**
755*******************************************************************************/
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530756static void bta_av_adjust_seps_idx(tBTA_AV_SCB *p_scb, UINT8 avdt_handle)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800757{
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530758 int xx;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700759 APPL_TRACE_DEBUG("bta_av_adjust_seps_idx codec_type: %d", p_scb->codec_type);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800760 for(xx=0; xx<BTA_AV_MAX_SEPS; xx++)
761 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700762 APPL_TRACE_DEBUG("av_handle: %d codec_type: %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800763 p_scb->seps[xx].av_handle, p_scb->seps[xx].codec_type);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530764 if((p_scb->seps[xx].av_handle && p_scb->codec_type == p_scb->seps[xx].codec_type)
765 && (p_scb->seps[xx].av_handle == avdt_handle))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800766 {
767 p_scb->sep_idx = xx;
768 p_scb->avdt_handle = p_scb->seps[xx].av_handle;
769 break;
770 }
771 }
772}
773
774/*******************************************************************************
775**
776** Function bta_av_switch_role
777**
778** Description Switch role was not started and a timer was started.
779** another attempt to switch role now - still opening.
780**
781** Returns void
782**
783*******************************************************************************/
784void bta_av_switch_role (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
785{
786 tBTA_AV_RS_RES switch_res = BTA_AV_RS_NONE;
787 tBTA_AV_API_OPEN *p_buf = &p_scb->q_info.open;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800788 UNUSED(p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800789
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700790 APPL_TRACE_DEBUG("bta_av_switch_role wait:x%x", p_scb->wait);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800791 if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_START)
792 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RETRY;
793
794 /* clear the masks set when the timer is started */
795 p_scb->wait &= ~(BTA_AV_WAIT_ROLE_SW_RES_OPEN|BTA_AV_WAIT_ROLE_SW_RES_START);
796
797 if (p_scb->q_tag == BTA_AV_Q_TAG_OPEN)
798 {
799 if (bta_av_switch_if_needed(p_scb) || !bta_av_link_role_ok(p_scb, A2D_SET_MULTL_BIT))
800 {
801 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_OPEN;
802 }
803 else
804 {
805 /* this should not happen in theory. Just in case...
806 * continue to do_disc_a2d */
807 switch_res = BTA_AV_RS_DONE;
808 }
809 }
810 else
811 {
812 /* report failure on OPEN */
813 switch_res = BTA_AV_RS_FAIL;
814 }
815
816 if (switch_res != BTA_AV_RS_NONE)
817 {
818 if (bta_av_cb.rs_idx == (p_scb->hdi + 1))
819 {
820 bta_av_cb.rs_idx = 0;
821 }
822 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_RETRY;
823 p_scb->q_tag = 0;
824 p_buf->switch_res = switch_res;
825 bta_av_do_disc_a2d(p_scb, (tBTA_AV_DATA *)p_buf);
826 }
827}
828
829/*******************************************************************************
830**
831** Function bta_av_role_res
832**
833** Description Handle the role changed event
834**
835**
836** Returns void
837**
838*******************************************************************************/
839void bta_av_role_res (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
840{
841 BOOLEAN initiator = FALSE;
842 tBTA_AV_START start;
843 tBTA_AV_OPEN av_open;
844
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700845 APPL_TRACE_DEBUG("bta_av_role_res q_tag:%d, wait:x%x, role:x%x", p_scb->q_tag, p_scb->wait, p_scb->role);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800846 if (p_scb->role & BTA_AV_ROLE_START_INT)
847 initiator = TRUE;
848
849 if (p_scb->q_tag == BTA_AV_Q_TAG_START)
850 {
851 if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_STARTED)
852 {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800853 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
854 if (p_data->role_res.hci_status != HCI_SUCCESS)
855 {
Kausik Sinnaswamy77d1cb62013-05-22 16:18:31 +0530856 p_scb->role &= ~BTA_AV_ROLE_START_INT;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800857 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
858 /* start failed because of role switch. */
859 start.chnl = p_scb->chnl;
860 start.status = BTA_AV_FAIL_ROLE;
861 start.hndl = p_scb->hndl;
862 start.initiator = initiator;
863 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV *) &start);
864 }
865 else
866 {
867 bta_av_start_ok(p_scb, p_data);
868 }
869 }
870 else if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_START)
871 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_FAILED;
872 }
873 else if (p_scb->q_tag == BTA_AV_Q_TAG_OPEN)
874 {
875 if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_OPEN)
876 {
877 p_scb->role &= ~BTA_AV_ROLE_START_INT;
878 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
879
880 if (p_data->role_res.hci_status != HCI_SUCCESS)
881 {
882 /* Open failed because of role switch. */
883 bdcpy(av_open.bd_addr, p_scb->peer_addr);
884 av_open.chnl = p_scb->chnl;
885 av_open.hndl = p_scb->hndl;
886 start.status = BTA_AV_FAIL_ROLE;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530887 if(p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC )
888 av_open.sep = AVDT_TSEP_SNK;
889 else if(p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK )
890 av_open.sep = AVDT_TSEP_SRC;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800891 (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV *)&av_open);
892 }
893 else
894 {
895 /* Continue av open process */
896 p_scb->q_info.open.switch_res = BTA_AV_RS_DONE;
897 bta_av_do_disc_a2d (p_scb, (tBTA_AV_DATA *)&(p_scb->q_info.open));
898 }
899 }
900 else
901 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700902 APPL_TRACE_WARNING ("Unexpected role switch event: q_tag = %d wait = %d", p_scb->q_tag, p_scb->wait);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800903 }
904 }
905
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700906 APPL_TRACE_DEBUG("wait:x%x, role:x%x", p_scb->wait, p_scb->role);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800907}
908
909/*******************************************************************************
910**
911** Function bta_av_delay_co
912**
913** Description Call the delay call-out function to report the delay report
914** from SNK
915**
916** Returns void
917**
918*******************************************************************************/
919void bta_av_delay_co (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
920{
921 p_scb->p_cos->delay(p_scb->hndl, p_data->str_msg.msg.delay_rpt_cmd.delay);
922}
923
924/*******************************************************************************
925**
926** Function bta_av_do_disc_a2d
927**
928** Description Do service discovery for A2DP.
929**
930** Returns void
931**
932*******************************************************************************/
933void bta_av_do_disc_a2d (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
934{
935 BOOLEAN ok_continue = FALSE;
936 tA2D_SDP_DB_PARAMS db_params;
937 UINT16 attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
938 ATTR_ID_PROTOCOL_DESC_LIST,
939 ATTR_ID_BT_PROFILE_DESC_LIST};
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530940 UINT16 sdp_uuid = 0; /* UUID for which SDP has to be done */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800941
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700942 APPL_TRACE_DEBUG("bta_av_do_disc_a2d use_rc: %d rs:%d, oc:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800943 p_data->api_open.use_rc, p_data->api_open.switch_res, bta_av_cb.audio_open_cnt);
944
945 memcpy (&(p_scb->open_api), &(p_data->api_open), sizeof(tBTA_AV_API_OPEN));
946
947 switch(p_data->api_open.switch_res)
948 {
949 case BTA_AV_RS_NONE:
950 if (bta_av_switch_if_needed(p_scb) || !bta_av_link_role_ok(p_scb, A2D_SET_MULTL_BIT))
951 {
952 /* waiting for role switch result. save the api to control block */
953 memcpy(&p_scb->q_info.open, &p_data->api_open, sizeof(tBTA_AV_API_OPEN));
954 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_OPEN;
955 p_scb->q_tag = BTA_AV_Q_TAG_OPEN;
956 }
957 else
958 {
959 ok_continue = TRUE;
960 }
961 break;
962
963 case BTA_AV_RS_FAIL:
964 /* report a new failure event */
965 p_scb->open_status = BTA_AV_FAIL_ROLE;
966 bta_av_ssm_execute(p_scb, BTA_AV_SDP_DISC_FAIL_EVT, NULL);
967 break;
968
969 case BTA_AV_RS_OK:
970 p_data = (tBTA_AV_DATA *)&p_scb->q_info.open;
971 /* continue to open if link role is ok */
972 if (bta_av_link_role_ok(p_scb, A2D_SET_MULTL_BIT))
973 {
974 ok_continue = TRUE;
975 }
976 else
977 {
978 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_OPEN;
979 }
980 break;
981
982 case BTA_AV_RS_DONE:
983 ok_continue = TRUE;
984 break;
985 }
986
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700987 APPL_TRACE_DEBUG("ok_continue: %d wait:x%x, q_tag: %d", ok_continue, p_scb->wait, p_scb->q_tag);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800988 if (!ok_continue)
989 return;
990
991 /* clear the role switch bits */
992 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
993
994 if (p_scb->wait & BTA_AV_WAIT_CHECK_RC)
995 {
996 p_scb->wait &= ~BTA_AV_WAIT_CHECK_RC;
997 bta_sys_start_timer(&p_scb->timer, BTA_AV_AVRC_TIMER_EVT, BTA_AV_RC_DISC_TIME_VAL);
998 }
999
1000 if (bta_av_cb.features & BTA_AV_FEAT_MASTER)
1001 {
Matthew Xied6151e92014-06-22 13:32:05 -07001002 L2CA_SetDesireRole(L2CAP_ROLE_DISALLOW_SWITCH);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001003
Matthew Xied6151e92014-06-22 13:32:05 -07001004 if (bta_av_cb.audio_open_cnt == 1)
1005 {
1006 /* there's already an A2DP connection. do not allow switch */
1007 bta_sys_clear_default_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH);
1008 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001009 }
1010 /* store peer addr other parameters */
1011 bta_av_save_addr(p_scb, p_data->api_open.bd_addr);
1012 p_scb->sec_mask = p_data->api_open.sec_mask;
1013 p_scb->use_rc = p_data->api_open.use_rc;
1014
1015 bta_sys_app_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
1016
1017 /* allocate discovery database */
1018 if (p_scb->p_disc_db == NULL)
1019 {
Pavlin Radoslavov258c2532015-09-27 20:59:05 -07001020 p_scb->p_disc_db = (tSDP_DISCOVERY_DB *) osi_getbuf(BTA_AV_DISC_BUF_SIZE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001021 }
1022
1023 /* only one A2D find service is active at a time */
1024 bta_av_cb.handle = p_scb->hndl;
1025
1026 if(p_scb->p_disc_db)
1027 {
1028 /* set up parameters */
1029 db_params.db_len = BTA_AV_DISC_BUF_SIZE;
1030 db_params.num_attr = 3;
1031 db_params.p_db = p_scb->p_disc_db;
1032 db_params.p_attrs = attr_list;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301033 p_scb->uuid_int = p_data->api_open.uuid;
1034 if (p_scb->uuid_int == UUID_SERVCLASS_AUDIO_SINK)
1035 sdp_uuid = UUID_SERVCLASS_AUDIO_SOURCE;
1036 else if (p_scb->uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
1037 sdp_uuid = UUID_SERVCLASS_AUDIO_SINK;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001038
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001039 APPL_TRACE_DEBUG("uuid_int 0x%x, Doing SDP For 0x%x", p_scb->uuid_int, sdp_uuid);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301040 if(A2D_FindService(sdp_uuid, p_scb->peer_addr, &db_params,
The Android Open Source Project5738f832012-12-12 16:00:35 -08001041 bta_av_a2d_sdp_cback) == A2D_SUCCESS)
1042 {
1043 return;
1044 }
1045 }
1046
1047 /* when the code reaches here, either the DB is NULL
1048 * or A2D_FindService is not successful */
1049 bta_av_a2d_sdp_cback(FALSE, NULL);
1050}
1051
1052/*******************************************************************************
1053**
1054** Function bta_av_cleanup
1055**
1056** Description cleanup AV stream control block.
1057**
1058** Returns void
1059**
1060*******************************************************************************/
1061void bta_av_cleanup(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1062{
1063 tBTA_AV_CONN_CHG msg;
1064 int xx;
1065 UINT8 role = BTA_AV_ROLE_AD_INT;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001066 UNUSED(p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001067
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001068 APPL_TRACE_DEBUG("bta_av_cleanup");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001069
1070 /* free any buffers */
1071 utl_freebuf((void **) &p_scb->p_cap);
1072 utl_freebuf((void **) &p_scb->p_disc_db);
1073 p_scb->avdt_version = 0;
1074
1075 /* initialize some control block variables */
1076 p_scb->open_status = BTA_AV_SUCCESS;
1077
1078 /* if de-registering shut everything down */
1079 msg.hdr.layer_specific = p_scb->hndl;
1080 p_scb->started = FALSE;
1081 p_scb->cong = FALSE;
1082 p_scb->role = role;
1083 p_scb->cur_psc_mask = 0;
1084 p_scb->wait = 0;
1085 p_scb->num_disc_snks = 0;
1086 bta_sys_stop_timer(&p_scb->timer);
Abhijit Adsule47b43102015-05-19 02:44:26 -05001087
1088 vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
1089 if (p_scb->offload_start_pending) {
1090 tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
1091 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
1092 }
1093 p_scb->offload_start_pending = FALSE;
1094
The Android Open Source Project5738f832012-12-12 16:00:35 -08001095 if (p_scb->deregistring)
1096 {
1097 /* remove stream */
1098 for(xx=0; xx<BTA_AV_MAX_SEPS; xx++)
1099 {
1100 if(p_scb->seps[xx].av_handle)
1101 AVDT_RemoveStream(p_scb->seps[xx].av_handle);
1102 p_scb->seps[xx].av_handle = 0;
1103 }
1104
1105 bta_av_dereg_comp((tBTA_AV_DATA *) &msg);
1106 }
1107 else
1108 {
1109 /* report stream closed to main SM */
1110 msg.is_up = FALSE;
1111 bdcpy(msg.peer_addr, p_scb->peer_addr);
1112 bta_av_conn_chg((tBTA_AV_DATA *) &msg);
1113 }
1114}
1115
1116/*******************************************************************************
1117**
1118** Function bta_av_free_sdb
1119**
1120** Description Free service discovery db buffer.
1121**
1122** Returns void
1123**
1124*******************************************************************************/
1125void bta_av_free_sdb(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1126{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001127 UNUSED(p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001128 utl_freebuf((void **) &p_scb->p_disc_db);
1129}
1130
1131/*******************************************************************************
1132**
1133** Function bta_av_config_ind
1134**
1135** Description Handle a stream configuration indication from the peer.
1136**
1137** Returns void
1138**
1139*******************************************************************************/
1140void bta_av_config_ind (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1141{
1142 tBTA_AV_CI_SETCONFIG setconfig;
1143 tAVDT_SEP_INFO *p_info;
1144 tAVDT_CFG *p_evt_cfg = &p_data->str_msg.cfg;
1145 UINT8 psc_mask = (p_evt_cfg->psc_mask | p_scb->cfg.psc_mask);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301146 UINT8 local_sep; /* sep type of local handle on which connection was received */
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301147 tBTA_AV_STR_MSG *p_msg = (tBTA_AV_STR_MSG *)p_data;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001148 UNUSED(p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001149
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301150 local_sep = bta_av_get_scb_sep_type(p_scb, p_msg->handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001151 p_scb->avdt_label = p_data->str_msg.msg.hdr.label;
1152 memcpy(p_scb->cfg.codec_info, p_evt_cfg->codec_info, AVDT_CODEC_SIZE);
1153 p_scb->codec_type = p_evt_cfg->codec_info[BTA_AV_CODEC_TYPE_IDX];
1154 bta_av_save_addr(p_scb, p_data->str_msg.bd_addr);
1155
1156 /* Clear collision mask */
1157 p_scb->coll_mask = 0;
1158 bta_sys_stop_timer(&bta_av_cb.acp_sig_tmr);
1159
1160 /* if no codec parameters in configuration, fail */
1161 if ((p_evt_cfg->num_codec == 0) ||
1162 /* or the peer requests for a service we do not support */
1163 ((psc_mask != p_scb->cfg.psc_mask) &&
1164 (psc_mask != (p_scb->cfg.psc_mask&~AVDT_PSC_DELAY_RPT))) )
1165 {
1166 setconfig.hndl = p_scb->hndl; /* we may not need this */
1167 setconfig.err_code = AVDT_ERR_UNSUP_CFG;
1168 bta_av_ssm_execute(p_scb, BTA_AV_CI_SETCONFIG_FAIL_EVT, (tBTA_AV_DATA *) &setconfig);
1169 }
1170 else
1171 {
1172 p_info = &p_scb->sep_info[0];
1173 p_info->in_use = 0;
1174 p_info->media_type = p_scb->media_type;
1175 p_info->seid = p_data->str_msg.msg.config_ind.int_seid;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301176
1177 /* Sep type of Peer will be oppsite role to our local sep */
1178 if (local_sep == AVDT_TSEP_SRC)
1179 p_info->tsep = AVDT_TSEP_SNK;
1180 else if (local_sep == AVDT_TSEP_SNK)
1181 p_info->tsep = AVDT_TSEP_SRC;
1182
The Android Open Source Project5738f832012-12-12 16:00:35 -08001183 p_scb->role |= BTA_AV_ROLE_AD_ACP;
1184 p_scb->cur_psc_mask = p_evt_cfg->psc_mask;
1185 if (bta_av_cb.features & BTA_AV_FEAT_RCTG)
1186 p_scb->use_rc = TRUE;
1187 else
1188 p_scb->use_rc = FALSE;
1189
1190 p_scb->num_seps = 1;
1191 p_scb->sep_info_idx = 0;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001192 APPL_TRACE_DEBUG("bta_av_config_ind: SEID: %d use_rc: %d cur_psc_mask:0x%x", p_info->seid, p_scb->use_rc, p_scb->cur_psc_mask);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301193 /* in case of A2DP SINK this is the first time peer data is being sent to co functions */
1194 if (local_sep == AVDT_TSEP_SNK)
1195 {
1196 p_scb->p_cos->setcfg(p_scb->hndl, p_scb->codec_type,
The Android Open Source Project5738f832012-12-12 16:00:35 -08001197 p_evt_cfg->codec_info,
1198 p_info->seid,
1199 p_scb->peer_addr,
1200 p_evt_cfg->num_protect,
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301201 p_evt_cfg->protect_info,
1202 AVDT_TSEP_SNK,
1203 p_msg->handle);
1204 }
1205 else
1206 {
1207 p_scb->p_cos->setcfg(p_scb->hndl, p_scb->codec_type,
1208 p_evt_cfg->codec_info,
1209 p_info->seid,
1210 p_scb->peer_addr,
1211 p_evt_cfg->num_protect,
1212 p_evt_cfg->protect_info,
1213 AVDT_TSEP_SRC,
1214 p_msg->handle);
1215 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001216 }
1217}
1218
1219/*******************************************************************************
1220**
1221** Function bta_av_disconnect_req
1222**
1223** Description Disconnect AVDTP connection.
1224**
1225** Returns void
1226**
1227*******************************************************************************/
1228void bta_av_disconnect_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1229{
1230 tBTA_AV_RCB *p_rcb;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001231 UNUSED(p_data);
1232
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001233 APPL_TRACE_DEBUG("bta_av_disconnect_req conn_lcb: 0x%x", bta_av_cb.conn_lcb);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001234
1235 bta_sys_stop_timer(&bta_av_cb.sig_tmr);
1236 bta_sys_stop_timer(&p_scb->timer);
1237 if(bta_av_cb.conn_lcb)
1238 {
1239 p_rcb = bta_av_get_rcb_by_shdl((UINT8)(p_scb->hdi + 1));
1240 if (p_rcb)
1241 bta_av_del_rc(p_rcb);
1242 AVDT_DisconnectReq(p_scb->peer_addr, bta_av_dt_cback[p_scb->hdi]);
1243 }
1244 else
1245 {
1246 bta_av_ssm_execute(p_scb, BTA_AV_AVDT_DISCONNECT_EVT, NULL);
1247 }
1248}
1249
1250/*******************************************************************************
1251**
1252** Function bta_av_security_req
1253**
1254** Description Send an AVDTP security request.
1255**
1256** Returns void
1257**
1258*******************************************************************************/
1259void bta_av_security_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1260{
1261 if (bta_av_cb.features & BTA_AV_FEAT_PROTECT)
1262 {
1263 AVDT_SecurityReq(p_scb->avdt_handle, p_data->api_protect_req.p_data,
1264 p_data->api_protect_req.len);
1265 }
1266}
1267
1268/*******************************************************************************
1269**
1270** Function bta_av_security_rsp
1271**
1272** Description Send an AVDTP security response.
1273**
1274** Returns void
1275**
1276*******************************************************************************/
1277void bta_av_security_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1278{
1279 if (bta_av_cb.features & BTA_AV_FEAT_PROTECT)
1280 {
1281 AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, p_data->api_protect_rsp.error_code,
1282 p_data->api_protect_rsp.p_data, p_data->api_protect_rsp.len);
1283 }
1284 else
1285 {
1286 AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_NSC,
1287 NULL, 0);
1288 }
1289}
1290
1291/*******************************************************************************
1292**
1293** Function bta_av_setconfig_rsp
1294**
1295** Description setconfig is OK
1296**
1297** Returns void
1298**
1299*******************************************************************************/
1300void bta_av_setconfig_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1301{
1302 UINT8 num = p_data->ci_setconfig.num_seid + 1;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301303 UINT8 avdt_handle = p_data->ci_setconfig.avdt_handle;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001304 UINT8 *p_seid = p_data->ci_setconfig.p_seid;
1305 int i;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301306 UINT8 local_sep;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001307
1308 /* we like this codec_type. find the sep_idx */
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301309 local_sep = bta_av_get_scb_sep_type(p_scb,avdt_handle);
1310 bta_av_adjust_seps_idx(p_scb, avdt_handle);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001311 APPL_TRACE_DEBUG("bta_av_setconfig_rsp: sep_idx: %d cur_psc_mask:0x%x", p_scb->sep_idx, p_scb->cur_psc_mask);
Andre Eisenbach948bea02014-07-18 18:43:18 -07001312
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301313 if ((AVDT_TSEP_SNK == local_sep) && (p_data->ci_setconfig.err_code == AVDT_SUCCESS) &&
1314 (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL))
1315 p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT,
1316 (tBTA_AV_MEDIA*)p_scb->cfg.codec_info);
1317
1318
The Android Open Source Project5738f832012-12-12 16:00:35 -08001319 AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, p_data->ci_setconfig.err_code,
1320 p_data->ci_setconfig.category);
1321
1322 bta_sys_stop_timer(&bta_av_cb.sig_tmr);
1323
1324 if(p_data->ci_setconfig.err_code == AVDT_SUCCESS)
1325 {
1326 p_scb->wait = BTA_AV_WAIT_ACP_CAPS_ON;
1327 if(p_data->ci_setconfig.recfg_needed)
1328 p_scb->role |= BTA_AV_ROLE_SUSPEND_OPT;
Andre Eisenbach948bea02014-07-18 18:43:18 -07001329 APPL_TRACE_DEBUG("bta_av_setconfig_rsp recfg_needed:%d role:x%x num:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001330 p_data->ci_setconfig.recfg_needed, p_scb->role, num);
1331 /* callout module tells BTA the number of "good" SEPs and their SEIDs.
1332 * getcap on these SEID */
1333 p_scb->num_seps = num;
1334
1335 if (p_scb->cur_psc_mask & AVDT_PSC_DELAY_RPT)
1336 p_scb->avdt_version = AVDT_VERSION_SYNC;
1337
1338
1339 if (p_scb->codec_type == BTA_AV_CODEC_SBC || num > 1)
1340 {
1341 /* if SBC is used by the SNK as INT, discover req is not sent in bta_av_config_ind.
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301342 * call disc_res now */
1343 /* this is called in A2DP SRC path only, In case of SINK we don't need it */
1344 if (local_sep == AVDT_TSEP_SRC)
1345 p_scb->p_cos->disc_res(p_scb->hndl, num, num, 0, p_scb->peer_addr,
1346 UUID_SERVCLASS_AUDIO_SOURCE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001347 }
1348 else
1349 {
1350 /* we do not know the peer device and it is using non-SBC codec
1351 * we need to know all the SEPs on SNK */
1352 bta_av_discover_req(p_scb, NULL);
1353 return;
1354 }
1355
1356 for (i = 1; i < num; i++)
1357 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001358 APPL_TRACE_DEBUG("sep_info[%d] SEID: %d", i, p_seid[i-1]);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001359 /* initialize the sep_info[] to get capabilities */
1360 p_scb->sep_info[i].in_use = FALSE;
1361 p_scb->sep_info[i].tsep = AVDT_TSEP_SNK;
1362 p_scb->sep_info[i].media_type = p_scb->media_type;
1363 p_scb->sep_info[i].seid = p_seid[i-1];
1364 }
Andre Eisenbach948bea02014-07-18 18:43:18 -07001365
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301366 /* only in case of local sep as SRC we need to look for other SEPs, In case of SINK we don't */
1367 if (local_sep == AVDT_TSEP_SRC)
Andre Eisenbach948bea02014-07-18 18:43:18 -07001368 {
1369 /* Make sure UUID has been initialized... */
1370 if (p_scb->uuid_int == 0)
1371 p_scb->uuid_int = p_scb->open_api.uuid;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301372 bta_av_next_getcap(p_scb, p_data);
Andre Eisenbach948bea02014-07-18 18:43:18 -07001373 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001374 }
1375}
1376
1377/*******************************************************************************
1378**
1379** Function bta_av_str_opened
1380**
1381** Description Stream opened OK (incoming/outgoing).
1382**
1383** Returns void
1384**
1385*******************************************************************************/
1386void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1387{
1388 tBTA_AV_CONN_CHG msg;
1389 tBTA_AV_OPEN open;
1390 UINT8 *p;
1391 UINT16 mtu;
1392
1393 msg.hdr.layer_specific = p_scb->hndl;
1394 msg.is_up = TRUE;
1395 bdcpy(msg.peer_addr, p_scb->peer_addr);
1396 p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle);
1397 bta_av_conn_chg((tBTA_AV_DATA *) &msg);
1398 /* set the congestion flag, so AV would not send media packets by accident */
1399 p_scb->cong = TRUE;
Abhijit Adsule47b43102015-05-19 02:44:26 -05001400 p_scb->offload_start_pending = FALSE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001401
1402
1403 p_scb->stream_mtu = p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE;
1404 mtu = bta_av_chk_mtu(p_scb, p_scb->stream_mtu);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001405 APPL_TRACE_DEBUG("bta_av_str_opened l2c_cid: 0x%x stream_mtu: %d mtu: %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001406 p_scb->l2c_cid, p_scb->stream_mtu, mtu);
1407 if(mtu == 0 || mtu > p_scb->stream_mtu)
1408 mtu = p_scb->stream_mtu;
1409
1410 /* Set the media channel as medium priority */
1411 L2CA_SetTxPriority(p_scb->l2c_cid, L2CAP_CHNL_PRIORITY_MEDIUM);
1412 L2CA_SetChnlFlushability (p_scb->l2c_cid, TRUE);
1413
1414 bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
1415 memset(&p_scb->q_info, 0, sizeof(tBTA_AV_Q_INFO));
1416
1417 p_scb->l2c_bufs = 0;
1418 p_scb->p_cos->open(p_scb->hndl,
1419 p_scb->codec_type, p_scb->cfg.codec_info, mtu);
1420
1421 {
1422 /* TODO check if other audio channel is open.
1423 * If yes, check if reconfig is needed
1424 * Rigt now we do not do this kind of checking.
1425 * BTA-AV is INT for 2nd audio connection.
1426 * The application needs to make sure the current codec_info is proper.
1427 * If one audio connection is open and another SNK attempts to connect to AV,
1428 * the connection will be rejected.
1429 */
1430 /* check if other audio channel is started. If yes, start */
1431 bdcpy(open.bd_addr, p_scb->peer_addr);
1432 open.chnl = p_scb->chnl;
1433 open.hndl = p_scb->hndl;
1434 open.status = BTA_AV_SUCCESS;
1435 open.starting = bta_av_chk_start(p_scb);
1436 open.edr = 0;
1437 if( NULL != (p = BTM_ReadRemoteFeatures(p_scb->peer_addr)))
1438 {
1439 if(HCI_EDR_ACL_2MPS_SUPPORTED(p))
1440 open.edr |= BTA_AV_EDR_2MBPS;
1441 if(HCI_EDR_ACL_3MPS_SUPPORTED(p))
1442 open.edr |= BTA_AV_EDR_3MBPS;
1443 }
1444#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
1445 bta_ar_avdt_conn(BTA_ID_AV, open.bd_addr);
1446#endif
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301447 if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC )
1448 open.sep = AVDT_TSEP_SNK;
1449 else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK )
1450 open.sep = AVDT_TSEP_SRC;
1451
The Android Open Source Project5738f832012-12-12 16:00:35 -08001452 (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV *) &open);
1453 if(open.starting)
1454 {
1455 bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
1456 }
1457 }
Anubhav Gupta6a277762014-11-13 19:58:09 +05301458
1459 // This code is used to pass PTS TC for AVDTP ABORT
1460 char value[PROPERTY_VALUE_MAX] = {0};
1461 if ((property_get("bluetooth.pts.force_a2dp_abort", value, "false"))
1462 && (!strcmp(value, "true")))
1463 {
1464 APPL_TRACE_ERROR ("%s: Calling AVDT_AbortReq", __func__);
1465 AVDT_AbortReq(p_scb->avdt_handle);
1466 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001467}
1468
1469/*******************************************************************************
1470**
1471** Function bta_av_security_ind
1472**
1473** Description Handle an AVDTP security indication.
1474**
1475** Returns void
1476**
1477*******************************************************************************/
1478void bta_av_security_ind (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1479{
1480 tBTA_AV_PROTECT_REQ protect_req;
1481
1482 p_scb->avdt_label = p_data->str_msg.msg.hdr.label;
1483
1484 if (bta_av_cb.features & BTA_AV_FEAT_PROTECT)
1485 {
1486 protect_req.chnl = p_scb->chnl;
1487 protect_req.hndl = p_scb->hndl;
1488 /*
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001489 APPL_TRACE_EVENT("sec ind handle: x%x", protect_req.hndl);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001490 */
1491 protect_req.p_data = p_data->str_msg.msg.security_ind.p_data;
1492 protect_req.len = p_data->str_msg.msg.security_ind.len;
1493
1494 (*bta_av_cb.p_cback)(BTA_AV_PROTECT_REQ_EVT, (tBTA_AV *) &protect_req);
1495 }
1496 /* app doesn't support security indication; respond with failure */
1497 else
1498 {
1499 AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_NSC, NULL, 0);
1500 }
1501}
1502
1503/*******************************************************************************
1504**
1505** Function bta_av_security_cfm
1506**
1507** Description Handle an AVDTP security confirm.
1508**
1509** Returns void
1510**
1511*******************************************************************************/
1512void bta_av_security_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1513{
1514 tBTA_AV_PROTECT_RSP protect_rsp;
1515
1516 if (bta_av_cb.features & BTA_AV_FEAT_PROTECT)
1517 {
1518 protect_rsp.chnl = p_scb->chnl;
1519 protect_rsp.hndl = p_scb->hndl;
1520 protect_rsp.p_data = p_data->str_msg.msg.security_cfm.p_data;
1521 protect_rsp.len = p_data->str_msg.msg.security_cfm.len;
1522 protect_rsp.err_code= p_data->str_msg.msg.hdr.err_code;
1523
1524 (*bta_av_cb.p_cback)(BTA_AV_PROTECT_RSP_EVT, (tBTA_AV *) &protect_rsp);
1525 }
1526}
1527
1528/*******************************************************************************
1529**
1530** Function bta_av_do_close
1531**
1532** Description Close stream.
1533**
1534** Returns void
1535**
1536*******************************************************************************/
1537void bta_av_do_close (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1538{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001539 UNUSED(p_data);
1540
The Android Open Source Project5738f832012-12-12 16:00:35 -08001541 /* stop stream if started */
1542 if (p_scb->co_started)
1543 {
1544 bta_av_str_stopped(p_scb, NULL);
1545 }
1546 bta_sys_stop_timer(&bta_av_cb.sig_tmr);
1547
1548 /* close stream */
1549 p_scb->started = FALSE;
1550
1551 /* drop the buffers queued in L2CAP */
1552 L2CA_FlushChannel (p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
1553
1554 AVDT_CloseReq(p_scb->avdt_handle);
1555 /* just in case that the link is congested, link is flow controled by peer or
1556 * for whatever reason the the close request can not be sent in time.
1557 * when this timer expires, AVDT_DisconnectReq will be called to disconnect the link
1558 */
1559 bta_sys_start_timer(&p_scb->timer,
1560 (UINT16)BTA_AV_API_CLOSE_EVT,
1561 BTA_AV_CLOSE_REQ_TIME_VAL);
1562
1563}
1564
1565/*******************************************************************************
1566**
1567** Function bta_av_connect_req
1568**
1569** Description Connect AVDTP connection.
1570**
1571** Returns void
1572**
1573*******************************************************************************/
1574void bta_av_connect_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1575{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001576 UNUSED(p_data);
1577
The Android Open Source Project5738f832012-12-12 16:00:35 -08001578 utl_freebuf((void **) &p_scb->p_disc_db);
1579
1580 if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR)
1581 {
1582 /* SNK initiated L2C connection while SRC was doing SDP. */
1583 /* Wait until timeout to check if SNK starts signalling. */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001584 APPL_TRACE_EVENT("bta_av_connect_req: coll_mask = 0x%2X", p_scb->coll_mask);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001585 return;
1586 }
1587
1588 AVDT_ConnectReq(p_scb->peer_addr, p_scb->sec_mask, bta_av_dt_cback[p_scb->hdi]);
1589}
1590
1591/*******************************************************************************
1592**
1593** Function bta_av_sdp_failed
1594**
1595** Description Service discovery failed.
1596**
1597** Returns void
1598**
1599*******************************************************************************/
1600void bta_av_sdp_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1601{
1602 if (!p_scb->open_status)
1603 p_scb->open_status = BTA_AV_FAIL_SDP;
1604
1605 utl_freebuf((void **) &p_scb->p_disc_db);
1606 bta_av_str_closed(p_scb, p_data);
1607}
1608
1609/*******************************************************************************
1610**
1611** Function bta_av_disc_results
1612**
1613** Description Handle the AVDTP discover results. Search through the
1614** results and find the first available stream, and get
1615** its capabilities.
1616**
1617** Returns void
1618**
1619*******************************************************************************/
1620void bta_av_disc_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1621{
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301622 UINT8 num_snks = 0, num_srcs =0, i;
1623 /* our uuid in case we initiate connection */
1624 UINT16 uuid_int = p_scb->uuid_int;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001625
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001626 APPL_TRACE_DEBUG(" initiator UUID 0x%x", uuid_int);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001627 /* store number of stream endpoints returned */
1628 p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps;
1629
1630 for (i = 0; i < p_scb->num_seps; i++)
1631 {
1632 /* steam not in use, is a sink, and is audio */
1633 if ((p_scb->sep_info[i].in_use == FALSE) &&
The Android Open Source Project5738f832012-12-12 16:00:35 -08001634 (p_scb->sep_info[i].media_type == p_scb->media_type))
1635 {
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301636 if((p_scb->sep_info[i].tsep == AVDT_TSEP_SNK) &&
1637 (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE))
1638 num_snks++;
1639
1640 if((p_scb->sep_info[i].tsep == AVDT_TSEP_SRC) &&
1641 (uuid_int == UUID_SERVCLASS_AUDIO_SINK))
1642 num_srcs++;
1643
The Android Open Source Project5738f832012-12-12 16:00:35 -08001644 }
1645 }
1646
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301647 p_scb->p_cos->disc_res(p_scb->hndl, p_scb->num_seps, num_snks, num_srcs, p_scb->peer_addr,
1648 uuid_int);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001649 p_scb->num_disc_snks = num_snks;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301650 p_scb->num_disc_srcs = num_srcs;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001651
1652 /* if we got any */
1653 if (p_scb->num_seps > 0)
1654 {
1655 /* initialize index into discovery results */
1656 p_scb->sep_info_idx = 0;
1657
1658 /* get the capabilities of the first available stream */
1659 bta_av_next_getcap(p_scb, p_data);
1660 }
1661 /* else we got discover response but with no streams; we're done */
1662 else
1663 {
1664 bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data);
1665 }
1666}
1667
1668/*******************************************************************************
1669**
1670** Function bta_av_disc_res_as_acp
1671**
1672** Description Handle the AVDTP discover results. Search through the
1673** results and find the first available stream, and get
1674** its capabilities.
1675**
1676** Returns void
1677**
1678*******************************************************************************/
1679void bta_av_disc_res_as_acp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1680{
1681 UINT8 num_snks = 0, i;
1682
1683 /* store number of stream endpoints returned */
1684 p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps;
1685
1686
1687
1688 for (i = 0; i < p_scb->num_seps; i++)
1689 {
1690 /* steam is a sink, and is audio */
1691 if ((p_scb->sep_info[i].tsep == AVDT_TSEP_SNK) &&
1692 (p_scb->sep_info[i].media_type == p_scb->media_type))
1693 {
1694 p_scb->sep_info[i].in_use = FALSE;
1695 num_snks++;
1696 }
1697 }
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301698 p_scb->p_cos->disc_res(p_scb->hndl, p_scb->num_seps, num_snks, 0, p_scb->peer_addr,
1699 UUID_SERVCLASS_AUDIO_SOURCE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001700 p_scb->num_disc_snks = num_snks;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301701 p_scb->num_disc_srcs = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001702
1703 /* if we got any */
1704 if (p_scb->num_seps > 0)
1705 {
1706 /* initialize index into discovery results */
1707 p_scb->sep_info_idx = 0;
1708
1709 /* get the capabilities of the first available stream */
1710 bta_av_next_getcap(p_scb, p_data);
1711 }
1712 /* else we got discover response but with no streams; we're done */
1713 else
1714 {
1715 bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data);
1716 }
1717}
1718
1719/*******************************************************************************
1720**
1721** Function bta_av_save_caps
1722**
1723** Description report the SNK SEP capabilities to application
1724**
1725** Returns void
1726**
1727*******************************************************************************/
1728void bta_av_save_caps(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1729{
1730 tAVDT_CFG cfg;
1731 tAVDT_SEP_INFO *p_info = &p_scb->sep_info[p_scb->sep_info_idx];
1732 UINT8 old_wait = p_scb->wait;
1733 BOOLEAN getcap_done = FALSE;
1734
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001735 APPL_TRACE_DEBUG("bta_av_save_caps num_seps:%d sep_info_idx:%d wait:x%x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001736 p_scb->num_seps, p_scb->sep_info_idx, p_scb->wait);
1737 memcpy(&cfg, p_scb->p_cap, sizeof(tAVDT_CFG));
1738 /* let application know the capability of the SNK */
1739 p_scb->p_cos->getcfg(p_scb->hndl, cfg.codec_info[BTA_AV_CODEC_TYPE_IDX],
1740 cfg.codec_info, &p_scb->sep_info_idx, p_info->seid,
1741 &cfg.num_protect, cfg.protect_info);
1742
1743 p_scb->sep_info_idx++;
1744 if(p_scb->num_seps > p_scb->sep_info_idx)
1745 {
1746 /* Some devices have seps at the end of the discover list, which is not */
1747 /* matching media type(video not audio). */
1748 /* In this case, we are done with getcap without sending another */
1749 /* request to AVDT. */
1750 if (!bta_av_next_getcap(p_scb, p_data))
1751 getcap_done = TRUE;
1752 }
1753 else
1754 getcap_done = TRUE;
1755
1756 if (getcap_done)
1757 {
1758 /* we are done getting capabilities. restore the p_cb->sep_info_idx */
1759 p_scb->sep_info_idx = 0;
1760 p_scb->wait &= ~(BTA_AV_WAIT_ACP_CAPS_ON|BTA_AV_WAIT_ACP_CAPS_STARTED);
1761 if (old_wait & BTA_AV_WAIT_ACP_CAPS_STARTED)
1762 {
1763 bta_av_start_ok (p_scb, NULL);
1764 }
1765 }
1766}
1767
1768/*******************************************************************************
1769**
1770** Function bta_av_set_use_rc
1771**
1772** Description set to use AVRC for this stream control block.
1773**
1774** Returns void
1775**
1776*******************************************************************************/
1777void bta_av_set_use_rc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1778{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001779 UNUSED(p_data);
1780
The Android Open Source Project5738f832012-12-12 16:00:35 -08001781 p_scb->use_rc = TRUE;
1782}
1783
1784/*******************************************************************************
1785**
1786** Function bta_av_cco_close
1787**
1788** Description call close call-out function.
1789**
1790** Returns void
1791**
1792*******************************************************************************/
1793void bta_av_cco_close (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1794{
1795 UINT16 mtu;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001796 UNUSED(p_data);
1797
The Android Open Source Project5738f832012-12-12 16:00:35 -08001798 mtu = bta_av_chk_mtu(p_scb, BTA_AV_MAX_A2DP_MTU);
1799
1800 p_scb->p_cos->close(p_scb->hndl, p_scb->codec_type, mtu);
1801}
1802
1803/*******************************************************************************
1804**
1805** Function bta_av_open_failed
1806**
1807** Description Failed to open an AVDT stream
1808**
1809** Returns void
1810**
1811*******************************************************************************/
1812void bta_av_open_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1813{
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001814
1815 BOOLEAN is_av_opened = FALSE;
1816 tBTA_AV_SCB * p_opened_scb = NULL;
1817 UINT8 idx;
1818 tBTA_AV_OPEN open;
1819
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001820 APPL_TRACE_DEBUG("bta_av_open_failed");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001821 p_scb->open_status = BTA_AV_FAIL_STREAM;
1822 bta_av_cco_close(p_scb, p_data);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001823
1824 /* check whether there is already an opened audio or video connection with the same device */
1825 for (idx = 0; (idx < BTA_AV_NUM_STRS) && (is_av_opened == FALSE); idx++ )
1826 {
1827 p_opened_scb = bta_av_cb.p_scb[idx];
1828 if (p_opened_scb && (p_opened_scb->state == BTA_AV_OPEN_SST) && (!bdcmp(p_opened_scb->peer_addr,p_scb->peer_addr )) )
1829 is_av_opened = TRUE;
1830
1831 }
1832
1833 /* if there is already an active AV connnection with the same bd_addr,
1834 don't send disconnect req, just report the open event with BTA_AV_FAIL_GET_CAP status */
1835 if (is_av_opened == TRUE)
1836 {
1837 bdcpy(open.bd_addr, p_scb->peer_addr);
1838 open.chnl = p_scb->chnl;
1839 open.hndl = p_scb->hndl;
1840 open.status = BTA_AV_FAIL_GET_CAP;
1841 open.starting = bta_av_chk_start(p_scb);
1842 open.edr = 0;
1843 /* set the state back to initial state */
1844 bta_av_set_scb_sst_init(p_scb);
1845
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301846 if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC )
1847 open.sep = AVDT_TSEP_SNK;
1848 else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK )
1849 open.sep = AVDT_TSEP_SRC;
1850
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001851 (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV *) &open);
1852
1853 }
1854 else
1855 {
1856 AVDT_DisconnectReq(p_scb->peer_addr, bta_av_dt_cback[p_scb->hdi]);
1857 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001858}
1859
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001860
The Android Open Source Project5738f832012-12-12 16:00:35 -08001861/*******************************************************************************
1862**
1863** Function bta_av_getcap_results
1864**
1865** Description Handle the AVDTP get capabilities results. Check the codec
1866** type and see if it matches ours. If it does not, get the
1867** capabilities of the next stream, if any.
1868**
1869** Returns void
1870**
1871*******************************************************************************/
1872void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1873{
1874 tAVDT_CFG cfg;
1875 UINT8 media_type;
1876 tAVDT_SEP_INFO *p_info = &p_scb->sep_info[p_scb->sep_info_idx];
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301877 UINT16 uuid_int; /* UUID for which connection was initiatied */
The Android Open Source Project5738f832012-12-12 16:00:35 -08001878
1879 memcpy(&cfg, &p_scb->cfg, sizeof(tAVDT_CFG));
1880 cfg.num_codec = 1;
1881 cfg.num_protect = p_scb->p_cap->num_protect;
1882 memcpy(cfg.codec_info, p_scb->p_cap->codec_info, AVDT_CODEC_SIZE);
1883 memcpy(cfg.protect_info, p_scb->p_cap->protect_info, AVDT_PROTECT_SIZE);
1884 media_type = p_scb->p_cap->codec_info[BTA_AV_MEDIA_TYPE_IDX] >> 4;
1885
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001886 APPL_TRACE_DEBUG("num_codec %d", p_scb->p_cap->num_codec);
1887 APPL_TRACE_DEBUG("media type x%x, x%x", media_type, p_scb->media_type);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001888#if AVDT_MULTIPLEXING == TRUE
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001889 APPL_TRACE_DEBUG("mux x%x, x%x", cfg.mux_mask, p_scb->p_cap->mux_mask);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001890#endif
1891
1892 /* if codec present and we get a codec configuration */
1893 if ((p_scb->p_cap->num_codec != 0) &&
1894 (media_type == p_scb->media_type) &&
1895 (p_scb->p_cos->getcfg(p_scb->hndl, p_scb->p_cap->codec_info[BTA_AV_CODEC_TYPE_IDX],
1896 cfg.codec_info, &p_scb->sep_info_idx, p_info->seid,
1897 &cfg.num_protect, cfg.protect_info) == 0))
1898 {
1899#if AVDT_MULTIPLEXING == TRUE
1900 cfg.mux_mask &= p_scb->p_cap->mux_mask;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001901 APPL_TRACE_DEBUG("mux_mask used x%x", cfg.mux_mask);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001902#endif
1903 /* save copy of codec type and configuration */
1904 p_scb->codec_type = cfg.codec_info[BTA_AV_CODEC_TYPE_IDX];
1905 memcpy(&p_scb->cfg, &cfg, sizeof(tAVDT_CFG));
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301906
1907 uuid_int = p_scb->uuid_int;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001908 APPL_TRACE_DEBUG(" initiator UUID = 0x%x ", uuid_int);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301909 if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
1910 bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SRC));
1911 else if (uuid_int == UUID_SERVCLASS_AUDIO_SINK)
1912 bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SNK));
1913
The Android Open Source Project5738f832012-12-12 16:00:35 -08001914 /* use only the services peer supports */
1915 cfg.psc_mask &= p_scb->p_cap->psc_mask;
1916 p_scb->cur_psc_mask = cfg.psc_mask;
1917
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301918 if ((uuid_int == UUID_SERVCLASS_AUDIO_SINK) &&
1919 (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL))
1920 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001921 APPL_TRACE_DEBUG(" Configure Deoder for Sink Connection ");
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301922 p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT,
1923 (tBTA_AV_MEDIA*)p_scb->cfg.codec_info);
1924 }
1925
The Android Open Source Project5738f832012-12-12 16:00:35 -08001926 /* open the stream */
1927 AVDT_OpenReq(p_scb->seps[p_scb->sep_idx].av_handle, p_scb->peer_addr,
1928 p_scb->sep_info[p_scb->sep_info_idx].seid, &cfg);
1929
1930 if (!bta_av_is_rcfg_sst(p_scb))
1931 {
1932 /* free capabilities buffer */
1933 utl_freebuf((void **) &p_scb->p_cap);
1934 }
1935 }
1936 else
1937 {
1938 /* try the next stream, if any */
1939 p_scb->sep_info_idx++;
1940 bta_av_next_getcap(p_scb, p_data);
1941 }
1942
1943}
1944
1945/*******************************************************************************
1946**
1947** Function bta_av_setconfig_rej
1948**
1949** Description Send AVDTP set config reject.
1950**
1951** Returns void
1952**
1953*******************************************************************************/
1954void bta_av_setconfig_rej (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1955{
1956 tBTA_AV_REJECT reject;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301957 UINT8 avdt_handle = p_data->ci_setconfig.avdt_handle;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001958
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301959 bta_av_adjust_seps_idx(p_scb, avdt_handle);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001960 APPL_TRACE_DEBUG("bta_av_setconfig_rej: sep_idx: %d",p_scb->sep_idx);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301961 AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_UNSUP_CFG, 0);
1962
The Android Open Source Project5738f832012-12-12 16:00:35 -08001963 bdcpy(reject.bd_addr, p_data->str_msg.bd_addr);
1964 reject.hndl = p_scb->hndl;
1965 (*bta_av_cb.p_cback)(BTA_AV_REJECT_EVT, (tBTA_AV *) &reject);
1966}
1967
1968/*******************************************************************************
1969**
1970** Function bta_av_discover_req
1971**
1972** Description Send an AVDTP discover request to the peer.
1973**
1974** Returns void
1975**
1976*******************************************************************************/
1977void bta_av_discover_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1978{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08001979 UNUSED(p_data);
1980
The Android Open Source Project5738f832012-12-12 16:00:35 -08001981 /* send avdtp discover request */
1982
1983 AVDT_DiscoverReq(p_scb->peer_addr, p_scb->sep_info, BTA_AV_NUM_SEPS, bta_av_dt_cback[p_scb->hdi]);
1984}
1985
1986/*******************************************************************************
1987**
1988** Function bta_av_conn_failed
1989**
1990** Description AVDTP connection failed.
1991**
1992** Returns void
1993**
1994*******************************************************************************/
1995void bta_av_conn_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
1996{
1997 p_scb->open_status = BTA_AV_FAIL_STREAM;
1998 bta_av_str_closed(p_scb, p_data);
1999}
2000
2001/*******************************************************************************
2002**
2003** Function bta_av_do_start
2004**
2005** Description Start stream.
2006**
2007** Returns void
2008**
2009*******************************************************************************/
2010void bta_av_do_start (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2011{
2012 UINT8 policy = HCI_ENABLE_SNIFF_MODE;
2013 UINT8 cur_role;
2014
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002015 APPL_TRACE_DEBUG("bta_av_do_start sco_occupied:%d, role:x%x, started:%d", bta_av_cb.sco_occupied, p_scb->role, p_scb->started);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002016 if (bta_av_cb.sco_occupied)
2017 {
2018 bta_av_start_failed(p_scb, p_data);
2019 return;
2020 }
2021
2022 /* disallow role switch during streaming, only if we are the master role
2023 * i.e. allow role switch, if we are slave.
2024 * It would not hurt us, if the peer device wants us to be master */
2025 if ((BTM_GetRole (p_scb->peer_addr, &cur_role) == BTM_SUCCESS) &&
2026 (cur_role == BTM_ROLE_MASTER) )
2027 {
2028 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
2029 }
2030
2031 bta_sys_clear_policy(BTA_ID_AV, policy, p_scb->peer_addr);
2032
2033 if ((p_scb->started == FALSE) && ((p_scb->role & BTA_AV_ROLE_START_INT) == 0))
2034 {
2035 p_scb->role |= BTA_AV_ROLE_START_INT;
2036 bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
2037
2038 AVDT_StartReq(&p_scb->avdt_handle, 1);
2039 }
Kausik Sinnaswamy77d1cb62013-05-22 16:18:31 +05302040 else if (p_scb->started)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002041 {
Kausik Sinnaswamy77d1cb62013-05-22 16:18:31 +05302042 p_scb->role |= BTA_AV_ROLE_START_INT;
Zhihai Xu379743b2013-09-29 13:42:13 -07002043 if ( p_scb->wait == 0 ) {
2044 if (p_scb->role & BTA_AV_ROLE_SUSPEND) {
2045 notify_start_failed(p_scb);
2046 } else {
2047 bta_av_start_ok(p_scb, NULL);
2048 }
2049 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002050 }
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002051 APPL_TRACE_DEBUG("started %d role:x%x", p_scb->started, p_scb->role);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002052}
2053
2054/*******************************************************************************
2055**
2056** Function bta_av_str_stopped
2057**
2058** Description Stream stopped.
2059**
2060** Returns void
2061**
2062*******************************************************************************/
2063void bta_av_str_stopped (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2064{
2065 tBTA_AV_SUSPEND suspend_rsp;
2066 UINT8 start = p_scb->started;
2067 BOOLEAN sus_evt = TRUE;
2068 BT_HDR *p_buf;
2069 UINT8 policy = HCI_ENABLE_SNIFF_MODE;
2070
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002071 APPL_TRACE_ERROR("bta_av_str_stopped:audio_open_cnt=%d, p_data %x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002072 bta_av_cb.audio_open_cnt, p_data);
2073
2074 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
2075 if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 || bta_av_cb.audio_open_cnt == 1)
2076 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
2077 bta_sys_set_policy(BTA_ID_AV, policy, p_scb->peer_addr);
2078
Chris Mantond44d6402015-03-06 14:41:32 -08002079 if (p_scb->co_started)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002080 {
Abhijit Adsule47b43102015-05-19 02:44:26 -05002081 vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
2082 if (p_scb->offload_start_pending) {
2083 tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
2084 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
2085 }
2086 p_scb->offload_start_pending = FALSE;
2087
The Android Open Source Project5738f832012-12-12 16:00:35 -08002088 bta_av_stream_chg(p_scb, FALSE);
2089 p_scb->co_started = FALSE;
2090
2091 p_scb->p_cos->stop(p_scb->hndl, p_scb->codec_type);
2092 L2CA_SetFlushTimeout(p_scb->peer_addr, L2CAP_DEFAULT_FLUSH_TO);
2093 }
2094
Chris Manton725278f2014-08-05 13:24:41 -07002095 /* if q_info.a2d_list is not empty, drop it now */
Chris Mantond44d6402015-03-06 14:41:32 -08002096 if (BTA_AV_CHNL_AUDIO == p_scb->chnl) {
2097 while (!list_is_empty(p_scb->a2d_list))
2098 {
2099 p_buf = (BT_HDR *)list_front(p_scb->a2d_list);
2100 list_remove(p_scb->a2d_list, p_buf);
Pavlin Radoslavov258c2532015-09-27 20:59:05 -07002101 osi_freebuf(p_buf);
Chris Mantond44d6402015-03-06 14:41:32 -08002102 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002103
2104 /* drop the audio buffers queued in L2CAP */
Chris Mantond44d6402015-03-06 14:41:32 -08002105 if (p_data && p_data->api_stop.flush)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002106 L2CA_FlushChannel (p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
2107 }
2108
2109 suspend_rsp.chnl = p_scb->chnl;
2110 suspend_rsp.hndl = p_scb->hndl;
2111
2112 if (p_data && p_data->api_stop.suspend)
2113 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002114 APPL_TRACE_DEBUG("suspending: %d, sup:%d", start, p_scb->suspend_sup);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002115 if ((start) && (p_scb->suspend_sup))
2116 {
2117 sus_evt = FALSE;
2118 p_scb->l2c_bufs = 0;
2119 AVDT_SuspendReq(&p_scb->avdt_handle, 1);
2120 }
2121
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002122 /* send SUSPEND_EVT event only if not in reconfiguring state and sus_evt is TRUE*/
2123 if ((sus_evt)&&(p_scb->state != BTA_AV_RCFG_SST))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002124 {
2125 suspend_rsp.status = BTA_AV_SUCCESS;
2126 suspend_rsp.initiator = TRUE;
2127 (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, (tBTA_AV *) &suspend_rsp);
2128 }
2129 }
2130 else
2131 {
2132 suspend_rsp.status = BTA_AV_SUCCESS;
2133 suspend_rsp.initiator = TRUE;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002134 APPL_TRACE_EVENT("bta_av_str_stopped status %d", suspend_rsp.status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002135
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002136 /* send STOP_EVT event only if not in reconfiguring state */
2137 if (p_scb->state != BTA_AV_RCFG_SST)
2138 {
2139 (*bta_av_cb.p_cback)(BTA_AV_STOP_EVT, (tBTA_AV *) &suspend_rsp);
2140 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002141 }
2142}
2143
2144/*******************************************************************************
2145**
2146** Function bta_av_reconfig
2147**
2148** Description process the reconfigure request.
2149** save the parameter in control block and
2150** suspend, reconfigure or close the stream
2151**
2152** Returns void
2153**
2154*******************************************************************************/
2155void bta_av_reconfig (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2156{
2157 tAVDT_CFG *p_cfg;
2158 tBTA_AV_API_STOP stop;
2159 tBTA_AV_RECONFIG evt;
2160 tBTA_AV_API_RCFG *p_rcfg = &p_data->api_reconfig;
2161
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002162 APPL_TRACE_DEBUG("bta_av_reconfig r:%d, s:%d idx: %d (o:%d)",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002163 p_scb->recfg_sup, p_scb->suspend_sup,
2164 p_scb->rcfg_idx, p_scb->sep_info_idx);
2165
2166 p_scb->num_recfg = 0;
2167 /* store the new configuration in control block */
2168 if (p_scb->p_cap == NULL)
2169 {
Pavlin Radoslavov258c2532015-09-27 20:59:05 -07002170 p_scb->p_cap = (tAVDT_CFG *) osi_getbuf(sizeof(tAVDT_CFG));
The Android Open Source Project5738f832012-12-12 16:00:35 -08002171 }
2172 if((p_cfg = p_scb->p_cap) == NULL)
2173 {
2174 /* report failure */
2175 evt.status = BTA_AV_FAIL_RESOURCES;
2176 evt.chnl = p_scb->chnl;
2177 evt.hndl = p_scb->hndl;
2178 (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV *)&evt);
2179
2180 /* this event is not possible in this state.
2181 * use it to bring the SSM back to open state */
2182 bta_av_ssm_execute(p_scb, BTA_AV_SDP_DISC_OK_EVT, NULL);
2183 return;
2184 }
2185
2186 /*if(bta_av_cb.features & BTA_AV_FEAT_RCCT)*/
2187 bta_sys_stop_timer(&p_scb->timer);
2188
2189 memcpy(p_cfg, &p_scb->cfg, sizeof(tAVDT_CFG));
2190 p_cfg->num_protect = p_rcfg->num_protect;
2191 memcpy(p_cfg->codec_info, p_rcfg->codec_info, AVDT_CODEC_SIZE);
2192 memcpy(p_cfg->protect_info, p_rcfg->p_protect_info, p_rcfg->num_protect);
2193 p_scb->rcfg_idx = p_rcfg->sep_info_idx;
2194 p_scb->p_cap->psc_mask = p_scb->cur_psc_mask;
2195
2196 /* if the requested index differs from the current one, we can only close/open */
2197 if ((p_scb->rcfg_idx == p_scb->sep_info_idx) &&
2198 (p_rcfg->suspend)&& (p_scb->recfg_sup) && (p_scb->suspend_sup))
2199 {
2200 if(p_scb->started)
2201 {
2202 stop.flush = FALSE;
2203 stop.suspend = TRUE;
2204 bta_av_str_stopped(p_scb, (tBTA_AV_DATA *)&stop);
2205 }
2206 else
2207 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002208 APPL_TRACE_DEBUG("Reconfig");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002209 AVDT_ReconfigReq(p_scb->avdt_handle, p_scb->p_cap);
2210 p_scb->p_cap->psc_mask = p_scb->cur_psc_mask;
2211 }
2212 }
2213 else
2214 {
2215 /* close the stream */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002216 APPL_TRACE_DEBUG("close/open num_protect: %d", p_cfg->num_protect);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002217 if(p_scb->started)
Kim Schulz15050772013-09-30 09:52:55 +02002218 {
The Android Open Source Project5738f832012-12-12 16:00:35 -08002219 bta_av_str_stopped(p_scb, NULL);
2220 p_scb->started = FALSE;
2221
2222 /* drop the buffers queued in L2CAP */
2223 L2CA_FlushChannel (p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
2224
2225 AVDT_CloseReq(p_scb->avdt_handle);
Kim Schulz15050772013-09-30 09:52:55 +02002226 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002227 }
2228}
2229
2230/*******************************************************************************
2231**
2232** Function bta_av_data_path
2233**
2234** Description Handle stream data path.
2235**
2236** Returns void
2237**
2238*******************************************************************************/
2239void bta_av_data_path (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2240{
Chris Mantond44d6402015-03-06 14:41:32 -08002241 BT_HDR *p_buf = NULL;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002242 UINT32 data_len;
2243 UINT32 timestamp;
2244 BOOLEAN new_buf = FALSE;
2245 UINT8 m_pt = 0x60 | p_scb->codec_type;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002246 tAVDT_DATA_OPT_MASK opt;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08002247 UNUSED(p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002248
Chris Mantond44d6402015-03-06 14:41:32 -08002249 if (p_scb->cong)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002250 {
Chris Mantond44d6402015-03-06 14:41:32 -08002251 return;
2252 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002253
Chris Mantond44d6402015-03-06 14:41:32 -08002254 /*
2255 APPL_TRACE_ERROR("q: %d", p_scb->l2c_bufs);
2256 */
2257 //Always get the current number of bufs que'd up
2258 p_scb->l2c_bufs = (UINT8)L2CA_FlushChannel (p_scb->l2c_cid, L2CAP_FLUSH_CHANS_GET);
2259
2260 if (!list_is_empty(p_scb->a2d_list)) {
2261 p_buf = (BT_HDR *)list_front(p_scb->a2d_list);
2262 list_remove(p_scb->a2d_list, p_buf);
2263 /* use q_info.a2d data, read the timestamp */
2264 timestamp = *(UINT32 *)(p_buf + 1);
2265 }
2266 else
2267 {
2268 new_buf = TRUE;
2269 /* a2d_list empty, call co_data, dup data to other channels */
2270 p_buf = (BT_HDR *)p_scb->p_cos->data(p_scb->codec_type, &data_len,
2271 &timestamp);
2272
2273 if (p_buf)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002274 {
Chris Mantond44d6402015-03-06 14:41:32 -08002275 /* use the offset area for the time stamp */
2276 *(UINT32 *)(p_buf + 1) = timestamp;
2277
2278 /* dup the data to other channels */
2279 bta_av_dup_audio_buf(p_scb, p_buf);
2280 }
2281 }
2282
2283 if(p_buf)
2284 {
2285 if(p_scb->l2c_bufs < (BTA_AV_QUEUE_DATA_CHK_NUM))
2286 {
2287 /* there's a buffer, just queue it to L2CAP */
2288 /* There's no need to increment it here, it is always read from L2CAP see above */
2289 /* p_scb->l2c_bufs++; */
2290 /*
2291 APPL_TRACE_ERROR("qw: %d", p_scb->l2c_bufs);
2292 */
2293
2294 /* opt is a bit mask, it could have several options set */
2295 opt = AVDT_DATA_OPT_NONE;
2296 if (p_scb->no_rtp_hdr)
2297 {
2298 opt |= AVDT_DATA_OPT_NO_RTP;
2299 }
2300
2301 AVDT_WriteReqOpt(p_scb->avdt_handle, p_buf, timestamp, m_pt, opt);
2302 p_scb->cong = TRUE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002303 }
2304 else
2305 {
Chris Mantond44d6402015-03-06 14:41:32 -08002306 /* there's a buffer, but L2CAP does not seem to be moving data */
2307 if(new_buf)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002308 {
Chris Mantond44d6402015-03-06 14:41:32 -08002309 /* just got this buffer from co_data,
2310 * put it in queue */
2311 list_append(p_scb->a2d_list, p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002312 }
2313 else
2314 {
Chris Mantond44d6402015-03-06 14:41:32 -08002315 /* just dequeue it from the a2d_list */
2316 if (list_length(p_scb->a2d_list) < 3) {
2317 /* put it back to the queue */
2318 list_prepend(p_scb->a2d_list, p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002319 }
2320 else
2321 {
Chris Mantond44d6402015-03-06 14:41:32 -08002322 /* too many buffers in a2d_list, drop it. */
2323 bta_av_co_audio_drop(p_scb->hndl);
Pavlin Radoslavov258c2532015-09-27 20:59:05 -07002324 osi_freebuf(p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002325 }
2326 }
2327 }
2328 }
2329}
2330
2331/*******************************************************************************
2332**
2333** Function bta_av_start_ok
2334**
2335** Description Stream started.
2336**
2337** Returns void
2338**
2339*******************************************************************************/
2340void bta_av_start_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2341{
2342 tBTA_AV_START start;
2343 tBTA_AV_API_STOP stop;
2344 BOOLEAN initiator = FALSE;
2345 BOOLEAN suspend = FALSE;
2346 UINT16 flush_to;
2347 UINT8 new_role = p_scb->role;
2348 BT_HDR hdr;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002349 UINT8 policy = HCI_ENABLE_SNIFF_MODE;
2350 UINT8 cur_role;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002351
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002352 APPL_TRACE_DEBUG("bta_av_start_ok wait:x%x, role:x%x", p_scb->wait, p_scb->role);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002353
2354 p_scb->started = TRUE;
2355 if (p_scb->sco_suspend)
2356 {
2357 p_scb->sco_suspend = FALSE;
2358 }
2359
2360 if (new_role & BTA_AV_ROLE_START_INT)
2361 initiator = TRUE;
2362
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302363 /* for A2DP SINK we do not send get_caps */
2364 if ((p_scb->avdt_handle == p_scb->seps[p_scb->sep_idx].av_handle)
2365 &&(p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK))
2366 {
2367 p_scb->wait &= ~(BTA_AV_WAIT_ACP_CAPS_ON);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002368 APPL_TRACE_DEBUG(" Local SEP type is SNK new wait is 0x%x",p_scb->wait);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302369 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002370 if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_FAILED)
2371 {
2372 /* role switch has failed */
2373 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_FAILED;
2374 p_data = (tBTA_AV_DATA *)&hdr;
2375 hdr.offset = BTA_AV_RS_FAIL;
2376 }
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002377 APPL_TRACE_DEBUG("wait:x%x", p_scb->wait);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002378
2379 if (p_data && (p_data->hdr.offset != BTA_AV_RS_NONE))
2380 {
2381 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
2382 if (p_data->hdr.offset == BTA_AV_RS_FAIL)
2383 {
2384 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
2385 start.chnl = p_scb->chnl;
2386 start.status = BTA_AV_FAIL_ROLE;
2387 start.hndl = p_scb->hndl;
2388 start.initiator = initiator;
2389 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV *) &start);
2390 return;
2391 }
2392 }
2393
2394 if (!bta_av_link_role_ok(p_scb, A2D_SET_ONE_BIT))
2395 p_scb->q_tag = BTA_AV_Q_TAG_START;
2396 else
2397 {
2398 /* The wait flag may be set here while we are already master on the link */
2399 /* this could happen if a role switch complete event occurred during reconfig */
2400 /* if we are now master on the link, there is no need to wait for the role switch, */
2401 /* complete anymore so we can clear the wait for role switch flag */
2402 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
2403 }
2404
2405 if (p_scb->wait & (BTA_AV_WAIT_ROLE_SW_RES_OPEN|BTA_AV_WAIT_ROLE_SW_RES_START))
2406 {
2407 p_scb->wait |= BTA_AV_WAIT_ROLE_SW_STARTED;
2408 p_scb->q_tag = BTA_AV_Q_TAG_START;
2409 }
2410
The Android Open Source Project5738f832012-12-12 16:00:35 -08002411 if (p_scb->wait)
2412 {
Matthew Xieafa6e1a2014-06-28 11:35:29 -07002413 APPL_TRACE_ERROR("wait:x%x q_tag:%d- not started", p_scb->wait, p_scb->q_tag);
Rohit Singhffc849a2014-01-23 18:57:11 +05302414 /* Clear first bit of p_scb->wait and not to return from this point else
2415 * HAL layer gets blocked. And if there is delay in Get Capability response as
2416 * first bit of p_scb->wait is cleared hence it ensures bt_av_start_ok is not called
2417 * again from bta_av_save_caps.
2418 */
2419 p_scb->wait &= ~BTA_AV_WAIT_ACP_CAPS_ON;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002420 }
2421
2422 /* tell role manager to check M/S role */
2423 bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
2424
2425 bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
2426
2427 if(p_scb->media_type == AVDT_MEDIA_AUDIO)
2428 {
2429 /* in normal logic, conns should be bta_av_cb.audio_count - 1,
2430 * However, bta_av_stream_chg is not called to increase bta_av_cb.audio_count yet.
2431 * If the code were to be re-arranged for some reasons, this number may need to be changed
2432 */
2433 p_scb->co_started = bta_av_cb.audio_open_cnt;
2434 flush_to = p_bta_av_cfg->p_audio_flush_to[p_scb->co_started - 1];
2435 }
2436 else
2437 {
2438 flush_to = p_bta_av_cfg->video_flush_to;
2439 }
2440 L2CA_SetFlushTimeout(p_scb->peer_addr, flush_to );
2441
2442 /* clear the congestion flag */
2443 p_scb->cong = FALSE;
2444
2445 if (new_role & BTA_AV_ROLE_START_INT)
2446 {
2447 new_role &= ~BTA_AV_ROLE_START_INT;
2448 }
2449 else if ((new_role & BTA_AV_ROLE_AD_ACP) && (new_role & BTA_AV_ROLE_SUSPEND_OPT))
2450 {
2451 suspend = TRUE;
2452 }
2453
2454 if (!suspend)
2455 {
2456 p_scb->q_tag = BTA_AV_Q_TAG_STREAM;
2457 bta_av_stream_chg(p_scb, TRUE);
2458 }
2459
2460 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002461 /* If sink starts stream, disable sniff mode here */
2462 if (!initiator)
2463 {
2464 /* If souce is the master role, disable role switch during streaming.
2465 * Otherwise allow role switch, if source is slave.
2466 * Because it would not hurt source, if the peer device wants source to be master */
2467 if ((BTM_GetRole (p_scb->peer_addr, &cur_role) == BTM_SUCCESS) &&
2468 (cur_role == BTM_ROLE_MASTER) )
2469 {
2470 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
2471 }
2472
2473 bta_sys_clear_policy(BTA_ID_AV, policy, p_scb->peer_addr);
2474 }
2475
The Android Open Source Project5738f832012-12-12 16:00:35 -08002476 p_scb->role = new_role;
2477 p_scb->role &= ~BTA_AV_ROLE_AD_ACP;
2478 p_scb->role &= ~BTA_AV_ROLE_SUSPEND_OPT;
2479
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002480 p_scb->no_rtp_hdr = FALSE;
2481 p_scb->p_cos->start(p_scb->hndl, p_scb->codec_type, p_scb->cfg.codec_info, &p_scb->no_rtp_hdr);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002482 p_scb->co_started = TRUE;
2483
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002484 APPL_TRACE_DEBUG("bta_av_start_ok suspending: %d, role:x%x, init %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002485 suspend, p_scb->role, initiator);
2486
2487 start.suspending = suspend;
2488 start.initiator = initiator;
2489 start.chnl = p_scb->chnl;
2490 start.status = BTA_AV_SUCCESS;
2491 start.hndl = p_scb->hndl;
2492 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV *) &start);
2493
2494 if(suspend)
2495 {
2496 p_scb->role |= BTA_AV_ROLE_SUSPEND;
2497 p_scb->cong = TRUE; /* do not allow the media data to go through */
2498 /* do not duplicate the media packets to this channel */
2499 p_scb->p_cos->stop(p_scb->hndl, p_scb->codec_type);
2500 p_scb->co_started = FALSE;
2501 stop.flush = FALSE;
2502 stop.suspend = TRUE;
2503 bta_av_ssm_execute(p_scb, BTA_AV_AP_STOP_EVT, (tBTA_AV_DATA *)&stop);
2504 }
2505 }
2506}
2507
2508/*******************************************************************************
2509**
2510** Function bta_av_start_failed
2511**
2512** Description Stream start failed.
2513**
2514** Returns void
2515**
2516*******************************************************************************/
2517void bta_av_start_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2518{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08002519 UNUSED(p_data);
2520
The Android Open Source Project5738f832012-12-12 16:00:35 -08002521 if(p_scb->started == FALSE && p_scb->co_started == FALSE)
2522 {
The Android Open Source Project5738f832012-12-12 16:00:35 -08002523 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
Zhihai Xu379743b2013-09-29 13:42:13 -07002524 notify_start_failed(p_scb);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002525 }
2526
2527 bta_sys_set_policy(BTA_ID_AV, (HCI_ENABLE_SNIFF_MODE|HCI_ENABLE_MASTER_SLAVE_SWITCH), p_scb->peer_addr);
2528 p_scb->sco_suspend = FALSE;
2529}
2530
2531/*******************************************************************************
2532**
2533** Function bta_av_str_closed
2534**
2535** Description Stream closed.
2536**
2537** Returns void
2538**
2539*******************************************************************************/
2540void bta_av_str_closed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2541{
2542 tBTA_AV data;
2543 tBTA_AV_EVT event;
2544 UINT16 mtu;
2545 UINT8 policy = HCI_ENABLE_SNIFF_MODE;
2546
2547 if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 || bta_av_cb.audio_open_cnt == 1)
2548 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
2549 bta_sys_set_policy(BTA_ID_AV, policy, p_scb->peer_addr);
2550 if (bta_av_cb.audio_open_cnt <= 1)
2551 {
2552 /* last connection - restore the allow switch flag */
2553 L2CA_SetDesireRole(L2CAP_ROLE_ALLOW_SWITCH);
2554 }
2555
2556 if (p_scb->open_status)
2557 {
2558 /* must be failure when opening the stream */
2559 bdcpy(data.open.bd_addr, p_scb->peer_addr);
2560 data.open.status = p_scb->open_status;
2561 data.open.chnl = p_scb->chnl;
2562 data.open.hndl = p_scb->hndl;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302563
2564 if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC )
2565 data.open.sep = AVDT_TSEP_SNK;
2566 else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK )
2567 data.open.sep = AVDT_TSEP_SRC;
2568
The Android Open Source Project5738f832012-12-12 16:00:35 -08002569 event = BTA_AV_OPEN_EVT;
2570 p_scb->open_status = BTA_AV_SUCCESS;
2571
2572 bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
2573 bta_av_cleanup(p_scb, p_data);
2574 (*bta_av_cb.p_cback)(event, &data);
2575 }
2576 else
2577 {
2578 /* do stop if we were started */
2579 if (p_scb->co_started)
2580 {
2581 bta_av_str_stopped(p_scb, NULL);
2582 }
2583
2584 /* Update common mtu shared by remaining connectons */
2585 mtu = bta_av_chk_mtu(p_scb, BTA_AV_MAX_A2DP_MTU);
2586
2587 {
2588 p_scb->p_cos->close(p_scb->hndl, p_scb->codec_type, mtu);
2589 data.close.chnl = p_scb->chnl;
2590 data.close.hndl = p_scb->hndl;
2591 event = BTA_AV_CLOSE_EVT;
2592
2593 bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
2594 bta_av_cleanup(p_scb, p_data);
2595 (*bta_av_cb.p_cback)(event, &data);
2596 }
2597 }
2598}
2599
2600/*******************************************************************************
2601**
2602** Function bta_av_clr_cong
2603**
2604** Description Clear stream congestion flag.
2605**
2606** Returns void
2607**
2608*******************************************************************************/
2609void bta_av_clr_cong (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2610{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08002611 UNUSED(p_data);
2612
The Android Open Source Project5738f832012-12-12 16:00:35 -08002613 if(p_scb->co_started)
2614 p_scb->cong = FALSE;
2615}
2616
2617/*******************************************************************************
2618**
2619** Function bta_av_suspend_cfm
2620**
2621** Description process the suspend response
2622**
2623** Returns void
2624**
2625*******************************************************************************/
2626void bta_av_suspend_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2627{
2628 tBTA_AV_SUSPEND suspend_rsp;
2629 UINT8 err_code = p_data->str_msg.msg.hdr.err_code;
2630 UINT8 policy = HCI_ENABLE_SNIFF_MODE;
2631
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002632 APPL_TRACE_DEBUG ("bta_av_suspend_cfm:audio_open_cnt = %d, err_code = %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002633 bta_av_cb.audio_open_cnt, err_code);
2634
Zhihai Xu5ae72cf2013-05-15 17:29:44 -07002635 if (p_scb->started == FALSE)
2636 {
2637 /* handle the condition where there is a collision of SUSPEND req from either side
2638 ** Second SUSPEND req could be rejected. Do not treat this as a failure
2639 */
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002640 APPL_TRACE_WARNING("bta_av_suspend_cfm: already suspended, ignore, err_code %d",
Zhihai Xu5ae72cf2013-05-15 17:29:44 -07002641 err_code);
2642 return;
2643 }
2644
The Android Open Source Project5738f832012-12-12 16:00:35 -08002645 suspend_rsp.status = BTA_AV_SUCCESS;
Zhihai Xu5ae72cf2013-05-15 17:29:44 -07002646 if (err_code && (err_code != AVDT_ERR_BAD_STATE))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002647 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002648 /* Disable suspend feature only with explicit rejection(not with timeout) */
2649 if (err_code != AVDT_ERR_TIMEOUT)
2650 {
2651 p_scb->suspend_sup = FALSE;
2652 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002653 suspend_rsp.status = BTA_AV_FAIL;
2654
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002655 APPL_TRACE_ERROR ("bta_av_suspend_cfm: suspend failed, closing connection");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002656
2657 /* SUSPEND failed. Close connection. */
2658 bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, NULL);
2659 }
2660 else
2661 {
2662 /* only set started to FALSE when suspend is successful */
2663 p_scb->started = FALSE;
2664 }
2665
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002666 if (p_scb->role & BTA_AV_ROLE_SUSPEND)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002667 {
2668 p_scb->role &= ~BTA_AV_ROLE_SUSPEND;
2669 p_scb->cong = FALSE;
2670 }
2671
2672 bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
2673 if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 || bta_av_cb.audio_open_cnt == 1)
2674 policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
2675 bta_sys_set_policy(BTA_ID_AV, policy, p_scb->peer_addr);
2676
2677 /* in case that we received suspend_ind, we may need to call co_stop here */
2678 if(p_scb->co_started)
2679 {
Abhijit Adsule47b43102015-05-19 02:44:26 -05002680 vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
2681 if (p_scb->offload_start_pending) {
2682 tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
2683 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
2684 }
2685 p_scb->offload_start_pending = FALSE;
2686
The Android Open Source Project5738f832012-12-12 16:00:35 -08002687 bta_av_stream_chg(p_scb, FALSE);
2688
2689 {
2690 p_scb->co_started = FALSE;
2691 p_scb->p_cos->stop(p_scb->hndl, p_scb->codec_type);
2692 }
2693 L2CA_SetFlushTimeout(p_scb->peer_addr, L2CAP_DEFAULT_FLUSH_TO);
2694 }
2695
2696 {
2697 suspend_rsp.chnl = p_scb->chnl;
2698 suspend_rsp.hndl = p_scb->hndl;
2699 suspend_rsp.initiator = p_data->str_msg.initiator;
2700 (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, (tBTA_AV *) &suspend_rsp);
2701 }
2702}
2703
2704/*******************************************************************************
2705**
2706** Function bta_av_rcfg_str_ok
2707**
2708** Description report reconfigure successful
2709**
2710** Returns void
2711**
2712*******************************************************************************/
2713void bta_av_rcfg_str_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2714{
2715 tBTA_AV_RECONFIG evt;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08002716 UNUSED(p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002717
2718 p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002719 APPL_TRACE_DEBUG("bta_av_rcfg_str_ok: l2c_cid: %d", p_scb->l2c_cid);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002720
2721 /* rc listen */
2722 bta_av_st_rc_timer(p_scb, NULL);
2723 utl_freebuf((void **)&p_scb->p_cap);
2724
2725 /* No need to keep the role bits once reconfig is done. */
2726 p_scb->role &= ~BTA_AV_ROLE_AD_ACP;
2727 p_scb->role &= ~BTA_AV_ROLE_SUSPEND_OPT;
2728 p_scb->role &= ~BTA_AV_ROLE_START_INT;
2729
2730 {
2731 /* reconfigure success */
2732 evt.status = BTA_AV_SUCCESS;
2733 evt.chnl = p_scb->chnl;
2734 evt.hndl = p_scb->hndl;
2735 (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV *)&evt);
2736 }
2737}
2738
2739/*******************************************************************************
2740**
2741** Function bta_av_rcfg_failed
2742**
2743** Description process reconfigure failed
2744**
2745** Returns void
2746**
2747*******************************************************************************/
2748void bta_av_rcfg_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2749{
2750 tBTA_AV_RECONFIG evt;
2751
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002752 APPL_TRACE_DEBUG("bta_av_rcfg_failed num_recfg: %d, conn_lcb:0x%x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002753 p_scb->num_recfg, bta_av_cb.conn_lcb);
2754 if(p_scb->num_recfg > BTA_AV_RECONFIG_RETRY)
2755 {
2756 bta_av_cco_close(p_scb, p_data);
2757 /* report failure */
2758 evt.status = BTA_AV_FAIL_STREAM;
2759 evt.chnl = p_scb->chnl;
2760 evt.hndl = p_scb->hndl;
2761 (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV *)&evt);
2762 /* go to closing state */
2763 bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, NULL);
2764 }
2765 else
2766 {
2767 /* open failed. try again */
2768 p_scb->num_recfg++;
2769 if(bta_av_cb.conn_lcb)
2770 {
2771 AVDT_DisconnectReq(p_scb->peer_addr, bta_av_dt_cback[p_scb->hdi]);
2772 }
2773 else
2774 {
2775 bta_av_connect_req(p_scb, NULL);
2776 }
2777 }
2778}
2779
2780/*******************************************************************************
2781**
2782** Function bta_av_rcfg_connect
2783**
2784** Description stream closed. reconnect the stream
2785**
2786** Returns void
2787**
2788*******************************************************************************/
2789void bta_av_rcfg_connect (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2790{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08002791 UNUSED(p_data);
2792
The Android Open Source Project5738f832012-12-12 16:00:35 -08002793 p_scb->cong = FALSE;
2794 p_scb->num_recfg++;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002795 APPL_TRACE_DEBUG("bta_av_rcfg_connect num_recfg: %d", p_scb->num_recfg);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002796 if(p_scb->num_recfg > BTA_AV_RECONFIG_RETRY)
2797 {
2798 /* let bta_av_rcfg_failed report fail */
2799 bta_av_rcfg_failed(p_scb, NULL);
2800 }
2801 else
2802 AVDT_ConnectReq(p_scb->peer_addr, p_scb->sec_mask, bta_av_dt_cback[p_scb->hdi]);
2803}
2804
2805/*******************************************************************************
2806**
2807** Function bta_av_rcfg_discntd
2808**
2809** Description AVDT disconnected. reconnect the stream
2810**
2811** Returns void
2812**
2813*******************************************************************************/
2814void bta_av_rcfg_discntd (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2815{
2816 tBTA_AV_RECONFIG evt;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08002817 UNUSED(p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002818
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002819 APPL_TRACE_DEBUG("bta_av_rcfg_discntd num_recfg: %d", p_scb->num_recfg);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002820 p_scb->num_recfg++;
2821 if(p_scb->num_recfg > BTA_AV_RECONFIG_RETRY)
2822 {
2823 /* report failure */
2824 evt.status = BTA_AV_FAIL_STREAM;
2825 evt.chnl = p_scb->chnl;
2826 evt.hndl = p_scb->hndl;
2827 (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV *)&evt);
2828 /* report close event & go to init state */
2829 bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, NULL);
2830 }
2831 else
2832 AVDT_ConnectReq(p_scb->peer_addr, p_scb->sec_mask, bta_av_dt_cback[p_scb->hdi]);
2833}
2834
2835/*******************************************************************************
2836**
2837** Function bta_av_suspend_cont
2838**
2839** Description received the suspend response.
2840** continue to reconfigure the stream
2841**
2842** Returns void
2843**
2844*******************************************************************************/
2845void bta_av_suspend_cont (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2846{
2847 UINT8 err_code = p_data->str_msg.msg.hdr.err_code;
2848 tBTA_AV_RECONFIG evt;
2849
2850 p_scb->started = FALSE;
2851 p_scb->cong = FALSE;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002852 if (err_code)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002853 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002854 if (AVDT_ERR_CONNECT == err_code)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002855 {
2856 /* report failure */
2857 evt.status = BTA_AV_FAIL;
2858 (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV *)&evt);
2859 bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, NULL);
2860 }
2861 else
2862 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002863 APPL_TRACE_ERROR("suspend rejected, try close");
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002864 /* Disable suspend feature only with explicit rejection(not with timeout) */
2865 if (err_code != AVDT_ERR_TIMEOUT)
2866 {
2867 p_scb->suspend_sup = FALSE;
2868 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002869 /* drop the buffers queued in L2CAP */
2870 L2CA_FlushChannel (p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
2871
2872 AVDT_CloseReq(p_scb->avdt_handle);
2873 }
2874 }
2875 else
2876 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002877 APPL_TRACE_DEBUG("bta_av_suspend_cont calling AVDT_ReconfigReq");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002878 /* reconfig the stream */
2879
2880 AVDT_ReconfigReq(p_scb->avdt_handle, p_scb->p_cap);
2881 p_scb->p_cap->psc_mask = p_scb->cur_psc_mask;
2882 }
2883}
2884
2885/*******************************************************************************
2886**
2887** Function bta_av_rcfg_cfm
2888**
2889** Description if reconfigure is successful, report the event
2890** otherwise, close the stream.
2891**
2892** Returns void
2893**
2894*******************************************************************************/
2895void bta_av_rcfg_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2896{
2897 UINT8 err_code = p_data->str_msg.msg.hdr.err_code;
2898
2899 /*
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002900 APPL_TRACE_DEBUG("bta_av_rcfg_cfm");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002901 */
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002902 if (err_code)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002903 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002904 APPL_TRACE_ERROR("reconfig rejected, try close");
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002905 /* Disable reconfiguration feature only with explicit rejection(not with timeout) */
2906 if (err_code != AVDT_ERR_TIMEOUT)
2907 {
2908 p_scb->recfg_sup = FALSE;
2909 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002910 /* started flag is FALSE when reconfigure command is sent */
2911 /* drop the buffers queued in L2CAP */
2912 L2CA_FlushChannel (p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL);
2913 AVDT_CloseReq(p_scb->avdt_handle);
2914 }
2915 else
2916 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002917 /* update the codec info after rcfg cfm */
2918 memcpy(p_scb->cfg.codec_info,p_data->str_msg.msg.reconfig_cfm.p_cfg->codec_info,AVDT_CODEC_SIZE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002919 /* take the SSM back to OPEN state */
2920 bta_av_ssm_execute(p_scb, BTA_AV_STR_OPEN_OK_EVT, NULL);
2921 }
2922}
2923
2924/*******************************************************************************
2925**
2926** Function bta_av_rcfg_open
2927**
2928** Description AVDT is connected. open the stream with the new configuration
2929**
2930** Returns void
2931**
2932*******************************************************************************/
2933void bta_av_rcfg_open (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2934{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08002935 UNUSED(p_data);
2936
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07002937 APPL_TRACE_DEBUG("bta_av_rcfg_open, num_disc_snks = %d", p_scb->num_disc_snks);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002938
2939 if (p_scb->num_disc_snks == 0)
2940 {
2941 /* Need to update call-out module so that it will be ready for discover */
2942 p_scb->p_cos->stop(p_scb->hndl, p_scb->codec_type);
2943
2944 /* send avdtp discover request */
2945 AVDT_DiscoverReq(p_scb->peer_addr, p_scb->sep_info, BTA_AV_NUM_SEPS, bta_av_dt_cback[p_scb->hdi]);
2946 }
2947 else
2948 {
2949 p_scb->codec_type = p_scb->p_cap->codec_info[BTA_AV_CODEC_TYPE_IDX];
2950 memcpy(p_scb->cfg.codec_info, p_scb->p_cap->codec_info, AVDT_CODEC_SIZE);
2951 /* we may choose to use a different SEP at reconfig.
2952 * adjust the sep_idx now */
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05302953 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 -08002954
2955 /* open the stream with the new config */
2956 p_scb->sep_info_idx = p_scb->rcfg_idx;
2957 AVDT_OpenReq(p_scb->avdt_handle, p_scb->peer_addr,
2958 p_scb->sep_info[p_scb->sep_info_idx].seid, p_scb->p_cap);
2959 }
2960
2961}
2962
2963/*******************************************************************************
2964**
2965** Function bta_av_security_rej
2966**
2967** Description Send an AVDTP security reject.
2968**
2969** Returns void
2970**
2971*******************************************************************************/
2972void bta_av_security_rej (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2973{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08002974 UNUSED(p_data);
2975
The Android Open Source Project5738f832012-12-12 16:00:35 -08002976 AVDT_SecurityRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_BAD_STATE,
2977 NULL, 0);
2978}
2979
2980/*******************************************************************************
2981**
2982** Function bta_av_chk_2nd_start
2983**
2984** Description check if this is 2nd stream and if it needs to be started.
2985** This function needs to be kept very similar to bta_av_chk_start
2986**
2987** Returns void
2988**
2989*******************************************************************************/
2990void bta_av_chk_2nd_start (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
2991{
2992 tBTA_AV_SCB *p_scbi;
2993 int i;
2994 BOOLEAN new_started = FALSE;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08002995 UNUSED(p_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002996
2997 if ((p_scb->chnl == BTA_AV_CHNL_AUDIO) && (bta_av_cb.audio_open_cnt >= 2))
2998 {
2999 /* more than one audio channel is connected */
3000 if (!(p_scb->role & BTA_AV_ROLE_SUSPEND_OPT))
3001 {
3002 /* this channel does not need to be reconfigured.
3003 * if there is other channel streaming, start the stream now */
3004 for(i=0; i<BTA_AV_NUM_STRS; i++)
3005 {
3006 p_scbi = bta_av_cb.p_scb[i];
3007 if(p_scbi && p_scbi->chnl == BTA_AV_CHNL_AUDIO && p_scbi->co_started)
3008 {
3009 if (!new_started)
3010 {
3011 /* start the new stream */
3012 new_started = TRUE;
3013 bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
3014 }
3015 /* may need to update the flush timeout of this already started stream */
3016 if (p_scbi->co_started != bta_av_cb.audio_open_cnt)
3017 {
3018 p_scbi->co_started = bta_av_cb.audio_open_cnt;
3019 L2CA_SetFlushTimeout(p_scbi->peer_addr, p_bta_av_cfg->p_audio_flush_to[p_scbi->co_started - 1] );
3020 }
3021 }
3022 }
3023 }
3024 }
3025}
3026
3027/*******************************************************************************
3028**
3029** Function bta_av_open_rc
3030**
3031** Description Send a message to main SM to open RC channel.
3032**
3033** Returns void
3034**
3035*******************************************************************************/
3036void bta_av_open_rc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
3037{
3038 tBTA_AV_START start;
3039
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003040 APPL_TRACE_DEBUG("bta_av_open_rc use_rc: %d, wait: x%x role:x%x", p_scb->use_rc, p_scb->wait, p_scb->role);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003041 if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) && (p_scb->q_tag == BTA_AV_Q_TAG_START))
3042 {
3043 /* waiting for role switch for some reason & the timer expires */
3044 if (!bta_av_link_role_ok(p_scb, A2D_SET_ONE_BIT))
3045 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07003046 APPL_TRACE_ERROR ("failed to start streaming for role management reasons!!");
The Android Open Source Project5738f832012-12-12 16:00:35 -08003047 bta_sys_stop_timer(&p_scb->timer);
3048 start.chnl = p_scb->chnl;
3049 start.status = BTA_AV_FAIL_ROLE;
3050 start.initiator = TRUE;
3051 start.hndl = p_scb->hndl;
3052 p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
3053 bta_av_cb.rs_idx = 0;
3054 (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV *) &start);
3055 }
3056 else
3057 {
3058 /* role switch is done. continue to start streaming */
3059 bta_av_cb.rs_idx = 0;
3060 p_data->hdr.offset = BTA_AV_RS_OK;
3061 bta_av_start_ok (p_scb, p_data);
3062 }
3063 return;
3064 }
3065
3066 if(p_scb->use_rc == TRUE || (p_scb->role & BTA_AV_ROLE_AD_ACP) )
3067 {
3068 if(bta_av_cb.disc)
3069 {
3070 /* AVRC discover db is in use */
3071 if(p_scb->rc_handle == BTA_AV_RC_HANDLE_NONE)
3072 {
3073 /* AVRC channel is not connected. delay a little bit */
3074 if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) == 0)
3075 bta_sys_start_timer(&p_scb->timer, BTA_AV_AVRC_TIMER_EVT, BTA_AV_RC_DISC_TIME_VAL);
3076 else
3077 p_scb->wait |= BTA_AV_WAIT_CHECK_RC;
3078 }
3079 }
3080 else
3081 {
3082 /* use main SM for AVRC SDP activities */
3083 bta_av_rc_disc((UINT8)(p_scb->hdi + 1));
3084 }
3085 }
3086 else
3087 {
3088 if(BTA_AV_RC_HANDLE_NONE != p_scb->rc_handle)
3089 {
3090 /* the open API said that this handle does not want a RC connection.
3091 * disconnect it now */
3092 AVRC_Close(p_scb->rc_handle);
3093 }
3094 }
3095}
3096
3097/*******************************************************************************
3098**
3099** Function bta_av_open_at_inc
3100**
3101** Description This function is called if API open is called by application
3102** while state-machine is at incoming state.
3103**
3104** Returns void
3105**
3106*******************************************************************************/
3107void bta_av_open_at_inc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
3108{
3109 tBTA_AV_API_OPEN *p_buf;
3110
3111 memcpy (&(p_scb->open_api), &(p_data->api_open), sizeof(tBTA_AV_API_OPEN));
3112
3113 if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR)
3114 {
3115 p_scb->coll_mask |= BTA_AV_COLL_API_CALLED;
3116
3117 /* API open will be handled at timeout if SNK did not start signalling. */
3118 /* API open will be ignored if SNK starts signalling. */
3119 }
3120 else
3121 {
3122 /* SNK did not start signalling, API was called N seconds timeout. */
3123 /* We need to switch to INIT state and start opening connection. */
3124 p_scb->coll_mask = 0;
3125 bta_av_set_scb_sst_init (p_scb);
3126
Pavlin Radoslavov258c2532015-09-27 20:59:05 -07003127 if ((p_buf = (tBTA_AV_API_OPEN *) osi_getbuf(sizeof(tBTA_AV_API_OPEN))) != NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -08003128 {
3129 memcpy(p_buf, &(p_scb->open_api), sizeof(tBTA_AV_API_OPEN));
3130 bta_sys_sendmsg(p_buf);
3131 }
3132 }
3133}
3134
Abhijit Adsule47b43102015-05-19 02:44:26 -05003135/*******************************************************************************
3136**
3137** Function bta_av_offload_req
3138**
3139** Description This function is called if application requests offload of
3140** a2dp audio.
3141**
3142** Returns void
3143**
3144*******************************************************************************/
3145void bta_av_offload_req(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
3146{
3147 tBTA_AV_STATUS status = BTA_AV_FAIL_RESOURCES;
3148 UINT16 mtu = bta_av_chk_mtu(p_scb, p_scb->stream_mtu);
3149
3150 APPL_TRACE_DEBUG("%s stream %s, audio channels open %d", __func__,
3151 p_scb->started ? "STARTED" : "STOPPED", bta_av_cb.audio_open_cnt);
3152
3153 /* Check if stream has already been started. */
3154 /* Support offload if only one audio source stream is open. */
3155 if (p_scb->started != TRUE) {
3156 status = BTA_AV_FAIL_STREAM;
3157
3158 } else if (bta_av_cb.audio_open_cnt == 1 &&
3159 p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC &&
3160 p_scb->chnl == BTA_AV_CHNL_AUDIO) {
3161
3162 bt_vendor_op_a2dp_offload_t a2dp_offload_start;
3163
3164 if (L2CA_GetConnectionConfig(p_scb->l2c_cid, &a2dp_offload_start.acl_data_size,
3165 &a2dp_offload_start.remote_cid, &a2dp_offload_start.lm_handle)) {
3166
3167 APPL_TRACE_DEBUG("%s l2cmtu %d lcid 0x%02X rcid 0x%02X lm_handle 0x%02X", __func__,
3168 a2dp_offload_start.acl_data_size, p_scb->l2c_cid,
3169 a2dp_offload_start.remote_cid, a2dp_offload_start.lm_handle);
3170
3171 a2dp_offload_start.bta_av_handle = p_scb->hndl;
3172 a2dp_offload_start.xmit_quota = BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA;
3173 a2dp_offload_start.stream_mtu = (mtu < p_scb->stream_mtu) ? mtu : p_scb->stream_mtu;
3174 a2dp_offload_start.local_cid = p_scb->l2c_cid;
3175 a2dp_offload_start.is_flushable = TRUE;
3176 a2dp_offload_start.stream_source = ((UINT32)(p_scb->cfg.codec_info[1] | p_scb->cfg.codec_info[2]));
3177
3178 memcpy(a2dp_offload_start.codec_info, p_scb->cfg.codec_info,
3179 sizeof(a2dp_offload_start.codec_info));
3180
3181 if (!vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_START, &a2dp_offload_start)) {
3182 status = BTA_AV_SUCCESS;
3183 p_scb->offload_start_pending = TRUE;
3184 }
3185 }
3186 }
3187
3188 if (status != BTA_AV_SUCCESS)
3189 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
3190}
3191
3192/*******************************************************************************
3193**
3194** Function bta_av_offload_rsp
3195**
3196** Description This function is called when the vendor lib responds to
3197** BT_VND_OP_A2DP_OFFLOAD_START.
3198**
3199** Returns void
3200**
3201*******************************************************************************/
3202void bta_av_offload_rsp(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
3203{
3204 tBTA_AV_STATUS status = p_data->api_status_rsp.status;
3205
3206 APPL_TRACE_DEBUG("%s stream %s status %s", __func__,
3207 p_scb->started ? "STARTED" : "STOPPED",
3208 status ? "FAIL" : "SUCCESS");
3209
3210 /* Check if stream has already been started. */
3211 if (status == BTA_AV_SUCCESS && p_scb->started != TRUE) {
3212 status = BTA_AV_FAIL_STREAM;
3213 }
3214
3215 p_scb->offload_start_pending = FALSE;
3216 (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
3217}
3218
The Android Open Source Project5738f832012-12-12 16:00:35 -08003219#endif /* BTA_AV_INCLUDED */