diff --git a/components/bt/host/bluedroid/api/esp_a2dp_api.c b/components/bt/host/bluedroid/api/esp_a2dp_api.c index 6e19be58f2..ee47563989 100644 --- a/components/bt/host/bluedroid/api/esp_a2dp_api.c +++ b/components/bt/host/bluedroid/api/esp_a2dp_api.c @@ -29,6 +29,10 @@ esp_err_t esp_a2d_sink_init(void) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_on_init || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; @@ -46,6 +50,10 @@ esp_err_t esp_a2d_sink_deinit(void) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; @@ -63,6 +71,10 @@ esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_A2DP; @@ -83,6 +95,10 @@ esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + bt_status_t stat; btc_av_args_t arg; btc_msg_t msg; @@ -105,6 +121,10 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + bt_status_t stat; btc_av_args_t arg; btc_msg_t msg; @@ -127,6 +147,10 @@ esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_sink_ongoing_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + if (callback == NULL) { return ESP_FAIL; } @@ -141,6 +165,10 @@ esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + bt_status_t stat; btc_av_args_t arg; btc_msg_t msg; @@ -164,6 +192,10 @@ esp_err_t esp_a2d_source_init(void) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_on_init || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; @@ -181,6 +213,10 @@ esp_err_t esp_a2d_source_deinit(void) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_on_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; @@ -198,6 +234,10 @@ esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_on_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + bt_status_t stat; btc_av_args_t arg; btc_msg_t msg; @@ -220,6 +260,10 @@ esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda) return ESP_ERR_INVALID_STATE; } + if (g_a2dp_on_deinit || g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + bt_status_t stat; btc_av_args_t arg; btc_msg_t msg; @@ -242,6 +286,10 @@ esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callbac return ESP_ERR_INVALID_STATE; } + if (g_a2dp_source_ongoing_deinit) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_A2DP; diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c index 5f987dbb32..c66ac28be8 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c @@ -1421,7 +1421,7 @@ static void btc_a2dp_source_handle_timer(UNUSED_ATTR void *context) log_tstamps_us("media task tx timer"); #if (BTA_AV_INCLUDED == TRUE) - if (btc_a2dp_source_state != BTC_A2DP_SOURCE_STATE_ON){ + if (btc_a2dp_source_state != BTC_A2DP_SOURCE_STATE_ON || g_a2dp_source_ongoing_deinit){ return; } 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 6f9a40ee00..52003751a2 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 @@ -48,6 +48,11 @@ bool g_av_with_rc; bool g_a2dp_on_init; // global variable to indicate a2dp is deinitialized bool g_a2dp_on_deinit; +// global variable to indicate a2dp source deinitialization is ongoing +bool g_a2dp_source_ongoing_deinit; +// global variable to indicate a2dp sink deinitialization is ongoing +bool g_a2dp_sink_ongoing_deinit; + /***************************************************************************** ** Constants & Macros @@ -136,6 +141,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *data); static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *data); static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *data); static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *data); +static void clean_up(int service_id); #if BTC_AV_SRC_INCLUDED static bt_status_t btc_a2d_src_init(void); @@ -704,6 +710,12 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) /* change state to idle, send acknowledgement if start is pending */ btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); + + if (g_a2dp_source_ongoing_deinit) { + clean_up(BTA_A2DP_SOURCE_SERVICE_ID); + } else if (g_a2dp_sink_ongoing_deinit) { + clean_up(BTA_A2DP_SINK_SERVICE_ID); + } break; } @@ -892,6 +904,12 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), close->disc_rsn); btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); + + if (g_a2dp_source_ongoing_deinit) { + clean_up(BTA_A2DP_SOURCE_SERVICE_ID); + } else if (g_a2dp_sink_ongoing_deinit) { + clean_up(BTA_A2DP_SINK_SERVICE_ID); + } break; CHECK_RC_EVENT(event, p_data); @@ -1014,6 +1032,8 @@ static bt_status_t btc_av_init(int service_id) #endif g_a2dp_on_init = false; g_a2dp_on_deinit = true; + g_a2dp_source_ongoing_deinit = false; + g_a2dp_sink_ongoing_deinit = false; goto av_init_fail; } @@ -1030,6 +1050,8 @@ static bt_status_t btc_av_init(int service_id) btc_a2dp_on_init(); g_a2dp_on_init = true; g_a2dp_on_deinit = false; + g_a2dp_source_ongoing_deinit = false; + g_a2dp_sink_ongoing_deinit = false; esp_a2d_cb_param_t param; memset(¶m, 0, sizeof(esp_a2d_cb_param_t)); @@ -1105,6 +1127,8 @@ static void clean_up(int service_id) #endif g_a2dp_on_init = false; g_a2dp_on_deinit = true; + g_a2dp_source_ongoing_deinit = false; + g_a2dp_sink_ongoing_deinit = false; esp_a2d_cb_param_t param; memset(¶m, 0, sizeof(esp_a2d_cb_param_t)); @@ -1538,7 +1562,15 @@ static bt_status_t btc_a2d_sink_connect(bt_bdaddr_t *remote_bda) static void btc_a2d_sink_deinit(void) { - clean_up(BTA_A2DP_SINK_SERVICE_ID); + g_a2dp_sink_ongoing_deinit = true; + if (btc_av_is_connected()) { + BTA_AvClose(btc_av_cb.bta_handle); + if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && g_av_with_rc == true) { + BTA_AvCloseRc(btc_av_cb.bta_handle); + } + } else { + clean_up(BTA_A2DP_SINK_SERVICE_ID); + } } #endif /* BTC_AV_SINK_INCLUDED */ @@ -1563,7 +1595,15 @@ static bt_status_t btc_a2d_src_init(void) static void btc_a2d_src_deinit(void) { - clean_up(BTA_A2DP_SOURCE_SERVICE_ID); + g_a2dp_source_ongoing_deinit = true; + if (btc_av_is_connected()) { + BTA_AvClose(btc_av_cb.bta_handle); + if (btc_av_cb.peer_sep == AVDT_TSEP_SNK && g_av_with_rc == true) { + BTA_AvCloseRc(btc_av_cb.bta_handle); + } + } else { + clean_up(BTA_A2DP_SOURCE_SERVICE_ID); + } } static bt_status_t btc_a2d_src_connect(bt_bdaddr_t *remote_bda) diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_av.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_av.h index a4b695c538..553f0ddec7 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_av.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_av.h @@ -40,6 +40,11 @@ extern bool g_av_with_rc; extern bool g_a2dp_on_init; // global variable to indicate a2dp is deinitialized extern bool g_a2dp_on_deinit; +// global variable to indicate a2dp source deinitialization is ongoing +extern bool g_a2dp_source_ongoing_deinit; +// global variable to indicate a2dp sink deinitialization is ongoing +extern bool g_a2dp_sink_ongoing_deinit; + /******************************************************************************* ** Type definitions for callback functions ********************************************************************************/