diff --git a/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h b/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h index cfff2f6646c..5f1d801931a 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h @@ -242,6 +242,7 @@ typedef enum { ESP_A2D_SNK_SET_DELAY_VALUE_EVT, /*!< indicate a2dp sink set delay report value complete, only used for A2DP SINK */ ESP_A2D_SNK_GET_DELAY_VALUE_EVT, /*!< indicate a2dp sink get delay report value complete, only used for A2DP SINK */ ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT, /*!< report delay value, only used for A2DP SRC */ + ESP_A2D_REPORT_SNK_CODEC_CAPS_EVT, /*!< report sink codec capabilities, only used for A2DP SRC */ } esp_a2d_cb_event_t; /** @@ -340,6 +341,14 @@ typedef union { uint16_t delay_value; /*!< delay report value */ } a2d_report_delay_value_stat; /*!< A2DP source received sink report value status */ + /** + * @brief ESP_A2D_REPORT_SNK_CODEC_CAPS_EVT + */ + struct a2d_report_snk_codec_caps_param { + esp_a2d_conn_hdl_t conn_hdl; /*!< connection handle */ + esp_a2d_mcc_t mcc; /*!< A2DP sink media codec capability information */ + } a2d_report_snk_codec_caps_stat; /*!< A2DP source received sink codec capabilities */ + } esp_a2d_cb_param_t; /** diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c index e237c8363c5..a5733c3547a 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c @@ -1780,6 +1780,50 @@ BOOLEAN bta_av_co_get_remote_bitpool_pref(UINT8 *min, UINT8 *max) return TRUE; } +/******************************************************************************* + ** + ** Function bta_av_co_get_peer_sink_caps + ** + ** Description Get the sink codec capabilities of the peer + ** + ** Returns TRUE if sink capabilities are available, FALSE otherwise + ** + *******************************************************************************/ +BOOLEAN bta_av_co_get_peer_sink_caps(tBTA_AV_HNDL hndl, UINT8 *p_codec_caps, UINT8 *p_codec_type) +{ + tBTA_AV_CO_PEER *p_peer; + tBTA_AV_CO_SINK *p_sink; + + FUNC_TRACE(); + + /* Find the peer info */ + p_peer = bta_av_co_get_peer(hndl); + if (p_peer == NULL) { + APPL_TRACE_ERROR("bta_av_co_get_peer_sink_caps could not find peer entry"); + return FALSE; + } + + /* Check if we have a selected sink */ + if (p_peer->p_snk == NULL) { + APPL_TRACE_ERROR("bta_av_co_get_peer_sink_caps no sink selected"); + return FALSE; + } + + p_sink = p_peer->p_snk; + + /* Copy the codec capabilities */ + if (p_codec_caps) { + memcpy(p_codec_caps, p_sink->codec_caps, AVDT_CODEC_SIZE); + } + + /* Copy the codec type */ + if (p_codec_type) { + *p_codec_type = p_sink->codec_type; + } + + return TRUE; +} + /* the call out functions for audio stream */ const tBTA_AV_CO_FUNCTS bta_av_a2d_cos = { bta_av_co_audio_init, diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c index e52102a845f..2f756a1d040 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c @@ -522,6 +522,30 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) } else { BTC_TRACE_WARNING("AVRC not Init, not using it."); } + } else if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) { + /* For A2DP source, report sink codec capabilities after connection established */ + UINT8 codec_caps[AVDT_CODEC_SIZE]; + UINT8 codec_type; + + if (bta_av_co_get_peer_sink_caps(btc_av_cb.bta_handle, codec_caps, &codec_type)) { + switch (codec_type) { + /* Currently only supports SBC */ + case BTA_AV_CODEC_SBC: { + param.a2d_report_snk_codec_caps_stat.conn_hdl = btc_av_cb.bta_handle; + param.a2d_report_snk_codec_caps_stat.mcc.type = ESP_A2D_MCT_SBC; + memcpy(¶m.a2d_report_snk_codec_caps_stat.mcc.cie, (uint8_t *)codec_caps + BTC_AV_SBC_CIE_OFFSET, BTC_AV_SBC_CIE_LEN); + btc_a2d_cb_to_app(ESP_A2D_REPORT_SNK_CODEC_CAPS_EVT, ¶m); + break; + } + + default: { + BTC_TRACE_WARNING("Unsupported codec type %d", codec_type); + break; + } + } + } else { + BTC_TRACE_WARNING("No sink capabilities available yet"); + } } } btc_queue_advance(); diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h b/components/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h index 9a4f6280d80..80bf92b7ec2 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/include/btc_av_co.h @@ -216,6 +216,17 @@ BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl); *******************************************************************************/ BOOLEAN bta_av_co_get_remote_bitpool_pref(UINT8 *min, UINT8 *max); +/******************************************************************************* + ** + ** Function bta_av_co_get_peer_sink_caps + ** + ** Description Get the sink codec capabilities of the peer + ** + ** Returns TRUE if sink capabilities are available, FALSE otherwise + ** + *******************************************************************************/ +BOOLEAN bta_av_co_get_peer_sink_caps(tBTA_AV_HNDL hndl, UINT8 *p_codec_caps, UINT8 *p_codec_type); + #endif ///BTA_AV_INCLUDED == TRUE #endif