]> granicus.if.org Git - esp-idf/commitdiff
component/bt: bug fix for hci data packet reassembler
authorwangmengyang <wangmengyang@espressif.com>
Tue, 15 Nov 2016 06:32:22 +0000 (14:32 +0800)
committerwangmengyang <wangmengyang@espressif.com>
Tue, 15 Nov 2016 06:32:22 +0000 (14:32 +0800)
1. bugfix for hci data packet reassembler
2. create new file btif_avk.c originated from btif_av.c to eliminate the avrc related logic

components/bt/bluedroid/bta/av/bta_av_main.c
components/bt/bluedroid/hci/packet_fragmenter.c
components/bt/bluedroid/include/bt_target.h
components/bt/bluedroid/utils/bt_utils.c
components/bt/component.mk
examples/09_a2dp/components/bluedroid_demos/app_project/SampleBtSdp.c
examples/09_a2dp/components/bluedroid_demos/btif/btif_av.c.bak [moved from examples/09_a2dp/components/bluedroid_demos/btif/btif_av.c with 95% similarity]
examples/09_a2dp/components/bluedroid_demos/btif/btif_avk.c [new file with mode: 0755]
examples/09_a2dp/components/bluedroid_demos/btif/btif_media_task.c
examples/09_a2dp/components/bluedroid_demos/btif/btif_rc.c
examples/09_a2dp/components/bluedroid_demos/component.mk

index a598b46ac91c8303732807784432906c5b586466..7acf903ca48d00c058ae2608aed3b93a7b3ba897 100755 (executable)
@@ -368,7 +368,7 @@ static tBTA_AV_SCB * bta_av_alloc_scb(tBTA_AV_CHNL chnl)
     }
     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;
     }
 
@@ -438,7 +438,7 @@ void bta_av_conn_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p
 #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
 
@@ -456,10 +456,10 @@ void bta_av_conn_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p
 #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]);
@@ -505,7 +505,7 @@ static void bta_av_api_sink_enable(tBTA_AV_DATA *p_data)
 {
     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);
@@ -605,7 +605,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
                                 (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
             }
@@ -631,7 +631,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
         */
         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)
         {
@@ -683,7 +683,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
                 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)
                 {
@@ -697,7 +697,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
                         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++;
                 }
@@ -747,7 +747,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
                 }
             }
             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
         {
@@ -911,7 +911,7 @@ void bta_av_restore_switch (void)
     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);
@@ -944,7 +944,7 @@ static void bta_av_sys_rs_cback (tBTA_SYS_CONN_STATUS status,UINT8 id, UINT8 app
     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 */
@@ -953,7 +953,7 @@ static void bta_av_sys_rs_cback (tBTA_SYS_CONN_STATUS status,UINT8 id, UINT8 app
         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))
             {
@@ -988,7 +988,7 @@ static void bta_av_sys_rs_cback (tBTA_SYS_CONN_STATUS status,UINT8 id, UINT8 app
         }
         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)
@@ -1024,7 +1024,7 @@ static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8
     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;
@@ -1036,7 +1036,7 @@ static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8
 
             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;
@@ -1055,7 +1055,7 @@ static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8
 
             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);
             }
         }
@@ -1128,7 +1128,7 @@ BOOLEAN bta_av_link_role_ok(tBTA_AV_SCB *p_scb, UINT8 bits)
 
     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)))
@@ -1179,7 +1179,7 @@ UINT16 bta_av_chk_mtu(tBTA_AV_SCB *p_scb, UINT16 mtu)
                 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)
                     {
@@ -1189,7 +1189,7 @@ UINT16 bta_av_chk_mtu(tBTA_AV_SCB *p_scb, UINT16 mtu)
                 }
             }
         }
-        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;
@@ -1262,10 +1262,10 @@ void bta_av_sm_execute(tBTA_AV_CB *p_cb, UINT16 event, tBTA_AV_DATA *p_data)
     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 */
@@ -1275,7 +1275,7 @@ void bta_av_sm_execute(tBTA_AV_CB *p_cb, UINT16 event, tBTA_AV_DATA *p_data)
 
     /* 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)
@@ -1308,9 +1308,9 @@ BOOLEAN bta_av_hdl_event(BT_HDR *p_msg)
     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);
@@ -1318,16 +1318,16 @@ BOOLEAN bta_av_hdl_event(BT_HDR *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);
index 675f222869d4145675d239385419830c9dc875cb..0da90388f6118b9aa28165dcca98e5e1d7fa16f8 100755 (executable)
@@ -161,8 +161,9 @@ static void reassemble_and_dispatch(BT_HDR *packet) {
       partial_packet->len = full_length;
       partial_packet->offset = packet->len;
 
-      memcpy(partial_packet->data, packet->data, packet->len);
-
+      // org: memcpy(partial_packet->data, packet->data, packet->len);
+      memcpy(partial_packet->data, packet->data+packet->offset, packet->len);
+      
       // Update the ACL data size to indicate the full expected length
       stream = partial_packet->data;
       STREAM_SKIP_UINT16(stream); // skip the handle
@@ -179,7 +180,10 @@ static void reassemble_and_dispatch(BT_HDR *packet) {
         return;
       }
 
-      packet->offset = HCI_ACL_PREAMBLE_SIZE;
+      // org: packet->offset = HCI_ACL_PREAMBLE_SIZE;
+      packet->offset += HCI_ACL_PREAMBLE_SIZE; // skip ACL preamble
+      packet->len -= HCI_ACL_PREAMBLE_SIZE;
+      
       projected_offset = partial_packet->offset + (packet->len - HCI_ACL_PREAMBLE_SIZE);
       if (projected_offset > partial_packet->len) { // len stores the expected length
         LOG_WARN("%s got packet which would exceed expected length of %d. Truncating.", __func__, partial_packet->len);
@@ -190,7 +194,8 @@ static void reassemble_and_dispatch(BT_HDR *packet) {
       memcpy(
         partial_packet->data + partial_packet->offset,
         packet->data + packet->offset,
-        packet->len - packet->offset
+        // org: packet->len - packet->offset
+       packet->len
       );
 
       // Free the old packet buffer, since we don't need it anymore
index 30d153edfbd6483cfb9312833b3b5d467dc46d88..ee70d0661dced4f612e40ce885df477deebb8253 100755 (executable)
 
 /* The IO capability of the local device (for Simple Pairing) */
 #ifndef BTM_LOCAL_IO_CAPS
-#define BTM_LOCAL_IO_CAPS               BTM_IO_CAP_IO
+#define BTM_LOCAL_IO_CAPS               BTM_IO_CAP_NONE
 #endif
 
 #ifndef BTM_LOCAL_IO_CAPS_BLE
@@ -1593,7 +1593,7 @@ Range: 2 octets
 **
 ******************************************************************************/
 #ifndef AVRC_INCLUDED
-#define AVRC_INCLUDED               FALSE
+#define AVRC_INCLUDED               TRUE
 #endif
 
 #ifndef AVRC_METADATA_INCLUDED
index 985b9537e4aad156acd42238d53b58a87b0c1bb0..410b83ea9eb4603c1a502658ef396c7f7ff0ae51 100644 (file)
@@ -12,6 +12,7 @@
 *******************************************************************************/
 void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task)
 {
+    (void) high_task;
     return;
 }
 
@@ -28,5 +29,6 @@ void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task)
 *******************************************************************************/
 void adjust_priority_a2dp(int start)
 {
+    (void) start;
     return;
 }
index de4e25e6f17e3ef512f097dca35389878d323102..814ed44ef2483f1a214b9286f1e9815a75547e25 100644 (file)
@@ -31,6 +31,7 @@ COMPONENT_ADD_INCLUDEDIRS :=  bluedroid/bta/include                   \
                                bluedroid/stack/avdt/include            \
                                bluedroid/stack/a2dp/include            \
                                bluedroid/stack/include                 \
+                               bluedroid/utils/include                 \
                                bluedroid/api/include           \
                                bluedroid/include                       \
                                include 
@@ -86,6 +87,7 @@ COMPONENT_SRCDIRS :=  bluedroid/bta/dm                        \
                        bluedroid/stack/avdt                    \
                        bluedroid/stack/a2dp                    \
                        bluedroid/stack                         \
+                       bluedroid/utils                         \
                        bluedroid/api                   \
                        bluedroid                               \
                        .
index d8e5b23ba16cb1c03c5445be5830fce7c9649584..d2ab070947c22cfac45612c9a110f49bd9b86817 100644 (file)
 #include "btif_stack_manager.h"
 #include "btif_sdp.h"
 #include "esp_gap_api.h"
-
 #include "bta_api.h"
+#include "bt_av.h"
+
+/* utl_set_device_class() */
+#include "utl.h"
 
 #include "alarm.h"
 typedef enum {
     BT_APP_EVT_STACK_ON,
     BT_APP_EVT_STACK_OFF,
-    BT_APP_EVT_ADD_SDP_RECORD_TO,
-    BT_APP_EVT_SDP_SEARCH_START_TO,
+    BT_APP_EVT_AV_OPEN_TO,
     BT_APP_EVT
 } tBT_APP_EVT;
 
@@ -27,49 +29,61 @@ typedef union {
     uint32_t dummy;
 } tBT_APP_EVT_DATA;
 
+extern const btav_interface_t *btif_av_get_sink_interface(void);
 static void bt_stack_evt(tBT_APP_EVT event, tBT_APP_EVT_DATA *p_data);
 static void bt_stack_state_changed(bt_state_t state);
-static int bt_sdp_add_record(void);
-static void bt_sdp_search_complete(bt_status_t status, bt_bdaddr_t *bd_addr, uint8_t* uuid, int num_records, bluetooth_sdp_record *records);
-
-// static bt_bdaddr_t peer_bd_addr = {{0x00, 0x1b, 0xdc, 0x08, 0x0f, 0xe7}};
-static bt_bdaddr_t peer_bd_addr = {{0xfc, 0x3f, 0x7c, 0xf1, 0x2c, 0x78}};
-
-/* root browse
-static const uint8_t target_uuid[16] = { 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x00,
-                                         0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
-*/
 
-/* UUID_MAP_MAS */
-static const uint8_t  target_uuid[] = {0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00,
-                                        0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
-
-/* UUID AUDIO Source */
-/*
-static const uint8_t  target_uuid[] = {0x00, 0x00, 0x11, 0x0A, 0x00, 0x00, 0x10, 0x00,
-                                        0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
-*/
+static bt_bdaddr_t peer_bd_addr = {{0x00, 0x1b, 0xdc, 0x08, 0x0f, 0xe7}};
+// static bt_bdaddr_t peer_bd_addr = {{0xfc, 0x3f, 0x7c, 0xf1, 0x2c, 0x78}};
 
 static bt_callbacks_t bt_callbacks = {
     bt_stack_state_changed
 };
 
-static btsdp_callbacks_t btsdp_callbacks = {
-    bt_sdp_search_complete
-};
-
 osi_alarm_t *app_alarm = NULL;
 
-static void bt_sdp_add_record_to(void *context)
+static void btav_conn_state_cb(btav_connection_state_t state,
+                              bt_bdaddr_t *bd_addr)
 {
-    (void)(context);
-    bt_stack_evt(BT_APP_EVT_ADD_SDP_RECORD_TO, NULL);
+    LOG_ERROR("===btav_conn_state_cb %d ===\n", state);
+    (void) bd_addr;
 }
 
-static void bt_sdp_search_start_to(void *context)
+static void btav_audio_state_cb(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
+{
+    LOG_ERROR("===btav_audio_state_cb %d ===\n", state);
+    (void) bd_addr;
+}
+
+static void btav_audio_cfg_cb(bt_bdaddr_t *bd_addr, uint32_t sample_rate, uint8_t channel_count)
+{
+    LOG_ERROR("===btav_audio_cfg_cb %d %d===\n", sample_rate, channel_count);
+    (void) bd_addr;
+}
+
+static btav_callbacks_t btav_cbs = {
+    sizeof (btav_callbacks_t),
+    btav_conn_state_cb,
+    btav_audio_state_cb,
+    btav_audio_cfg_cb
+};
+
+static void btav_open_to(void *context)
 {
     (void)(context);
-    bt_stack_evt(BT_APP_EVT_SDP_SEARCH_START_TO, NULL);
+    bt_stack_evt(BT_APP_EVT_AV_OPEN_TO, NULL);
+}
+
+static void btav_set_device_class(void)
+{
+    tBTA_UTL_COD cod;
+    memset(&cod, 0, sizeof(tBTA_UTL_COD));
+    cod.major = BTM_COD_MAJOR_AUDIO;
+    cod.minor = BTM_COD_MINOR_LOUDSPEAKER;
+    cod.service = BTM_COD_SERVICE_CAPTURING | BTM_COD_SERVICE_AUDIO;
+    utl_set_device_class(&cod, BTA_UTL_SET_COD_ALL);
+    LOG_ERROR("set class of device: major 0x%x, minor 0x%x, service 0x%x\n",
+              cod.major, cod.minor, cod.service);
 }
 
 static void bt_app_stack_evt(UINT16 event, char *p_param)
@@ -78,27 +92,21 @@ static void bt_app_stack_evt(UINT16 event, char *p_param)
     case BT_APP_EVT_STACK_ON: {
        char *dev_name = "SDP_SERVER_CLIENT";
        BTM_SetTraceLevel(BT_TRACE_LEVEL_DEBUG);
+        btav_set_device_class();
        BTA_DmSetDeviceName(dev_name);
-    
         esp_bt_gap_set_scan_mode(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
-        BTIF_SdpInit(&btsdp_callbacks);
-
-        app_alarm = osi_alarm_new("app_alarm", bt_sdp_add_record_to, NULL, 1000, false);
+        btif_av_get_sink_interface()->init(&btav_cbs);
+        
+        // app_alarm = osi_alarm_new("app_alarm", bt_sdp_add_record_to, NULL, 1000, false);
+        app_alarm = osi_alarm_new("app_alarm", btav_open_to, NULL, 1000, false);
         osi_alarm_set(app_alarm, 1000);
     }
         break;
-    case BT_APP_EVT_ADD_SDP_RECORD_TO: {
-        bt_sdp_add_record();
-        osi_alarm_free(app_alarm);
-        app_alarm = NULL;
-        app_alarm = osi_alarm_new("app_alarm", bt_sdp_search_start_to, NULL, 20000, false);
-        osi_alarm_set(app_alarm, 20000);
-    }
-        break;
-    case BT_APP_EVT_SDP_SEARCH_START_TO: {
+    case BT_APP_EVT_AV_OPEN_TO: {
+        LOG_ERROR("**BT_APP_EVT_AV_OPEN_TO\n");
+       // btif_av_get_sink_interface()->connect(&peer_bd_addr);
         osi_alarm_free(app_alarm);
         app_alarm = NULL;
-        BTIF_SdpSearch(&peer_bd_addr, target_uuid);
     }
         break;
     default:
@@ -120,44 +128,6 @@ static void bt_stack_state_changed(bt_state_t state)
     }
 }
 
-static int bt_sdp_add_record(void)
-{
-    int handle;
-    bluetooth_sdp_sap_record sap_svr;
-    memset (&sap_svr, 0, sizeof(bluetooth_sdp_sap_record));
-    
-    sap_svr.hdr.type = SDP_TYPE_SAP_SERVER;
-    sap_svr.hdr.rfcomm_channel_number = 2;
-    sap_svr.hdr.service_name = "SIM ACCESS";
-    sap_svr.hdr.service_name_length = 10;
-    sap_svr.hdr.profile_version = 0x0100;
-
-    BTIF_SdpCreateRecord((bluetooth_sdp_record *)(&sap_svr), &handle);
-    return handle;
-}
-
-static void bt_sdp_search_complete(bt_status_t status, bt_bdaddr_t *bd_addr, uint8_t* uuid, int num_records, bluetooth_sdp_record *records)
-{
-    uint8_t *addr = bd_addr->address;
-    bluetooth_sdp_hdr_overlay *p = &records->mas.hdr;
-    LOG_ERROR("sdp search cmpl: st %d, bd_addr: %02x:%02x:%02x:%02x:%02x:%02x, records %d\n",
-              status, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], num_records);
-    if (p->service_name_length > 0) {
-        LOG_ERROR("service name: %s\n", p->service_name);
-    }
-    LOG_ERROR("rfc_chl_num %d, l2cap_psm %d, version %02x\n",
-             p->rfcomm_channel_number, p->l2cap_psm, p->profile_version);
-#if 0
-    uint8_t *addr = bd_addr->address;
-    bluetooth_sdp_hdr_overlay *p = &records->hdr;
-    LOG_ERROR("sdp search cmpl: st %d, bd_addr: %02x:%02x:%02x:%02x:%02x:%02x, records %d, len:%d\n",
-              status, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], num_records, p->user1_ptr_len);
-    if (p->service_name_length > 0) {
-        LOG_ERROR("service name: %s\n", p->service_name);
-    }
-#endif
-}
-
 void app_main_entry(void)
 {
     bt_status_t stat;
similarity index 95%
rename from examples/09_a2dp/components/bluedroid_demos/btif/btif_av.c
rename to examples/09_a2dp/components/bluedroid_demos/btif/btif_av.c.bak
index dd9575a73c3472f9d2777a566d3d185edaee8dfb..41eed003a81d9f77c0c2d31d5772680ab68b56ba 100755 (executable)
@@ -110,12 +110,12 @@ static TIMER_LIST_ENT tle_av_open_on_rc;
 #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 */
@@ -232,7 +232,7 @@ static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
     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;
@@ -240,7 +240,7 @@ static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
     }
     else
     {
-        BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
+        BTIF_TRACE_ERROR("%s No connected RC peers\n", __FUNCTION__);
     }
 }
 
@@ -278,7 +278,7 @@ static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_ad
 
 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)
@@ -331,7 +331,7 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
              * 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,
@@ -349,14 +349,14 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
 
         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;
 
@@ -377,7 +377,7 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
 
 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)
@@ -391,7 +391,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
             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;
@@ -401,7 +401,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
             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)
@@ -415,7 +415,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
             }
             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;
@@ -447,7 +447,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
             // 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),
@@ -460,13 +460,13 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
             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;
@@ -477,12 +477,12 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
             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;
             }
@@ -490,7 +490,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *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;
 
@@ -512,7 +512,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
 
 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)
@@ -562,7 +562,7 @@ static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *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;
    }
@@ -584,13 +584,13 @@ 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", __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;
     }
 
@@ -614,7 +614,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
 
         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))
@@ -628,7 +628,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
             {
                 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);
                 }
             }
@@ -692,7 +692,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
             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)
@@ -706,11 +706,11 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
             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);
             }
@@ -720,7 +720,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *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;
 
@@ -742,7 +742,7 @@ 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", __FUNCTION__,
+    BTIF_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__,
                      dump_av_sm_event_name(event), btif_av_cb.flags);
 
     switch (event)
@@ -815,7 +815,7 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data
 
         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 */
@@ -886,7 +886,7 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *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;
 
@@ -991,7 +991,7 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
              (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;
@@ -1009,7 +1009,7 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
             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);
         }
     }
 }
@@ -1057,7 +1057,7 @@ bt_status_t btif_av_init()
 
 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)
@@ -1078,7 +1078,7 @@ static bt_status_t init_src(btav_callbacks_t* callbacks)
 
 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)
@@ -1102,7 +1102,7 @@ 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", __FUNCTION__);
+    BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
 
     btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
 
@@ -1111,7 +1111,7 @@ static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
 
 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);
@@ -1119,7 +1119,7 @@ static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
 
 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);
@@ -1136,7 +1136,7 @@ static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
 *******************************************************************************/
 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
 {
-    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+    BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
 
     CHECK_BTAV_INIT();
 
@@ -1156,7 +1156,7 @@ static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
 *******************************************************************************/
 static void cleanup(void)
 {
-    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+    BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
 
     btif_a2dp_stop_media_task();
 
@@ -1171,7 +1171,7 @@ static void cleanup(void)
 }
 
 static void cleanup_src(void) {
-    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+    BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
 
     if (bt_av_src_callbacks)
     {
@@ -1182,7 +1182,7 @@ static void cleanup_src(void) {
 }
 
 static void cleanup_sink(void) {
-    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+    BTIF_TRACE_EVENT("%s\n", __FUNCTION__);
 
     if (bt_av_sink_callbacks)
     {
@@ -1237,7 +1237,7 @@ 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",
+    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 */
@@ -1268,7 +1268,7 @@ 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",
+    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 */
@@ -1366,7 +1366,7 @@ bt_status_t btif_av_sink_execute_service(BOOLEAN b_enable)
 *******************************************************************************/
 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;
 }
 
@@ -1381,7 +1381,7 @@ const btav_interface_t *btif_av_get_src_interface(void)
 *******************************************************************************/
 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;
 }
 
@@ -1414,7 +1414,7 @@ BOOLEAN btif_av_is_connected(void)
 *******************************************************************************/
 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;
@@ -1432,6 +1432,6 @@ BOOLEAN btif_av_is_peer_edr(void)
 ******************************************************************************/
 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;
 }
diff --git a/examples/09_a2dp/components/bluedroid_demos/btif/btif_avk.c b/examples/09_a2dp/components/bluedroid_demos/btif/btif_avk.c
new file mode 100755 (executable)
index 0000000..38916a1
--- /dev/null
@@ -0,0 +1,1364 @@
+/******************************************************************************
+ *
+ *  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;
+}
index 67a1ec1249da5fe3061ad9b53ae67b01b426a83b..9fa74792186e36d3c792ee67e59294eac3d91cc4 100755 (executable)
@@ -334,6 +334,14 @@ static fixed_queue_t *btif_media_cmd_msg_queue = NULL;
 static xTaskHandle  xBtifMediaTaskHandle = NULL;
 static QueueHandle_t xBtifMediaQueue = NULL;
 
+/*****************************************************************************
+ **  temporary hacked functions. TODO: port these functions or remove them?
+ *****************************************************************************/
+BOOLEAN btif_hf_is_call_idle(void)
+{
+    return FALSE;
+}
+
 /*****************************************************************************
  **  Misc helper functions
  *****************************************************************************/
index ccb2cfeb58b0ed029313ff1b0305eb7c5bff6253..8e88d76d83726fd23b0ad54f8d48082eca7faaf0 100755 (executable)
@@ -31,6 +31,7 @@
 #include "bta_api.h"
 #include "bta_av_api.h"
 #include "avrc_defs.h"
+#include "avrc_api.h"
 #include "gki.h"
 
 #define LOG_TAG "bt_btif_avrc"
@@ -206,11 +207,23 @@ static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL;
 extern BOOLEAN btif_hf_call_terminated_recently();
 extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
 
-
 /*****************************************************************************
 **  Functions
 ******************************************************************************/
 
+/*****************************************************************************
+ ** temporarily hacked functions. TODO: remove or port these functions
+ *****************************************************************************/
+BOOLEAN btif_hf_call_terminated_recently(void)
+{
+    return FALSE;
+}
+
+BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod)
+{
+    return FALSE;
+}
+
 /*****************************************************************************
 **   Local uinput helper functions
 ******************************************************************************/
index 9b0268fe6383f3b06584745de412c0e1fe97fe69..3260abf0ef720716f849999b18a9a6690f822378 100755 (executable)
@@ -19,8 +19,8 @@ COMPONENT_SRCDIRS :=  \
                        app_core                                \
                        app_project                             \
                        udrv/ulinux                             \
-                       embdrv/sbc/encoder                      \
-                       embdrv/sbc/decoder                      \
+                       embdrv/sbc/encoder/srce                 \
+                       embdrv/sbc/decoder/srce                 \
                        btif/co                                 \
                        btif