1 /******************************************************************************
2 *
3 * Copyright (C) 2009-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 *
22 * Filename: btif_av.c
23 *
24 * Description: Bluedroid AV implementation
25 *
26 *****************************************************************************/
27
28 #include <assert.h>
29 #include <string.h>
30
31 #include <hardware/bluetooth.h>
32 #include <system/audio.h>
33 #include "hardware/bt_av.h"
34 #include "osi/include/allocator.h"
35
36 #define LOG_TAG "bt_btif_av"
37
38 #include "btif_av.h"
39 #include "btif_util.h"
40 #include "btif_profile_queue.h"
41 #include "bta_api.h"
42 #include "btif_media.h"
43 #include "bta_av_api.h"
44 #include "gki.h"
45 #include "btu.h"
46 #include "bt_utils.h"
47
48 /*****************************************************************************
49 ** Constants & Macros
50 ******************************************************************************/
51 #define BTIF_AV_SERVICE_NAME "Advanced Audio"
52
53 #define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS 2
54
55 typedef enum {
56 BTIF_AV_STATE_IDLE = 0x0,
57 BTIF_AV_STATE_OPENING,
58 BTIF_AV_STATE_OPENED,
59 BTIF_AV_STATE_STARTED,
60 BTIF_AV_STATE_CLOSING
61 } btif_av_state_t;
62
63 /* Should not need dedicated suspend state as actual actions are no
64 different than open state. Suspend flags are needed however to prevent
65 media task from trying to restart stream during remote suspend or while
66 we are in the process of a local suspend */
67
68 #define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
69 #define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2
70 #define BTIF_AV_FLAG_PENDING_START 0x4
71 #define BTIF_AV_FLAG_PENDING_STOP 0x8
72
73 /*****************************************************************************
74 ** Local type definitions
75 ******************************************************************************/
76
77 typedef struct
78 {
79 tBTA_AV_HNDL bta_handle;
80 bt_bdaddr_t peer_bda;
81 btif_sm_handle_t sm_handle;
82 UINT8 flags;
83 tBTA_AV_EDR edr;
84 UINT8 peer_sep; /* sep type of peer device */
85 } btif_av_cb_t;
86
87 typedef struct
88 {
89 bt_bdaddr_t *target_bda;
90 uint16_t uuid;
91 } btif_av_connect_req_t;
92
93 typedef struct
94 {
95 int sample_rate;
96 int channel_count;
97 } btif_av_sink_config_req_t;
98
99 /*****************************************************************************
100 ** Static variables
101 ******************************************************************************/
102 static btav_callbacks_t *bt_av_src_callbacks = NULL;
103 static btav_callbacks_t *bt_av_sink_callbacks = NULL;
104 static btif_av_cb_t btif_av_cb = {0};
105 static TIMER_LIST_ENT tle_av_open_on_rc;
106
107 /* both interface and media task needs to be ready to alloc incoming request */
108 #define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
109 || (btif_av_cb.sm_handle == NULL))\
110 {\
111 BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
112 return BT_STATUS_NOT_READY;\
113 }\
114 else\
115 {\
116 BTIF_TRACE_EVENT("%s", __FUNCTION__);\
117 }
118
119 /* Helper macro to avoid code duplication in the state machine handlers */
120 #define CHECK_RC_EVENT(e, d) \
121 case BTA_AV_RC_OPEN_EVT: \
122 case BTA_AV_RC_CLOSE_EVT: \
123 case BTA_AV_REMOTE_CMD_EVT: \
124 case BTA_AV_VENDOR_CMD_EVT: \
125 case BTA_AV_META_MSG_EVT: \
126 case BTA_AV_RC_FEAT_EVT: \
127 case BTA_AV_REMOTE_RSP_EVT: \
128 { \
129 btif_rc_handler(e, d);\
130 }break; \
131
132 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
133 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
134 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
135 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
136 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
137
138 static const btif_sm_handler_t btif_av_state_handlers[] =
139 {
140 btif_av_state_idle_handler,
141 btif_av_state_opening_handler,
142 btif_av_state_opened_handler,
143 btif_av_state_started_handler,
144 btif_av_state_closing_handler
145 };
146
147 static void btif_av_event_free_data(btif_sm_event_t event, void *p_data);
148
149 /*************************************************************************
150 ** Extern functions
151 *************************************************************************/
152 extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
153 extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
154 extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
155
156 /*****************************************************************************
157 ** Local helper functions
158 ******************************************************************************/
159
dump_av_sm_state_name(btif_av_state_t state)160 const char *dump_av_sm_state_name(btif_av_state_t state)
161 {
162 switch (state)
163 {
164 CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
165 CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
166 CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
167 CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
168 CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
169 default: return "UNKNOWN_STATE";
170 }
171 }
172
dump_av_sm_event_name(btif_av_sm_event_t event)173 const char *dump_av_sm_event_name(btif_av_sm_event_t event)
174 {
175 switch((int)event)
176 {
177 CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
178 CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
179 CASE_RETURN_STR(BTA_AV_OPEN_EVT)
180 CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
181 CASE_RETURN_STR(BTA_AV_START_EVT)
182 CASE_RETURN_STR(BTA_AV_STOP_EVT)
183 CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
184 CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
185 CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
186 CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
187 CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
188 CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
189 CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
190 CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
191 CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
192 CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
193 CASE_RETURN_STR(BTA_AV_PENDING_EVT)
194 CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
195 CASE_RETURN_STR(BTA_AV_REJECT_EVT)
196 CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
197 CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
198 CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
199 CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
200 CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
201 CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
202 CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
203 CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
204 CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
205 default: return "UNKNOWN_EVENT";
206 }
207 }
208
209 /****************************************************************************
210 ** Local helper functions
211 *****************************************************************************/
212 /*******************************************************************************
213 **
214 ** Function btif_initiate_av_open_tmr_hdlr
215 **
216 ** Description Timer to trigger AV open if the remote headset establishes
217 ** RC connection w/o AV connection. The timer is needed to IOP
218 ** with headsets that do establish AV after RC connection.
219 **
220 ** Returns void
221 **
222 *******************************************************************************/
btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT * tle)223 static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
224 {
225 BD_ADDR peer_addr;
226 UNUSED(tle);
227 btif_av_connect_req_t connect_req;
228 UNUSED(tle);
229 /* is there at least one RC connection - There should be */
230 if (btif_rc_get_connected_peer(peer_addr)) {
231 BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
232 /* In case of AVRCP connection request, we will initiate SRC connection */
233 connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
234 connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
235 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
236 }
237 else
238 {
239 BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
240 }
241 }
242
243 /*****************************************************************************
244 ** Static functions
245 ******************************************************************************/
246
btif_report_connection_state(btav_connection_state_t state,bt_bdaddr_t * bd_addr)247 static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
248 {
249 if (bt_av_sink_callbacks != NULL) {
250 HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
251 } else if (bt_av_src_callbacks != NULL) {
252 HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
253 }
254 }
255
btif_report_audio_state(btav_audio_state_t state,bt_bdaddr_t * bd_addr)256 static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
257 {
258 if (bt_av_sink_callbacks != NULL) {
259 HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
260 } else if (bt_av_src_callbacks != NULL) {
261 HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
262 }
263 }
264
265 /*****************************************************************************
266 **
267 ** Function btif_av_state_idle_handler
268 **
269 ** Description State managing disconnected AV link
270 **
271 ** Returns TRUE if event was processed, FALSE otherwise
272 **
273 *******************************************************************************/
274
btif_av_state_idle_handler(btif_sm_event_t event,void * p_data)275 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
276 {
277 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
278 dump_av_sm_event_name(event), btif_av_cb.flags);
279
280 switch (event)
281 {
282 case BTIF_SM_ENTER_EVT:
283 /* clear the peer_bda */
284 memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
285 btif_av_cb.flags = 0;
286 btif_av_cb.edr = 0;
287 btif_a2dp_on_idle();
288 break;
289
290 case BTIF_SM_EXIT_EVT:
291 break;
292
293 case BTA_AV_ENABLE_EVT:
294 break;
295
296 case BTA_AV_REGISTER_EVT:
297 btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
298 break;
299
300 case BTA_AV_PENDING_EVT:
301 case BTIF_AV_CONNECT_REQ_EVT:
302 {
303 if (event == BTIF_AV_CONNECT_REQ_EVT)
304 {
305 memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
306 sizeof(bt_bdaddr_t));
307 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
308 TRUE, BTA_SEC_AUTHENTICATE, ((btif_av_connect_req_t*)p_data)->uuid);
309 }
310 else if (event == BTA_AV_PENDING_EVT)
311 {
312 bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
313 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
314 TRUE, BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SOURCE);
315 }
316 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
317 } break;
318
319 case BTA_AV_RC_OPEN_EVT:
320 /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
321 * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
322 * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
323 * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
324 * headsets, as some headsets initiate the AVRC connection first and then
325 * immediately initiate the AV connection
326 *
327 * TODO: We may need to do this only on an AVRCP Play. FixMe
328 */
329
330 BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
331 memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
332 tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
333 btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
334 BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS);
335 btif_rc_handler(event, p_data);
336 break;
337
338 case BTA_AV_REMOTE_CMD_EVT:
339 case BTA_AV_VENDOR_CMD_EVT:
340 case BTA_AV_META_MSG_EVT:
341 case BTA_AV_RC_FEAT_EVT:
342 case BTA_AV_REMOTE_RSP_EVT:
343 btif_rc_handler(event, (tBTA_AV*)p_data);
344 break;
345
346 case BTA_AV_RC_CLOSE_EVT:
347 if (tle_av_open_on_rc.in_use) {
348 BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
349 btu_stop_timer(&tle_av_open_on_rc);
350 }
351 btif_rc_handler(event, p_data);
352 break;
353
354 default:
355 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
356 dump_av_sm_event_name(event));
357 return FALSE;
358
359 }
360
361 return TRUE;
362 }
363 /*****************************************************************************
364 **
365 ** Function btif_av_state_opening_handler
366 **
367 ** Description Intermediate state managing events during establishment
368 ** of avdtp channel
369 **
370 ** Returns TRUE if event was processed, FALSE otherwise
371 **
372 *******************************************************************************/
373
btif_av_state_opening_handler(btif_sm_event_t event,void * p_data)374 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
375 {
376 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
377 dump_av_sm_event_name(event), btif_av_cb.flags);
378
379 switch (event)
380 {
381 case BTIF_SM_ENTER_EVT:
382 /* inform the application that we are entering connecting state */
383 btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
384 break;
385
386 case BTIF_SM_EXIT_EVT:
387 break;
388
389 case BTA_AV_REJECT_EVT:
390 BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT ");
391 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
392 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
393 break;
394
395 case BTA_AV_OPEN_EVT:
396 {
397 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
398 btav_connection_state_t state;
399 btif_sm_state_t av_state;
400 BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
401 p_bta_data->open.edr);
402
403 if (p_bta_data->open.status == BTA_AV_SUCCESS)
404 {
405 state = BTAV_CONNECTION_STATE_CONNECTED;
406 av_state = BTIF_AV_STATE_OPENED;
407 btif_av_cb.edr = p_bta_data->open.edr;
408
409 btif_av_cb.peer_sep = p_bta_data->open.sep;
410 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
411 }
412 else
413 {
414 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
415 p_bta_data->open.status );
416 state = BTAV_CONNECTION_STATE_DISCONNECTED;
417 av_state = BTIF_AV_STATE_IDLE;
418 }
419
420 /* inform the application of the event */
421 btif_report_connection_state(state, &(btif_av_cb.peer_bda));
422 /* change state to open/idle based on the status */
423 btif_sm_change_state(btif_av_cb.sm_handle, av_state);
424 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
425 {
426 /* if queued PLAY command, send it now */
427 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
428 (p_bta_data->open.status == BTA_AV_SUCCESS));
429 }
430 else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
431 {
432 /* if queued PLAY command, send it now */
433 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
434 /* Bring up AVRCP connection too */
435 BTA_AvOpenRc(btif_av_cb.bta_handle);
436 }
437 btif_queue_advance();
438 } break;
439
440 case BTIF_AV_SINK_CONFIG_REQ_EVT:
441 {
442 btif_av_sink_config_req_t req;
443 // copy to avoid alignment problems
444 memcpy(&req, p_data, sizeof(req));
445
446 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
447 req.channel_count);
448 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
449 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
450 req.sample_rate, req.channel_count);
451 }
452 } break;
453
454 case BTIF_AV_CONNECT_REQ_EVT:
455 // Check for device, if same device which moved to opening then ignore callback
456 if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
457 sizeof(btif_av_cb.peer_bda)) == 0)
458 {
459 BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Connect Req", __func__);
460 btif_queue_advance();
461 break;
462 }
463 else
464 {
465 BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request", __func__);
466 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t*)p_data);
467 btif_queue_advance();
468 break;
469 }
470
471 case BTA_AV_PENDING_EVT:
472 // Check for device, if same device which moved to opening then ignore callback
473 if (memcmp (((tBTA_AV*)p_data)->pend.bd_addr, &(btif_av_cb.peer_bda),
474 sizeof(btif_av_cb.peer_bda)) == 0)
475 {
476 BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Pending Req", __func__);
477 break;
478 }
479 else
480 {
481 BTIF_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request", __func__);
482 BTA_AvDisconnect(((tBTA_AV*)p_data)->pend.bd_addr);
483 break;
484 }
485
486 CHECK_RC_EVENT(event, p_data);
487
488 default:
489 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
490 dump_av_sm_event_name(event));
491 return FALSE;
492
493 }
494 return TRUE;
495 }
496
497
498 /*****************************************************************************
499 **
500 ** Function btif_av_state_closing_handler
501 **
502 ** Description Intermediate state managing events during closing
503 ** of avdtp channel
504 **
505 ** Returns TRUE if event was processed, FALSE otherwise
506 **
507 *******************************************************************************/
508
btif_av_state_closing_handler(btif_sm_event_t event,void * p_data)509 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
510 {
511 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
512 dump_av_sm_event_name(event), btif_av_cb.flags);
513
514 switch (event)
515 {
516 case BTIF_SM_ENTER_EVT:
517 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
518 {
519 /* immediately stop transmission of frames */
520 btif_a2dp_set_tx_flush(TRUE);
521 /* wait for audioflinger to stop a2dp */
522 }
523 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
524 {
525 btif_a2dp_set_rx_flush(TRUE);
526 }
527 break;
528
529 case BTA_AV_STOP_EVT:
530 case BTIF_AV_STOP_STREAM_REQ_EVT:
531 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
532 {
533 /* immediately flush any pending tx frames while suspend is pending */
534 btif_a2dp_set_tx_flush(TRUE);
535 }
536 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
537 {
538 btif_a2dp_set_rx_flush(TRUE);
539 }
540
541 btif_a2dp_on_stopped(NULL);
542 break;
543
544 case BTIF_SM_EXIT_EVT:
545 break;
546
547 case BTA_AV_CLOSE_EVT:
548
549 /* inform the application that we are disconnecting */
550 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
551
552 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
553 break;
554
555 /* Handle the RC_CLOSE event for the cleanup */
556 case BTA_AV_RC_CLOSE_EVT:
557 btif_rc_handler(event, (tBTA_AV*)p_data);
558 break;
559
560 default:
561 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
562 dump_av_sm_event_name(event));
563 return FALSE;
564 }
565 return TRUE;
566 }
567
568
569 /*****************************************************************************
570 **
571 ** Function btif_av_state_opened_handler
572 **
573 ** Description Handles AV events while AVDTP is in OPEN state
574 **
575 ** Returns TRUE if event was processed, FALSE otherwise
576 **
577 *******************************************************************************/
578
btif_av_state_opened_handler(btif_sm_event_t event,void * p_data)579 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
580 {
581 tBTA_AV *p_av = (tBTA_AV*)p_data;
582
583 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
584 dump_av_sm_event_name(event), btif_av_cb.flags);
585
586 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
587 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
588 {
589 BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
590 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
591 }
592
593 switch (event)
594 {
595 case BTIF_SM_ENTER_EVT:
596 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
597 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
598 break;
599
600 case BTIF_SM_EXIT_EVT:
601 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
602 break;
603
604 case BTIF_AV_START_STREAM_REQ_EVT:
605 if (btif_av_cb.peer_sep != AVDT_TSEP_SRC)
606 btif_a2dp_setup_codec();
607 BTA_AvStart();
608 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
609 break;
610
611 case BTA_AV_START_EVT:
612 {
613 BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
614 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
615
616 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
617 return TRUE;
618
619 /* if remote tries to start a2dp when DUT is a2dp source
620 * then suspend. In case a2dp is sink and call is active
621 * then disconnect the AVDTP channel
622 */
623 if (!(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START))
624 {
625 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
626 {
627 BTIF_TRACE_EVENT("%s: trigger suspend as remote initiated!!", __FUNCTION__);
628 btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
629 }
630 }
631
632 /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/
633 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
634 {
635 if (btif_a2dp_on_started(&p_av->start,
636 ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
637 {
638 /* only clear pending flag after acknowledgement */
639 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
640 }
641 }
642
643 /* remain in open state if status failed */
644 if (p_av->start.status != BTA_AV_SUCCESS)
645 return FALSE;
646
647 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
648 {
649 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
650 }
651
652 /* change state to started, send acknowledgement if start is pending */
653 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
654 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
655 btif_a2dp_on_started(NULL, TRUE);
656 /* pending start flag will be cleared when exit current state */
657 }
658 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
659
660 } break;
661
662 case BTIF_AV_DISCONNECT_REQ_EVT:
663 BTA_AvClose(btif_av_cb.bta_handle);
664 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
665 BTA_AvCloseRc(btif_av_cb.bta_handle);
666 }
667
668 /* inform the application that we are disconnecting */
669 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
670 break;
671
672 case BTA_AV_CLOSE_EVT:
673 /* avdtp link is closed */
674 btif_a2dp_on_stopped(NULL);
675
676 /* inform the application that we are disconnected */
677 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
678
679 /* change state to idle, send acknowledgement if start is pending */
680 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
681 btif_a2dp_ack_fail();
682 /* pending start flag will be cleared when exit current state */
683 }
684 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
685 break;
686
687 case BTA_AV_RECONFIG_EVT:
688 if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
689 (p_av->reconfig.status == BTA_AV_SUCCESS))
690 {
691 APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
692 BTA_AvStart();
693 }
694 else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
695 {
696 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
697 btif_a2dp_ack_fail();
698 }
699 break;
700
701 case BTIF_AV_CONNECT_REQ_EVT:
702 if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
703 sizeof(btif_av_cb.peer_bda)) == 0)
704 {
705 BTIF_TRACE_DEBUG("%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device", __func__);
706 }
707 else
708 {
709 BTIF_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req", __func__);
710 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
711 (bt_bdaddr_t*)p_data);
712 }
713 btif_queue_advance();
714 break;
715
716 CHECK_RC_EVENT(event, p_data);
717
718 default:
719 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
720 dump_av_sm_event_name(event));
721 return FALSE;
722
723 }
724 return TRUE;
725 }
726
727 /*****************************************************************************
728 **
729 ** Function btif_av_state_started_handler
730 **
731 ** Description Handles AV events while A2DP stream is started
732 **
733 ** Returns TRUE if event was processed, FALSE otherwise
734 **
735 *******************************************************************************/
736
btif_av_state_started_handler(btif_sm_event_t event,void * p_data)737 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
738 {
739 tBTA_AV *p_av = (tBTA_AV*)p_data;
740
741 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
742 dump_av_sm_event_name(event), btif_av_cb.flags);
743
744 switch (event)
745 {
746 case BTIF_SM_ENTER_EVT:
747
748 /* we are again in started state, clear any remote suspend flags */
749 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
750
751 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
752
753 /* increase the a2dp consumer task priority temporarily when start
754 ** audio playing, to avoid overflow the audio packet queue. */
755 adjust_priority_a2dp(TRUE);
756
757 break;
758
759 case BTIF_SM_EXIT_EVT:
760 /* restore the a2dp consumer task priority when stop audio playing. */
761 adjust_priority_a2dp(FALSE);
762
763 break;
764
765 case BTIF_AV_START_STREAM_REQ_EVT:
766 /* we were remotely started, just ack back the local request */
767 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
768 btif_a2dp_on_started(NULL, TRUE);
769 break;
770
771 /* fixme -- use suspend = true always to work around issue with BTA AV */
772 case BTIF_AV_STOP_STREAM_REQ_EVT:
773 case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
774
775 /* set pending flag to ensure btif task is not trying to restart
776 stream while suspend is in progress */
777 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
778
779 /* if we were remotely suspended but suspend locally, local suspend
780 always overrides */
781 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
782
783 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
784 {
785 /* immediately stop transmission of frames while suspend is pending */
786 btif_a2dp_set_tx_flush(TRUE);
787 }
788
789 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
790 btif_a2dp_set_rx_flush(TRUE);
791 btif_a2dp_on_stopped(NULL);
792 }
793
794 BTA_AvStop(TRUE);
795 break;
796
797 case BTIF_AV_DISCONNECT_REQ_EVT:
798
799 /* request avdtp to close */
800 BTA_AvClose(btif_av_cb.bta_handle);
801 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
802 BTA_AvCloseRc(btif_av_cb.bta_handle);
803 }
804
805 /* inform the application that we are disconnecting */
806 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
807
808 /* wait in closing state until fully closed */
809 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
810 break;
811
812 case BTA_AV_SUSPEND_EVT:
813
814 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
815 p_av->suspend.status, p_av->suspend.initiator);
816
817 /* a2dp suspended, stop media task until resumed */
818 btif_a2dp_on_suspended(&p_av->suspend);
819
820 /* if not successful, remain in current state */
821 if (p_av->suspend.status != BTA_AV_SUCCESS)
822 {
823 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
824
825 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
826 {
827 /* suspend failed, reset back tx flush state */
828 btif_a2dp_set_tx_flush(FALSE);
829 }
830 return FALSE;
831 }
832
833 if (p_av->suspend.initiator != TRUE)
834 {
835 /* remote suspend, notify HAL and await audioflinger to
836 suspend/stop stream */
837
838 /* set remote suspend flag to block media task from restarting
839 stream only if we did not already initiate a local suspend */
840 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
841 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
842
843 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
844 }
845 else
846 {
847 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
848 }
849
850 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
851
852 /* suspend completed and state changed, clear pending status */
853 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
854 break;
855
856 case BTA_AV_STOP_EVT:
857
858 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
859 btif_a2dp_on_stopped(&p_av->suspend);
860
861 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
862
863 /* if stop was successful, change state to open */
864 if (p_av->suspend.status == BTA_AV_SUCCESS)
865 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
866
867 break;
868
869 case BTA_AV_CLOSE_EVT:
870
871 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
872
873 /* avdtp link is closed */
874 btif_a2dp_on_stopped(NULL);
875
876 /* inform the application that we are disconnected */
877 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
878
879 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
880 break;
881
882 CHECK_RC_EVENT(event, p_data);
883
884 default:
885 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
886 dump_av_sm_event_name(event));
887 return FALSE;
888
889 }
890 return TRUE;
891 }
892
893 /*****************************************************************************
894 ** Local event handlers
895 ******************************************************************************/
896
btif_av_handle_event(UINT16 event,char * p_param)897 static void btif_av_handle_event(UINT16 event, char* p_param)
898 {
899 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
900 btif_av_event_free_data(event, p_param);
901 }
902
btif_av_event_deep_copy(UINT16 event,char * p_dest,char * p_src)903 void btif_av_event_deep_copy(UINT16 event, char *p_dest, char *p_src)
904 {
905 tBTA_AV *av_src = (tBTA_AV *)p_src;
906 tBTA_AV *av_dest = (tBTA_AV *)p_dest;
907
908 // First copy the structure
909 memcpy(p_dest, p_src, sizeof(tBTA_AV));
910
911 switch (event)
912 {
913 case BTA_AV_META_MSG_EVT:
914 if (av_src->meta_msg.p_data && av_src->meta_msg.len)
915 {
916 av_dest->meta_msg.p_data = osi_calloc(av_src->meta_msg.len);
917 assert(av_dest->meta_msg.p_data);
918 memcpy(av_dest->meta_msg.p_data, av_src->meta_msg.p_data, av_src->meta_msg.len);
919 }
920
921 if (av_src->meta_msg.p_msg)
922 {
923 av_dest->meta_msg.p_msg = osi_calloc(sizeof(tAVRC_MSG));
924 assert(av_dest->meta_msg.p_msg);
925 memcpy(av_dest->meta_msg.p_msg, av_src->meta_msg.p_msg, sizeof(tAVRC_MSG));
926
927 if (av_src->meta_msg.p_msg->vendor.p_vendor_data &&
928 av_src->meta_msg.p_msg->vendor.vendor_len)
929 {
930 av_dest->meta_msg.p_msg->vendor.p_vendor_data = osi_calloc(
931 av_src->meta_msg.p_msg->vendor.vendor_len);
932 assert(av_dest->meta_msg.p_msg->vendor.p_vendor_data);
933 memcpy(av_dest->meta_msg.p_msg->vendor.p_vendor_data,
934 av_src->meta_msg.p_msg->vendor.p_vendor_data,
935 av_src->meta_msg.p_msg->vendor.vendor_len);
936 }
937 }
938 break;
939
940 default:
941 break;
942 }
943 }
944
btif_av_event_free_data(btif_sm_event_t event,void * p_data)945 static void btif_av_event_free_data(btif_sm_event_t event, void *p_data)
946 {
947 switch (event)
948 {
949 case BTA_AV_META_MSG_EVT:
950 {
951 tBTA_AV *av = (tBTA_AV*)p_data;
952 if (av->meta_msg.p_data)
953 osi_free(av->meta_msg.p_data);
954
955 if (av->meta_msg.p_msg)
956 {
957 if (av->meta_msg.p_msg->vendor.p_vendor_data)
958 osi_free(av->meta_msg.p_msg->vendor.p_vendor_data);
959 osi_free(av->meta_msg.p_msg);
960 }
961 }
962 break;
963
964 default:
965 break;
966 }
967 }
968
bte_av_callback(tBTA_AV_EVT event,tBTA_AV * p_data)969 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
970 {
971 btif_transfer_context(btif_av_handle_event, event,
972 (char*)p_data, sizeof(tBTA_AV), btif_av_event_deep_copy);
973 }
974
bte_av_media_callback(tBTA_AV_EVT event,tBTA_AV_MEDIA * p_data)975 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
976 {
977 btif_sm_state_t state;
978 UINT8 que_len;
979 tA2D_STATUS a2d_status;
980 tA2D_SBC_CIE sbc_cie;
981 btif_av_sink_config_req_t config_req;
982
983 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
984 {
985 state= btif_sm_get_state(btif_av_cb.sm_handle);
986 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
987 (state == BTIF_AV_STATE_OPENED) )
988 {
989 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
990 BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
991 }
992 else
993 return;
994 }
995
996 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
997 /* send a command to BT Media Task */
998 btif_reset_decoder((UINT8*)p_data);
999
1000 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
1001 if (a2d_status == A2D_SUCCESS) {
1002 /* Switch to BTIF context */
1003 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
1004 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
1005 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
1006 (char*)&config_req, sizeof(config_req), NULL);
1007 } else {
1008 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
1009 }
1010 }
1011 }
1012 /*******************************************************************************
1013 **
1014 ** Function btif_av_init
1015 **
1016 ** Description Initializes btif AV if not already done
1017 **
1018 ** Returns bt_status_t
1019 **
1020 *******************************************************************************/
1021
btif_av_init()1022 bt_status_t btif_av_init()
1023 {
1024 if (btif_av_cb.sm_handle == NULL)
1025 {
1026 if (!btif_a2dp_start_media_task())
1027 return BT_STATUS_FAIL;
1028
1029 /* Also initialize the AV state machine */
1030 btif_av_cb.sm_handle =
1031 btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
1032
1033 btif_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
1034 #if (BTA_AV_SINK_INCLUDED == TRUE)
1035 btif_enable_service(BTA_A2DP_SINK_SERVICE_ID);
1036 #endif
1037
1038 btif_a2dp_on_init();
1039 }
1040
1041 return BT_STATUS_SUCCESS;
1042 }
1043
1044 /*******************************************************************************
1045 **
1046 ** Function init_src
1047 **
1048 ** Description Initializes the AV interface for source mode
1049 **
1050 ** Returns bt_status_t
1051 **
1052 *******************************************************************************/
1053
init_src(btav_callbacks_t * callbacks)1054 static bt_status_t init_src(btav_callbacks_t* callbacks)
1055 {
1056 BTIF_TRACE_EVENT("%s()", __func__);
1057
1058 bt_status_t status = btif_av_init();
1059 if (status == BT_STATUS_SUCCESS)
1060 bt_av_src_callbacks = callbacks;
1061
1062 return status;
1063 }
1064
1065 /*******************************************************************************
1066 **
1067 ** Function init_sink
1068 **
1069 ** Description Initializes the AV interface for sink mode
1070 **
1071 ** Returns bt_status_t
1072 **
1073 *******************************************************************************/
1074
init_sink(btav_callbacks_t * callbacks)1075 static bt_status_t init_sink(btav_callbacks_t* callbacks)
1076 {
1077 BTIF_TRACE_EVENT("%s()", __func__);
1078
1079 bt_status_t status = btif_av_init();
1080 if (status == BT_STATUS_SUCCESS)
1081 bt_av_sink_callbacks = callbacks;
1082
1083 return status;
1084 }
1085
1086 /*******************************************************************************
1087 **
1088 ** Function connect
1089 **
1090 ** Description Establishes the AV signalling channel with the remote headset
1091 **
1092 ** Returns bt_status_t
1093 **
1094 *******************************************************************************/
1095
connect_int(bt_bdaddr_t * bd_addr,uint16_t uuid)1096 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
1097 {
1098 btif_av_connect_req_t connect_req;
1099 connect_req.target_bda = bd_addr;
1100 connect_req.uuid = uuid;
1101 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1102
1103 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
1104
1105 return BT_STATUS_SUCCESS;
1106 }
1107
src_connect_sink(bt_bdaddr_t * bd_addr)1108 static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
1109 {
1110 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1111 CHECK_BTAV_INIT();
1112
1113 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
1114 }
1115
sink_connect_src(bt_bdaddr_t * bd_addr)1116 static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
1117 {
1118 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1119 CHECK_BTAV_INIT();
1120
1121 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1122 }
1123
1124 /*******************************************************************************
1125 **
1126 ** Function disconnect
1127 **
1128 ** Description Tears down the AV signalling channel with the remote headset
1129 **
1130 ** Returns bt_status_t
1131 **
1132 *******************************************************************************/
disconnect(bt_bdaddr_t * bd_addr)1133 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1134 {
1135 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1136
1137 CHECK_BTAV_INIT();
1138
1139 /* Switch to BTIF context */
1140 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1141 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1142 }
1143
1144 /*******************************************************************************
1145 **
1146 ** Function cleanup
1147 **
1148 ** Description Shuts down the AV interface and does the cleanup
1149 **
1150 ** Returns None
1151 **
1152 *******************************************************************************/
cleanup(void)1153 static void cleanup(void)
1154 {
1155 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1156
1157 btif_a2dp_stop_media_task();
1158
1159 btif_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
1160 #if (BTA_AV_SINK_INCLUDED == TRUE)
1161 btif_disable_service(BTA_A2DP_SINK_SERVICE_ID);
1162 #endif
1163
1164 /* Also shut down the AV state machine */
1165 btif_sm_shutdown(btif_av_cb.sm_handle);
1166 btif_av_cb.sm_handle = NULL;
1167 }
1168
cleanup_src(void)1169 static void cleanup_src(void) {
1170 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1171
1172 if (bt_av_src_callbacks)
1173 {
1174 bt_av_src_callbacks = NULL;
1175 if (bt_av_sink_callbacks == NULL)
1176 cleanup();
1177 }
1178 }
1179
cleanup_sink(void)1180 static void cleanup_sink(void) {
1181 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1182
1183 if (bt_av_sink_callbacks)
1184 {
1185 bt_av_sink_callbacks = NULL;
1186 if (bt_av_src_callbacks == NULL)
1187 cleanup();
1188 }
1189 }
1190
1191 static const btav_interface_t bt_av_src_interface = {
1192 sizeof(btav_interface_t),
1193 init_src,
1194 src_connect_sink,
1195 disconnect,
1196 cleanup_src,
1197 };
1198
1199 static const btav_interface_t bt_av_sink_interface = {
1200 sizeof(btav_interface_t),
1201 init_sink,
1202 sink_connect_src,
1203 disconnect,
1204 cleanup_sink,
1205 };
1206
1207 /*******************************************************************************
1208 **
1209 ** Function btif_av_get_sm_handle
1210 **
1211 ** Description Fetches current av SM handle
1212 **
1213 ** Returns None
1214 **
1215 *******************************************************************************/
1216
btif_av_get_sm_handle(void)1217 btif_sm_handle_t btif_av_get_sm_handle(void)
1218 {
1219 return btif_av_cb.sm_handle;
1220 }
1221
1222 /*******************************************************************************
1223 **
1224 ** Function btif_av_stream_ready
1225 **
1226 ** Description Checks whether AV is ready for starting a stream
1227 **
1228 ** Returns None
1229 **
1230 *******************************************************************************/
1231
btif_av_stream_ready(void)1232 BOOLEAN btif_av_stream_ready(void)
1233 {
1234 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1235
1236 BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
1237 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1238
1239 /* also make sure main adapter is enabled */
1240 if (btif_is_enabled() == 0)
1241 {
1242 BTIF_TRACE_EVENT("main adapter not enabled");
1243 return FALSE;
1244 }
1245
1246 /* check if we are remotely suspended or stop is pending */
1247 if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
1248 return FALSE;
1249
1250 return (state == BTIF_AV_STATE_OPENED);
1251 }
1252
1253 /*******************************************************************************
1254 **
1255 ** Function btif_av_stream_started_ready
1256 **
1257 ** Description Checks whether AV ready for media start in streaming state
1258 **
1259 ** Returns None
1260 **
1261 *******************************************************************************/
1262
btif_av_stream_started_ready(void)1263 BOOLEAN btif_av_stream_started_ready(void)
1264 {
1265 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1266
1267 BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
1268 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1269
1270 /* disallow media task to start if we have pending actions */
1271 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1272 | BTIF_AV_FLAG_PENDING_STOP))
1273 return FALSE;
1274
1275 return (state == BTIF_AV_STATE_STARTED);
1276 }
1277
1278 /*******************************************************************************
1279 **
1280 ** Function btif_dispatch_sm_event
1281 **
1282 ** Description Send event to AV statemachine
1283 **
1284 ** Returns None
1285 **
1286 *******************************************************************************/
1287
1288 /* used to pass events to AV statemachine from other tasks */
btif_dispatch_sm_event(btif_av_sm_event_t event,void * p_data,int len)1289 void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1290 {
1291 /* Switch to BTIF context */
1292 btif_transfer_context(btif_av_handle_event, event,
1293 (char*)p_data, len, NULL);
1294 }
1295
1296 /*******************************************************************************
1297 **
1298 ** Function btif_av_execute_service
1299 **
1300 ** Description Initializes/Shuts down the service
1301 **
1302 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1303 **
1304 *******************************************************************************/
btif_av_execute_service(BOOLEAN b_enable)1305 bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1306 {
1307 if (b_enable)
1308 {
1309 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1310 * handle this request in order to allow incoming connections to succeed.
1311 * We need to put this back once support for this is added */
1312
1313 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1314 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1315 * be initiated by the app/audioflinger layers */
1316 #if (AVRC_METADATA_INCLUDED == TRUE)
1317 BTA_AvEnable(BTA_SEC_AUTHENTICATE,
1318 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1319 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1320 |BTA_AV_FEAT_RCCT
1321 |BTA_AV_FEAT_ADV_CTRL
1322 #endif
1323 ,bte_av_callback);
1324 #else
1325 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1326 bte_av_callback);
1327 #endif
1328 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
1329 }
1330 else {
1331 BTA_AvDeregister(btif_av_cb.bta_handle);
1332 BTA_AvDisable();
1333 }
1334 return BT_STATUS_SUCCESS;
1335 }
1336
1337 /*******************************************************************************
1338 **
1339 ** Function btif_av_sink_execute_service
1340 **
1341 ** Description Initializes/Shuts down the service
1342 **
1343 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1344 **
1345 *******************************************************************************/
btif_av_sink_execute_service(BOOLEAN b_enable)1346 bt_status_t btif_av_sink_execute_service(BOOLEAN b_enable)
1347 {
1348 #if (BTA_AV_SINK_INCLUDED == TRUE)
1349 BTA_AvEnable_Sink(b_enable);
1350 #endif
1351 return BT_STATUS_SUCCESS;
1352 }
1353
1354 /*******************************************************************************
1355 **
1356 ** Function btif_av_get_src_interface
1357 **
1358 ** Description Get the AV callback interface for A2DP source profile
1359 **
1360 ** Returns btav_interface_t
1361 **
1362 *******************************************************************************/
btif_av_get_src_interface(void)1363 const btav_interface_t *btif_av_get_src_interface(void)
1364 {
1365 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1366 return &bt_av_src_interface;
1367 }
1368
1369 /*******************************************************************************
1370 **
1371 ** Function btif_av_get_sink_interface
1372 **
1373 ** Description Get the AV callback interface for A2DP sink profile
1374 **
1375 ** Returns btav_interface_t
1376 **
1377 *******************************************************************************/
btif_av_get_sink_interface(void)1378 const btav_interface_t *btif_av_get_sink_interface(void)
1379 {
1380 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1381 return &bt_av_sink_interface;
1382 }
1383
1384 /*******************************************************************************
1385 **
1386 ** Function btif_av_is_connected
1387 **
1388 ** Description Checks if av has a connected sink
1389 **
1390 ** Returns BOOLEAN
1391 **
1392 *******************************************************************************/
btif_av_is_connected(void)1393 BOOLEAN btif_av_is_connected(void)
1394 {
1395 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1396 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
1397 }
1398
1399 /*******************************************************************************
1400 **
1401 ** Function btif_av_is_peer_edr
1402 **
1403 ** Description Check if the connected a2dp device supports
1404 ** EDR or not. Only when connected this function
1405 ** will accurately provide a true capability of
1406 ** remote peer. If not connected it will always be false.
1407 **
1408 ** Returns TRUE if remote device is capable of EDR
1409 **
1410 *******************************************************************************/
btif_av_is_peer_edr(void)1411 BOOLEAN btif_av_is_peer_edr(void)
1412 {
1413 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
1414
1415 if (btif_av_cb.edr)
1416 return TRUE;
1417 else
1418 return FALSE;
1419 }
1420
1421 /******************************************************************************
1422 **
1423 ** Function btif_av_clear_remote_suspend_flag
1424 **
1425 ** Description Clears btif_av_cd.flags if BTIF_AV_FLAG_REMOTE_SUSPEND is set
1426 **
1427 ** Returns void
1428 ******************************************************************************/
btif_av_clear_remote_suspend_flag(void)1429 void btif_av_clear_remote_suspend_flag(void)
1430 {
1431 BTIF_TRACE_DEBUG("%s: flag :%x",__func__, btif_av_cb.flags);
1432 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
1433 }
1434