Skip to content

Commit 683ddf8

Browse files
committed
Merge branch 'bugfix/a2dp_deinit_crash' into 'master'
fix(bt): fixed crash caused by deinit during A2DP connection initiation Closes IDFCI-3092, BT-4158, BTQABR2023-617, IDFCI-6268, and BT-4134 See merge request espressif/esp-idf!43534
2 parents 862f000 + 86975e6 commit 683ddf8

File tree

1 file changed

+43
-31
lines changed
  • components/bt/host/bluedroid/btc/profile/std/a2dp

1 file changed

+43
-31
lines changed

components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *data);
148148
static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *data);
149149
static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *data);
150150
static void clean_up(int service_id);
151+
static BOOLEAN btc_a2d_deinit_if_ongoing(void);
151152

152153
#if BTC_AV_SRC_INCLUDED
153154
static bt_status_t btc_a2d_src_init(void);
@@ -332,11 +333,13 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data)
332333

333334
switch (event) {
334335
case BTC_SM_ENTER_EVT:
335-
/* clear the peer_bda */
336-
memset(&btc_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
337-
btc_av_cb.flags = 0;
338-
btc_av_cb.edr = 0;
339-
btc_a2dp_on_idle();
336+
if (btc_a2d_deinit_if_ongoing() == FALSE) {
337+
/* clear the peer_bda */
338+
memset(&btc_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
339+
btc_av_cb.flags = 0;
340+
btc_av_cb.edr = 0;
341+
btc_a2dp_on_idle();
342+
}
340343
break;
341344

342345
case BTC_SM_EXIT_EVT:
@@ -511,22 +514,18 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
511514
/* change state to open/idle based on the status */
512515
btc_sm_change_state(btc_av_cb.sm_handle, av_state);
513516

514-
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
515-
/* if queued PLAY command, send it now */
516-
/* necessary to add this?
517-
btc_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
518-
(p_bta_data->open.status == BTA_AV_SUCCESS));
519-
*/
520-
} else if (btc_av_cb.peer_sep == AVDT_TSEP_SRC &&
521-
(p_bta_data->open.status == BTA_AV_SUCCESS)) {
522-
/* Bring up AVRCP connection too if AVRC Initialized */
523-
if(g_av_with_rc) {
524-
BTA_AvOpenRc(btc_av_cb.bta_handle);
525-
} else {
526-
BTC_TRACE_WARNING("AVRC not Init, not using it.");
517+
if (p_bta_data->open.status == BTA_AV_SUCCESS && !btc_a2d_deinit_if_ongoing()) {
518+
if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
519+
/* Bring up AVRCP connection too if AVRC Initialized */
520+
if(g_av_with_rc) {
521+
BTA_AvOpenRc(btc_av_cb.bta_handle);
522+
} else {
523+
BTC_TRACE_WARNING("AVRC not Init, not using it.");
524+
}
527525
}
528526
}
529527
btc_queue_advance();
528+
530529
} break;
531530

532531
case BTC_AV_CONFIG_EVT: {
@@ -805,12 +804,6 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
805804

806805
/* change state to idle, send acknowledgement if start is pending */
807806
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
808-
809-
if (g_a2dp_source_ongoing_deinit) {
810-
clean_up(BTA_A2DP_SOURCE_SERVICE_ID);
811-
} else if (g_a2dp_sink_ongoing_deinit) {
812-
clean_up(BTA_A2DP_SINK_SERVICE_ID);
813-
}
814807
break;
815808
}
816809

@@ -1014,11 +1007,6 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
10141007
close->disc_rsn);
10151008
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
10161009

1017-
if (g_a2dp_source_ongoing_deinit) {
1018-
clean_up(BTA_A2DP_SOURCE_SERVICE_ID);
1019-
} else if (g_a2dp_sink_ongoing_deinit) {
1020-
clean_up(BTA_A2DP_SINK_SERVICE_ID);
1021-
}
10221010
break;
10231011

10241012
CHECK_RC_EVENT(event, p_data);
@@ -1848,13 +1836,17 @@ static void btc_a2d_sink_get_delay_value(void)
18481836

18491837
static void btc_a2d_sink_deinit(void)
18501838
{
1839+
// Cleanup will only occur when the state is IDLE.
1840+
// If connected, it will first disconnect and then wait for the state to change to IDLE before performing cleanup.
1841+
// If in any other state, it will wait for the process to complete and then call btc_a2d_sink_deinit again.
18511842
g_a2dp_sink_ongoing_deinit = true;
18521843
if (btc_av_is_connected()) {
18531844
BTA_AvClose(btc_av_cb.bta_handle);
18541845
if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && g_av_with_rc == true) {
18551846
BTA_AvCloseRc(btc_av_cb.bta_handle);
18561847
}
1857-
} else {
1848+
} else if (btc_sm_get_state(btc_av_cb.sm_handle) == BTC_AV_STATE_IDLE) {
1849+
/* Only clean up when idle */
18581850
clean_up(BTA_A2DP_SINK_SERVICE_ID);
18591851
}
18601852
}
@@ -1881,13 +1873,16 @@ static bt_status_t btc_a2d_src_init(void)
18811873

18821874
static void btc_a2d_src_deinit(void)
18831875
{
1876+
// Cleanup will only occur when the state is IDLE.
1877+
// If connected, it will first disconnect and then wait for the state to change to IDLE before performing cleanup.
1878+
// If in any other state, it will wait for the process to complete and then call btc_a2d_src_deinit again.
18841879
g_a2dp_source_ongoing_deinit = true;
18851880
if (btc_av_is_connected()) {
18861881
BTA_AvClose(btc_av_cb.bta_handle);
18871882
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK && g_av_with_rc == true) {
18881883
BTA_AvCloseRc(btc_av_cb.bta_handle);
18891884
}
1890-
} else {
1885+
} else if (btc_sm_get_state(btc_av_cb.sm_handle) == BTC_AV_STATE_IDLE) {
18911886
clean_up(BTA_A2DP_SOURCE_SERVICE_ID);
18921887
}
18931888
}
@@ -1932,6 +1927,23 @@ bt_status_t btc_a2d_src_audio_data_send(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_aud
19321927

19331928
#endif /* BTC_AV_SRC_INCLUDED */
19341929

1930+
static BOOLEAN btc_a2d_deinit_if_ongoing(void)
1931+
{
1932+
#if BTC_AV_SRC_INCLUDED
1933+
if (g_a2dp_source_ongoing_deinit) {
1934+
btc_a2d_src_deinit();
1935+
return TRUE;
1936+
}
1937+
#endif
1938+
#if BTC_AV_SINK_INCLUDED
1939+
if (g_a2dp_sink_ongoing_deinit) {
1940+
btc_a2d_sink_deinit();
1941+
return TRUE;
1942+
}
1943+
#endif
1944+
return FALSE;
1945+
}
1946+
19351947
uint16_t btc_a2d_conn_handle_get(void)
19361948
{
19371949
return btc_av_cb.bta_handle;

0 commit comments

Comments
 (0)