]> granicus.if.org Git - esp-idf/commitdiff
component/bt: bugfix that A2DP sink device can be connected by another A2DP sink...
authorwangmengyang <wangmengyang@espressif.com>
Tue, 4 Sep 2018 12:32:59 +0000 (20:32 +0800)
committerbot <bot@espressif.com>
Mon, 10 Sep 2018 03:35:58 +0000 (03:35 +0000)
In pevious implementation, A2DP sink will register an A2DP source Stream End Point(SEP) although the SEP is not\
supposed to be used. Now remove the unused SEP for source so that only one role of A2DP can be supported at one
time. Service record in local SDP server only includes at most one service for A2DP sink role or source

components/bt/bluedroid/bta/av/bta_av_aact.c
components/bt/bluedroid/bta/av/bta_av_api.c
components/bt/bluedroid/bta/av/bta_av_main.c
components/bt/bluedroid/bta/av/include/bta_av_int.h
components/bt/bluedroid/bta/include/bta/bta_av_api.h
components/bt/bluedroid/bta/include/bta/bta_av_co.h
components/bt/bluedroid/btc/core/btc_dm.c
components/bt/bluedroid/btc/profile/std/a2dp/bta_av_co.c
components/bt/bluedroid/btc/profile/std/a2dp/btc_av.c

index 9ac791c6fa21fb77f476e4f7a4a95bf549a70de5..06c5022b2bb76c259f478d3a736bb7f5410fc69f 100644 (file)
@@ -1544,6 +1544,17 @@ void bta_av_disc_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
     /* store number of stream endpoints returned */
     p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps;
 
+    UINT8 num_seps = (p_scb->num_seps < BTA_AV_NUM_SEPS) ? p_scb->num_seps : BTA_AV_NUM_SEPS;
+    memcpy(p_scb->sep_info, p_data->str_msg.msg.discover_cfm.p_sep_info, sizeof(tAVDT_SEP_INFO) * num_seps);
+    for (i = 0; i < p_data->str_msg.msg.discover_cfm.num_seps; i++) {
+        APPL_TRACE_DEBUG("peer sep %d, in use %d, seid %d, media type %d,  tsep %d",
+                           i,
+                           p_data->str_msg.msg.discover_cfm.p_sep_info[i].in_use,
+                           p_data->str_msg.msg.discover_cfm.p_sep_info[i].seid,
+                           p_data->str_msg.msg.discover_cfm.p_sep_info[i].media_type,
+                           p_data->str_msg.msg.discover_cfm.p_sep_info[i].tsep
+                           );
+    }
     for (i = 0; i < p_scb->num_seps; i++) {
         /* steam not in use, is a sink, and is audio */
         if ((p_scb->sep_info[i].in_use == FALSE) &&
@@ -1557,7 +1568,7 @@ void bta_av_disc_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
                     (uuid_int == UUID_SERVCLASS_AUDIO_SINK)) {
                 num_srcs++;
             }
-
+            APPL_TRACE_DEBUG("num srcs: %d, num_snks: %d\n", num_snks, num_srcs);
         }
     }
 
index 0a75551a0e84881ecae080e679affc127cf545ed..a0daa89f15a3ce14c0d35cd2e308472bc2825a6c 100644 (file)
@@ -105,7 +105,7 @@ void BTA_AvDisable(void)
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id, tBTA_AV_DATA_CBACK  *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos)
+void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id, tBTA_AV_DATA_CBACK  *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos, UINT8 tsep)
 {
     tBTA_AV_API_REG  *p_buf;
 
@@ -122,6 +122,7 @@ void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id,
         p_buf->app_id = app_id;
         p_buf->p_app_data_cback = p_data_cback;
         p_buf->bta_av_cos = bta_av_cos;
+        p_buf->tsep = tsep;
         bta_sys_sendmsg(p_buf);
     }
 }
index 8a376f58c60997943ec75c78530aa1330622c036..a72626b26a6541f2e58152af0a5e423bf1d8bc1f 100644 (file)
@@ -578,18 +578,20 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
             }
 
             /* Set the Capturing service class bit */
+            if (p_data->api_reg.tsep == AVDT_TSEP_SRC) {
+                cod.service = BTM_COD_SERVICE_CAPTURING;
+            } else {
 #if (BTA_AV_SINK_INCLUDED == TRUE)
-            cod.service = BTM_COD_SERVICE_CAPTURING | BTM_COD_SERVICE_RENDERING;
-#else
-            cod.service = BTM_COD_SERVICE_CAPTURING;
+                cod.service = BTM_COD_SERVICE_RENDERING;
 #endif
+            }
             utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
         } /* if 1st channel */
 
         /* get stream configuration and create stream */
         /* memset(&cs.cfg,0,sizeof(tAVDT_CFG)); */
         cs.cfg.num_codec = 1;
-        cs.tsep = AVDT_TSEP_SRC;
+        cs.tsep = p_data->api_reg.tsep;
 
         /*
          * memset of cs takes care setting call back pointers to null.
@@ -637,11 +639,10 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
             memcpy(&p_scb->cfg, &cs.cfg, sizeof(tAVDT_CFG));
             while (index < BTA_AV_MAX_SEPS &&
                     (p_scb->p_cos->init)(&codec_type, cs.cfg.codec_info,
-                                         &cs.cfg.num_protect, cs.cfg.protect_info, index) == TRUE) {
+                                         &cs.cfg.num_protect, cs.cfg.protect_info, p_data->api_reg.tsep) == TRUE) {
 
 #if (BTA_AV_SINK_INCLUDED == TRUE)
-                if (index == 1) {
-                    cs.tsep = AVDT_TSEP_SNK;
+                if (p_data->api_reg.tsep == AVDT_TSEP_SNK) {
                     cs.p_data_cback = bta_av_stream_data_cback;
                 }
                 APPL_TRACE_DEBUG(" SEP Type = %d\n", cs.tsep);
@@ -667,18 +668,20 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
             }
 
             if (!bta_av_cb.reg_audio) {
-                /* create the SDP records on the 1st audio channel */
-                bta_av_cb.sdp_a2d_handle = SDP_CreateRecord();
-                A2D_AddRecord(UUID_SERVCLASS_AUDIO_SOURCE, p_service_name, NULL,
-                              A2D_SUPF_PLAYER, bta_av_cb.sdp_a2d_handle);
-                bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
-
+                if (p_data->api_reg.tsep == AVDT_TSEP_SRC) {
+                    /* create the SDP records on the 1st audio channel */
+                    bta_av_cb.sdp_a2d_handle = SDP_CreateRecord();
+                    A2D_AddRecord(UUID_SERVCLASS_AUDIO_SOURCE, p_service_name, NULL,
+                                  A2D_SUPF_PLAYER, bta_av_cb.sdp_a2d_handle);
+                    bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
+                } else {
 #if (BTA_AV_SINK_INCLUDED == TRUE)
-                bta_av_cb.sdp_a2d_snk_handle = SDP_CreateRecord();
-                A2D_AddRecord(UUID_SERVCLASS_AUDIO_SINK, p_avk_service_name, NULL,
-                              A2D_SUPF_PLAYER, bta_av_cb.sdp_a2d_snk_handle);
-                bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SINK);
+                    bta_av_cb.sdp_a2d_snk_handle = SDP_CreateRecord();
+                    A2D_AddRecord(UUID_SERVCLASS_AUDIO_SINK, p_avk_service_name, NULL,
+                                  A2D_SUPF_PLAYER, bta_av_cb.sdp_a2d_snk_handle);
+                    bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SINK);
 #endif
+                }
                 /* start listening when A2DP is registered */
                 if (bta_av_cb.features & BTA_AV_FEAT_RCTG) {
                     bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
index 0c9da001c67a6c0e2e22ef812bb76820d202d4fa..7fc6643f9f229ca614e2ff557ef4e7349f6ee071 100644 (file)
@@ -158,44 +158,6 @@ enum {
 /*****************************************************************************
 **  Data types
 *****************************************************************************/
-#if 0
-/* function types for call-out functions */
-typedef BOOLEAN (*tBTA_AV_CO_INIT) (UINT8 *p_codec_type, UINT8 *p_codec_info,
-                                    UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
-typedef void (*tBTA_AV_CO_DISC_RES) (tBTA_AV_HNDL hndl, UINT8 num_seps,
-                                     UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local);
-typedef UINT8 (*tBTA_AV_CO_GETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
-                                    UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid,
-                                    UINT8 *p_num_protect, UINT8 *p_protect_info);
-typedef void (*tBTA_AV_CO_SETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
-                                   UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr,
-                                   UINT8 num_protect, UINT8 *p_protect_info,
-                                   UINT8 t_local_sep, UINT8 avdt_handle);
-typedef void (*tBTA_AV_CO_OPEN) (tBTA_AV_HNDL hndl,
-                                 tBTA_AV_CODEC codec_type, UINT8 *p_codec_info,
-                                 UINT16 mtu);
-typedef void (*tBTA_AV_CO_CLOSE) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT16 mtu);
-typedef void (*tBTA_AV_CO_START) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr);
-typedef void (*tBTA_AV_CO_STOP) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type);
-typedef void *(*tBTA_AV_CO_DATAPATH) (tBTA_AV_CODEC codec_type,
-                                      UINT32 *p_len, UINT32 *p_timestamp);
-typedef void (*tBTA_AV_CO_DELAY) (tBTA_AV_HNDL hndl, UINT16 delay);
-
-/* the call-out functions for one stream */
-typedef struct {
-    tBTA_AV_CO_INIT     init;
-    tBTA_AV_CO_DISC_RES disc_res;
-    tBTA_AV_CO_GETCFG   getcfg;
-    tBTA_AV_CO_SETCFG   setcfg;
-    tBTA_AV_CO_OPEN     open;
-    tBTA_AV_CO_CLOSE    close;
-    tBTA_AV_CO_START    start;
-    tBTA_AV_CO_STOP     stop;
-    tBTA_AV_CO_DATAPATH data;
-    tBTA_AV_CO_DELAY    delay;
-} tBTA_AV_CO_FUNCTS;
-#endif
-
 /* data type for BTA_AV_API_ENABLE_EVT */
 typedef struct {
     BT_HDR              hdr;
@@ -209,7 +171,8 @@ typedef struct {
     BT_HDR              hdr;
     char                p_service_name[BTA_SERVICE_NAME_LEN + 1];
     UINT8               app_id;
-    tBTA_AV_DATA_CBACK       *p_app_data_cback;
+    UINT8               tsep; // local SEP type
+    tBTA_AV_DATA_CBACK  *p_app_data_cback;
     tBTA_AV_CO_FUNCTS   *bta_av_cos;
 } tBTA_AV_API_REG;
 
index 6e70acf946a24014ebe5f3f4d5e18825b8b18c5c..87c2d374a456e7cf0476a302c6482d4114c23445 100644 (file)
@@ -98,7 +98,7 @@ typedef UINT8 tBTA_AV_HNDL;
 #endif
 
 #ifndef BTA_AV_MAX_SEPS
-#define BTA_AV_MAX_SEPS         2
+#define BTA_AV_MAX_SEPS         1
 #endif
 
 #ifndef BTA_AV_MAX_A2DP_MTU
@@ -259,7 +259,7 @@ typedef UINT8 tBTA_AV_ERR;
 
 /* function types for call-out functions */
 typedef BOOLEAN (*tBTA_AV_CO_INIT) (UINT8 *p_codec_type, UINT8 *p_codec_info,
-                                    UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
+                                    UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 tsep);
 typedef void (*tBTA_AV_CO_DISC_RES) (tBTA_AV_HNDL hndl, UINT8 num_seps,
                                      UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local);
 typedef UINT8 (*tBTA_AV_CO_GETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
@@ -580,7 +580,7 @@ void BTA_AvDisable(void);
 **
 *******************************************************************************/
 void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name,
-                    UINT8 app_id, tBTA_AV_DATA_CBACK  *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos);
+                    UINT8 app_id, tBTA_AV_DATA_CBACK  *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos, UINT8 tsep);
 
 /*******************************************************************************
 **
index 403b7a9217abeba35c0e7d6136ae4105944ef863..03c07c33f91d322a6f788a915260b207789c5403 100644 (file)
@@ -85,7 +85,7 @@ typedef struct {
 **
 *******************************************************************************/
 extern BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info,
-                                    UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
+                                    UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 tsep);
 
 /*******************************************************************************
 **
index afcc30013b3d8776c65375c63d771004d5bce141..9a0a3ee8158de4163a0a2833a87daa412dfcdc36 100644 (file)
@@ -54,7 +54,7 @@ static btc_dm_local_key_cb_t ble_local_key_cb;
 **  Externs
 ******************************************************************************/
 #if BTC_AV_INCLUDED
-extern bt_status_t btc_av_execute_service(BOOLEAN b_enable);
+extern bt_status_t btc_av_source_execute_service(BOOLEAN b_enable);
 extern bt_status_t btc_av_sink_execute_service(BOOLEAN b_enable);
 #endif
 #if BTC_HF_CLIENT_INCLUDED
@@ -488,7 +488,7 @@ static bt_status_t btc_in_execute_service_request(tBTA_SERVICE_ID service_id,
     switch (service_id) {
 #if BTC_AV_INCLUDED
     case BTA_A2DP_SOURCE_SERVICE_ID:
-        btc_av_execute_service(b_enable);
+        btc_av_source_execute_service(b_enable);
         break;
     case BTA_A2DP_SINK_SERVICE_ID:
         btc_av_sink_execute_service(b_enable);
index fc1f3e836fc596cf6f628009c47c4288914bcd92..2e72bd8cbaa771efffb59249850532ab2aacc29c 100644 (file)
@@ -267,11 +267,11 @@ static tBTA_AV_CO_PEER *bta_av_co_get_peer(tBTA_AV_HNDL hndl)
  **
  *******************************************************************************/
 BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info, UINT8 *p_num_protect,
-                             UINT8 *p_protect_info, UINT8 index)
+                             UINT8 *p_protect_info, UINT8 tsep)
 {
     FUNC_TRACE();
 
-    APPL_TRACE_DEBUG("bta_av_co_audio_init: %d", index);
+    APPL_TRACE_DEBUG("bta_av_co_audio_init: %d", tsep);
 
     /* By default - no content protection info */
     *p_num_protect = 0;
@@ -280,29 +280,24 @@ BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info, UINT8 *p_
     /* reset remote preference through setconfig */
     bta_av_co_cb.codec_cfg_setconfig.id = BTC_AV_CODEC_NONE;
 
-    switch (index) {
-    case BTC_SV_AV_AA_SBC_INDEX:
+    if (tsep == AVDT_TSEP_SRC) {
 #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
-    {
-        UINT8 *p = p_protect_info;
-
-        /* Content protection info - support SCMS-T */
-        *p_num_protect = 1;
-        *p++ = BTA_AV_CP_LOSC;
-        UINT16_TO_STREAM(p, BTA_AV_CP_SCMS_T_ID);
-
-    }
+        do {
+            UINT8 *p = p_protect_info;
+
+            /* Content protection info - support SCMS-T */
+            *p_num_protect = 1;
+            *p++ = BTA_AV_CP_LOSC;
+            UINT16_TO_STREAM(p, BTA_AV_CP_SCMS_T_ID);
+        } while (0);
 #endif
         /* Set up for SBC codec  for SRC*/
-    *p_codec_type = BTA_AV_CODEC_SBC;
+        *p_codec_type = BTA_AV_CODEC_SBC;
 
         /* This should not fail because we are using constants for parameters */
-    A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &bta_av_co_sbc_caps, p_codec_info);
-
-        /* Codec is valid */
-    return TRUE;
-#if (BTA_AV_SINK_INCLUDED == TRUE)
-    case BTC_SV_AV_AA_SBC_SINK_INDEX:
+        A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &bta_av_co_sbc_caps, p_codec_info);
+        return TRUE;
+    } else if (tsep == AVDT_TSEP_SNK) {
         *p_codec_type = BTA_AV_CODEC_SBC;
 
         /* This should not fail because we are using constants for parameters */
@@ -310,9 +305,8 @@ BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info, UINT8 *p_
 
         /* Codec is valid */
         return TRUE;
-#endif
-    default:
-        /* Not valid */
+    } else {
+        APPL_TRACE_WARNING("invalid SEP type %d", tsep);
         return FALSE;
     }
 }
index 2911a0d7cec5c104a9772673e343ca345d5ab426..27842f3d3f88188b6c2f5ca1245ae5e54284420f 100644 (file)
@@ -315,8 +315,10 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data)
                        TRUE, BTA_SEC_AUTHENTICATE, ((btc_av_connect_req_t *)p_data)->uuid);
         } else if (event == BTA_AV_PENDING_EVT) {
             bdcpy(btc_av_cb.peer_bda.address, ((tBTA_AV *)p_data)->pend.bd_addr);
+            UINT16 uuid = (btc_av_cb.service_id == BTA_A2DP_SOURCE_SERVICE_ID) ? UUID_SERVCLASS_AUDIO_SOURCE :
+                UUID_SERVCLASS_AUDIO_SINK;
             BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle,
-                       TRUE, BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SOURCE);
+                       TRUE, BTA_SEC_AUTHENTICATE, uuid);
         }
         btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENING);
     } break;
@@ -402,8 +404,8 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
         tBTA_AV *p_bta_data = (tBTA_AV *)p_data;
         esp_a2d_connection_state_t state;
         btc_sm_state_t av_state;
-        BTC_TRACE_DEBUG("status:%d, edr 0x%x\n", p_bta_data->open.status,
-                  p_bta_data->open.edr);
+        BTC_TRACE_DEBUG("status:%d, edr 0x%x, peer sep %d\n", p_bta_data->open.status,
+                        p_bta_data->open.edr, p_bta_data->open.sep);
 
         if (p_bta_data->open.status == BTA_AV_SUCCESS) {
             state = ESP_A2D_CONNECTION_STATE_CONNECTED;
@@ -978,10 +980,10 @@ static bt_status_t btc_av_init(int service_id)
         btc_av_cb.sm_handle =
             btc_sm_init((const btc_sm_handler_t *)btc_av_state_handlers, BTC_AV_STATE_IDLE);
 
-        btc_dm_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
-
         if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
             btc_dm_enable_service(BTA_A2DP_SINK_SERVICE_ID);
+        } else {
+            btc_dm_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
         }
 
         btc_a2dp_on_init();
@@ -1213,7 +1215,7 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
 **
 *******************************************************************************/
-bt_status_t btc_av_execute_service(BOOLEAN b_enable)
+bt_status_t btc_av_execute_service(BOOLEAN b_enable, UINT8 tsep)
 {
     if (b_enable) {
         /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
@@ -1227,7 +1229,7 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable)
                      | BTA_AV_FEAT_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR
                      | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL,
                      bte_av_callback);
-        BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos);
+        BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, tsep);
     } else {
         BTA_AvDeregister(btc_av_cb.bta_handle);
         BTA_AvDisable();
@@ -1235,6 +1237,20 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable)
     return BT_STATUS_SUCCESS;
 }
 
+/*******************************************************************************
+**
+** Function         btc_av_source_execute_service
+**
+** Description      Initializes/Shuts down the A2DP source service
+**
+** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btc_av_source_execute_service(BOOLEAN b_enable)
+{
+    return btc_av_execute_service(b_enable, AVDT_TSEP_SRC);
+}
+
 /*******************************************************************************
 **
 ** Function         btc_av_sink_execute_service
@@ -1246,6 +1262,10 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable)
 *******************************************************************************/
 bt_status_t btc_av_sink_execute_service(BOOLEAN b_enable)
 {
+    bt_status_t ret = btc_av_execute_service(b_enable, AVDT_TSEP_SNK);
+    if (ret != BT_STATUS_SUCCESS) {
+        return ret;
+    }
 #if (BTA_AV_SINK_INCLUDED == TRUE)
     BTA_AvEnable_Sink(b_enable);
 #endif