Merge branch 'feat/set_encoder_params_v5.3' into 'release/v5.3'

fix(bt/bluedroid): Handle stream reconfiguration via stream close and re-open for A2DP ACP(v5.3)

See merge request espressif/esp-idf!45467
This commit is contained in:
Wang Meng Yang
2026-02-03 13:42:53 +08:00
5 changed files with 47 additions and 10 deletions
@@ -468,6 +468,10 @@ static void bta_av_proc_stream_evt(UINT8 handle, BD_ADDR bd_addr, UINT8 event, t
* from the 2nd SEP. */
if ((bta_av_find_lcb(bd_addr, BTA_AV_LCB_FIND) != NULL) && (bta_av_is_scb_init(p_scb))) {
bta_av_set_scb_sst_incoming (p_scb);
/* Mark this forced switch so we can notify upper layers (BTC) from BTA thread
* when handling STR_CONFIG_IND_EVT. */
p_scb->force_incoming = TRUE;
APPL_TRACE_DEBUG("change state to incoming");
/* When ACP_CONNECT_EVT was received, we put first available scb to incoming state.
* Later when we receive AVDT_CONFIG_IND_EVT, we use a new p_scb and set its state to
@@ -1114,6 +1118,16 @@ void bta_av_config_ind (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
tBTA_AV_STR_MSG *p_msg = (tBTA_AV_STR_MSG *)p_data;
UNUSED(p_data);
/* If stream SSM was force-switched to INCOMING due to CONFIG_IND while in INIT,
* notify upper layers early so BTC can move to OPENING and handle upcoming config/open events. */
if (p_scb->force_incoming) {
tBTA_AV evt;
memset(&evt, 0, sizeof(evt));
bdcpy(evt.incoming.bd_addr, p_data->str_msg.bd_addr);
(*bta_av_cb.p_cback)(BTA_AV_INCOMING_CFG_EVT, &evt);
p_scb->force_incoming = FALSE;
}
local_sep = bta_av_get_scb_sep_type(p_scb, p_msg->handle);
p_scb->avdt_label = p_data->str_msg.msg.hdr.label;
memcpy(p_scb->cfg.codec_info, p_evt_cfg->codec_info, AVDT_CODEC_SIZE);
@@ -405,8 +405,8 @@ typedef union {
#define BTA_AV_Q_TAG_START 0x02 /* before start sending media packets */
#define BTA_AV_Q_TAG_STREAM 0x03 /* during streaming */
#define BTA_AV_WAIT_ACP_CAPS_ON 0x01 /* retriving the peer capabilities */
#define BTA_AV_WAIT_ACP_CAPS_STARTED 0x02 /* started while retriving peer capabilities */
#define BTA_AV_WAIT_ACP_CAPS_ON 0x01 /* retrieving the peer capabilities */
#define BTA_AV_WAIT_ACP_CAPS_STARTED 0x02 /* started while retrieving peer capabilities */
#define BTA_AV_WAIT_ROLE_SW_RES_OPEN 0x04 /* waiting for role switch result after API_OPEN, before STR_OPENED */
#define BTA_AV_WAIT_ROLE_SW_RES_START 0x08 /* waiting for role switch result before streaming */
#define BTA_AV_WAIT_ROLE_SW_STARTED 0x10 /* started while waiting for role switch result */
@@ -462,7 +462,7 @@ typedef struct {
BOOLEAN use_rc; /* TRUE if AVRCP is allowed */
BOOLEAN started; /* TRUE if stream started */
UINT8 co_started; /* non-zero, if stream started from call-out perspective */
BOOLEAN recfg_sup; /* TRUE if the first attempt to reconfigure the stream was successfull, else False if command fails */
BOOLEAN recfg_sup; /* TRUE if the first attempt to reconfigure the stream was successful, else False if command fails */
BOOLEAN suspend_sup; /* TRUE if Suspend stream is supported, else FALSE if suspend command fails */
BOOLEAN deregistring; /* TRUE if deregistering */
BOOLEAN sco_suspend; /* TRUE if SUSPEND is issued automatically for SCO */
@@ -471,8 +471,9 @@ typedef struct {
UINT8 wait; /* set 0x1, when getting Caps as ACP, set 0x2, when started */
UINT8 q_tag; /* identify the associated q_info union member */
BOOLEAN no_rtp_hdr; /* TRUE if add no RTP header*/
UINT8 disc_rsn; /* disconenction reason */
UINT8 disc_rsn; /* disconnection reason */
UINT16 uuid_int; /*intended UUID of Initiator to connect to */
BOOLEAN force_incoming; /* TRUE if stream SSM state is force-switched to INCOMING due to CONFIG_IND while in INIT, else FALSE */
} tBTA_AV_SCB;
#define BTA_AV_RC_ROLE_MASK 0x10
@@ -253,8 +253,14 @@ typedef UINT8 tBTA_AV_ERR;
#define BTA_AV_SET_DELAY_VALUE_EVT 22 /* set delay reporting value */
#define BTA_AV_GET_DELAY_VALUE_EVT 23 /* get delay reporting value */
#define BTA_AV_SNK_PSC_CFG_EVT 24 /* Protocol service capabilities. */
/* Incoming stream configuration indication received while local stream SSM is in INIT state.
* This is used to notify upper layers (BTC) that the stream state was force-switched to INCOMING
* to handle the new signalling/configuration. */
#define BTA_AV_INCOMING_CFG_EVT 25
/* Max BTA event */
#define BTA_AV_MAX_EVT 25
#define BTA_AV_MAX_EVT 26
/* function types for call-out functions */
@@ -481,6 +487,10 @@ typedef struct {
UINT16 psc_mask;
} tBTA_AV_SNK_PSC_CFG;
/* data associated with BTA_AV_INCOMING_CFG_EVT */
typedef struct {
BD_ADDR bd_addr;
} tBTA_AV_INCOMING;
/* union of data associated with AV callback */
typedef union {
@@ -506,6 +516,7 @@ typedef union {
tBTA_AV_RC_FEAT rc_feat;
tBTA_AV_DELAY delay;
tBTA_AV_SNK_PSC_CFG psc;
tBTA_AV_INCOMING incoming;
} tBTA_AV;
/* union of data associated with AV Media callback */
@@ -387,7 +387,7 @@ void bta_av_build_src_cfg (UINT8 *p_pref_cfg, UINT8 *p_src_cap)
/* now try to build a preferred one */
/* parse configuration */
if ((status = A2D_ParsSbcInfo(&src_cap, p_src_cap, TRUE)) != 0) {
APPL_TRACE_DEBUG(" Cant parse src cap ret = %d", status);
APPL_TRACE_DEBUG(" Can't parse src cap ret = %d", status);
return ;
}
@@ -1100,8 +1100,8 @@ static BOOLEAN bta_av_co_audio_codec_cfg_matches_caps(UINT8 codec_id, const UINT
p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]);
/* Must match all items exactly except bitpool boundaries which can be adjusted */
if (!((p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF] & p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF]) &&
(p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF] & p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF]))) {
if ((~p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF] & p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF]) ||
(~p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF] & p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF])) {
APPL_TRACE_EVENT("FALSE %x %x %x %x",
p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF],
p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF],
@@ -1729,7 +1729,7 @@ BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl)
** of our exported bitpool range. If set we will set the
** remote preference.
**
** Returns TRUE if config set, FALSE otherwize
** Returns TRUE if config set, FALSE otherwise
**
*******************************************************************************/
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -212,6 +212,7 @@ UNUSED_ATTR static const char *dump_av_sm_event_name(btc_av_sm_event_t event)
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_INCOMING_CFG_EVT)
CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
CASE_RETURN_STR(BTA_AV_REJECT_EVT)
CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
@@ -357,6 +358,16 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data)
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENING);
} break;
case BTA_AV_INCOMING_CFG_EVT: {
/* Upper layer notification that incoming CONFIG_IND was received while stream SSM was in INIT
* and BTA force-switched to INCOMING. BTC should move to OPENING so upcoming CONFIG/OPEN/START
* can be handled in the correct state, but MUST NOT call BTA_AvOpen() here to avoid
* restarting discovery/open procedure while config is already in progress. */
bdcpy(btc_av_cb.peer_bda.address, ((tBTA_AV *)p_data)->incoming.bd_addr);
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENING);
break;
}
case BTC_AV_DISCONNECT_REQ_EVT:
BTC_TRACE_WARNING("No Link At All.");
btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &((btc_av_disconn_req_t *)p_data)->target_bda, 0);