blob: 439915301a5da72706e1b41a12e608286a10412f [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
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 <hardware/bluetooth.h>
Mike Lockwood3e8a2422014-05-23 12:42:24 -070029#include <system/audio.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080030#include "hardware/bt_av.h"
31
32#define LOG_TAG "BTIF_AV"
33
34#include "btif_av.h"
35#include "btif_util.h"
36#include "btif_profile_queue.h"
37#include "bta_api.h"
38#include "btif_media.h"
39#include "bta_av_api.h"
40#include "gki.h"
41#include "bd.h"
42#include "btu.h"
Zhihai Xu4128e362014-01-08 11:45:17 -080043#include "bt_utils.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080044
45/*****************************************************************************
46** Constants & Macros
47******************************************************************************/
48#define BTIF_AV_SERVICE_NAME "Advanced Audio"
49
50#define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS 2
51
52typedef enum {
53 BTIF_AV_STATE_IDLE = 0x0,
54 BTIF_AV_STATE_OPENING,
55 BTIF_AV_STATE_OPENED,
56 BTIF_AV_STATE_STARTED,
57 BTIF_AV_STATE_CLOSING
58} btif_av_state_t;
59
60/* Should not need dedicated suspend state as actual actions are no
61 different than open state. Suspend flags are needed however to prevent
62 media task from trying to restart stream during remote suspend or while
63 we are in the process of a local suspend */
64
65#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
66#define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2
Mattias Agren5fd74f02013-04-05 19:04:35 +020067#define BTIF_AV_FLAG_PENDING_START 0x4
68#define BTIF_AV_FLAG_PENDING_STOP 0x8
The Android Open Source Project5738f832012-12-12 16:00:35 -080069
70/*****************************************************************************
71** Local type definitions
72******************************************************************************/
73
74typedef struct
75{
76 tBTA_AV_HNDL bta_handle;
77 bt_bdaddr_t peer_bda;
78 btif_sm_handle_t sm_handle;
79 UINT8 flags;
Mattias Agrenb8ceaa42013-04-05 17:27:27 +020080 tBTA_AV_EDR edr;
Mike Lockwood3e8a2422014-05-23 12:42:24 -070081 UINT8 peer_sep; /* sep type of peer device */
The Android Open Source Project5738f832012-12-12 16:00:35 -080082} btif_av_cb_t;
83
Hemant Guptaf7dd9f52013-10-24 15:37:17 +053084typedef struct
85{
86 bt_bdaddr_t *target_bda;
87 uint16_t uuid;
88} btif_av_connect_req_t;
Mike Lockwood3e8a2422014-05-23 12:42:24 -070089
90typedef struct
91{
92 int sample_rate;
93 int channel_count;
94} btif_av_sink_config_req_t;
95
The Android Open Source Project5738f832012-12-12 16:00:35 -080096/*****************************************************************************
97** Static variables
98******************************************************************************/
Mike Lockwood3e8a2422014-05-23 12:42:24 -070099static btav_callbacks_t *bt_av_src_callbacks = NULL;
100static btav_callbacks_t *bt_av_sink_callbacks = NULL;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800101static btif_av_cb_t btif_av_cb;
102static TIMER_LIST_ENT tle_av_open_on_rc;
103
104/* both interface and media task needs to be ready to alloc incoming request */
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700105#define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
106 || (btif_av_cb.sm_handle == NULL))\
The Android Open Source Project5738f832012-12-12 16:00:35 -0800107{\
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700108 BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
The Android Open Source Project5738f832012-12-12 16:00:35 -0800109 return BT_STATUS_NOT_READY;\
110}\
111else\
112{\
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700113 BTIF_TRACE_EVENT("%s", __FUNCTION__);\
The Android Open Source Project5738f832012-12-12 16:00:35 -0800114}
115
116/* Helper macro to avoid code duplication in the state machine handlers */
117#define CHECK_RC_EVENT(e, d) \
118 case BTA_AV_RC_OPEN_EVT: \
119 case BTA_AV_RC_CLOSE_EVT: \
120 case BTA_AV_REMOTE_CMD_EVT: \
121 case BTA_AV_VENDOR_CMD_EVT: \
122 case BTA_AV_META_MSG_EVT: \
123 case BTA_AV_RC_FEAT_EVT: \
124 { \
125 btif_rc_handler(e, d);\
126 }break; \
127
128static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
129static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
130static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
131static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
132static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
133
134static const btif_sm_handler_t btif_av_state_handlers[] =
135{
136 btif_av_state_idle_handler,
137 btif_av_state_opening_handler,
138 btif_av_state_opened_handler,
139 btif_av_state_started_handler,
140 btif_av_state_closing_handler
141};
142
143/*************************************************************************
144** Extern functions
145*************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -0800146extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
147extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
148extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
149
150/*****************************************************************************
151** Local helper functions
152******************************************************************************/
153
154const char *dump_av_sm_state_name(btif_av_state_t state)
155{
156 switch (state)
157 {
158 CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
159 CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
160 CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
161 CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
162 CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
163 default: return "UNKNOWN_STATE";
164 }
165}
166
167const char *dump_av_sm_event_name(btif_av_sm_event_t event)
168{
169 switch((int)event)
170 {
171 CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
172 CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
173 CASE_RETURN_STR(BTA_AV_OPEN_EVT)
174 CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
175 CASE_RETURN_STR(BTA_AV_START_EVT)
176 CASE_RETURN_STR(BTA_AV_STOP_EVT)
177 CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
178 CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
179 CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
180 CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
181 CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
182 CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
183 CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
184 CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
185 CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
186 CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
187 CASE_RETURN_STR(BTA_AV_PENDING_EVT)
188 CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
189 CASE_RETURN_STR(BTA_AV_REJECT_EVT)
190 CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
191 CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
192 CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
193 CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
194 CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
195 CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
196 CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
197 CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700198 CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800199 default: return "UNKNOWN_EVENT";
200 }
201}
202
203/****************************************************************************
204** Local helper functions
205*****************************************************************************/
206/*******************************************************************************
207**
208** Function btif_initiate_av_open_tmr_hdlr
209**
210** Description Timer to trigger AV open if the remote headset establishes
211** RC connection w/o AV connection. The timer is needed to IOP
212** with headsets that do establish AV after RC connection.
213**
214** Returns void
215**
216*******************************************************************************/
217static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
218{
219 BD_ADDR peer_addr;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800220 UNUSED(tle);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530221 btif_av_connect_req_t connect_req;
222 UNUSED(tle);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800223 /* is there at least one RC connection - There should be */
224 if (btif_rc_get_connected_peer(peer_addr)) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700225 BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530226 /* In case of AVRCP connection request, we will initiate SRC connection */
227 connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
228 connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
229 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800230 }
231 else
232 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700233 BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800234 }
235}
236
237/*****************************************************************************
238** Static functions
239******************************************************************************/
240
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700241static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
242{
243 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
244 HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
245 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
246 HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
247 }
248}
249
250static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
251{
252 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
253 HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
254 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
255 HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
256 }
257}
258
The Android Open Source Project5738f832012-12-12 16:00:35 -0800259/*****************************************************************************
260**
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530261** Function btif_av_state_idle_handler
The Android Open Source Project5738f832012-12-12 16:00:35 -0800262**
263** Description State managing disconnected AV link
264**
265** Returns TRUE if event was processed, FALSE otherwise
266**
267*******************************************************************************/
268
269static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
270{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700271 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800272 dump_av_sm_event_name(event), btif_av_cb.flags);
273
274 switch (event)
275 {
276 case BTIF_SM_ENTER_EVT:
277 /* clear the peer_bda */
278 memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
279 btif_av_cb.flags = 0;
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200280 btif_av_cb.edr = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800281 btif_a2dp_on_idle();
282 break;
283
284 case BTIF_SM_EXIT_EVT:
285 break;
286
287 case BTA_AV_ENABLE_EVT:
288 break;
289
290 case BTA_AV_REGISTER_EVT:
291 btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
292 break;
293
294 case BTA_AV_PENDING_EVT:
295 case BTIF_AV_CONNECT_REQ_EVT:
296 {
297 if (event == BTIF_AV_CONNECT_REQ_EVT)
298 {
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530299 memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
300 sizeof(bt_bdaddr_t));
301 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
302 TRUE, BTA_SEC_NONE, ((btif_av_connect_req_t*)p_data)->uuid);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800303 }
304 else if (event == BTA_AV_PENDING_EVT)
305 {
306 bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530307 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
308 TRUE, BTA_SEC_NONE, UUID_SERVCLASS_AUDIO_SOURCE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800309 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800310 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
311 } break;
312
313 case BTA_AV_RC_OPEN_EVT:
314 /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
315 * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
316 * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
317 * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
318 * headsets, as some headsets initiate the AVRC connection first and then
319 * immediately initiate the AV connection
320 *
321 * TODO: We may need to do this only on an AVRCP Play. FixMe
322 */
323
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700324 BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800325 memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
326 tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
327 btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
328 BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS);
329 btif_rc_handler(event, p_data);
330 break;
331
332 case BTA_AV_REMOTE_CMD_EVT:
333 case BTA_AV_VENDOR_CMD_EVT:
334 case BTA_AV_META_MSG_EVT:
335 case BTA_AV_RC_FEAT_EVT:
336 btif_rc_handler(event, (tBTA_AV*)p_data);
337 break;
338
339 case BTA_AV_RC_CLOSE_EVT:
340 if (tle_av_open_on_rc.in_use) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700341 BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800342 btu_stop_timer(&tle_av_open_on_rc);
343 }
344 btif_rc_handler(event, p_data);
345 break;
346
347 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700348 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800349 dump_av_sm_event_name(event));
350 return FALSE;
351
352 }
353 return TRUE;
354}
355/*****************************************************************************
356**
357** Function btif_av_state_opening_handler
358**
359** Description Intermediate state managing events during establishment
360** of avdtp channel
361**
362** Returns TRUE if event was processed, FALSE otherwise
363**
364*******************************************************************************/
365
366static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
367{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700368 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800369 dump_av_sm_event_name(event), btif_av_cb.flags);
370
371 switch (event)
372 {
373 case BTIF_SM_ENTER_EVT:
374 /* inform the application that we are entering connecting state */
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700375 btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800376 break;
377
378 case BTIF_SM_EXIT_EVT:
379 break;
380
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530381 case BTA_AV_REJECT_EVT:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700382 BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT ");
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700383 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530384 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
385 break;
386
The Android Open Source Project5738f832012-12-12 16:00:35 -0800387 case BTA_AV_OPEN_EVT:
388 {
389 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
390 btav_connection_state_t state;
391 btif_sm_state_t av_state;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700392 BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200393 p_bta_data->open.edr);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800394
395 if (p_bta_data->open.status == BTA_AV_SUCCESS)
396 {
397 state = BTAV_CONNECTION_STATE_CONNECTED;
398 av_state = BTIF_AV_STATE_OPENED;
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200399 btif_av_cb.edr = p_bta_data->open.edr;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530400
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700401 btif_av_cb.peer_sep = p_bta_data->open.sep;
402 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800403 }
404 else
405 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700406 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800407 p_bta_data->open.status );
408 state = BTAV_CONNECTION_STATE_DISCONNECTED;
409 av_state = BTIF_AV_STATE_IDLE;
410 }
411
412 /* inform the application of the event */
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700413 btif_report_connection_state(state, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800414 /* change state to open/idle based on the status */
415 btif_sm_change_state(btif_av_cb.sm_handle, av_state);
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700416 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530417 {
418 /* if queued PLAY command, send it now */
419 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800420 (p_bta_data->open.status == BTA_AV_SUCCESS));
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530421 }
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700422 else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530423 {
424 /* if queued PLAY command, send it now */
425 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
Mike Lockwood4ad470e2014-06-02 16:21:49 -0700426 /* Bring up AVRCP connection too */
427 BTA_AvOpenRc(btif_av_cb.bta_handle);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530428 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800429 btif_queue_advance();
430 } break;
431
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700432 case BTIF_AV_SINK_CONFIG_REQ_EVT:
433 {
434 btif_av_sink_config_req_t req;
435 // copy to avoid alignment problems
436 memcpy(&req, p_data, sizeof(req));
437
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700438 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700439 req.channel_count);
440 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
441 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
442 req.sample_rate, req.channel_count);
443 }
444 } break;
445
The Android Open Source Project5738f832012-12-12 16:00:35 -0800446 CHECK_RC_EVENT(event, p_data);
447
448 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700449 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800450 dump_av_sm_event_name(event));
451 return FALSE;
452
453 }
454 return TRUE;
455}
456
457
458/*****************************************************************************
459**
460** Function btif_av_state_closing_handler
461**
462** Description Intermediate state managing events during closing
463** of avdtp channel
464**
465** Returns TRUE if event was processed, FALSE otherwise
466**
467*******************************************************************************/
468
469static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
470{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700471 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800472 dump_av_sm_event_name(event), btif_av_cb.flags);
473
474 switch (event)
475 {
476 case BTIF_SM_ENTER_EVT:
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700477 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530478 {
479 /* immediately stop transmission of frames */
480 btif_a2dp_set_tx_flush(TRUE);
481 /* wait for audioflinger to stop a2dp */
482 }
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700483 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530484 {
485 btif_a2dp_set_rx_flush(TRUE);
486 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800487 break;
488
Mattias Agren5fd74f02013-04-05 19:04:35 +0200489 case BTA_AV_STOP_EVT:
The Android Open Source Project5738f832012-12-12 16:00:35 -0800490 case BTIF_AV_STOP_STREAM_REQ_EVT:
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700491 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530492 {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800493 /* immediately flush any pending tx frames while suspend is pending */
494 btif_a2dp_set_tx_flush(TRUE);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530495 }
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700496 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530497 {
498 btif_a2dp_set_rx_flush(TRUE);
499 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800500
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530501 btif_a2dp_on_stopped(NULL);
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700502 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800503
504 case BTIF_SM_EXIT_EVT:
505 break;
506
507 case BTA_AV_CLOSE_EVT:
508
509 /* inform the application that we are disconnecting */
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700510 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800511
512 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
513 break;
514
515 /* Handle the RC_CLOSE event for the cleanup */
516 case BTA_AV_RC_CLOSE_EVT:
517 btif_rc_handler(event, (tBTA_AV*)p_data);
518 break;
519
520 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700521 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800522 dump_av_sm_event_name(event));
523 return FALSE;
524 }
525 return TRUE;
526}
527
528
529/*****************************************************************************
530**
531** Function btif_av_state_opened_handler
532**
533** Description Handles AV events while AVDTP is in OPEN state
534**
535** Returns TRUE if event was processed, FALSE otherwise
536**
537*******************************************************************************/
538
539static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
540{
541 tBTA_AV *p_av = (tBTA_AV*)p_data;
542
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700543 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800544 dump_av_sm_event_name(event), btif_av_cb.flags);
545
546 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
547 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
548 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700549 BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800550 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
551 }
552
553 switch (event)
554 {
555 case BTIF_SM_ENTER_EVT:
Mattias Agren5fd74f02013-04-05 19:04:35 +0200556 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
557 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
Mattias Agrenb8ceaa42013-04-05 17:27:27 +0200558 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800559
560 case BTIF_SM_EXIT_EVT:
Mattias Agren5fd74f02013-04-05 19:04:35 +0200561 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800562 break;
563
564 case BTIF_AV_START_STREAM_REQ_EVT:
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700565 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530566 {
567 BTA_AvStart();
568 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
569 break;
570 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800571 btif_a2dp_setup_codec();
572 BTA_AvStart();
Mattias Agren5fd74f02013-04-05 19:04:35 +0200573 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800574 break;
575
576 case BTA_AV_START_EVT:
577 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700578 BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800579 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
580
581 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
582 return TRUE;
583
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530584 /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700585 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530586 {
587 if (btif_a2dp_on_started(&p_av->start,
588 ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
589 {
590 /* only clear pending flag after acknowledgement */
591 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
592 }
Zhihai Xu379743b2013-09-29 13:42:13 -0700593 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800594
595 /* remain in open state if status failed */
596 if (p_av->start.status != BTA_AV_SUCCESS)
597 return FALSE;
598
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700599 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530600 {
601 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
602 }
603
Zhihai Xu379743b2013-09-29 13:42:13 -0700604 /* change state to started, send acknowledgement if start is pending */
605 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700606 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530607 btif_a2dp_on_started(NULL, TRUE);
Zhihai Xu379743b2013-09-29 13:42:13 -0700608 /* pending start flag will be cleared when exit current state */
609 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800610 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
611
612 } break;
613
614 case BTIF_AV_DISCONNECT_REQ_EVT:
615 BTA_AvClose(btif_av_cb.bta_handle);
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700616 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
617 BTA_AvCloseRc(btif_av_cb.bta_handle);
618 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800619
620 /* inform the application that we are disconnecting */
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700621 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800622 break;
623
624 case BTA_AV_CLOSE_EVT:
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530625 /* avdtp link is closed */
Mattias Agren5fd74f02013-04-05 19:04:35 +0200626 btif_a2dp_on_stopped(NULL);
627
The Android Open Source Project5738f832012-12-12 16:00:35 -0800628 /* inform the application that we are disconnected */
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700629 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800630
Zhihai Xu379743b2013-09-29 13:42:13 -0700631 /* change state to idle, send acknowledgement if start is pending */
632 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
633 btif_a2dp_ack_fail();
634 /* pending start flag will be cleared when exit current state */
635 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800636 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
637 break;
638
Mattias Agren5fd74f02013-04-05 19:04:35 +0200639 case BTA_AV_RECONFIG_EVT:
640 if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
641 (p_av->reconfig.status == BTA_AV_SUCCESS))
642 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700643 APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
Mattias Agren5fd74f02013-04-05 19:04:35 +0200644 BTA_AvStart();
645 }
646 else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
647 {
648 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
649 btif_a2dp_ack_fail();
650 }
651 break;
652
The Android Open Source Project5738f832012-12-12 16:00:35 -0800653 CHECK_RC_EVENT(event, p_data);
654
655 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700656 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800657 dump_av_sm_event_name(event));
658 return FALSE;
659
660 }
661 return TRUE;
662}
663
664/*****************************************************************************
665**
666** Function btif_av_state_started_handler
667**
668** Description Handles AV events while A2DP stream is started
669**
670** Returns TRUE if event was processed, FALSE otherwise
671**
672*******************************************************************************/
673
674static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
675{
676 tBTA_AV *p_av = (tBTA_AV*)p_data;
677
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700678 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800679 dump_av_sm_event_name(event), btif_av_cb.flags);
680
681 switch (event)
682 {
683 case BTIF_SM_ENTER_EVT:
684
685 /* we are again in started state, clear any remote suspend flags */
686 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
687
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700688 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
Zhihai Xu4128e362014-01-08 11:45:17 -0800689
690 /* increase the a2dp consumer task priority temporarily when start
691 ** audio playing, to avoid overflow the audio packet queue. */
692 adjust_priority_a2dp(TRUE);
693
The Android Open Source Project5738f832012-12-12 16:00:35 -0800694 break;
695
696 case BTIF_SM_EXIT_EVT:
Zhihai Xu4128e362014-01-08 11:45:17 -0800697 /* restore the a2dp consumer task priority when stop audio playing. */
698 adjust_priority_a2dp(FALSE);
699
The Android Open Source Project5738f832012-12-12 16:00:35 -0800700 break;
701
Mattias Agren5fd74f02013-04-05 19:04:35 +0200702 case BTIF_AV_START_STREAM_REQ_EVT:
703 /* we were remotely started, just ack back the local request */
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700704 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530705 btif_a2dp_on_started(NULL, TRUE);
Mattias Agren5fd74f02013-04-05 19:04:35 +0200706 break;
707
The Android Open Source Project5738f832012-12-12 16:00:35 -0800708 /* fixme -- use suspend = true always to work around issue with BTA AV */
709 case BTIF_AV_STOP_STREAM_REQ_EVT:
710 case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
711
712 /* set pending flag to ensure btif task is not trying to restart
713 stream while suspend is in progress */
714 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
715
716 /* if we were remotely suspended but suspend locally, local suspend
717 always overrides */
718 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
719
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700720 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530721 {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800722 /* immediately stop transmission of frames while suspend is pending */
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530723 btif_a2dp_set_tx_flush(TRUE);
724 }
725
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700726 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530727 btif_a2dp_set_rx_flush(TRUE);
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700728 btif_a2dp_on_stopped(NULL);
729 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800730
731 BTA_AvStop(TRUE);
732 break;
733
734 case BTIF_AV_DISCONNECT_REQ_EVT:
735
736 /* request avdtp to close */
737 BTA_AvClose(btif_av_cb.bta_handle);
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700738 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
739 BTA_AvCloseRc(btif_av_cb.bta_handle);
740 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800741
742 /* inform the application that we are disconnecting */
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700743 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800744
745 /* wait in closing state until fully closed */
746 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
747 break;
748
749 case BTA_AV_SUSPEND_EVT:
750
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700751 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800752 p_av->suspend.status, p_av->suspend.initiator);
753
754 /* a2dp suspended, stop media task until resumed */
755 btif_a2dp_on_suspended(&p_av->suspend);
756
757 /* if not successful, remain in current state */
758 if (p_av->suspend.status != BTA_AV_SUCCESS)
759 {
760 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
761
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700762 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530763 {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800764 /* suspend failed, reset back tx flush state */
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530765 btif_a2dp_set_tx_flush(FALSE);
766 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800767 return FALSE;
768 }
769
770 if (p_av->suspend.initiator != TRUE)
771 {
772 /* remote suspend, notify HAL and await audioflinger to
773 suspend/stop stream */
774
775 /* set remote suspend flag to block media task from restarting
776 stream only if we did not already initiate a local suspend */
777 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
778 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
779
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700780 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800781 }
782 else
783 {
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700784 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800785 }
786
787 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
788
789 /* suspend completed and state changed, clear pending status */
790 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
791 break;
792
793 case BTA_AV_STOP_EVT:
794
Mattias Agren5fd74f02013-04-05 19:04:35 +0200795 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800796 btif_a2dp_on_stopped(&p_av->suspend);
797
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700798 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800799
800 /* if stop was successful, change state to open */
801 if (p_av->suspend.status == BTA_AV_SUCCESS)
802 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
803
804 break;
805
806 case BTA_AV_CLOSE_EVT:
807
Mattias Agren5fd74f02013-04-05 19:04:35 +0200808 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
809
The Android Open Source Project5738f832012-12-12 16:00:35 -0800810 /* avdtp link is closed */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800811 btif_a2dp_on_stopped(NULL);
812
813 /* inform the application that we are disconnected */
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700814 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800815
816 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
817 break;
818
819 CHECK_RC_EVENT(event, p_data);
820
821 default:
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700822 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800823 dump_av_sm_event_name(event));
824 return FALSE;
825
826 }
827 return TRUE;
828}
829
830/*****************************************************************************
831** Local event handlers
832******************************************************************************/
833
834static void btif_av_handle_event(UINT16 event, char* p_param)
835{
836 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
837}
838
839static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
840{
841 /* Switch to BTIF context */
842 btif_transfer_context(btif_av_handle_event, event,
843 (char*)p_data, sizeof(tBTA_AV), NULL);
844}
845
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530846static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
847{
848 btif_sm_state_t state;
849 UINT8 que_len;
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700850 tA2D_STATUS a2d_status;
851 tA2D_SBC_CIE sbc_cie;
852 btif_av_sink_config_req_t config_req;
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530853
854 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
855 {
856 state= btif_sm_get_state(btif_av_cb.sm_handle);
857 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
858 (state == BTIF_AV_STATE_OPENED) )
859 {
860 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700861 BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530862 }
863 else
864 return;
865 }
866
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700867 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
868 /* send a command to BT Media Task */
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530869 btif_reset_decoder((UINT8*)p_data);
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700870
871 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
872 if (a2d_status == A2D_SUCCESS) {
873 /* Switch to BTIF context */
874 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
875 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
876 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
877 (char*)&config_req, sizeof(config_req), NULL);
878 } else {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700879 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700880 }
881 }
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530882}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800883/*******************************************************************************
884**
885** Function btif_av_init
886**
887** Description Initializes btif AV if not already done
888**
889** Returns bt_status_t
890**
891*******************************************************************************/
892
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700893bt_status_t btif_av_init()
The Android Open Source Project5738f832012-12-12 16:00:35 -0800894{
895 if (btif_av_cb.sm_handle == NULL)
896 {
897 if (btif_a2dp_start_media_task() != GKI_SUCCESS)
898 return BT_STATUS_FAIL;
899
900 btif_enable_service(BTA_A2DP_SERVICE_ID);
901
The Android Open Source Project5738f832012-12-12 16:00:35 -0800902 /* Also initialize the AV state machine */
903 btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
904
905 btif_a2dp_on_init();
906
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700907 return BT_STATUS_SUCCESS;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800908 }
909
910 return BT_STATUS_DONE;
911}
912
913/*******************************************************************************
914**
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700915** Function init_src
The Android Open Source Project5738f832012-12-12 16:00:35 -0800916**
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700917** Description Initializes the AV interface for source mode
The Android Open Source Project5738f832012-12-12 16:00:35 -0800918**
919** Returns bt_status_t
920**
921*******************************************************************************/
922
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700923static bt_status_t init_src(btav_callbacks_t* callbacks)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800924{
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700925 bt_status_t status;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800926
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700927 BTIF_TRACE_EVENT("%s", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800928
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700929 if (bt_av_sink_callbacks != NULL) {
930 // already did btif_av_init()
931 status = BT_STATUS_SUCCESS;
932 } else {
933 status = btif_av_init();
934 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800935
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700936 if (status == BT_STATUS_SUCCESS) {
937 bt_av_src_callbacks = callbacks;
938 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800939
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700940 return status;
941}
942
943/*******************************************************************************
944**
945** Function init_sink
946**
947** Description Initializes the AV interface for sink mode
948**
949** Returns bt_status_t
950**
951*******************************************************************************/
952
953static bt_status_t init_sink(btav_callbacks_t* callbacks)
954{
955 bt_status_t status;
956
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700957 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Mike Lockwood3e8a2422014-05-23 12:42:24 -0700958
959 if (bt_av_src_callbacks != NULL) {
960 // already did btif_av_init()
961 status = BT_STATUS_SUCCESS;
962 } else {
963 status = btif_av_init();
964 }
965
966 if (status == BT_STATUS_SUCCESS) {
967 bt_av_sink_callbacks = callbacks;
968 BTA_AvEnable_Sink(TRUE);
969 }
970
971 return status;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800972}
973
974/*******************************************************************************
975**
976** Function connect
977**
978** Description Establishes the AV signalling channel with the remote headset
979**
980** Returns bt_status_t
981**
982*******************************************************************************/
983
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530984static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800985{
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530986 btif_av_connect_req_t connect_req;
987 connect_req.target_bda = bd_addr;
988 connect_req.uuid = uuid;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700989 BTIF_TRACE_EVENT("%s", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800990
Hemant Guptaf7dd9f52013-10-24 15:37:17 +0530991 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800992
993 return BT_STATUS_SUCCESS;
994}
995
Matthew Xied6151e92014-06-22 13:32:05 -0700996static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800997{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700998 BTIF_TRACE_EVENT("%s", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800999 CHECK_BTAV_INIT();
1000
1001 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
1002}
1003
Matthew Xied6151e92014-06-22 13:32:05 -07001004static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
1005{
Matthew Xieafa6e1a2014-06-28 11:35:29 -07001006 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Matthew Xied6151e92014-06-22 13:32:05 -07001007 CHECK_BTAV_INIT();
1008
1009 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1010}
1011
The Android Open Source Project5738f832012-12-12 16:00:35 -08001012/*******************************************************************************
1013**
1014** Function disconnect
1015**
1016** Description Tears down the AV signalling channel with the remote headset
1017**
1018** Returns bt_status_t
1019**
1020*******************************************************************************/
1021static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1022{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001023 BTIF_TRACE_EVENT("%s", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001024
1025 CHECK_BTAV_INIT();
1026
1027 /* Switch to BTIF context */
1028 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1029 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1030}
1031
1032/*******************************************************************************
1033**
1034** Function cleanup
1035**
1036** Description Shuts down the AV interface and does the cleanup
1037**
1038** Returns None
1039**
1040*******************************************************************************/
1041static void cleanup(void)
1042{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001043 BTIF_TRACE_EVENT("%s", __FUNCTION__);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001044
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001045 btif_a2dp_stop_media_task();
The Android Open Source Project5738f832012-12-12 16:00:35 -08001046
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001047 btif_disable_service(BTA_A2DP_SERVICE_ID);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001048
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001049 /* Also shut down the AV state machine */
1050 btif_sm_shutdown(btif_av_cb.sm_handle);
1051 btif_av_cb.sm_handle = NULL;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001052}
1053
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001054static void cleanup_src(void) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001055 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001056
1057 if (bt_av_src_callbacks)
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301058 {
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001059 bt_av_src_callbacks = NULL;
1060 if (bt_av_sink_callbacks == NULL)
1061 cleanup();
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301062 }
1063}
1064
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001065static void cleanup_sink(void) {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001066 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001067
1068 if (bt_av_sink_callbacks)
1069 {
1070 bt_av_sink_callbacks = NULL;
1071 if (bt_av_src_callbacks == NULL)
1072 cleanup();
1073 }
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301074}
1075
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001076static const btav_interface_t bt_av_src_interface = {
The Android Open Source Project5738f832012-12-12 16:00:35 -08001077 sizeof(btav_interface_t),
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001078 init_src,
Matthew Xied6151e92014-06-22 13:32:05 -07001079 src_connect_sink,
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001080 disconnect,
1081 cleanup_src,
1082};
1083
1084static const btav_interface_t bt_av_sink_interface = {
1085 sizeof(btav_interface_t),
1086 init_sink,
Matthew Xied6151e92014-06-22 13:32:05 -07001087 sink_connect_src,
The Android Open Source Project5738f832012-12-12 16:00:35 -08001088 disconnect,
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001089 cleanup_sink,
The Android Open Source Project5738f832012-12-12 16:00:35 -08001090};
1091
1092/*******************************************************************************
1093**
1094** Function btif_av_get_sm_handle
1095**
1096** Description Fetches current av SM handle
1097**
1098** Returns None
1099**
1100*******************************************************************************/
1101
1102btif_sm_handle_t btif_av_get_sm_handle(void)
1103{
1104 return btif_av_cb.sm_handle;
1105}
1106
1107/*******************************************************************************
1108**
1109** Function btif_av_stream_ready
1110**
1111** Description Checks whether AV is ready for starting a stream
1112**
1113** Returns None
1114**
1115*******************************************************************************/
1116
1117BOOLEAN btif_av_stream_ready(void)
1118{
1119 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1120
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001121 BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001122 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1123
1124 /* also make sure main adapter is enabled */
1125 if (btif_is_enabled() == 0)
1126 {
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001127 BTIF_TRACE_EVENT("main adapter not enabled");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001128 return FALSE;
1129 }
1130
Mattias Agren5fd74f02013-04-05 19:04:35 +02001131 /* check if we are remotely suspended or stop is pending */
1132 if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
The Android Open Source Project5738f832012-12-12 16:00:35 -08001133 return FALSE;
1134
1135 return (state == BTIF_AV_STATE_OPENED);
1136}
1137
1138/*******************************************************************************
1139**
1140** Function btif_av_stream_started_ready
1141**
1142** Description Checks whether AV ready for media start in streaming state
1143**
1144** Returns None
1145**
1146*******************************************************************************/
1147
1148BOOLEAN btif_av_stream_started_ready(void)
1149{
1150 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1151
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001152 BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001153 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1154
Mattias Agren5fd74f02013-04-05 19:04:35 +02001155 /* disallow media task to start if we have pending actions */
1156 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1157 | BTIF_AV_FLAG_PENDING_STOP))
The Android Open Source Project5738f832012-12-12 16:00:35 -08001158 return FALSE;
1159
1160 return (state == BTIF_AV_STATE_STARTED);
1161}
1162
1163/*******************************************************************************
1164**
1165** Function btif_dispatch_sm_event
1166**
1167** Description Send event to AV statemachine
1168**
1169** Returns None
1170**
1171*******************************************************************************/
1172
1173/* used to pass events to AV statemachine from other tasks */
1174void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1175{
1176 /* Switch to BTIF context */
1177 btif_transfer_context(btif_av_handle_event, event,
1178 (char*)p_data, len, NULL);
1179}
1180
1181/*******************************************************************************
1182**
1183** Function btif_av_execute_service
1184**
1185** Description Initializes/Shuts down the service
1186**
1187** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1188**
1189*******************************************************************************/
1190bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1191{
1192 if (b_enable)
1193 {
1194 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1195 * handle this request in order to allow incoming connections to succeed.
1196 * We need to put this back once support for this is added */
1197
1198 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1199 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1200 * be initiated by the app/audioflinger layers */
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001201#if (AVRC_METADATA_INCLUDED == TRUE)
1202 BTA_AvEnable(BTA_SEC_AUTHENTICATE,
Satya Calloji247c68f2013-08-01 02:14:43 -07001203 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1204#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1205 |BTA_AV_FEAT_RCCT
1206 |BTA_AV_FEAT_ADV_CTRL
1207#endif
1208 ,bte_av_callback);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001209#else
The Android Open Source Project5738f832012-12-12 16:00:35 -08001210 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1211 bte_av_callback);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001212#endif
Hemant Guptaf7dd9f52013-10-24 15:37:17 +05301213 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001214 }
1215 else {
1216 BTA_AvDeregister(btif_av_cb.bta_handle);
1217 BTA_AvDisable();
1218 }
1219 return BT_STATUS_SUCCESS;
1220}
1221
1222/*******************************************************************************
1223**
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001224** Function btif_av_get_src_interface
The Android Open Source Project5738f832012-12-12 16:00:35 -08001225**
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001226** Description Get the AV callback interface for A2DP source profile
The Android Open Source Project5738f832012-12-12 16:00:35 -08001227**
1228** Returns btav_interface_t
1229**
1230*******************************************************************************/
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001231const btav_interface_t *btif_av_get_src_interface(void)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001232{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001233 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001234 return &bt_av_src_interface;
1235}
1236
1237/*******************************************************************************
1238**
1239** Function btif_av_get_sink_interface
1240**
1241** Description Get the AV callback interface for A2DP sink profile
1242**
1243** Returns btav_interface_t
1244**
1245*******************************************************************************/
1246const btav_interface_t *btif_av_get_sink_interface(void)
1247{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -07001248 BTIF_TRACE_EVENT("%s", __FUNCTION__);
Mike Lockwood3e8a2422014-05-23 12:42:24 -07001249 return &bt_av_sink_interface;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001250}
1251
1252/*******************************************************************************
1253**
Mattias Agren5fd74f02013-04-05 19:04:35 +02001254** Function btif_av_is_connected
The Android Open Source Project5738f832012-12-12 16:00:35 -08001255**
Mattias Agren5fd74f02013-04-05 19:04:35 +02001256** Description Checks if av has a connected sink
The Android Open Source Project5738f832012-12-12 16:00:35 -08001257**
Mattias Agren5fd74f02013-04-05 19:04:35 +02001258** Returns BOOLEAN
The Android Open Source Project5738f832012-12-12 16:00:35 -08001259**
1260*******************************************************************************/
1261BOOLEAN btif_av_is_connected(void)
1262{
1263 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1264 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
1265}
Mattias Agrenb8ceaa42013-04-05 17:27:27 +02001266
1267/*******************************************************************************
1268**
1269** Function btif_av_is_peer_edr
1270**
1271** Description Check if the connected a2dp device supports
1272** EDR or not. Only when connected this function
1273** will accurately provide a true capability of
1274** remote peer. If not connected it will always be false.
1275**
1276** Returns TRUE if remote device is capable of EDR
1277**
1278*******************************************************************************/
1279BOOLEAN btif_av_is_peer_edr(void)
1280{
1281 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
1282
1283 if (btif_av_cb.edr)
1284 return TRUE;
1285 else
1286 return FALSE;
1287}
1288