btif_av.c revision 7bc6e981a647ea7c246d2d37b425ee187218eeb3
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/******************************************************************************
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  Copyright (C) 2009-2012 Broadcom Corporation
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  Licensed under the Apache License, Version 2.0 (the "License");
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  you may not use this file except in compliance with the License.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  You may obtain a copy of the License at:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  http://www.apache.org/licenses/LICENSE-2.0
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  Unless required by applicable law or agreed to in writing, software
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  distributed under the License is distributed on an "AS IS" BASIS,
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  See the License for the specific language governing permissions and
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  limitations under the License.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ******************************************************************************/
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*****************************************************************************
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  Filename:      btif_av.c
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  Description:   Bluedroid AV implementation
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *****************************************************************************/
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <hardware/bluetooth.h>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <system/audio.h>
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hardware/bt_av.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_TAG "BTIF_AV"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "btif_av.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "btif_util.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "btif_profile_queue.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "bta_api.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "btif_media.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "bta_av_api.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gki.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "bd.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "btu.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "bt_utils.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*****************************************************************************
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Constants & Macros
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)******************************************************************************/
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BTIF_AV_SERVICE_NAME "Advanced Audio"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS  2
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BTIF_AV_STATE_IDLE = 0x0,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BTIF_AV_STATE_OPENING,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BTIF_AV_STATE_OPENED,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BTIF_AV_STATE_STARTED,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BTIF_AV_STATE_CLOSING
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} btif_av_state_t;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Should not need dedicated suspend state as actual actions are no
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   different than open state. Suspend flags are needed however to prevent
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   media task from trying to restart stream during remote suspend or while
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   we are in the process of a local suspend */
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BTIF_AV_FLAG_REMOTE_SUSPEND        0x2
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BTIF_AV_FLAG_PENDING_START         0x4
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BTIF_AV_FLAG_PENDING_STOP          0x8
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*****************************************************************************
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Local type definitions
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)******************************************************************************/
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tBTA_AV_HNDL bta_handle;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bt_bdaddr_t peer_bda;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    btif_sm_handle_t sm_handle;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UINT8 flags;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tBTA_AV_EDR edr;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UINT8   peer_sep;  /* sep type of peer device */
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} btif_av_cb_t;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bt_bdaddr_t *target_bda;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint16_t uuid;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} btif_av_connect_req_t;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int sample_rate;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int channel_count;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} btif_av_sink_config_req_t;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*****************************************************************************
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Static variables
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)******************************************************************************/
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static btav_callbacks_t *bt_av_src_callbacks = NULL;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static btav_callbacks_t *bt_av_sink_callbacks = NULL;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static btif_av_cb_t btif_av_cb;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static TIMER_LIST_ENT tle_av_open_on_rc;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* both interface and media task needs to be ready to alloc incoming request */
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        || (btif_av_cb.sm_handle == NULL))\
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){\
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return BT_STATUS_NOT_READY;\
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}\
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)else\
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){\
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     BTIF_TRACE_EVENT("%s", __FUNCTION__);\
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Helper macro to avoid code duplication in the state machine handlers */
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_RC_EVENT(e, d) \
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case BTA_AV_RC_OPEN_EVT: \
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case BTA_AV_RC_CLOSE_EVT: \
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case BTA_AV_REMOTE_CMD_EVT: \
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case BTA_AV_VENDOR_CMD_EVT: \
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case BTA_AV_META_MSG_EVT: \
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case BTA_AV_RC_FEAT_EVT: \
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case BTA_AV_REMOTE_RSP_EVT: \
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { \
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         btif_rc_handler(e, d);\
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }break; \
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const btif_sm_handler_t btif_av_state_handlers[] =
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    btif_av_state_idle_handler,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    btif_av_state_opening_handler,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    btif_av_state_opened_handler,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    btif_av_state_started_handler,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    btif_av_state_closing_handler
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*************************************************************************
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Extern functions
146*************************************************************************/
147extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
148extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
149extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
150
151/*****************************************************************************
152** Local helper functions
153******************************************************************************/
154
155const char *dump_av_sm_state_name(btif_av_state_t state)
156{
157    switch (state)
158    {
159        CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
160        CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
161        CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
162        CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
163        CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
164        default: return "UNKNOWN_STATE";
165    }
166}
167
168const char *dump_av_sm_event_name(btif_av_sm_event_t event)
169{
170    switch((int)event)
171    {
172        CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
173        CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
174        CASE_RETURN_STR(BTA_AV_OPEN_EVT)
175        CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
176        CASE_RETURN_STR(BTA_AV_START_EVT)
177        CASE_RETURN_STR(BTA_AV_STOP_EVT)
178        CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
179        CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
180        CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
181        CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
182        CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
183        CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
184        CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
185        CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
186        CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
187        CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
188        CASE_RETURN_STR(BTA_AV_PENDING_EVT)
189        CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
190        CASE_RETURN_STR(BTA_AV_REJECT_EVT)
191        CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
192        CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
193        CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
194        CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
195        CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
196        CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
197        CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
198        CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
199        CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
200        default: return "UNKNOWN_EVENT";
201   }
202}
203
204/****************************************************************************
205**  Local helper functions
206*****************************************************************************/
207/*******************************************************************************
208**
209** Function         btif_initiate_av_open_tmr_hdlr
210**
211** Description      Timer to trigger AV open if the remote headset establishes
212**                  RC connection w/o AV connection. The timer is needed to IOP
213**                  with headsets that do establish AV after RC connection.
214**
215** Returns          void
216**
217*******************************************************************************/
218static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
219{
220    BD_ADDR peer_addr;
221    UNUSED(tle);
222    btif_av_connect_req_t connect_req;
223    UNUSED(tle);
224    /* is there at least one RC connection - There should be */
225    if (btif_rc_get_connected_peer(peer_addr)) {
226       BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
227       /* In case of AVRCP connection request, we will initiate SRC connection */
228       connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
229       connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
230       btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
231    }
232    else
233    {
234        BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
235    }
236}
237
238/*****************************************************************************
239**  Static functions
240******************************************************************************/
241
242static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
243{
244    if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
245        HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
246    } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
247        HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
248    }
249}
250
251static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
252{
253    if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
254        HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
255    } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
256        HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
257    }
258}
259
260/*****************************************************************************
261**
262** Function     btif_av_state_idle_handler
263**
264** Description  State managing disconnected AV link
265**
266** Returns      TRUE if event was processed, FALSE otherwise
267**
268*******************************************************************************/
269
270static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
271{
272    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
273                     dump_av_sm_event_name(event), btif_av_cb.flags);
274
275    switch (event)
276    {
277        case BTIF_SM_ENTER_EVT:
278            /* clear the peer_bda */
279            memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
280            btif_av_cb.flags = 0;
281            btif_av_cb.edr = 0;
282            btif_a2dp_on_idle();
283            break;
284
285        case BTIF_SM_EXIT_EVT:
286            break;
287
288        case BTA_AV_ENABLE_EVT:
289            break;
290
291        case BTA_AV_REGISTER_EVT:
292            btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
293            break;
294
295        case BTA_AV_PENDING_EVT:
296        case BTIF_AV_CONNECT_REQ_EVT:
297        {
298             if (event == BTIF_AV_CONNECT_REQ_EVT)
299             {
300                 memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
301                                                                   sizeof(bt_bdaddr_t));
302                 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
303                    TRUE, BTA_SEC_NONE, ((btif_av_connect_req_t*)p_data)->uuid);
304             }
305             else if (event == BTA_AV_PENDING_EVT)
306             {
307                  bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
308                  BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
309                    TRUE, BTA_SEC_NONE, UUID_SERVCLASS_AUDIO_SOURCE);
310             }
311             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
312        } break;
313
314        case BTA_AV_RC_OPEN_EVT:
315            /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
316             * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
317             * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
318             * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
319             * headsets, as some headsets initiate the AVRC connection first and then
320             * immediately initiate the AV connection
321             *
322             * TODO: We may need to do this only on an AVRCP Play. FixMe
323             */
324
325            BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
326            memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
327            tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
328            btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
329                            BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS);
330            btif_rc_handler(event, p_data);
331            break;
332
333        case BTA_AV_REMOTE_CMD_EVT:
334        case BTA_AV_VENDOR_CMD_EVT:
335        case BTA_AV_META_MSG_EVT:
336        case BTA_AV_RC_FEAT_EVT:
337        case BTA_AV_REMOTE_RSP_EVT:
338            btif_rc_handler(event, (tBTA_AV*)p_data);
339            break;
340
341        case BTA_AV_RC_CLOSE_EVT:
342            if (tle_av_open_on_rc.in_use) {
343                BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
344                btu_stop_timer(&tle_av_open_on_rc);
345            }
346            btif_rc_handler(event, p_data);
347            break;
348
349        default:
350            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
351                                dump_av_sm_event_name(event));
352            return FALSE;
353
354    }
355    return TRUE;
356}
357/*****************************************************************************
358**
359** Function        btif_av_state_opening_handler
360**
361** Description     Intermediate state managing events during establishment
362**                 of avdtp channel
363**
364** Returns         TRUE if event was processed, FALSE otherwise
365**
366*******************************************************************************/
367
368static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
369{
370    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
371                     dump_av_sm_event_name(event), btif_av_cb.flags);
372
373    switch (event)
374    {
375        case BTIF_SM_ENTER_EVT:
376            /* inform the application that we are entering connecting state */
377            btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
378            break;
379
380        case BTIF_SM_EXIT_EVT:
381            break;
382
383        case BTA_AV_REJECT_EVT:
384            BTIF_TRACE_DEBUG(" Received  BTA_AV_REJECT_EVT ");
385            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
386            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
387            break;
388
389        case BTA_AV_OPEN_EVT:
390        {
391            tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
392            btav_connection_state_t state;
393            btif_sm_state_t av_state;
394            BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
395                               p_bta_data->open.edr);
396
397            if (p_bta_data->open.status == BTA_AV_SUCCESS)
398            {
399                 state = BTAV_CONNECTION_STATE_CONNECTED;
400                 av_state = BTIF_AV_STATE_OPENED;
401                 btif_av_cb.edr = p_bta_data->open.edr;
402
403                 btif_av_cb.peer_sep = p_bta_data->open.sep;
404                 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
405            }
406            else
407            {
408                BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
409                                     p_bta_data->open.status );
410                state = BTAV_CONNECTION_STATE_DISCONNECTED;
411                av_state  = BTIF_AV_STATE_IDLE;
412            }
413
414            /* inform the application of the event */
415            btif_report_connection_state(state, &(btif_av_cb.peer_bda));
416            /* change state to open/idle based on the status */
417            btif_sm_change_state(btif_av_cb.sm_handle, av_state);
418            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
419            {
420                /* if queued PLAY command,  send it now */
421                btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
422                                             (p_bta_data->open.status == BTA_AV_SUCCESS));
423            }
424            else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
425            {
426                /* if queued PLAY command,  send it now */
427                btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
428                /* Bring up AVRCP connection too */
429                BTA_AvOpenRc(btif_av_cb.bta_handle);
430            }
431            btif_queue_advance();
432        } break;
433
434        case BTIF_AV_SINK_CONFIG_REQ_EVT:
435        {
436            btif_av_sink_config_req_t req;
437            // copy to avoid alignment problems
438            memcpy(&req, p_data, sizeof(req));
439
440            BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
441                    req.channel_count);
442            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
443                HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
444                        req.sample_rate, req.channel_count);
445            }
446        } break;
447
448        CHECK_RC_EVENT(event, p_data);
449
450        default:
451            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
452                                dump_av_sm_event_name(event));
453            return FALSE;
454
455   }
456   return TRUE;
457}
458
459
460/*****************************************************************************
461**
462** Function        btif_av_state_closing_handler
463**
464** Description     Intermediate state managing events during closing
465**                 of avdtp channel
466**
467** Returns         TRUE if event was processed, FALSE otherwise
468**
469*******************************************************************************/
470
471static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
472{
473    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
474                     dump_av_sm_event_name(event), btif_av_cb.flags);
475
476    switch (event)
477    {
478        case BTIF_SM_ENTER_EVT:
479            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
480            {
481                /* immediately stop transmission of frames */
482                btif_a2dp_set_tx_flush(TRUE);
483                /* wait for audioflinger to stop a2dp */
484            }
485            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
486            {
487                btif_a2dp_set_rx_flush(TRUE);
488            }
489            break;
490
491        case BTA_AV_STOP_EVT:
492        case BTIF_AV_STOP_STREAM_REQ_EVT:
493            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
494            {
495              /* immediately flush any pending tx frames while suspend is pending */
496              btif_a2dp_set_tx_flush(TRUE);
497            }
498            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
499            {
500                btif_a2dp_set_rx_flush(TRUE);
501            }
502
503            btif_a2dp_on_stopped(NULL);
504            break;
505
506        case BTIF_SM_EXIT_EVT:
507            break;
508
509        case BTA_AV_CLOSE_EVT:
510
511            /* inform the application that we are disconnecting */
512            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
513
514            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
515            break;
516
517        /* Handle the RC_CLOSE event for the cleanup */
518        case BTA_AV_RC_CLOSE_EVT:
519            btif_rc_handler(event, (tBTA_AV*)p_data);
520            break;
521
522        default:
523            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
524                                dump_av_sm_event_name(event));
525            return FALSE;
526   }
527   return TRUE;
528}
529
530
531/*****************************************************************************
532**
533** Function     btif_av_state_opened_handler
534**
535** Description  Handles AV events while AVDTP is in OPEN state
536**
537** Returns      TRUE if event was processed, FALSE otherwise
538**
539*******************************************************************************/
540
541static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
542{
543    tBTA_AV *p_av = (tBTA_AV*)p_data;
544
545    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
546                     dump_av_sm_event_name(event), btif_av_cb.flags);
547
548    if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
549         (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
550    {
551        BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
552        btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
553    }
554
555    switch (event)
556    {
557        case BTIF_SM_ENTER_EVT:
558            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
559            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
560            break;
561
562        case BTIF_SM_EXIT_EVT:
563            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
564            break;
565
566        case BTIF_AV_START_STREAM_REQ_EVT:
567            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
568            {
569                BTA_AvStart();
570                btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
571                break;
572            }
573            btif_a2dp_setup_codec();
574            BTA_AvStart();
575            btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
576            break;
577
578        case BTA_AV_START_EVT:
579        {
580            BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
581                p_av->start.status, p_av->start.suspending, p_av->start.initiator);
582
583            if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
584                return TRUE;
585
586            /*  In case peer is A2DP SRC we do not want to ack commands on UIPC*/
587            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
588            {
589                if (btif_a2dp_on_started(&p_av->start,
590                    ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
591                {
592                    /* only clear pending flag after acknowledgement */
593                    btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
594                }
595            }
596
597            /* remain in open state if status failed */
598            if (p_av->start.status != BTA_AV_SUCCESS)
599                return FALSE;
600
601            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
602            {
603                btif_a2dp_set_rx_flush(FALSE); /*  remove flush state, ready for streaming*/
604            }
605
606            /* change state to started, send acknowledgement if start is pending */
607            if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
608                if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
609                    btif_a2dp_on_started(NULL, TRUE);
610                /* pending start flag will be cleared when exit current state */
611            }
612            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
613
614        } break;
615
616        case BTIF_AV_DISCONNECT_REQ_EVT:
617            BTA_AvClose(btif_av_cb.bta_handle);
618            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
619                BTA_AvCloseRc(btif_av_cb.bta_handle);
620            }
621
622            /* inform the application that we are disconnecting */
623            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
624            break;
625
626        case BTA_AV_CLOSE_EVT:
627             /* avdtp link is closed */
628            btif_a2dp_on_stopped(NULL);
629
630            /* inform the application that we are disconnected */
631            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
632
633            /* change state to idle, send acknowledgement if start is pending */
634            if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
635                btif_a2dp_ack_fail();
636                /* pending start flag will be cleared when exit current state */
637            }
638            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
639            break;
640
641        case BTA_AV_RECONFIG_EVT:
642            if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
643                (p_av->reconfig.status == BTA_AV_SUCCESS))
644            {
645               APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
646               BTA_AvStart();
647            }
648            else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
649            {
650               btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
651               btif_a2dp_ack_fail();
652            }
653            break;
654
655        CHECK_RC_EVENT(event, p_data);
656
657        default:
658            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
659                               dump_av_sm_event_name(event));
660            return FALSE;
661
662    }
663    return TRUE;
664}
665
666/*****************************************************************************
667**
668** Function     btif_av_state_started_handler
669**
670** Description  Handles AV events while A2DP stream is started
671**
672** Returns      TRUE if event was processed, FALSE otherwise
673**
674*******************************************************************************/
675
676static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
677{
678    tBTA_AV *p_av = (tBTA_AV*)p_data;
679
680    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
681                     dump_av_sm_event_name(event), btif_av_cb.flags);
682
683    switch (event)
684    {
685        case BTIF_SM_ENTER_EVT:
686
687            /* we are again in started state, clear any remote suspend flags */
688            btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
689
690            btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
691
692            /* increase the a2dp consumer task priority temporarily when start
693            ** audio playing, to avoid overflow the audio packet queue. */
694            adjust_priority_a2dp(TRUE);
695
696            break;
697
698        case BTIF_SM_EXIT_EVT:
699            /* restore the a2dp consumer task priority when stop audio playing. */
700            adjust_priority_a2dp(FALSE);
701
702            break;
703
704        case BTIF_AV_START_STREAM_REQ_EVT:
705            /* we were remotely started, just ack back the local request */
706            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
707                btif_a2dp_on_started(NULL, TRUE);
708            break;
709
710        /* fixme -- use suspend = true always to work around issue with BTA AV */
711        case BTIF_AV_STOP_STREAM_REQ_EVT:
712        case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
713
714            /* set pending flag to ensure btif task is not trying to restart
715               stream while suspend is in progress */
716            btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
717
718            /* if we were remotely suspended but suspend locally, local suspend
719               always overrides */
720            btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
721
722            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
723            {
724            /* immediately stop transmission of frames while suspend is pending */
725                btif_a2dp_set_tx_flush(TRUE);
726            }
727
728            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
729                btif_a2dp_set_rx_flush(TRUE);
730                btif_a2dp_on_stopped(NULL);
731            }
732
733            BTA_AvStop(TRUE);
734            break;
735
736        case BTIF_AV_DISCONNECT_REQ_EVT:
737
738            /* request avdtp to close */
739            BTA_AvClose(btif_av_cb.bta_handle);
740            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
741                BTA_AvCloseRc(btif_av_cb.bta_handle);
742            }
743
744            /* inform the application that we are disconnecting */
745            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
746
747            /* wait in closing state until fully closed */
748            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
749            break;
750
751        case BTA_AV_SUSPEND_EVT:
752
753            BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
754                 p_av->suspend.status, p_av->suspend.initiator);
755
756            /* a2dp suspended, stop media task until resumed */
757            btif_a2dp_on_suspended(&p_av->suspend);
758
759            /* if not successful, remain in current state */
760            if (p_av->suspend.status != BTA_AV_SUCCESS)
761            {
762                btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
763
764               if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
765               {
766                /* suspend failed, reset back tx flush state */
767                    btif_a2dp_set_tx_flush(FALSE);
768               }
769                return FALSE;
770            }
771
772            if (p_av->suspend.initiator != TRUE)
773            {
774                /* remote suspend, notify HAL and await audioflinger to
775                   suspend/stop stream */
776
777                /* set remote suspend flag to block media task from restarting
778                   stream only if we did not already initiate a local suspend */
779                if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
780                    btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
781
782                btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
783            }
784            else
785            {
786                btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
787            }
788
789            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
790
791            /* suspend completed and state changed, clear pending status */
792            btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
793            break;
794
795        case BTA_AV_STOP_EVT:
796
797            btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
798            btif_a2dp_on_stopped(&p_av->suspend);
799
800            btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
801
802            /* if stop was successful, change state to open */
803            if (p_av->suspend.status == BTA_AV_SUCCESS)
804                btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
805
806            break;
807
808        case BTA_AV_CLOSE_EVT:
809
810             btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
811
812            /* avdtp link is closed */
813            btif_a2dp_on_stopped(NULL);
814
815            /* inform the application that we are disconnected */
816            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
817
818            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
819            break;
820
821        CHECK_RC_EVENT(event, p_data);
822
823        default:
824            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
825                                 dump_av_sm_event_name(event));
826            return FALSE;
827
828    }
829    return TRUE;
830}
831
832/*****************************************************************************
833**  Local event handlers
834******************************************************************************/
835
836static void btif_av_handle_event(UINT16 event, char* p_param)
837{
838    btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
839}
840
841static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
842{
843    /* Switch to BTIF context */
844    btif_transfer_context(btif_av_handle_event, event,
845                          (char*)p_data, sizeof(tBTA_AV), NULL);
846}
847
848static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
849{
850    btif_sm_state_t state;
851    UINT8 que_len;
852    tA2D_STATUS a2d_status;
853    tA2D_SBC_CIE sbc_cie;
854    btif_av_sink_config_req_t config_req;
855
856    if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
857    {
858        state= btif_sm_get_state(btif_av_cb.sm_handle);
859        if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
860             (state == BTIF_AV_STATE_OPENED) )
861        {
862            que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
863            BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
864        }
865        else
866            return;
867    }
868
869    if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
870        /* send a command to BT Media Task */
871        btif_reset_decoder((UINT8*)p_data);
872
873        a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
874        if (a2d_status == A2D_SUCCESS) {
875            /* Switch to BTIF context */
876            config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
877            config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
878            btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
879                                     (char*)&config_req, sizeof(config_req), NULL);
880        } else {
881            APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
882        }
883    }
884}
885/*******************************************************************************
886**
887** Function         btif_av_init
888**
889** Description      Initializes btif AV if not already done
890**
891** Returns          bt_status_t
892**
893*******************************************************************************/
894
895bt_status_t btif_av_init()
896{
897    if (btif_av_cb.sm_handle == NULL)
898    {
899        if (btif_a2dp_start_media_task() != GKI_SUCCESS)
900            return BT_STATUS_FAIL;
901
902        btif_enable_service(BTA_A2DP_SERVICE_ID);
903
904        /* Also initialize the AV state machine */
905        btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
906
907        btif_a2dp_on_init();
908
909       return BT_STATUS_SUCCESS;
910    }
911
912    return BT_STATUS_DONE;
913}
914
915/*******************************************************************************
916**
917** Function         init_src
918**
919** Description      Initializes the AV interface for source mode
920**
921** Returns          bt_status_t
922**
923*******************************************************************************/
924
925static bt_status_t init_src(btav_callbacks_t* callbacks)
926{
927    bt_status_t status;
928
929    BTIF_TRACE_EVENT("%s", __FUNCTION__);
930
931    if (bt_av_sink_callbacks != NULL) {
932        // already did btif_av_init()
933        status = BT_STATUS_SUCCESS;
934    } else {
935        status = btif_av_init();
936    }
937
938    if (status == BT_STATUS_SUCCESS) {
939        bt_av_src_callbacks = callbacks;
940    }
941
942    return status;
943}
944
945/*******************************************************************************
946**
947** Function         init_sink
948**
949** Description      Initializes the AV interface for sink mode
950**
951** Returns          bt_status_t
952**
953*******************************************************************************/
954
955static bt_status_t init_sink(btav_callbacks_t* callbacks)
956{
957    bt_status_t status;
958
959    BTIF_TRACE_EVENT("%s", __FUNCTION__);
960
961    if (bt_av_src_callbacks != NULL) {
962        // already did btif_av_init()
963        status = BT_STATUS_SUCCESS;
964    } else {
965        status = btif_av_init();
966    }
967
968    if (status == BT_STATUS_SUCCESS) {
969        bt_av_sink_callbacks = callbacks;
970        BTA_AvEnable_Sink(TRUE);
971    }
972
973    return status;
974}
975
976/*******************************************************************************
977**
978** Function         connect
979**
980** Description      Establishes the AV signalling channel with the remote headset
981**
982** Returns          bt_status_t
983**
984*******************************************************************************/
985
986static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
987{
988    btif_av_connect_req_t connect_req;
989    connect_req.target_bda = bd_addr;
990    connect_req.uuid = uuid;
991    BTIF_TRACE_EVENT("%s", __FUNCTION__);
992
993    btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
994
995    return BT_STATUS_SUCCESS;
996}
997
998static bt_status_t connect_src(bt_bdaddr_t *bd_addr)
999{
1000    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1001    CHECK_BTAV_INIT();
1002
1003    return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
1004}
1005
1006static bt_status_t connect_sink(bt_bdaddr_t *bd_addr)
1007{
1008    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1009    CHECK_BTAV_INIT();
1010
1011    return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1012}
1013
1014/*******************************************************************************
1015**
1016** Function         disconnect
1017**
1018** Description      Tears down the AV signalling channel with the remote headset
1019**
1020** Returns          bt_status_t
1021**
1022*******************************************************************************/
1023static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1024{
1025    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1026
1027    CHECK_BTAV_INIT();
1028
1029    /* Switch to BTIF context */
1030    return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1031                                 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1032}
1033
1034/*******************************************************************************
1035**
1036** Function         cleanup
1037**
1038** Description      Shuts down the AV interface and does the cleanup
1039**
1040** Returns          None
1041**
1042*******************************************************************************/
1043static void cleanup(void)
1044{
1045    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1046
1047    btif_a2dp_stop_media_task();
1048
1049    btif_disable_service(BTA_A2DP_SERVICE_ID);
1050
1051    /* Also shut down the AV state machine */
1052    btif_sm_shutdown(btif_av_cb.sm_handle);
1053    btif_av_cb.sm_handle = NULL;
1054}
1055
1056static void cleanup_src(void) {
1057    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1058
1059    if (bt_av_src_callbacks)
1060    {
1061        bt_av_src_callbacks = NULL;
1062        if (bt_av_sink_callbacks == NULL)
1063            cleanup();
1064    }
1065}
1066
1067static void cleanup_sink(void) {
1068    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1069
1070    if (bt_av_sink_callbacks)
1071    {
1072        bt_av_sink_callbacks = NULL;
1073        if (bt_av_src_callbacks == NULL)
1074            cleanup();
1075    }
1076}
1077
1078static const btav_interface_t bt_av_src_interface = {
1079    sizeof(btav_interface_t),
1080    init_src,
1081    connect_src,
1082    disconnect,
1083    cleanup_src,
1084};
1085
1086static const btav_interface_t bt_av_sink_interface = {
1087    sizeof(btav_interface_t),
1088    init_sink,
1089    connect_sink,
1090    disconnect,
1091    cleanup_sink,
1092};
1093
1094/*******************************************************************************
1095**
1096** Function         btif_av_get_sm_handle
1097**
1098** Description      Fetches current av SM handle
1099**
1100** Returns          None
1101**
1102*******************************************************************************/
1103
1104btif_sm_handle_t btif_av_get_sm_handle(void)
1105{
1106    return btif_av_cb.sm_handle;
1107}
1108
1109/*******************************************************************************
1110**
1111** Function         btif_av_stream_ready
1112**
1113** Description      Checks whether AV is ready for starting a stream
1114**
1115** Returns          None
1116**
1117*******************************************************************************/
1118
1119BOOLEAN btif_av_stream_ready(void)
1120{
1121    btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1122
1123    BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
1124                btif_av_cb.sm_handle, state, btif_av_cb.flags);
1125
1126    /* also make sure main adapter is enabled */
1127    if (btif_is_enabled() == 0)
1128    {
1129        BTIF_TRACE_EVENT("main adapter not enabled");
1130        return FALSE;
1131    }
1132
1133    /* check if we are remotely suspended or stop is pending */
1134    if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
1135        return FALSE;
1136
1137    return (state == BTIF_AV_STATE_OPENED);
1138}
1139
1140/*******************************************************************************
1141**
1142** Function         btif_av_stream_started_ready
1143**
1144** Description      Checks whether AV ready for media start in streaming state
1145**
1146** Returns          None
1147**
1148*******************************************************************************/
1149
1150BOOLEAN btif_av_stream_started_ready(void)
1151{
1152    btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1153
1154    BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
1155                btif_av_cb.sm_handle, state, btif_av_cb.flags);
1156
1157    /* disallow media task to start if we have pending actions */
1158    if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1159        | BTIF_AV_FLAG_PENDING_STOP))
1160        return FALSE;
1161
1162    return (state == BTIF_AV_STATE_STARTED);
1163}
1164
1165/*******************************************************************************
1166**
1167** Function         btif_dispatch_sm_event
1168**
1169** Description      Send event to AV statemachine
1170**
1171** Returns          None
1172**
1173*******************************************************************************/
1174
1175/* used to pass events to AV statemachine from other tasks */
1176void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1177{
1178    /* Switch to BTIF context */
1179    btif_transfer_context(btif_av_handle_event, event,
1180                          (char*)p_data, len, NULL);
1181}
1182
1183/*******************************************************************************
1184**
1185** Function         btif_av_execute_service
1186**
1187** Description      Initializes/Shuts down the service
1188**
1189** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1190**
1191*******************************************************************************/
1192bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1193{
1194     if (b_enable)
1195     {
1196         /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1197          * handle this request in order to allow incoming connections to succeed.
1198          * We need to put this back once support for this is added */
1199
1200         /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1201          * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1202          * be initiated by the app/audioflinger layers */
1203#if (AVRC_METADATA_INCLUDED == TRUE)
1204         BTA_AvEnable(BTA_SEC_AUTHENTICATE,
1205             BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1206#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1207             |BTA_AV_FEAT_RCCT
1208             |BTA_AV_FEAT_ADV_CTRL
1209#endif
1210             ,bte_av_callback);
1211#else
1212         BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1213                      bte_av_callback);
1214#endif
1215         BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
1216     }
1217     else {
1218         BTA_AvDeregister(btif_av_cb.bta_handle);
1219         BTA_AvDisable();
1220     }
1221     return BT_STATUS_SUCCESS;
1222}
1223
1224/*******************************************************************************
1225**
1226** Function         btif_av_get_src_interface
1227**
1228** Description      Get the AV callback interface for A2DP source profile
1229**
1230** Returns          btav_interface_t
1231**
1232*******************************************************************************/
1233const btav_interface_t *btif_av_get_src_interface(void)
1234{
1235    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1236    return &bt_av_src_interface;
1237}
1238
1239/*******************************************************************************
1240**
1241** Function         btif_av_get_sink_interface
1242**
1243** Description      Get the AV callback interface for A2DP sink profile
1244**
1245** Returns          btav_interface_t
1246**
1247*******************************************************************************/
1248const btav_interface_t *btif_av_get_sink_interface(void)
1249{
1250    BTIF_TRACE_EVENT("%s", __FUNCTION__);
1251    return &bt_av_sink_interface;
1252}
1253
1254/*******************************************************************************
1255**
1256** Function         btif_av_is_connected
1257**
1258** Description      Checks if av has a connected sink
1259**
1260** Returns          BOOLEAN
1261**
1262*******************************************************************************/
1263BOOLEAN btif_av_is_connected(void)
1264{
1265    btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1266    return ((state == BTIF_AV_STATE_OPENED) || (state ==  BTIF_AV_STATE_STARTED));
1267}
1268
1269/*******************************************************************************
1270**
1271** Function         btif_av_is_peer_edr
1272**
1273** Description      Check if the connected a2dp device supports
1274**                  EDR or not. Only when connected this function
1275**                  will accurately provide a true capability of
1276**                  remote peer. If not connected it will always be false.
1277**
1278** Returns          TRUE if remote device is capable of EDR
1279**
1280*******************************************************************************/
1281BOOLEAN btif_av_is_peer_edr(void)
1282{
1283    ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
1284
1285    if (btif_av_cb.edr)
1286        return TRUE;
1287    else
1288        return FALSE;
1289}
1290
1291