}
else if(chnl != BTA_AV_CHNL_AUDIO)
{
- APPL_TRACE_ERROR("bad channel: %d", chnl);
+ APPL_TRACE_ERROR("bad channel: %d\n", chnl);
sts = BTA_AV_FAIL;
}
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
else if (AVDT_CONNECT_IND_EVT == event)
{
- APPL_TRACE_DEBUG("CONN_IND is ACP:%d", p_data->hdr.err_param);
+ APPL_TRACE_DEBUG("CONN_IND is ACP:%d\n", p_data->hdr.err_param);
}
#endif
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
if(p_scb)
{
- APPL_TRACE_DEBUG("scb hndl x%x, role x%x", p_scb->hndl, p_scb->role);
+ APPL_TRACE_DEBUG("scb hndl x%x, role x%x\n", p_scb->hndl, p_scb->role);
}
#endif
- APPL_TRACE_DEBUG("conn_cback bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
+ APPL_TRACE_DEBUG("conn_cback bd_addr:%02x-%02x-%02x-%02x-%02x-%02x\n",
bd_addr[0], bd_addr[1],
bd_addr[2], bd_addr[3],
bd_addr[4], bd_addr[5]);
{
UINT16 activate_sink = 0;
activate_sink = p_data->hdr.layer_specific;
- APPL_TRACE_DEBUG("bta_av_api_sink_enable %d ", activate_sink)
+ APPL_TRACE_DEBUG("bta_av_api_sink_enable %d \n", activate_sink)
char p_service_name[BTA_SERVICE_NAME_LEN+1];
BCM_STRNCPY_S(p_service_name, sizeof(p_service_name),
BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
(UINT8)(bta_av_cb.sec_mask & (~BTA_SEC_AUTHORIZE)), BTA_ID_AV);
#endif
- bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL,
+ bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target\n", NULL,
p_bta_av_cfg->avrc_tg_cat, BTA_ID_AV);
#endif
}
*/
cs.nsc_mask = AVDT_NSC_RECONFIG |
((bta_av_cb.features & BTA_AV_FEAT_PROTECT) ? 0 : AVDT_NSC_SECURITY);
- APPL_TRACE_DEBUG("nsc_mask: 0x%x", cs.nsc_mask);
+ APPL_TRACE_DEBUG("nsc_mask: 0x%x\n", cs.nsc_mask);
if (p_data->api_reg.p_service_name[0] == 0)
{
cs.tsep = AVDT_TSEP_SNK;
cs.p_data_cback = bta_av_stream_data_cback;
}
- APPL_TRACE_DEBUG(" SEP Type = %d",cs.tsep);
+ APPL_TRACE_DEBUG(" SEP Type = %d\n",cs.tsep);
#endif
if(AVDT_CreateStream(&p_scb->seps[index].av_handle, &cs) == AVDT_SUCCESS)
{
p_scb->seps[index].p_app_data_cback = NULL; /* In case of A2DP SOURCE we don't need a callback to handle media packets */
#endif
- APPL_TRACE_DEBUG("audio[%d] av_handle: %d codec_type: %d",
+ APPL_TRACE_DEBUG("audio[%d] av_handle: %d codec_type: %d\n",
index, p_scb->seps[index].av_handle, p_scb->seps[index].codec_type);
index++;
}
}
}
bta_av_cb.reg_audio |= BTA_AV_HNDL_TO_MSK(p_scb->hdi);
- APPL_TRACE_DEBUG("reg_audio: 0x%x",bta_av_cb.reg_audio);
+ APPL_TRACE_DEBUG("reg_audio: 0x%x\n",bta_av_cb.reg_audio);
}
else
{
int i;
UINT8 mask;
- APPL_TRACE_DEBUG("reg_audio: 0x%x",bta_av_cb.reg_audio);
+ APPL_TRACE_DEBUG("reg_audio: 0x%x\n",bta_av_cb.reg_audio);
for(i=0; i<BTA_AV_NUM_STRS; i++)
{
mask = BTA_AV_HNDL_TO_MSK(i);
UINT8 peer_idx = 0;
UNUSED(status);
- APPL_TRACE_DEBUG("bta_av_sys_rs_cback: %d", bta_av_cb.rs_idx);
+ APPL_TRACE_DEBUG("bta_av_sys_rs_cback: %d\n", bta_av_cb.rs_idx);
for(i=0; i<BTA_AV_NUM_STRS; i++)
{
/* loop through all the SCBs to find matching peer addresses and report the role change event */
if (p_scb && (bdcmp (peer_addr, p_scb->peer_addr) == 0) &&
(p_buf = (tBTA_AV_ROLE_RES *) GKI_getbuf(sizeof(tBTA_AV_ROLE_RES))) != NULL)
{
- APPL_TRACE_DEBUG("new_role:%d, hci_status:x%x hndl: x%x", id, app_id, p_scb->hndl);
+ APPL_TRACE_DEBUG("new_role:%d, hci_status:x%x hndl: x%x\n", id, app_id, p_scb->hndl);
/*
if ((id != BTM_ROLE_MASTER) && (app_id != HCI_SUCCESS))
{
}
if (p_scb && p_scb->q_tag == BTA_AV_Q_TAG_OPEN)
{
- APPL_TRACE_DEBUG ("bta_av_sys_rs_cback: rs_idx(%d), hndl:x%x q_tag: %d",
+ APPL_TRACE_DEBUG ("bta_av_sys_rs_cback: rs_idx(%d), hndl:x%x q_tag: %d\n",
bta_av_cb.rs_idx, p_scb->hndl, p_scb->q_tag);
if(HCI_SUCCESS == app_id || HCI_ERR_NO_CONNECTION == app_id)
UNUSED(app_id);
UNUSED(peer_addr);
- APPL_TRACE_DEBUG("bta_av_sco_chg_cback:%d status:%d", id, status);
+ APPL_TRACE_DEBUG("bta_av_sco_chg_cback:%d status:%d\n", id, status);
if(id)
{
bta_av_cb.sco_occupied = TRUE;
if( p_scb && p_scb->co_started && (p_scb->sco_suspend == FALSE))
{
- APPL_TRACE_DEBUG("suspending scb:%d", i);
+ APPL_TRACE_DEBUG("suspending scb:%d\n", i);
/* scb is used and started, not suspended automatically */
p_scb->sco_suspend = TRUE;
stop.flush = FALSE;
if( p_scb && p_scb->sco_suspend ) /* scb is used and suspended for SCO */
{
- APPL_TRACE_DEBUG("starting scb:%d", i);
+ APPL_TRACE_DEBUG("starting scb:%d\n", i);
bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
}
}
if (BTM_GetRole(p_scb->peer_addr, &role) == BTM_SUCCESS)
{
- LOG_INFO("%s hndl:x%x role:%d conn_audio:x%x bits:%d features:x%x",
+ LOG_INFO("%s hndl:x%x role:%d conn_audio:x%x bits:%d features:x%x\n",
__func__, p_scb->hndl, role, bta_av_cb.conn_audio, bits,
bta_av_cb.features);
if (BTM_ROLE_MASTER != role && (A2D_BitsSet(bta_av_cb.conn_audio) > bits || (bta_av_cb.features & BTA_AV_FEAT_MASTER)))
if((p_scb != p_scbi) && p_scbi && (p_scbi->chnl == BTA_AV_CHNL_AUDIO) )
{
mask = BTA_AV_HNDL_TO_MSK(i);
- APPL_TRACE_DEBUG("[%d] mtu: %d, mask:0x%x",
+ APPL_TRACE_DEBUG("[%d] mtu: %d, mask:0x%x\n",
i, p_scbi->stream_mtu, mask);
if(bta_av_cb.conn_audio & mask)
{
}
}
}
- APPL_TRACE_DEBUG("bta_av_chk_mtu audio count:%d, conn_audio:0x%x, ret:%d",
+ APPL_TRACE_DEBUG("bta_av_chk_mtu audio count:%d, conn_audio:0x%x, ret:%d\n",
bta_av_cb.audio_open_cnt, bta_av_cb.conn_audio, ret_mtu);
}
return ret_mtu;
UINT8 action;
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
- APPL_TRACE_EVENT("AV event=0x%x(%s) state=%d(%s)",
+ APPL_TRACE_EVENT("AV event=0x%x(%s) state=%d(%s)\n",
event, bta_av_evt_code(event), p_cb->state, bta_av_st_code(p_cb->state));
#else
- APPL_TRACE_EVENT("AV event=0x%x state=%d", event, p_cb->state);
+ APPL_TRACE_EVENT("AV event=0x%x state=%d\n", event, p_cb->state);
#endif
/* look up the state table for the current state */
/* set next state */
p_cb->state = state_table[event][BTA_AV_NEXT_STATE];
- APPL_TRACE_EVENT("next state=%d", p_cb->state);
+ APPL_TRACE_EVENT("next state=%d\n", p_cb->state);
/* execute action functions */
if ((action = state_table[event][BTA_AV_ACTION_COL]) != BTA_AV_IGNORE)
if(event >= first_event)
{
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
- APPL_TRACE_VERBOSE("AV nsm event=0x%x(%s)", event, bta_av_evt_code(event));
+ APPL_TRACE_VERBOSE("AV nsm event=0x%x(%s)\n", event, bta_av_evt_code(event));
#else
- APPL_TRACE_VERBOSE("AV nsm event=0x%x", event);
+ APPL_TRACE_VERBOSE("AV nsm event=0x%x\n", event);
#endif
/* non state machine events */
(*bta_av_nsm_act[event - BTA_AV_FIRST_NSM_EVT]) ((tBTA_AV_DATA *) p_msg);
else if (event >= BTA_AV_FIRST_SM_EVT && event <= BTA_AV_LAST_SM_EVT)
{
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
- APPL_TRACE_VERBOSE("AV sm event=0x%x(%s)", event, bta_av_evt_code(event));
+ APPL_TRACE_VERBOSE("AV sm event=0x%x(%s)\n", event, bta_av_evt_code(event));
#else
- APPL_TRACE_VERBOSE("AV sm event=0x%x", event);
+ APPL_TRACE_VERBOSE("AV sm event=0x%x\n", event);
#endif
/* state machine events */
bta_av_sm_execute(&bta_av_cb, p_msg->event, (tBTA_AV_DATA *) p_msg);
}
else
{
- APPL_TRACE_VERBOSE("handle=0x%x", p_msg->layer_specific);
+ APPL_TRACE_VERBOSE("handle=0x%x\n", p_msg->layer_specific);
/* stream state machine events */
bta_av_ssm_execute( bta_av_hndl_to_scb(p_msg->layer_specific),
p_msg->event, (tBTA_AV_DATA *) p_msg);
#define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
|| (btif_av_cb.sm_handle == NULL))\
{\
- BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
+ BTIF_TRACE_WARNING("%s: BTAV not initialized\n", __FUNCTION__);\
return BT_STATUS_NOT_READY;\
}\
else\
{\
- BTIF_TRACE_EVENT("%s", __FUNCTION__);\
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);\
}
/* Helper macro to avoid code duplication in the state machine handlers */
UNUSED(tle);
/* is there at least one RC connection - There should be */
if (btif_rc_get_connected_peer(peer_addr)) {
- BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
+ BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer\n", __FUNCTION__);
/* In case of AVRCP connection request, we will initiate SRC connection */
connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
}
else
{
- BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
+ BTIF_TRACE_ERROR("%s No connected RC peers\n", __FUNCTION__);
}
}
static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
{
- BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
dump_av_sm_event_name(event), btif_av_cb.flags);
switch (event)
* TODO: We may need to do this only on an AVRCP Play. FixMe
*/
- BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
+ BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV\n");
memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
case BTA_AV_RC_CLOSE_EVT:
if (tle_av_open_on_rc.in_use) {
- BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
+ BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.\n");
btu_stop_timer(&tle_av_open_on_rc);
}
btif_rc_handler(event, p_data);
break;
default:
- BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
dump_av_sm_event_name(event));
return FALSE;
static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
{
- BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
dump_av_sm_event_name(event), btif_av_cb.flags);
switch (event)
break;
case BTA_AV_REJECT_EVT:
- BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT ");
+ BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT \n");
btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
break;
tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
btav_connection_state_t state;
btif_sm_state_t av_state;
- BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
+ BTIF_TRACE_DEBUG("status:%d, edr 0x%x\n",p_bta_data->open.status,
p_bta_data->open.edr);
if (p_bta_data->open.status == BTA_AV_SUCCESS)
}
else
{
- BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
+ BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d\n",
p_bta_data->open.status );
state = BTAV_CONNECTION_STATE_DISCONNECTED;
av_state = BTIF_AV_STATE_IDLE;
// copy to avoid alignment problems
memcpy(&req, p_data, sizeof(req));
- BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
+ BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d\n", req.sample_rate,
req.channel_count);
if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
sizeof(btif_av_cb.peer_bda)) == 0)
{
- BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Connect Req", __func__);
+ BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Connect Req\n", __func__);
btif_queue_advance();
break;
}
else
{
- BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request", __func__);
+ BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request\n", __func__);
btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t*)p_data);
btif_queue_advance();
break;
if (memcmp (((tBTA_AV*)p_data)->pend.bd_addr, &(btif_av_cb.peer_bda),
sizeof(btif_av_cb.peer_bda)) == 0)
{
- BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Pending Req", __func__);
+ BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Pending Req\n", __func__);
break;
}
else
{
- BTIF_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request", __func__);
+ BTIF_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request\n", __func__);
BTA_AvDisconnect(((tBTA_AV*)p_data)->pend.bd_addr);
break;
}
CHECK_RC_EVENT(event, p_data);
default:
- BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
dump_av_sm_event_name(event));
return FALSE;
static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
{
- BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
dump_av_sm_event_name(event), btif_av_cb.flags);
switch (event)
break;
default:
- BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
dump_av_sm_event_name(event));
return FALSE;
}
{
tBTA_AV *p_av = (tBTA_AV*)p_data;
- BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
dump_av_sm_event_name(event), btif_av_cb.flags);
if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
(p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
{
- BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY\n", __FUNCTION__);
btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
}
case BTA_AV_START_EVT:
{
- BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
+ BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d\n",
p_av->start.status, p_av->start.suspending, p_av->start.initiator);
if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
{
if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
{
- BTIF_TRACE_EVENT("%s: trigger suspend as remote initiated!!", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s: trigger suspend as remote initiated!!\n", __FUNCTION__);
btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
}
}
if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
(p_av->reconfig.status == BTA_AV_SUCCESS))
{
- APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
+ APPL_TRACE_WARNING("reconfig done BTA_AVstart()\n");
BTA_AvStart();
}
else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
sizeof(btif_av_cb.peer_bda)) == 0)
{
- BTIF_TRACE_DEBUG("%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device", __func__);
+ BTIF_TRACE_DEBUG("%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device\n", __func__);
}
else
{
- BTIF_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req", __func__);
+ BTIF_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req\n", __func__);
btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
(bt_bdaddr_t*)p_data);
}
CHECK_RC_EVENT(event, p_data);
default:
- BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
dump_av_sm_event_name(event));
return FALSE;
{
tBTA_AV *p_av = (tBTA_AV*)p_data;
- BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
dump_av_sm_event_name(event), btif_av_cb.flags);
switch (event)
case BTA_AV_SUSPEND_EVT:
- BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
+ BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d\n",
p_av->suspend.status, p_av->suspend.initiator);
/* a2dp suspended, stop media task until resumed */
CHECK_RC_EVENT(event, p_data);
default:
- BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
dump_av_sm_event_name(event));
return FALSE;
(state == BTIF_AV_STATE_OPENED) )
{
que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
- BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
+ BTIF_TRACE_DEBUG(" Packets in Que %d\n",que_len);
}
else
return;
btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
(char*)&config_req, sizeof(config_req), NULL);
} else {
- APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
+ APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
}
}
}
static bt_status_t init_src(btav_callbacks_t* callbacks)
{
- BTIF_TRACE_EVENT("%s()", __func__);
+ BTIF_TRACE_EVENT("%s()\n", __func__);
bt_status_t status = btif_av_init();
if (status == BT_STATUS_SUCCESS)
static bt_status_t init_sink(btav_callbacks_t* callbacks)
{
- BTIF_TRACE_EVENT("%s()", __func__);
+ BTIF_TRACE_EVENT("%s()\n", __func__);
bt_status_t status = btif_av_init();
if (status == BT_STATUS_SUCCESS)
btif_av_connect_req_t connect_req;
connect_req.target_bda = bd_addr;
connect_req.uuid = uuid;
- BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
{
- BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
CHECK_BTAV_INIT();
return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
{
- BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
CHECK_BTAV_INIT();
return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
*******************************************************************************/
static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
{
- BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
CHECK_BTAV_INIT();
*******************************************************************************/
static void cleanup(void)
{
- BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
btif_a2dp_stop_media_task();
}
static void cleanup_src(void) {
- BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
if (bt_av_src_callbacks)
{
}
static void cleanup_sink(void) {
- BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
if (bt_av_sink_callbacks)
{
{
btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
- BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
+ BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x\n",
btif_av_cb.sm_handle, state, btif_av_cb.flags);
/* also make sure main adapter is enabled */
{
btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
- BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
+ BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x\n",
btif_av_cb.sm_handle, state, btif_av_cb.flags);
/* disallow media task to start if we have pending actions */
*******************************************************************************/
const btav_interface_t *btif_av_get_src_interface(void)
{
- BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
return &bt_av_src_interface;
}
*******************************************************************************/
const btav_interface_t *btif_av_get_sink_interface(void)
{
- BTIF_TRACE_EVENT("%s", __FUNCTION__);
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
return &bt_av_sink_interface;
}
*******************************************************************************/
BOOLEAN btif_av_is_peer_edr(void)
{
- ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
+ ASSERTC(btif_av_is_connected(), "No active a2dp connection\n", 0);
if (btif_av_cb.edr)
return TRUE;
******************************************************************************/
void btif_av_clear_remote_suspend_flag(void)
{
- BTIF_TRACE_DEBUG("%s: flag :%x",__func__, btif_av_cb.flags);
+ BTIF_TRACE_DEBUG("%s: flag :%x\n",__func__, btif_av_cb.flags);
btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
}
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/*****************************************************************************
+ *
+ * Filename: btif_av.c
+ *
+ * Description: Bluedroid AV implementation
+ *
+ *****************************************************************************/
+
+// #include <assert.h>
+#include "bt_trace.h"
+#include <string.h>
+
+// #include <hardware/bluetooth.h>
+#include "bt_defs.h"
+// #include <system/audio.h>
+#include "bt_av.h"
+#include "allocator.h"
+
+#define LOG_TAG "bt_btif_av"
+
+#include "btif_av.h"
+#include "btif_util.h"
+#include "btif_profile_queue.h"
+#include "bta_api.h"
+#include "btif_media.h"
+#include "bta_av_api.h"
+#include "gki.h"
+#include "btu.h"
+#include "bt_utils.h"
+
+/*****************************************************************************
+** Constants & Macros
+******************************************************************************/
+#define BTIF_AV_SERVICE_NAME "Advanced Audio"
+
+#define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS 2
+
+typedef enum {
+ BTIF_AV_STATE_IDLE = 0x0,
+ BTIF_AV_STATE_OPENING,
+ BTIF_AV_STATE_OPENED,
+ BTIF_AV_STATE_STARTED,
+ BTIF_AV_STATE_CLOSING
+} btif_av_state_t;
+
+/* Should not need dedicated suspend state as actual actions are no
+ different than open state. Suspend flags are needed however to prevent
+ media task from trying to restart stream during remote suspend or while
+ we are in the process of a local suspend */
+
+#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
+#define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2
+#define BTIF_AV_FLAG_PENDING_START 0x4
+#define BTIF_AV_FLAG_PENDING_STOP 0x8
+
+/*****************************************************************************
+** Local type definitions
+******************************************************************************/
+
+typedef struct
+{
+ tBTA_AV_HNDL bta_handle;
+ bt_bdaddr_t peer_bda;
+ btif_sm_handle_t sm_handle;
+ UINT8 flags;
+ tBTA_AV_EDR edr;
+ UINT8 peer_sep; /* sep type of peer device */
+} btif_av_cb_t;
+
+typedef struct
+{
+ bt_bdaddr_t *target_bda;
+ uint16_t uuid;
+} btif_av_connect_req_t;
+
+typedef struct
+{
+ int sample_rate;
+ int channel_count;
+} btif_av_sink_config_req_t;
+
+/*****************************************************************************
+** Static variables
+******************************************************************************/
+static btav_callbacks_t *bt_av_src_callbacks = NULL;
+static btav_callbacks_t *bt_av_sink_callbacks = NULL;
+static btif_av_cb_t btif_av_cb = {0};
+static TIMER_LIST_ENT tle_av_open_on_rc;
+
+/* both interface and media task needs to be ready to alloc incoming request */
+#define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
+ || (btif_av_cb.sm_handle == NULL))\
+{\
+ BTIF_TRACE_WARNING("%s: BTAV not initialized\n", __FUNCTION__);\
+ return BT_STATUS_NOT_READY;\
+}\
+else\
+{\
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);\
+}
+
+/* Helper macro to avoid code duplication in the state machine handlers */
+#define CHECK_RC_EVENT(e, d) \
+ case BTA_AV_RC_OPEN_EVT: \
+ case BTA_AV_RC_CLOSE_EVT: \
+ case BTA_AV_REMOTE_CMD_EVT: \
+ case BTA_AV_VENDOR_CMD_EVT: \
+ case BTA_AV_META_MSG_EVT: \
+ case BTA_AV_RC_FEAT_EVT: \
+ case BTA_AV_REMOTE_RSP_EVT: \
+ { \
+ }break; \
+
+static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
+static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
+static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
+static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
+static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
+
+static const btif_sm_handler_t btif_av_state_handlers[] =
+{
+ btif_av_state_idle_handler,
+ btif_av_state_opening_handler,
+ btif_av_state_opened_handler,
+ btif_av_state_started_handler,
+ btif_av_state_closing_handler
+};
+
+static void btif_av_event_free_data(btif_sm_event_t event, void *p_data);
+
+/*************************************************************************
+** Extern functions
+*************************************************************************/
+
+extern tBTA_AV_CO_FUNCTS bta_av_a2d_cos;
+/*****************************************************************************
+** Local helper functions
+******************************************************************************/
+
+const char *dump_av_sm_state_name(btif_av_state_t state)
+{
+ switch (state)
+ {
+ CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
+ CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
+ CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
+ CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
+ CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
+ default: return "UNKNOWN_STATE";
+ }
+}
+
+const char *dump_av_sm_event_name(btif_av_sm_event_t event)
+{
+ switch((int)event)
+ {
+ CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
+ CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
+ CASE_RETURN_STR(BTA_AV_OPEN_EVT)
+ CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
+ CASE_RETURN_STR(BTA_AV_START_EVT)
+ CASE_RETURN_STR(BTA_AV_STOP_EVT)
+ CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
+ CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
+ CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
+ CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
+ CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
+ CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
+ CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
+ CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
+ CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
+ CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
+ CASE_RETURN_STR(BTA_AV_PENDING_EVT)
+ CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
+ CASE_RETURN_STR(BTA_AV_REJECT_EVT)
+ CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
+ CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
+ CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
+ CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
+ CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
+ CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
+ CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
+ CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
+ CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
+ default: return "UNKNOWN_EVENT";
+ }
+}
+
+/****************************************************************************
+** Local helper functions
+*****************************************************************************/
+
+/*****************************************************************************
+** Static functions
+******************************************************************************/
+
+static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
+{
+ if (bt_av_sink_callbacks != NULL) {
+ HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
+ } else if (bt_av_src_callbacks != NULL) {
+ HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
+ }
+}
+
+static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
+{
+ if (bt_av_sink_callbacks != NULL) {
+ HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
+ } else if (bt_av_src_callbacks != NULL) {
+ HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
+ }
+}
+
+/*****************************************************************************
+**
+** Function btif_av_state_idle_handler
+**
+** Description State managing disconnected AV link
+**
+** Returns TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
+{
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
+ dump_av_sm_event_name(event), btif_av_cb.flags);
+
+ switch (event)
+ {
+ case BTIF_SM_ENTER_EVT:
+ /* clear the peer_bda */
+ memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
+ btif_av_cb.flags = 0;
+ btif_av_cb.edr = 0;
+ btif_a2dp_on_idle();
+ break;
+
+ case BTIF_SM_EXIT_EVT:
+ break;
+
+ case BTA_AV_ENABLE_EVT:
+ break;
+
+ case BTA_AV_REGISTER_EVT:
+ btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
+ break;
+
+ case BTA_AV_PENDING_EVT:
+ case BTIF_AV_CONNECT_REQ_EVT:
+ {
+ if (event == BTIF_AV_CONNECT_REQ_EVT)
+ {
+ memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
+ sizeof(bt_bdaddr_t));
+ BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
+ TRUE, BTA_SEC_AUTHENTICATE, ((btif_av_connect_req_t*)p_data)->uuid);
+ }
+ else if (event == BTA_AV_PENDING_EVT)
+ {
+ bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
+ BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
+ TRUE, BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SOURCE);
+ }
+ btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
+ } break;
+
+ case BTA_AV_RC_OPEN_EVT:
+ case BTA_AV_REMOTE_CMD_EVT:
+ case BTA_AV_VENDOR_CMD_EVT:
+ case BTA_AV_META_MSG_EVT:
+ case BTA_AV_RC_FEAT_EVT:
+ case BTA_AV_REMOTE_RSP_EVT:
+ case BTA_AV_RC_CLOSE_EVT:
+ BTIF_TRACE_WARNING("%s : unhandled RC event:%s\n", __FUNCTION__,
+ dump_av_sm_event_name(event));
+ break;
+ default:
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
+ dump_av_sm_event_name(event));
+ return FALSE;
+
+ }
+
+ return TRUE;
+}
+/*****************************************************************************
+**
+** Function btif_av_state_opening_handler
+**
+** Description Intermediate state managing events during establishment
+** of avdtp channel
+**
+** Returns TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
+{
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
+ dump_av_sm_event_name(event), btif_av_cb.flags);
+
+ switch (event)
+ {
+ case BTIF_SM_ENTER_EVT:
+ /* inform the application that we are entering connecting state */
+ btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
+ break;
+
+ case BTIF_SM_EXIT_EVT:
+ break;
+
+ case BTA_AV_REJECT_EVT:
+ BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT \n");
+ btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
+ btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+ break;
+
+ case BTA_AV_OPEN_EVT:
+ {
+ tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
+ btav_connection_state_t state;
+ btif_sm_state_t av_state;
+ BTIF_TRACE_DEBUG("status:%d, edr 0x%x\n",p_bta_data->open.status,
+ p_bta_data->open.edr);
+
+ if (p_bta_data->open.status == BTA_AV_SUCCESS)
+ {
+ state = BTAV_CONNECTION_STATE_CONNECTED;
+ av_state = BTIF_AV_STATE_OPENED;
+ btif_av_cb.edr = p_bta_data->open.edr;
+
+ btif_av_cb.peer_sep = p_bta_data->open.sep;
+ btif_a2dp_set_peer_sep(p_bta_data->open.sep);
+ }
+ else
+ {
+ BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d\n",
+ p_bta_data->open.status );
+ state = BTAV_CONNECTION_STATE_DISCONNECTED;
+ av_state = BTIF_AV_STATE_IDLE;
+ }
+
+ /* inform the application of the event */
+ btif_report_connection_state(state, &(btif_av_cb.peer_bda));
+ /* change state to open/idle based on the status */
+ btif_sm_change_state(btif_av_cb.sm_handle, av_state);
+#if 0
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+ {
+ /* if queued PLAY command, send it now */
+ btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
+ (p_bta_data->open.status == BTA_AV_SUCCESS));
+ }
+ else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+ {
+ /* if queued PLAY command, send it now */
+ btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
+ /* Bring up AVRCP connection too */
+ BTA_AvOpenRc(btif_av_cb.bta_handle);
+ }
+#endif /* #if 0*/
+ btif_queue_advance();
+ } break;
+
+ case BTIF_AV_SINK_CONFIG_REQ_EVT:
+ {
+ btif_av_sink_config_req_t req;
+ // copy to avoid alignment problems
+ memcpy(&req, p_data, sizeof(req));
+
+ BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d\n", req.sample_rate,
+ req.channel_count);
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
+ HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
+ req.sample_rate, req.channel_count);
+ }
+ } break;
+
+ case BTIF_AV_CONNECT_REQ_EVT:
+ // Check for device, if same device which moved to opening then ignore callback
+ if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
+ sizeof(btif_av_cb.peer_bda)) == 0)
+ {
+ BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Connect Req\n", __func__);
+ btif_queue_advance();
+ break;
+ }
+ else
+ {
+ BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request\n", __func__);
+ btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t*)p_data);
+ btif_queue_advance();
+ break;
+ }
+
+ case BTA_AV_PENDING_EVT:
+ // Check for device, if same device which moved to opening then ignore callback
+ if (memcmp (((tBTA_AV*)p_data)->pend.bd_addr, &(btif_av_cb.peer_bda),
+ sizeof(btif_av_cb.peer_bda)) == 0)
+ {
+ BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Pending Req\n", __func__);
+ break;
+ }
+ else
+ {
+ BTIF_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request\n", __func__);
+ BTA_AvDisconnect(((tBTA_AV*)p_data)->pend.bd_addr);
+ break;
+ }
+
+ CHECK_RC_EVENT(event, p_data);
+
+ default:
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
+ dump_av_sm_event_name(event));
+ return FALSE;
+
+ }
+ return TRUE;
+}
+
+
+/*****************************************************************************
+**
+** Function btif_av_state_closing_handler
+**
+** Description Intermediate state managing events during closing
+** of avdtp channel
+**
+** Returns TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
+{
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
+ dump_av_sm_event_name(event), btif_av_cb.flags);
+
+ switch (event)
+ {
+ case BTIF_SM_ENTER_EVT:
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+ {
+ /* immediately stop transmission of frames */
+ btif_a2dp_set_tx_flush(TRUE);
+ /* wait for audioflinger to stop a2dp */
+ }
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+ {
+ btif_a2dp_set_rx_flush(TRUE);
+ }
+ break;
+
+ case BTA_AV_STOP_EVT:
+ case BTIF_AV_STOP_STREAM_REQ_EVT:
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+ {
+ /* immediately flush any pending tx frames while suspend is pending */
+ btif_a2dp_set_tx_flush(TRUE);
+ }
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+ {
+ btif_a2dp_set_rx_flush(TRUE);
+ }
+
+ btif_a2dp_on_stopped(NULL);
+ break;
+
+ case BTIF_SM_EXIT_EVT:
+ break;
+
+ case BTA_AV_CLOSE_EVT:
+
+ /* inform the application that we are disconnecting */
+ btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
+
+ btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+ break;
+
+ /* Handle the RC_CLOSE event for the cleanup */
+ case BTA_AV_RC_CLOSE_EVT:
+ BTIF_TRACE_WARNING("%s : unhandled RC event:%s\n", __FUNCTION__,
+ dump_av_sm_event_name(event));
+ break;
+
+ default:
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
+ dump_av_sm_event_name(event));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*****************************************************************************
+**
+** Function btif_av_state_opened_handler
+**
+** Description Handles AV events while AVDTP is in OPEN state
+**
+** Returns TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
+{
+ tBTA_AV *p_av = (tBTA_AV*)p_data;
+
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
+ dump_av_sm_event_name(event), btif_av_cb.flags);
+
+ if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
+ (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
+ {
+ BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY\n", __FUNCTION__);
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
+ }
+
+ switch (event)
+ {
+ case BTIF_SM_ENTER_EVT:
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
+ break;
+
+ case BTIF_SM_EXIT_EVT:
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
+ break;
+
+ case BTIF_AV_START_STREAM_REQ_EVT:
+ if (btif_av_cb.peer_sep != AVDT_TSEP_SRC)
+ btif_a2dp_setup_codec();
+ BTA_AvStart();
+ btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
+ break;
+
+ case BTA_AV_START_EVT:
+ {
+ BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d\n",
+ p_av->start.status, p_av->start.suspending, p_av->start.initiator);
+
+ if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
+ return TRUE;
+
+ /* if remote tries to start a2dp when DUT is a2dp source
+ * then suspend. In case a2dp is sink and call is active
+ * then disconnect the AVDTP channel
+ */
+ if (!(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START))
+ {
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+ {
+ BTIF_TRACE_EVENT("%s: trigger suspend as remote initiated!!\n", __FUNCTION__);
+ btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
+ }
+ }
+
+ /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+ {
+ if (btif_a2dp_on_started(&p_av->start,
+ ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
+ {
+ /* only clear pending flag after acknowledgement */
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
+ }
+ }
+
+ /* remain in open state if status failed */
+ if (p_av->start.status != BTA_AV_SUCCESS)
+ return FALSE;
+
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+ {
+ btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
+ }
+
+ /* change state to started, send acknowledgement if start is pending */
+ if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+ btif_a2dp_on_started(NULL, TRUE);
+ /* pending start flag will be cleared when exit current state */
+ }
+ btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
+
+ } break;
+
+ case BTIF_AV_DISCONNECT_REQ_EVT:
+ BTA_AvClose(btif_av_cb.bta_handle);
+
+ /* inform the application that we are disconnecting */
+ btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
+ break;
+
+ case BTA_AV_CLOSE_EVT:
+ /* avdtp link is closed */
+ btif_a2dp_on_stopped(NULL);
+
+ /* inform the application that we are disconnected */
+ btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
+
+ /* change state to idle, send acknowledgement if start is pending */
+ if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
+ btif_a2dp_ack_fail();
+ /* pending start flag will be cleared when exit current state */
+ }
+ btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+ break;
+
+ case BTA_AV_RECONFIG_EVT:
+ if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
+ (p_av->reconfig.status == BTA_AV_SUCCESS))
+ {
+ APPL_TRACE_WARNING("reconfig done BTA_AVstart()\n");
+ BTA_AvStart();
+ }
+ else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
+ {
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
+ btif_a2dp_ack_fail();
+ }
+ break;
+
+ case BTIF_AV_CONNECT_REQ_EVT:
+ if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
+ sizeof(btif_av_cb.peer_bda)) == 0)
+ {
+ BTIF_TRACE_DEBUG("%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device\n", __func__);
+ }
+ else
+ {
+ BTIF_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req\n", __func__);
+ btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
+ (bt_bdaddr_t*)p_data);
+ }
+ btif_queue_advance();
+ break;
+
+ CHECK_RC_EVENT(event, p_data);
+
+ default:
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
+ dump_av_sm_event_name(event));
+ return FALSE;
+
+ }
+ return TRUE;
+}
+
+/*****************************************************************************
+**
+** Function btif_av_state_started_handler
+**
+** Description Handles AV events while A2DP stream is started
+**
+** Returns TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
+{
+ tBTA_AV *p_av = (tBTA_AV*)p_data;
+
+ BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
+ dump_av_sm_event_name(event), btif_av_cb.flags);
+
+ switch (event)
+ {
+ case BTIF_SM_ENTER_EVT:
+
+ /* we are again in started state, clear any remote suspend flags */
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
+
+ btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
+
+ /* increase the a2dp consumer task priority temporarily when start
+ ** audio playing, to avoid overflow the audio packet queue. */
+ adjust_priority_a2dp(TRUE);
+
+ break;
+
+ case BTIF_SM_EXIT_EVT:
+ /* restore the a2dp consumer task priority when stop audio playing. */
+ adjust_priority_a2dp(FALSE);
+
+ break;
+
+ case BTIF_AV_START_STREAM_REQ_EVT:
+ /* we were remotely started, just ack back the local request */
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+ btif_a2dp_on_started(NULL, TRUE);
+ break;
+
+ /* fixme -- use suspend = true always to work around issue with BTA AV */
+ case BTIF_AV_STOP_STREAM_REQ_EVT:
+ case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
+
+ /* set pending flag to ensure btif task is not trying to restart
+ stream while suspend is in progress */
+ btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
+
+ /* if we were remotely suspended but suspend locally, local suspend
+ always overrides */
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
+
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+ {
+ /* immediately stop transmission of frames while suspend is pending */
+ btif_a2dp_set_tx_flush(TRUE);
+ }
+
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
+ btif_a2dp_set_rx_flush(TRUE);
+ btif_a2dp_on_stopped(NULL);
+ }
+
+ BTA_AvStop(TRUE);
+ break;
+
+ case BTIF_AV_DISCONNECT_REQ_EVT:
+
+ /* request avdtp to close */
+ BTA_AvClose(btif_av_cb.bta_handle);
+
+ /* inform the application that we are disconnecting */
+ btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
+
+ /* wait in closing state until fully closed */
+ btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
+ break;
+
+ case BTA_AV_SUSPEND_EVT:
+
+ BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d\n",
+ p_av->suspend.status, p_av->suspend.initiator);
+
+ /* a2dp suspended, stop media task until resumed */
+ btif_a2dp_on_suspended(&p_av->suspend);
+
+ /* if not successful, remain in current state */
+ if (p_av->suspend.status != BTA_AV_SUCCESS)
+ {
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
+
+ if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+ {
+ /* suspend failed, reset back tx flush state */
+ btif_a2dp_set_tx_flush(FALSE);
+ }
+ return FALSE;
+ }
+
+ if (p_av->suspend.initiator != TRUE)
+ {
+ /* remote suspend, notify HAL and await audioflinger to
+ suspend/stop stream */
+
+ /* set remote suspend flag to block media task from restarting
+ stream only if we did not already initiate a local suspend */
+ if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
+ btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
+
+ btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
+ }
+ else
+ {
+ btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
+ }
+
+ btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
+
+ /* suspend completed and state changed, clear pending status */
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
+ break;
+
+ case BTA_AV_STOP_EVT:
+
+ btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
+ btif_a2dp_on_stopped(&p_av->suspend);
+
+ btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
+
+ /* if stop was successful, change state to open */
+ if (p_av->suspend.status == BTA_AV_SUCCESS)
+ btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
+
+ break;
+
+ case BTA_AV_CLOSE_EVT:
+
+ btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
+
+ /* avdtp link is closed */
+ btif_a2dp_on_stopped(NULL);
+
+ /* inform the application that we are disconnected */
+ btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
+
+ btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+ break;
+
+ CHECK_RC_EVENT(event, p_data);
+
+ default:
+ BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
+ dump_av_sm_event_name(event));
+ return FALSE;
+
+ }
+ return TRUE;
+}
+
+/*****************************************************************************
+** Local event handlers
+******************************************************************************/
+
+static void btif_av_handle_event(UINT16 event, char* p_param)
+{
+ btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
+ btif_av_event_free_data(event, p_param);
+}
+
+void btif_av_event_deep_copy(UINT16 event, char *p_dest, char *p_src)
+{
+ tBTA_AV *av_src = (tBTA_AV *)p_src;
+ tBTA_AV *av_dest = (tBTA_AV *)p_dest;
+
+ // First copy the structure
+ memcpy(p_dest, p_src, sizeof(tBTA_AV));
+
+ switch (event)
+ {
+ case BTA_AV_META_MSG_EVT:
+ if (av_src->meta_msg.p_data && av_src->meta_msg.len)
+ {
+ av_dest->meta_msg.p_data = osi_calloc(av_src->meta_msg.len);
+ assert(av_dest->meta_msg.p_data);
+ memcpy(av_dest->meta_msg.p_data, av_src->meta_msg.p_data, av_src->meta_msg.len);
+ }
+
+ if (av_src->meta_msg.p_msg)
+ {
+ av_dest->meta_msg.p_msg = osi_calloc(sizeof(tAVRC_MSG));
+ assert(av_dest->meta_msg.p_msg);
+ memcpy(av_dest->meta_msg.p_msg, av_src->meta_msg.p_msg, sizeof(tAVRC_MSG));
+
+ if (av_src->meta_msg.p_msg->vendor.p_vendor_data &&
+ av_src->meta_msg.p_msg->vendor.vendor_len)
+ {
+ av_dest->meta_msg.p_msg->vendor.p_vendor_data = osi_calloc(
+ av_src->meta_msg.p_msg->vendor.vendor_len);
+ assert(av_dest->meta_msg.p_msg->vendor.p_vendor_data);
+ memcpy(av_dest->meta_msg.p_msg->vendor.p_vendor_data,
+ av_src->meta_msg.p_msg->vendor.p_vendor_data,
+ av_src->meta_msg.p_msg->vendor.vendor_len);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void btif_av_event_free_data(btif_sm_event_t event, void *p_data)
+{
+ switch (event)
+ {
+ case BTA_AV_META_MSG_EVT:
+ {
+ tBTA_AV *av = (tBTA_AV*)p_data;
+ if (av->meta_msg.p_data)
+ osi_free(av->meta_msg.p_data);
+
+ if (av->meta_msg.p_msg)
+ {
+ if (av->meta_msg.p_msg->vendor.p_vendor_data)
+ osi_free(av->meta_msg.p_msg->vendor.p_vendor_data);
+ osi_free(av->meta_msg.p_msg);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
+{
+ btif_transfer_context(btif_av_handle_event, event,
+ (char*)p_data, sizeof(tBTA_AV), btif_av_event_deep_copy);
+}
+
+static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
+{
+ btif_sm_state_t state;
+ UINT8 que_len;
+ tA2D_STATUS a2d_status;
+ tA2D_SBC_CIE sbc_cie;
+ btif_av_sink_config_req_t config_req;
+
+ if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
+ {
+ state= btif_sm_get_state(btif_av_cb.sm_handle);
+ if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
+ (state == BTIF_AV_STATE_OPENED) )
+ {
+ que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
+ BTIF_TRACE_DEBUG(" Packets in Que %d\n",que_len);
+ }
+ else
+ return;
+ }
+
+ if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
+ /* send a command to BT Media Task */
+ btif_reset_decoder((UINT8*)p_data);
+
+ a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
+ if (a2d_status == A2D_SUCCESS) {
+ /* Switch to BTIF context */
+ config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
+ config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
+ btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
+ (char*)&config_req, sizeof(config_req), NULL);
+ } else {
+ APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
+ }
+ }
+}
+/*******************************************************************************
+**
+** Function btif_av_init
+**
+** Description Initializes btif AV if not already done
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_av_init()
+{
+ if (btif_av_cb.sm_handle == NULL)
+ {
+ if (!btif_a2dp_start_media_task())
+ return BT_STATUS_FAIL;
+
+ /* Also initialize the AV state machine */
+ btif_av_cb.sm_handle =
+ btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
+
+ btif_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+ btif_enable_service(BTA_A2DP_SINK_SERVICE_ID);
+#endif
+
+ btif_a2dp_on_init();
+ }
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function init_src
+**
+** Description Initializes the AV interface for source mode
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+static bt_status_t init_src(btav_callbacks_t* callbacks)
+{
+ BTIF_TRACE_EVENT("%s()\n", __func__);
+
+ bt_status_t status = btif_av_init();
+ if (status == BT_STATUS_SUCCESS)
+ bt_av_src_callbacks = callbacks;
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function init_sink
+**
+** Description Initializes the AV interface for sink mode
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+static bt_status_t init_sink(btav_callbacks_t* callbacks)
+{
+ BTIF_TRACE_EVENT("%s()\n", __func__);
+
+ bt_status_t status = btif_av_init();
+ if (status == BT_STATUS_SUCCESS)
+ bt_av_sink_callbacks = callbacks;
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function connect
+**
+** Description Establishes the AV signalling channel with the remote headset
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
+{
+ btif_av_connect_req_t connect_req;
+ connect_req.target_bda = bd_addr;
+ connect_req.uuid = uuid;
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
+
+ btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
+
+ return BT_STATUS_SUCCESS;
+}
+
+static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
+{
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
+ CHECK_BTAV_INIT();
+
+ return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
+}
+
+static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
+{
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
+ CHECK_BTAV_INIT();
+
+ return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
+}
+
+/*******************************************************************************
+**
+** Function disconnect
+**
+** Description Tears down the AV signalling channel with the remote headset
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
+{
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
+
+ CHECK_BTAV_INIT();
+
+ /* Switch to BTIF context */
+ return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
+ (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
+}
+
+/*******************************************************************************
+**
+** Function cleanup
+**
+** Description Shuts down the AV interface and does the cleanup
+**
+** Returns None
+**
+*******************************************************************************/
+static void cleanup(void)
+{
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
+
+ btif_a2dp_stop_media_task();
+
+ btif_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+ btif_disable_service(BTA_A2DP_SINK_SERVICE_ID);
+#endif
+
+ /* Also shut down the AV state machine */
+ btif_sm_shutdown(btif_av_cb.sm_handle);
+ btif_av_cb.sm_handle = NULL;
+}
+
+static void cleanup_src(void) {
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
+
+ if (bt_av_src_callbacks)
+ {
+ bt_av_src_callbacks = NULL;
+ if (bt_av_sink_callbacks == NULL)
+ cleanup();
+ }
+}
+
+static void cleanup_sink(void) {
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
+
+ if (bt_av_sink_callbacks)
+ {
+ bt_av_sink_callbacks = NULL;
+ if (bt_av_src_callbacks == NULL)
+ cleanup();
+ }
+}
+
+static const btav_interface_t bt_av_src_interface = {
+ sizeof(btav_interface_t),
+ init_src,
+ src_connect_sink,
+ disconnect,
+ cleanup_src,
+};
+
+static const btav_interface_t bt_av_sink_interface = {
+ sizeof(btav_interface_t),
+ init_sink,
+ sink_connect_src,
+ disconnect,
+ cleanup_sink,
+};
+
+/*******************************************************************************
+**
+** Function btif_av_get_sm_handle
+**
+** Description Fetches current av SM handle
+**
+** Returns None
+**
+*******************************************************************************/
+
+btif_sm_handle_t btif_av_get_sm_handle(void)
+{
+ return btif_av_cb.sm_handle;
+}
+
+/*******************************************************************************
+**
+** Function btif_av_stream_ready
+**
+** Description Checks whether AV is ready for starting a stream
+**
+** Returns None
+**
+*******************************************************************************/
+
+BOOLEAN btif_av_stream_ready(void)
+{
+ btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
+
+ BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x\n",
+ btif_av_cb.sm_handle, state, btif_av_cb.flags);
+
+ /* also make sure main adapter is enabled */
+ if (btif_is_enabled() == 0)
+ {
+ BTIF_TRACE_EVENT("main adapter not enabled");
+ return FALSE;
+ }
+
+ /* check if we are remotely suspended or stop is pending */
+ if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
+ return FALSE;
+
+ return (state == BTIF_AV_STATE_OPENED);
+}
+
+/*******************************************************************************
+**
+** Function btif_av_stream_started_ready
+**
+** Description Checks whether AV ready for media start in streaming state
+**
+** Returns None
+**
+*******************************************************************************/
+
+BOOLEAN btif_av_stream_started_ready(void)
+{
+ btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
+
+ BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x\n",
+ btif_av_cb.sm_handle, state, btif_av_cb.flags);
+
+ /* disallow media task to start if we have pending actions */
+ if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
+ | BTIF_AV_FLAG_PENDING_STOP))
+ return FALSE;
+
+ return (state == BTIF_AV_STATE_STARTED);
+}
+
+/*******************************************************************************
+**
+** Function btif_dispatch_sm_event
+**
+** Description Send event to AV statemachine
+**
+** Returns None
+**
+*******************************************************************************/
+
+/* used to pass events to AV statemachine from other tasks */
+void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
+{
+ /* Switch to BTIF context */
+ btif_transfer_context(btif_av_handle_event, event,
+ (char*)p_data, len, NULL);
+}
+
+/*******************************************************************************
+**
+** Function btif_av_execute_service
+**
+** Description Initializes/Shuts down the service
+**
+** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_av_execute_service(BOOLEAN b_enable)
+{
+ if (b_enable)
+ {
+ /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
+ * handle this request in order to allow incoming connections to succeed.
+ * We need to put this back once support for this is added */
+
+ /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
+ * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
+ * be initiated by the app/audioflinger layers */
+ BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_NO_SCO_SSPD),
+ bte_av_callback);
+ BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos);
+ }
+ else {
+ BTA_AvDeregister(btif_av_cb.bta_handle);
+ BTA_AvDisable();
+ }
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_av_sink_execute_service
+**
+** Description Initializes/Shuts down the service
+**
+** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_av_sink_execute_service(BOOLEAN b_enable)
+{
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+ BTA_AvEnable_Sink(b_enable);
+#endif
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_av_get_src_interface
+**
+** Description Get the AV callback interface for A2DP source profile
+**
+** Returns btav_interface_t
+**
+*******************************************************************************/
+const btav_interface_t *btif_av_get_src_interface(void)
+{
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
+ return &bt_av_src_interface;
+}
+
+/*******************************************************************************
+**
+** Function btif_av_get_sink_interface
+**
+** Description Get the AV callback interface for A2DP sink profile
+**
+** Returns btav_interface_t
+**
+*******************************************************************************/
+const btav_interface_t *btif_av_get_sink_interface(void)
+{
+ BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
+ return &bt_av_sink_interface;
+}
+
+/*******************************************************************************
+**
+** Function btif_av_is_connected
+**
+** Description Checks if av has a connected sink
+**
+** Returns BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN btif_av_is_connected(void)
+{
+ btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
+ return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
+}
+
+/*******************************************************************************
+**
+** Function btif_av_is_peer_edr
+**
+** Description Check if the connected a2dp device supports
+** EDR or not. Only when connected this function
+** will accurately provide a true capability of
+** remote peer. If not connected it will always be false.
+**
+** Returns TRUE if remote device is capable of EDR
+**
+*******************************************************************************/
+BOOLEAN btif_av_is_peer_edr(void)
+{
+ ASSERTC(btif_av_is_connected(), "No active a2dp connection\n", 0);
+
+ if (btif_av_cb.edr)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/******************************************************************************
+**
+** Function btif_av_clear_remote_suspend_flag
+**
+** Description Clears btif_av_cd.flags if BTIF_AV_FLAG_REMOTE_SUSPEND is set
+**
+** Returns void
+******************************************************************************/
+void btif_av_clear_remote_suspend_flag(void)
+{
+ BTIF_TRACE_DEBUG("%s: flag :%x\n",__func__, btif_av_cb.flags);
+ btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
+}