mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
feat: Add default SBC SEP in A2DP init
This commit is contained in:
@@ -257,6 +257,7 @@ typedef enum {
|
||||
ESP_A2D_SEP_REG_FAIL, /*!< A2DP stream endpoint register generic fail */
|
||||
ESP_A2D_SEP_REG_UNSUPPORTED, /*!< A2DP stream endpoint register fail, unsupported codec type or param */
|
||||
ESP_A2D_SEP_REG_INVALID_STATE, /*!< A2DP stream endpoint register fail, invalid state */
|
||||
ESP_A2D_SEP_REG_SBC_REQUIRED, /*!< A2DP stream endpoint register fail, at least one SBC SEP must remain */
|
||||
} esp_a2d_sep_reg_state_t;
|
||||
|
||||
/**
|
||||
@@ -511,7 +512,11 @@ esp_err_t esp_a2d_sink_init(void);
|
||||
* SEP index repeatedly will overwrite the old one.
|
||||
* It is necessary to set BT_A2DP_USE_EXTERNAL_CODEC to y.
|
||||
*
|
||||
* @note The SEID determines the priority of negotiating the configuration with the peer for initiator.
|
||||
* @note After A2DP sink init, every SEID is pre-registered with the mandatory default SBC SEP.
|
||||
* Calling this API overwrites that SEID. A2DP requires at least one SBC SEP; registering a
|
||||
* non-SBC codec that would overwrite the last SBC SEP fails with ESP_A2D_SEP_REG_SBC_REQUIRED.
|
||||
* Therefore using AAC (or other non-SBC codecs) requires ESP_A2D_MAX_SEPS >= 2.
|
||||
* The SEID determines the priority of negotiating the configuration with the peer for initiator.
|
||||
* The lower the SEID, the higher the priority of the codec capability.
|
||||
*
|
||||
* @param[in] seid: local SEP identifier, start from 0, less than ESP_A2D_MAX_SEPS
|
||||
@@ -667,7 +672,11 @@ esp_err_t esp_a2d_source_set_pref_mcc(esp_a2d_conn_hdl_t conn_hdl, const esp_a2d
|
||||
* SEP index repeatedly will overwrite the old one.
|
||||
* It is necessary to set BT_A2DP_USE_EXTERNAL_CODEC to y.
|
||||
*
|
||||
* @note The SEID determines the priority of negotiating the configuration with the peer for initiator.
|
||||
* @note After A2DP source init, every SEID is pre-registered with the mandatory default SBC SEP.
|
||||
* Calling this API overwrites that SEID. A2DP requires at least one SBC SEP; registering a
|
||||
* non-SBC codec that would overwrite the last SBC SEP fails with ESP_A2D_SEP_REG_SBC_REQUIRED.
|
||||
* Therefore using AAC (or other non-SBC codecs) requires ESP_A2D_MAX_SEPS >= 2.
|
||||
* The SEID determines the priority of negotiating the configuration with the peer for initiator.
|
||||
* The lower the SEID, the higher the priority of the codec capability.
|
||||
*
|
||||
* @param[in] seid: local SEP identifier, start from 0, less than ESP_A2D_MAX_SEPS
|
||||
|
||||
@@ -542,10 +542,8 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
|
||||
tAVDT_CS cs;
|
||||
char *p_service_name;
|
||||
tBTA_UTL_COD cod;
|
||||
#if (BTA_AV_EXT_CODEC == FALSE)
|
||||
tBTA_AV_CODEC codec_type;
|
||||
UINT8 index = 0;
|
||||
#endif
|
||||
char p_avk_service_name[BTA_SERVICE_NAME_LEN + 1];
|
||||
BCM_STRLCPY_S(p_avk_service_name, BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN + 1);
|
||||
|
||||
@@ -667,10 +665,25 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
|
||||
|
||||
/* keep the configuration in the stream control block */
|
||||
memcpy(&p_scb->cfg, &cs.cfg, sizeof(tAVDT_CFG));
|
||||
#if (BTA_AV_EXT_CODEC == FALSE)
|
||||
while (index < BTA_AV_MAX_SEPS &&
|
||||
(p_scb->p_cos->init)(index, &codec_type, cs.cfg.codec_info,
|
||||
&cs.cfg.num_protect, cs.cfg.protect_info, p_data->api_reg.tsep) == TRUE) {
|
||||
/*
|
||||
* Create local SEPs:
|
||||
* - Internal codec: init() supplies SBC (typically one SEP).
|
||||
* - External codec: A2DP mandates SBC, so pre-fill every SEID with
|
||||
* the default SBC SEP; app register_stream_endpoint() may overwrite.
|
||||
*/
|
||||
while (index < BTA_AV_MAX_SEPS) {
|
||||
#if (BTA_AV_EXT_CODEC == TRUE)
|
||||
if (bta_av_co_audio_build_sbc_default(p_data->api_reg.tsep, &codec_type,
|
||||
cs.cfg.codec_info) != TRUE) {
|
||||
APPL_TRACE_ERROR("failed to build default SBC SEP for seid %d", index);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if ((p_scb->p_cos->init)(index, &codec_type, cs.cfg.codec_info,
|
||||
&cs.cfg.num_protect, cs.cfg.protect_info,
|
||||
p_data->api_reg.tsep) != TRUE) {
|
||||
break;
|
||||
}
|
||||
|
||||
#if (BTA_AV_SINK_INCLUDED == TRUE)
|
||||
if (p_data->api_reg.tsep == AVDT_TSEP_SNK) {
|
||||
@@ -698,7 +711,6 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!bta_av_cb.reg_audio) {
|
||||
if (p_data->api_reg.tsep == AVDT_TSEP_SRC) {
|
||||
|
||||
@@ -87,6 +87,19 @@ typedef struct {
|
||||
extern BOOLEAN bta_av_co_audio_init(UINT8 seid, UINT8 *p_codec_type, UINT8 *p_codec_info,
|
||||
UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 tsep);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_co_audio_build_sbc_default
|
||||
**
|
||||
** Description Build the mandatory default SBC codec capability for the
|
||||
** given SEP type (source or sink).
|
||||
**
|
||||
** Returns TRUE if built successfully, FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN bta_av_co_audio_build_sbc_default(UINT8 tsep, UINT8 *p_codec_type,
|
||||
UINT8 *p_codec_info);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_co_audio_disc_res
|
||||
|
||||
@@ -298,6 +298,37 @@ static void bta_av_co_report_peer_all_snk_codec_caps(tBTA_AV_HNDL hndl)
|
||||
}
|
||||
#endif /* BTC_AV_SRC_INCLUDED */
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_co_audio_build_sbc_default
|
||||
**
|
||||
** Description Build the mandatory default SBC codec capability for the
|
||||
** given SEP type (source or sink).
|
||||
**
|
||||
** Returns TRUE if built successfully, FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_av_co_audio_build_sbc_default(UINT8 tsep, UINT8 *p_codec_type, UINT8 *p_codec_info)
|
||||
{
|
||||
FUNC_TRACE();
|
||||
|
||||
if (p_codec_type == NULL || p_codec_info == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*p_codec_type = BTA_AV_CODEC_SBC;
|
||||
if (tsep == AVDT_TSEP_SRC) {
|
||||
return (A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *)&bta_av_co_sbc_caps,
|
||||
p_codec_info) == A2D_SUCCESS);
|
||||
} else if (tsep == AVDT_TSEP_SNK) {
|
||||
return (A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *)&bta_av_co_sbc_sink_caps,
|
||||
p_codec_info) == A2D_SUCCESS);
|
||||
}
|
||||
|
||||
APPL_TRACE_WARNING("bta_av_co_audio_build_sbc_default invalid SEP type %d", tsep);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_co_audio_init
|
||||
|
||||
@@ -1242,9 +1242,15 @@ static bt_status_t btc_av_init(int service_id)
|
||||
|
||||
#if (BTC_AV_EXT_CODEC == TRUE)
|
||||
UINT8 index;
|
||||
UINT8 tsep = (service_id == BTA_A2DP_SINK_SERVICE_ID) ? AVDT_TSEP_SNK : AVDT_TSEP_SRC;
|
||||
for (index = 0; index < BTA_AV_MAX_SEPS; index++) {
|
||||
btc_av_cb.codec_caps[index].id = BTC_AV_CODEC_NONE;
|
||||
memset(btc_av_cb.codec_caps[index].info, 0, AVDT_CODEC_SIZE);
|
||||
/* A2DP mandates SBC: fill every SEID with the default SBC capability */
|
||||
if (bta_av_co_audio_build_sbc_default(tsep, &btc_av_cb.codec_caps[index].id,
|
||||
btc_av_cb.codec_caps[index].info) != TRUE) {
|
||||
BTC_TRACE_ERROR("%s: failed to build default SBC for seid %d", __func__, index);
|
||||
btc_av_cb.codec_caps[index].id = BTC_AV_CODEC_NONE;
|
||||
memset(btc_av_cb.codec_caps[index].info, 0, AVDT_CODEC_SIZE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1629,6 +1635,7 @@ static void btc_av_reg_sep(uint8_t tsep, uint8_t seid, esp_a2d_mcc_t *mcc)
|
||||
tBTA_AV_DATA_CBACK *p_data_cback = NULL;
|
||||
esp_a2d_cb_param_t param;
|
||||
tBTA_AV_CODEC codec_type = ESP_A2D_MCT_NON_A2DP;
|
||||
UINT8 index;
|
||||
|
||||
param.a2d_sep_reg_stat.seid = seid;
|
||||
if (btc_av_cb.sm_handle == NULL || btc_sm_get_state(btc_av_cb.sm_handle) != BTC_AV_STATE_IDLE) {
|
||||
@@ -1638,6 +1645,27 @@ static void btc_av_reg_sep(uint8_t tsep, uint8_t seid, esp_a2d_mcc_t *mcc)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* A2DP requires at least one SBC SEP. Reject a non-SBC registration that
|
||||
* would overwrite the last remaining SBC capability.
|
||||
*/
|
||||
if (mcc->type != ESP_A2D_MCT_SBC) {
|
||||
BOOLEAN has_other_sbc = FALSE;
|
||||
for (index = 0; index < BTA_AV_MAX_SEPS; index++) {
|
||||
if (index != seid && btc_av_cb.codec_caps[index].id == BTC_AV_CODEC_SBC) {
|
||||
has_other_sbc = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_other_sbc) {
|
||||
param.a2d_sep_reg_stat.reg_state = ESP_A2D_SEP_REG_SBC_REQUIRED;
|
||||
btc_a2d_cb_to_app(ESP_A2D_SEP_REG_STATE_EVT, ¶m);
|
||||
BTC_TRACE_WARNING("%s: refuse seid %d codec 0x%02x, at least one SBC SEP is required",
|
||||
__func__, seid, mcc->type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (tsep == AVDT_TSEP_SNK) {
|
||||
p_data_cback = bte_av_media_sink_callback;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user