mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +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_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_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_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;
|
} 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.
|
* SEP index repeatedly will overwrite the old one.
|
||||||
* It is necessary to set BT_A2DP_USE_EXTERNAL_CODEC to y.
|
* 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.
|
* 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
|
* @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.
|
* SEP index repeatedly will overwrite the old one.
|
||||||
* It is necessary to set BT_A2DP_USE_EXTERNAL_CODEC to y.
|
* 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.
|
* 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
|
* @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;
|
tAVDT_CS cs;
|
||||||
char *p_service_name;
|
char *p_service_name;
|
||||||
tBTA_UTL_COD cod;
|
tBTA_UTL_COD cod;
|
||||||
#if (BTA_AV_EXT_CODEC == FALSE)
|
|
||||||
tBTA_AV_CODEC codec_type;
|
tBTA_AV_CODEC codec_type;
|
||||||
UINT8 index = 0;
|
UINT8 index = 0;
|
||||||
#endif
|
|
||||||
char p_avk_service_name[BTA_SERVICE_NAME_LEN + 1];
|
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);
|
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 */
|
/* keep the configuration in the stream control block */
|
||||||
memcpy(&p_scb->cfg, &cs.cfg, sizeof(tAVDT_CFG));
|
memcpy(&p_scb->cfg, &cs.cfg, sizeof(tAVDT_CFG));
|
||||||
#if (BTA_AV_EXT_CODEC == FALSE)
|
/*
|
||||||
while (index < BTA_AV_MAX_SEPS &&
|
* Create local SEPs:
|
||||||
(p_scb->p_cos->init)(index, &codec_type, cs.cfg.codec_info,
|
* - Internal codec: init() supplies SBC (typically one SEP).
|
||||||
&cs.cfg.num_protect, cs.cfg.protect_info, p_data->api_reg.tsep) == TRUE) {
|
* - 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 (BTA_AV_SINK_INCLUDED == TRUE)
|
||||||
if (p_data->api_reg.tsep == AVDT_TSEP_SNK) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!bta_av_cb.reg_audio) {
|
if (!bta_av_cb.reg_audio) {
|
||||||
if (p_data->api_reg.tsep == AVDT_TSEP_SRC) {
|
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,
|
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);
|
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
|
** 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 */
|
#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
|
** 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)
|
#if (BTC_AV_EXT_CODEC == TRUE)
|
||||||
UINT8 index;
|
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++) {
|
for (index = 0; index < BTA_AV_MAX_SEPS; index++) {
|
||||||
btc_av_cb.codec_caps[index].id = BTC_AV_CODEC_NONE;
|
/* A2DP mandates SBC: fill every SEID with the default SBC capability */
|
||||||
memset(btc_av_cb.codec_caps[index].info, 0, AVDT_CODEC_SIZE);
|
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
|
#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;
|
tBTA_AV_DATA_CBACK *p_data_cback = NULL;
|
||||||
esp_a2d_cb_param_t param;
|
esp_a2d_cb_param_t param;
|
||||||
tBTA_AV_CODEC codec_type = ESP_A2D_MCT_NON_A2DP;
|
tBTA_AV_CODEC codec_type = ESP_A2D_MCT_NON_A2DP;
|
||||||
|
UINT8 index;
|
||||||
|
|
||||||
param.a2d_sep_reg_stat.seid = seid;
|
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) {
|
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;
|
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) {
|
if (tsep == AVDT_TSEP_SNK) {
|
||||||
p_data_cback = bte_av_media_sink_callback;
|
p_data_cback = bte_av_media_sink_callback;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user