From 59234501dd5b99044838aa69fca116ce5d76ac70 Mon Sep 17 00:00:00 2001 From: weitianhua Date: Thu, 23 Jul 2020 11:24:17 +0800 Subject: [PATCH 1/5] Add bda_addr for esp_bt_a2dp_disconn_req API 1. Add reaction for a2dp snk & src disconn req when no link up 2. Change state machine set before EVT upto APP layer in some cases 3. Add bool open_fail to choose whether post disconnection evt to app layer --- .../bt/host/bluedroid/api/esp_a2dp_api.c | 10 +- .../bluedroid/btc/profile/std/a2dp/btc_av.c | 91 ++++++++++++------- .../btc/profile/std/include/btc_av.h | 4 + 3 files changed, 70 insertions(+), 35 deletions(-) diff --git a/components/bt/host/bluedroid/api/esp_a2dp_api.c b/components/bt/host/bluedroid/api/esp_a2dp_api.c index a7a2df08d7..6e19be58f2 100644 --- a/components/bt/host/bluedroid/api/esp_a2dp_api.c +++ b/components/bt/host/bluedroid/api/esp_a2dp_api.c @@ -106,6 +106,7 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda) } bt_status_t stat; + btc_av_args_t arg; btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; @@ -113,7 +114,8 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda) msg.act = BTC_AV_SINK_API_DISCONNECT_EVT; /* Switch to BTC context */ - stat = btc_transfer_context(&msg, NULL, 0, NULL); + memcpy(&(arg.disconn), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL); return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } @@ -219,14 +221,18 @@ esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda) } bt_status_t stat; + btc_av_args_t arg; btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_A2DP; msg.act = BTC_AV_SRC_API_DISCONNECT_EVT; + memset(&arg, 0, sizeof(btc_av_args_t)); + /* Switch to BTC context */ - stat = btc_transfer_context(&msg, NULL, 0, NULL); + memcpy(&(arg.src_disconn), remote_bda, sizeof(bt_bdaddr_t)); + stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL); return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } 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 be1f1f9628..c62bca169f 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 @@ -89,9 +89,20 @@ typedef struct { uint16_t uuid; } btc_av_connect_req_t; +typedef struct { + bt_bdaddr_t target_bda; +} btc_av_disconn_req_t; + +typedef struct { + esp_a2d_connection_state_t state; + btc_sm_state_t av_state; +} btc_av_open_t; /***************************************************************************** ** Static variables ******************************************************************************/ +btc_av_open_t av_open; +bool open_fail = false; + #if A2D_DYNAMIC_MEMORY == FALSE static btc_av_cb_t btc_av_cb = {0}; #else @@ -289,8 +300,10 @@ static void btc_report_audio_state(esp_a2d_audio_state_t state, bt_bdaddr_t *bd_ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) { - BTC_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__, + BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); + // Init av_open struct + memset(&av_open, 0, sizeof(btc_av_open_t)); switch (event) { case BTC_SM_ENTER_EVT: @@ -299,6 +312,11 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) btc_av_cb.flags = 0; btc_av_cb.edr = 0; btc_a2dp_on_idle(); + if(open_fail) { + BTC_TRACE_ERROR("AV_OPEN fail: Sta %d , SM Sta %d\n",av_open.state, av_open.av_state); + /* inform the application of the event */ + btc_report_connection_state(av_open.state, &(btc_av_cb.peer_bda), 0); + } break; case BTC_SM_EXIT_EVT: @@ -328,6 +346,11 @@ 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 BTC_AV_DISCONNECT_REQ_EVT: + BTC_TRACE_WARNING("BTC_AV_DISCONNECT_REQ_EVT received when no link up."); + btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &((btc_av_disconn_req_t *)p_data)->target_bda, 0); + break; + case BTA_AV_RC_OPEN_EVT: /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore, @@ -387,7 +410,7 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) { - BTC_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__, + BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); switch (event) { @@ -401,34 +424,32 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) case BTA_AV_REJECT_EVT: BTC_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT \n"); - btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), 0); + open_fail = true; btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); break; case BTA_AV_OPEN_EVT: { tBTA_AV *p_bta_data = (tBTA_AV *)p_data; - esp_a2d_connection_state_t state; - btc_sm_state_t av_state; BTC_TRACE_DEBUG("status:%d, edr 0x%x, peer sep %d\n", p_bta_data->open.status, p_bta_data->open.edr, p_bta_data->open.sep); if (p_bta_data->open.status == BTA_AV_SUCCESS) { - state = ESP_A2D_CONNECTION_STATE_CONNECTED; - av_state = BTC_AV_STATE_OPENED; + av_open.state = ESP_A2D_CONNECTION_STATE_CONNECTED; + av_open.av_state = BTC_AV_STATE_OPENED; btc_av_cb.edr = p_bta_data->open.edr; btc_av_cb.peer_sep = p_bta_data->open.sep; } else { BTC_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d\n", p_bta_data->open.status ); - state = ESP_A2D_CONNECTION_STATE_DISCONNECTED; - av_state = BTC_AV_STATE_IDLE; + av_open.state = ESP_A2D_CONNECTION_STATE_DISCONNECTED; + av_open.av_state = BTC_AV_STATE_IDLE; + open_fail = true; } - /* inform the application of the event */ - btc_report_connection_state(state, &(btc_av_cb.peer_bda), 0); /* change state to open/idle based on the status */ - btc_sm_change_state(btc_av_cb.sm_handle, av_state); + btc_sm_change_state(btc_av_cb.sm_handle, av_open.av_state); + if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) { /* if queued PLAY command, send it now */ /* necessary to add this? @@ -503,7 +524,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data) { - BTC_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__, + BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); switch (event) { @@ -546,7 +567,7 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data) /* inform the application that we are disconnecting */ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), close->disc_rsn); - + open_fail = false; btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); break; } @@ -579,7 +600,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) { tBTA_AV *p_av = (tBTA_AV *)p_data; - BTC_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__, + BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btc_av_cb.flags & BTC_AV_FLAG_REMOTE_SUSPEND) && @@ -592,6 +613,8 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) case BTC_SM_ENTER_EVT: btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_STOP; btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_START; + /* inform the application of the event */ + btc_report_connection_state(av_open.state, &(btc_av_cb.peer_bda), 0); break; case BTC_SM_EXIT_EVT: @@ -670,18 +693,18 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) case BTA_AV_CLOSE_EVT: { /* avdtp link is closed */ btc_a2dp_on_stopped(NULL); - tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data; /* inform the application that we are disconnected */ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), close->disc_rsn); - + open_fail = false; /* change state to idle, send acknowledgement if start is pending */ + btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); + if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) { btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE); /* pending start flag will be cleared when exit current state */ } - btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); break; } @@ -733,7 +756,7 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) { tBTA_AV *p_av = (tBTA_AV *)p_data; - BTC_TRACE_DEBUG("%s event:%s flags %x\n", __FUNCTION__, + BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); switch (event) { @@ -799,11 +822,11 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) BTA_AvCloseRc(btc_av_cb.bta_handle); } - /* inform the application that we are disconnecting */ - btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btc_av_cb.peer_bda), 0); - /* wait in closing state until fully closed */ btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_CLOSING); + + /* inform the application that we are disconnecting */ + btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btc_av_cb.peer_bda), 0); break; case BTA_AV_SUSPEND_EVT: @@ -826,6 +849,10 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) return FALSE; } + btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED); + /* suspend completed and state changed, clear pending status */ + btc_av_cb.flags &= ~BTC_AV_FLAG_LOCAL_SUSPEND_PENDING; + if (p_av->suspend.initiator != TRUE) { /* remote suspend, notify HAL and await audioflinger to suspend/stop stream */ @@ -840,11 +867,6 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) } else { btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda)); } - - btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED); - - /* suspend completed and state changed, clear pending status */ - btc_av_cb.flags &= ~BTC_AV_FLAG_LOCAL_SUSPEND_PENDING; break; case BTA_AV_STOP_EVT: @@ -852,13 +874,12 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) btc_av_cb.flags |= BTC_AV_FLAG_PENDING_STOP; btc_a2dp_on_stopped(&p_av->suspend); - btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda)); - /* if stop was successful, change state to open */ if (p_av->suspend.status == BTA_AV_SUCCESS) { btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED); } + btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda)); break; case BTA_AV_CLOSE_EVT: { @@ -867,13 +888,13 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) /* avdtp link is closed */ btc_a2dp_on_stopped(NULL); + open_fail = false; + btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data; /* inform the application that we are disconnected */ 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); break; } @@ -1411,7 +1432,9 @@ void btc_a2dp_call_handler(btc_msg_t *msg) } case BTC_AV_SINK_API_DISCONNECT_EVT: { CHECK_BTAV_INIT(); - btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_DISCONNECT_REQ_EVT, NULL); + btc_av_disconn_req_t disconn_req; + memcpy(&disconn_req.target_bda, &arg->disconn, sizeof(bt_bdaddr_t)); + btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_DISCONNECT_REQ_EVT, &disconn_req); break; } case BTC_AV_SINK_API_REG_DATA_CB_EVT: { @@ -1434,7 +1457,9 @@ void btc_a2dp_call_handler(btc_msg_t *msg) } case BTC_AV_SRC_API_DISCONNECT_EVT: { CHECK_BTAV_INIT(); - btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_DISCONNECT_REQ_EVT, NULL); + btc_av_disconn_req_t disconn_req; + memcpy(&disconn_req.target_bda, &arg->src_disconn, sizeof(bt_bdaddr_t)); + btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_DISCONNECT_REQ_EVT, &disconn_req); break; } case BTC_AV_SRC_API_REG_DATA_CB_EVT: { 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 4f3554bb39..cc546923e6 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 @@ -77,6 +77,8 @@ typedef union { esp_a2d_mcc_t mcc; // BTC_AV_SINK_API_CONNECT_EVT bt_bdaddr_t connect; + // BTC_AV_SINK_API_DISCONNECT_EVT + bt_bdaddr_t disconn; // BTC_AV_SINK_API_REG_DATA_CB_EVT esp_a2d_sink_data_cb_t data_cb; #endif /* BTC_AV_SINK_INCLUDED */ @@ -85,6 +87,8 @@ typedef union { esp_a2d_source_data_cb_t src_data_cb; // BTC_AV_SRC_API_CONNECT bt_bdaddr_t src_connect; + // BTC_AV_SRC_API_DISCONNECT_EVT + bt_bdaddr_t src_disconn; #endif /* BTC_AV_SRC_INCLUDED */ // BTC_AV_API_MEDIA_CTRL_EVT esp_a2d_media_ctrl_t ctrl; From 306c978195f4e3786628b491ae462740147c2cf7 Mon Sep 17 00:00:00 2001 From: weitianhua Date: Mon, 27 Jul 2020 21:57:44 +0800 Subject: [PATCH 2/5] Rewrite a2dp clean_up function --- .../host/bluedroid/btc/profile/std/a2dp/btc_av.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) 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 c62bca169f..1126a5f6d5 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 @@ -1081,11 +1081,13 @@ static void clean_up(int service_id) btc_av_cb.tle_av_open_on_rc = NULL; } #endif /* BTC_AV_SRC_INCLUDED */ + btc_dm_disable_service(BTA_A2DP_SOURCE_SERVICE_ID); } - btc_dm_disable_service(BTA_A2DP_SOURCE_SERVICE_ID); - if (service_id == BTA_A2DP_SINK_SERVICE_ID) { +#if BTC_AV_SINK_INCLUDED + btc_a2dp_sink_shutdown(); +#endif /* BTC_AV_SINK_INCLUDED */ btc_dm_disable_service(BTA_A2DP_SINK_SERVICE_ID); } @@ -1093,15 +1095,9 @@ static void clean_up(int service_id) btc_sm_shutdown(btc_av_cb.sm_handle); btc_av_cb.sm_handle = NULL; - if (service_id == BTA_A2DP_SINK_SERVICE_ID) { -#if BTC_AV_SINK_INCLUDED - btc_a2dp_sink_shutdown(); -#endif /* BTC_AV_SINK_INCLUDED */ - } - #if A2D_DYNAMIC_MEMORY == TRUE - osi_free(btc_av_cb_ptr); - btc_av_cb_ptr = NULL; + osi_free(btc_av_cb_ptr); + btc_av_cb_ptr = NULL; #endif } From b16deb447380d825fab26e8a912f5e1132d6f139 Mon Sep 17 00:00:00 2001 From: weitianhua Date: Tue, 28 Jul 2020 22:10:50 +0800 Subject: [PATCH 3/5] Remove uneccessary macro Separate AVRC from A2DP when AVRC not Initialized --- .../bt/host/bluedroid/bta/av/bta_av_act.c | 7 +-- .../bt/host/bluedroid/bta/av/bta_av_main.c | 10 --- .../bluedroid/bta/include/bta/bta_av_api.h | 6 -- .../bluedroid/btc/profile/std/a2dp/btc_a2dp.c | 2 +- .../btc/profile/std/a2dp/btc_a2dp_source.c | 2 - .../bluedroid/btc/profile/std/a2dp/btc_av.c | 62 ++++++++++++------- .../bluedroid/btc/profile/std/avrc/btc_avrc.c | 6 ++ .../btc/profile/std/include/btc_av.h | 2 + 8 files changed, 52 insertions(+), 45 deletions(-) diff --git a/components/bt/host/bluedroid/bta/av/bta_av_act.c b/components/bt/host/bluedroid/bta/av/bta_av_act.c index bc5484add1..e3687da832 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_act.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_act.c @@ -208,11 +208,8 @@ static void bta_av_rc_ctrl_cback(UINT8 handle, UINT8 event, UINT16 result, BD_AD UINT16 msg_event = 0; UNUSED(result); -#if (defined(BTA_AV_MIN_DEBUG_TRACES) && BTA_AV_MIN_DEBUG_TRACES == TRUE) - APPL_TRACE_EVENT("rc_ctrl handle: %d event=0x%x", handle, event); -#else - APPL_TRACE_EVENT("bta_av_rc_ctrl_cback handle: %d event=0x%x", handle, event); -#endif + APPL_TRACE_EVENT("%s handle: %d event: 0x%x",__func__, handle, event); + if (event == AVRC_OPEN_IND_EVT) { /* save handle of opened connection bta_av_cb.rc_handle = handle;*/ diff --git a/components/bt/host/bluedroid/bta/av/bta_av_main.c b/components/bt/host/bluedroid/bta/av/bta_av_main.c index 77d43c0425..335905c1e6 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_main.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_main.c @@ -568,13 +568,8 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data) if (bta_av_cb.features & (BTA_AV_FEAT_RCTG)) { /* register with no authorization; let AVDTP use authorization instead */ #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) -#if (BTA_AV_WITH_AVCTP_AUTHORIZATION == TRUE) - bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu, - bta_av_cb.sec_mask, BTA_ID_AV); -#else bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu, (UINT8)(bta_av_cb.sec_mask & (~BTA_SEC_AUTHORIZE)), BTA_ID_AV); -#endif if (p_data->api_reg.tsep == AVDT_TSEP_SRC) { bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target\n", NULL, p_bta_av_cfg->avrc_src_tg_cat, BTA_ID_AV); @@ -703,13 +698,8 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data) /* if TG is not supported, we need to register to AVCT now */ if ((bta_av_cb.features & (BTA_AV_FEAT_RCTG)) == 0) { #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) -#if (BTA_AV_WITH_AVCTP_AUTHORIZATION == TRUE) - bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu, - bta_av_cb.sec_mask, BTA_ID_AV); -#else bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu, (UINT8)(bta_av_cb.sec_mask & (~BTA_SEC_AUTHORIZE)), BTA_ID_AV); -#endif #endif } #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_av_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_av_api.h index 5efc2662c4..65d7e35cae 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_av_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_av_api.h @@ -36,12 +36,6 @@ /***************************************************************************** ** Constants and data types *****************************************************************************/ -/* Set to TRUE if seperate authorization prompt desired for AVCTP besides A2DP authorization */ -/* Typically FALSE when AVRCP is used in conjunction with A2DP */ -#ifndef BTA_AV_WITH_AVCTP_AUTHORIZATION -#define BTA_AV_WITH_AVCTP_AUTHORIZATION FALSE -#endif - /* AV status values */ #define BTA_AV_SUCCESS 0 /* successful operation */ #define BTA_AV_FAIL 1 /* generic failure */ diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c index 43d8f93290..b3561007a2 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c @@ -38,7 +38,7 @@ *******************************************************************************/ void btc_a2dp_on_init(void) { - //tput_mon(1, 0, 1); + BTC_TRACE_EVENT("A2DP Initialized."); } /***************************************************************************** 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 7ddade158b..9e943c3cef 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 @@ -1216,8 +1216,6 @@ BOOLEAN btc_media_aa_read_feeding(void) /* Read Data from data channel */ nb_byte_read = btc_aa_src_data_read((uint8_t *)read_buffer, read_size); - //tput_mon(TRUE, nb_byte_read, FALSE); - if (nb_byte_read < read_size) { APPL_TRACE_WARNING("### UNDERRUN :: ONLY READ %d BYTES OUT OF %d ###", nb_byte_read, read_size); 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 1126a5f6d5..22258c8836 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 @@ -101,7 +101,6 @@ typedef struct { ** Static variables ******************************************************************************/ btc_av_open_t av_open; -bool open_fail = false; #if A2D_DYNAMIC_MEMORY == FALSE static btc_av_cb_t btc_av_cb = {0}; @@ -327,6 +326,9 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) case BTA_AV_REGISTER_EVT: btc_av_cb.bta_handle = ((tBTA_AV *)p_data)->registr.hndl; + // Init av_open struct and av_open_state + memset(&av_open, 0, sizeof(btc_av_open_t)); + open_fail = false; break; case BTA_AV_PENDING_EVT: @@ -334,14 +336,24 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) if (event == BTC_AV_CONNECT_REQ_EVT) { memcpy(&btc_av_cb.peer_bda, &((btc_av_connect_req_t *)p_data)->target_bda, sizeof(bt_bdaddr_t)); - BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle, - TRUE, BTA_SEC_AUTHENTICATE, ((btc_av_connect_req_t *)p_data)->uuid); + if (av_with_rc) { + BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle, + TRUE, BTA_SEC_AUTHENTICATE, ((btc_av_connect_req_t *)p_data)->uuid); + } else { + BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle, + FALSE, BTA_SEC_AUTHENTICATE, ((btc_av_connect_req_t *)p_data)->uuid); + } } else if (event == BTA_AV_PENDING_EVT) { bdcpy(btc_av_cb.peer_bda.address, ((tBTA_AV *)p_data)->pend.bd_addr); UINT16 uuid = (btc_av_cb.service_id == BTA_A2DP_SOURCE_SERVICE_ID) ? UUID_SERVCLASS_AUDIO_SOURCE : UUID_SERVCLASS_AUDIO_SINK; - BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle, - TRUE, BTA_SEC_AUTHENTICATE, uuid); + if (av_with_rc) { + BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle, + TRUE, BTA_SEC_AUTHENTICATE, uuid); + } else { + BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle, + FALSE, BTA_SEC_AUTHENTICATE, uuid); + } } btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENING); } break; @@ -353,15 +365,14 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) case BTA_AV_RC_OPEN_EVT: /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So - * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore, - * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state. - * We initiate the AV connection after a small 3s timeout to avoid any collisions from the - * headsets, as some headsets initiate the AVRC connection first and then - * immediately initiate the AV connection - * - * TODO: We may need to do this only on an AVRCP Play. FixMe - */ - + * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore, + * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state. + * We initiate the AV connection after a small 3s timeout to avoid any collisions from the + * headsets, as some headsets initiate the AVRC connection first and then + * immediately initiate the AV connection + * + * TODO: We may need to do this only on an AVRCP Play. FixMe + */ #if BTC_AV_SRC_INCLUDED BTC_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV"); btc_av_cb.tle_av_open_on_rc = osi_alarm_new("AVconn", btc_initiate_av_open_tmr_hdlr, NULL, BTC_TIMEOUT_AV_OPEN_ON_RC_SECS * 1000); @@ -458,8 +469,12 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) */ } else if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && (p_bta_data->open.status == BTA_AV_SUCCESS)) { - /* Bring up AVRCP connection too */ - BTA_AvOpenRc(btc_av_cb.bta_handle); + /* Bring up AVRCP connection too if AVRC Initialized */ + if(av_with_rc) { + BTA_AvOpenRc(btc_av_cb.bta_handle); + } else { + BTC_TRACE_WARNING("AVRC not Init, not using it."); + } } btc_queue_advance(); } break; @@ -1273,11 +1288,16 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable, UINT8 tsep) /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not * auto-suspend av streaming on AG events(SCO or Call). The suspend shall * be initiated by the app/audioflinger layers */ - BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_NO_SCO_SSPD) - | BTA_AV_FEAT_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR - | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL, - bte_av_callback); - BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, &bta_avrc_cos, tsep); + if (av_with_rc) { + BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD | + BTA_AV_FEAT_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR | + BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL, + bte_av_callback); + BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, &bta_avrc_cos, tsep); + } else { + BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD, bte_av_callback); + BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, NULL, tsep); + } } else { BTA_AvDeregister(btc_av_cb.bta_handle); BTA_AvDisable(); diff --git a/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c b/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c index 20ce222c26..b4a17cf818 100644 --- a/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c +++ b/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c @@ -1011,6 +1011,9 @@ static void btc_avrc_ct_init(void) return; } + // indicate that using A2DP with AVRC + av_with_rc = true; + /// initialize CT-specific resources s_rc_ct_init = BTC_RC_CT_INIT_MAGIC; @@ -1039,6 +1042,9 @@ static void btc_avrc_ct_deinit(void) return; } + // indicate that using A2DP with AVRC + av_with_rc = true; + /// deinit CT-specific resources s_rc_ct_init = 0; 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 cc546923e6..20e0e563aa 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 @@ -33,6 +33,8 @@ #include "bta/bta_av_api.h" #if (BTC_AV_INCLUDED == TRUE) +bool open_fail; +bool av_with_rc; /******************************************************************************* ** Type definitions for callback functions ********************************************************************************/ From e940e1d72ad2a0df648053a4aa2c0227c8ddade5 Mon Sep 17 00:00:00 2001 From: weitianhua Date: Tue, 1 Sep 2020 11:57:49 +0800 Subject: [PATCH 4/5] Add global header and change declaration position --- .../bluedroid/btc/profile/std/a2dp/btc_av.c | 28 +++++++++++-------- .../bluedroid/btc/profile/std/avrc/btc_avrc.c | 4 +-- .../btc/profile/std/include/btc_av.h | 4 +-- 3 files changed, 20 insertions(+), 16 deletions(-) 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 22258c8836..5cc2562670 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 @@ -42,6 +42,9 @@ #if BTC_AV_INCLUDED +bool g_av_open_fail; +bool g_av_with_rc; + /***************************************************************************** ** Constants & Macros ******************************************************************************/ @@ -311,8 +314,9 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) btc_av_cb.flags = 0; btc_av_cb.edr = 0; btc_a2dp_on_idle(); - if(open_fail) { - BTC_TRACE_ERROR("AV_OPEN fail: Sta %d , SM Sta %d\n",av_open.state, av_open.av_state); + + if(g_av_open_fail) { + BTC_TRACE_ERROR("AV_OPEN: Sta %d , SM Sta %d\n",av_open.state, av_open.av_state); /* inform the application of the event */ btc_report_connection_state(av_open.state, &(btc_av_cb.peer_bda), 0); } @@ -328,7 +332,7 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) btc_av_cb.bta_handle = ((tBTA_AV *)p_data)->registr.hndl; // Init av_open struct and av_open_state memset(&av_open, 0, sizeof(btc_av_open_t)); - open_fail = false; + g_av_open_fail = false; break; case BTA_AV_PENDING_EVT: @@ -336,7 +340,7 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) if (event == BTC_AV_CONNECT_REQ_EVT) { memcpy(&btc_av_cb.peer_bda, &((btc_av_connect_req_t *)p_data)->target_bda, sizeof(bt_bdaddr_t)); - if (av_with_rc) { + if (g_av_with_rc) { BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle, TRUE, BTA_SEC_AUTHENTICATE, ((btc_av_connect_req_t *)p_data)->uuid); } else { @@ -347,7 +351,7 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) bdcpy(btc_av_cb.peer_bda.address, ((tBTA_AV *)p_data)->pend.bd_addr); UINT16 uuid = (btc_av_cb.service_id == BTA_A2DP_SOURCE_SERVICE_ID) ? UUID_SERVCLASS_AUDIO_SOURCE : UUID_SERVCLASS_AUDIO_SINK; - if (av_with_rc) { + if (g_av_with_rc) { BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle, TRUE, BTA_SEC_AUTHENTICATE, uuid); } else { @@ -435,7 +439,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) case BTA_AV_REJECT_EVT: BTC_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT \n"); - open_fail = true; + g_av_open_fail = true; btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); break; @@ -455,7 +459,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) p_bta_data->open.status ); av_open.state = ESP_A2D_CONNECTION_STATE_DISCONNECTED; av_open.av_state = BTC_AV_STATE_IDLE; - open_fail = true; + g_av_open_fail = true; } /* change state to open/idle based on the status */ @@ -470,7 +474,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) } else if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && (p_bta_data->open.status == BTA_AV_SUCCESS)) { /* Bring up AVRCP connection too if AVRC Initialized */ - if(av_with_rc) { + if(g_av_with_rc) { BTA_AvOpenRc(btc_av_cb.bta_handle); } else { BTC_TRACE_WARNING("AVRC not Init, not using it."); @@ -582,7 +586,7 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data) /* inform the application that we are disconnecting */ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), close->disc_rsn); - open_fail = false; + g_av_open_fail = false; btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); break; } @@ -712,7 +716,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) /* inform the application that we are disconnected */ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), close->disc_rsn); - open_fail = false; + g_av_open_fail = false; /* change state to idle, send acknowledgement if start is pending */ btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); @@ -903,7 +907,7 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) /* avdtp link is closed */ btc_a2dp_on_stopped(NULL); - open_fail = false; + g_av_open_fail = false; btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data; @@ -1288,7 +1292,7 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable, UINT8 tsep) /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not * auto-suspend av streaming on AG events(SCO or Call). The suspend shall * be initiated by the app/audioflinger layers */ - if (av_with_rc) { + if (g_av_with_rc) { BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD | BTA_AV_FEAT_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL, diff --git a/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c b/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c index b4a17cf818..e7b94bfdd0 100644 --- a/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c +++ b/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c @@ -1012,7 +1012,7 @@ static void btc_avrc_ct_init(void) } // indicate that using A2DP with AVRC - av_with_rc = true; + g_av_with_rc = true; /// initialize CT-specific resources s_rc_ct_init = BTC_RC_CT_INIT_MAGIC; @@ -1043,7 +1043,7 @@ static void btc_avrc_ct_deinit(void) } // indicate that using A2DP with AVRC - av_with_rc = true; + g_av_with_rc = true; /// deinit CT-specific resources s_rc_ct_init = 0; 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 20e0e563aa..c68661c8f2 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 @@ -33,8 +33,8 @@ #include "bta/bta_av_api.h" #if (BTC_AV_INCLUDED == TRUE) -bool open_fail; -bool av_with_rc; +extern bool g_av_open_fail; +extern bool g_av_with_rc; /******************************************************************************* ** Type definitions for callback functions ********************************************************************************/ From 84cda60478d7a657be039339c706f4366ee2e861 Mon Sep 17 00:00:00 2001 From: weitianhua Date: Tue, 1 Sep 2020 19:57:51 +0800 Subject: [PATCH 5/5] Redesign separating AVRC & A2DP 1. Add g_av_with_rc to avrc_tg_init function 2. Remove g_av_open_fail 3. Add comment in API files 4. Add a2dp init & deinit state variable to inidcate a2dp statement --- .../bluedroid/api/include/api/esp_a2dp_api.h | 6 +- .../bluedroid/api/include/api/esp_avrc_api.h | 12 +- .../bluedroid/btc/profile/std/a2dp/btc_av.c | 135 ++++++++---------- .../bluedroid/btc/profile/std/avrc/btc_avrc.c | 36 ++++- .../btc/profile/std/include/btc_av.h | 7 +- 5 files changed, 107 insertions(+), 89 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h b/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h index 903b17c32b..d28edd4b94 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h @@ -194,7 +194,8 @@ esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback); /** * * @brief Initialize the bluetooth A2DP sink module. This function should be called - * after esp_bluedroid_enable() completes successfully + * after esp_bluedroid_enable() completes successfully. Note: A2DP can work independently. + * If you want to use AVRC together, you should initiate AVRC first. * * @return * - ESP_OK: if the initialization request is sent successfully @@ -265,7 +266,8 @@ esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl); /** * * @brief Initialize the bluetooth A2DP source module. This function should be called - * after esp_bluedroid_enable() completes successfully + * after esp_bluedroid_enable() completes successfully. Note: A2DP can work independently. + * If you want to use AVRC together, you should initiate AVRC first. * * @return * - ESP_OK: if the initialization request is sent successfully diff --git a/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h b/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h index e75eb637df..2f4f1eee70 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h @@ -414,7 +414,8 @@ esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback); /** * * @brief Initialize the bluetooth AVRCP controller module, This function should be called - * after esp_bluedroid_enable() completes successfully + * after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently, + * AVRC should be used along with A2DP and AVRC should be initialized before A2DP. * * @return * - ESP_OK: success @@ -427,7 +428,8 @@ esp_err_t esp_avrc_ct_init(void); /** * * @brief De-initialize AVRCP controller module. This function should be called after - * after esp_bluedroid_enable() completes successfully + * after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently, + * AVRC should be used along with A2DP and AVRC should be deinitialized before A2DP. * * @return * - ESP_OK: success @@ -543,7 +545,8 @@ esp_err_t esp_avrc_tg_register_callback(esp_avrc_tg_cb_t callback); /** * * @brief Initialize the bluetooth AVRCP target module, This function should be called - * after esp_bluedroid_enable() completes successfully + * after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently, + * AVRC should be used along with A2DP and AVRC should be initialized before A2DP. * * @return * - ESP_OK: success @@ -556,7 +559,8 @@ esp_err_t esp_avrc_tg_init(void); /** * * @brief De-initialize AVRCP target module. This function should be called after - * after esp_bluedroid_enable() completes successfully + * after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently, + * AVRC should be used along with A2DP and AVRC should be deinitialized before A2DP. * * @return * - ESP_OK: success 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 5cc2562670..0aeacd1916 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 @@ -42,8 +42,12 @@ #if BTC_AV_INCLUDED -bool g_av_open_fail; +// global variable to inidcate avrc is initialized with a2dp bool g_av_with_rc; +// global variable to indicate a2dp is initialized +bool g_a2dp_on_init; +// global variable to indicate a2dp is deinitialized +bool g_a2dp_on_deinit; /***************************************************************************** ** Constants & Macros @@ -96,14 +100,9 @@ typedef struct { bt_bdaddr_t target_bda; } btc_av_disconn_req_t; -typedef struct { - esp_a2d_connection_state_t state; - btc_sm_state_t av_state; -} btc_av_open_t; /***************************************************************************** ** Static variables ******************************************************************************/ -btc_av_open_t av_open; #if A2D_DYNAMIC_MEMORY == FALSE static btc_av_cb_t btc_av_cb = {0}; @@ -304,8 +303,6 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) { BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); - // Init av_open struct - memset(&av_open, 0, sizeof(btc_av_open_t)); switch (event) { case BTC_SM_ENTER_EVT: @@ -314,12 +311,6 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) btc_av_cb.flags = 0; btc_av_cb.edr = 0; btc_a2dp_on_idle(); - - if(g_av_open_fail) { - BTC_TRACE_ERROR("AV_OPEN: Sta %d , SM Sta %d\n",av_open.state, av_open.av_state); - /* inform the application of the event */ - btc_report_connection_state(av_open.state, &(btc_av_cb.peer_bda), 0); - } break; case BTC_SM_EXIT_EVT: @@ -330,9 +321,6 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) case BTA_AV_REGISTER_EVT: btc_av_cb.bta_handle = ((tBTA_AV *)p_data)->registr.hndl; - // Init av_open struct and av_open_state - memset(&av_open, 0, sizeof(btc_av_open_t)); - g_av_open_fail = false; break; case BTA_AV_PENDING_EVT: @@ -363,20 +351,20 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) } break; case BTC_AV_DISCONNECT_REQ_EVT: - BTC_TRACE_WARNING("BTC_AV_DISCONNECT_REQ_EVT received when no link up."); + 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); break; case BTA_AV_RC_OPEN_EVT: /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So - * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore, - * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state. - * We initiate the AV connection after a small 3s timeout to avoid any collisions from the - * headsets, as some headsets initiate the AVRC connection first and then - * immediately initiate the AV connection - * - * TODO: We may need to do this only on an AVRCP Play. FixMe - */ + * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore, + * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state. + * We initiate the AV connection after a small 3s timeout to avoid any collisions from the + * headsets, as some headsets initiate the AVRC connection first and then + * immediately initiate the AV connection + * + * TODO: We may need to do this only on an AVRCP Play. FixMe + */ #if BTC_AV_SRC_INCLUDED BTC_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV"); btc_av_cb.tle_av_open_on_rc = osi_alarm_new("AVconn", btc_initiate_av_open_tmr_hdlr, NULL, BTC_TIMEOUT_AV_OPEN_ON_RC_SECS * 1000); @@ -407,7 +395,6 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event)); return FALSE; - } return TRUE; @@ -438,32 +425,34 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) break; case BTA_AV_REJECT_EVT: - BTC_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT \n"); - g_av_open_fail = true; + BTC_TRACE_WARNING(" Received BTA_AV_REJECT_EVT \n"); + btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), 0); btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); break; case BTA_AV_OPEN_EVT: { tBTA_AV *p_bta_data = (tBTA_AV *)p_data; + esp_a2d_connection_state_t conn_stat; + btc_sm_state_t av_state; BTC_TRACE_DEBUG("status:%d, edr 0x%x, peer sep %d\n", p_bta_data->open.status, p_bta_data->open.edr, p_bta_data->open.sep); if (p_bta_data->open.status == BTA_AV_SUCCESS) { - av_open.state = ESP_A2D_CONNECTION_STATE_CONNECTED; - av_open.av_state = BTC_AV_STATE_OPENED; btc_av_cb.edr = p_bta_data->open.edr; - btc_av_cb.peer_sep = p_bta_data->open.sep; - } else { - BTC_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d\n", - p_bta_data->open.status ); - av_open.state = ESP_A2D_CONNECTION_STATE_DISCONNECTED; - av_open.av_state = BTC_AV_STATE_IDLE; - g_av_open_fail = true; - } + conn_stat = ESP_A2D_CONNECTION_STATE_CONNECTED; + av_state = BTC_AV_STATE_OPENED; + } else { + BTC_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d\n", p_bta_data->open.status); + + conn_stat = ESP_A2D_CONNECTION_STATE_DISCONNECTED; + av_state = BTC_AV_STATE_IDLE; + } + /* inform the application of the event */ + btc_report_connection_state(conn_stat, &(btc_av_cb.peer_bda), 0); /* change state to open/idle based on the status */ - btc_sm_change_state(btc_av_cb.sm_handle, av_open.av_state); + btc_sm_change_state(btc_av_cb.sm_handle, av_state); if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) { /* if queued PLAY command, send it now */ @@ -518,13 +507,11 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) break; } - CHECK_RC_EVENT(event, p_data); + CHECK_RC_EVENT(event, p_data); default: - BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, - dump_av_sm_event_name(event)); + BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event)); return FALSE; - } return TRUE; } @@ -584,9 +571,7 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data) case BTA_AV_CLOSE_EVT: { tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data; /* inform the application that we are disconnecting */ - btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), - close->disc_rsn); - g_av_open_fail = false; + 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); break; } @@ -597,14 +582,12 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data) break; default: - BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, - dump_av_sm_event_name(event)); + BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event)); return FALSE; } return TRUE; } - /***************************************************************************** ** ** Function btc_av_state_opened_handler @@ -614,7 +597,6 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data) ** Returns TRUE if event was processed, FALSE otherwise ** *******************************************************************************/ - static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) { tBTA_AV *p_av = (tBTA_AV *)p_data; @@ -632,8 +614,6 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) case BTC_SM_ENTER_EVT: btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_STOP; btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_START; - /* inform the application of the event */ - btc_report_connection_state(av_open.state, &(btc_av_cb.peer_bda), 0); break; case BTC_SM_EXIT_EVT: @@ -701,7 +681,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) case BTC_AV_DISCONNECT_REQ_EVT: BTA_AvClose(btc_av_cb.bta_handle); - if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) { + if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && g_av_with_rc == true) { BTA_AvCloseRc(btc_av_cb.bta_handle); } @@ -716,14 +696,14 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) /* inform the application that we are disconnected */ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), close->disc_rsn); - g_av_open_fail = false; - /* change state to idle, send acknowledgement if start is pending */ - btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) { btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE); /* pending start flag will be cleared when exit current state */ } + + /* change state to idle, send acknowledgement if start is pending */ + btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); break; } @@ -750,7 +730,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) btc_queue_advance(); break; - CHECK_RC_EVENT(event, p_data); + CHECK_RC_EVENT(event, p_data); default: BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, @@ -837,15 +817,15 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) /* request avdtp to close */ BTA_AvClose(btc_av_cb.bta_handle); - if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) { + if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && g_av_with_rc == true) { BTA_AvCloseRc(btc_av_cb.bta_handle); } - /* wait in closing state until fully closed */ - btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_CLOSING); - /* inform the application that we are disconnecting */ btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btc_av_cb.peer_bda), 0); + + /* wait in closing state until fully closed */ + btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_CLOSING); break; case BTA_AV_SUSPEND_EVT: @@ -868,10 +848,6 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) return FALSE; } - btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED); - /* suspend completed and state changed, clear pending status */ - btc_av_cb.flags &= ~BTC_AV_FLAG_LOCAL_SUSPEND_PENDING; - if (p_av->suspend.initiator != TRUE) { /* remote suspend, notify HAL and await audioflinger to suspend/stop stream */ @@ -886,6 +862,11 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) } else { btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda)); } + + btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED); + + /* suspend completed and state changed, clear pending status */ + btc_av_cb.flags &= ~BTC_AV_FLAG_LOCAL_SUSPEND_PENDING; break; case BTA_AV_STOP_EVT: @@ -893,29 +874,25 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) btc_av_cb.flags |= BTC_AV_FLAG_PENDING_STOP; btc_a2dp_on_stopped(&p_av->suspend); + btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda)); + /* if stop was successful, change state to open */ if (p_av->suspend.status == BTA_AV_SUCCESS) { btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED); } - - btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda)); break; - case BTA_AV_CLOSE_EVT: { - + case BTA_AV_CLOSE_EVT: btc_av_cb.flags |= BTC_AV_FLAG_PENDING_STOP; /* avdtp link is closed */ btc_a2dp_on_stopped(NULL); - g_av_open_fail = false; - btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); - tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data; /* inform the application that we are disconnected */ 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); break; - } CHECK_RC_EVENT(event, p_data); @@ -1002,7 +979,6 @@ static void btc_av_event_free_data(btc_sm_event_t event, void *p_data) ** Returns bt_status_t ** *******************************************************************************/ - static bt_status_t btc_av_init(int service_id) { @@ -1036,6 +1012,8 @@ static bt_status_t btc_av_init(int service_id) osi_free(btc_av_cb_ptr); btc_av_cb_ptr = NULL; #endif + g_a2dp_on_init = false; + g_a2dp_on_deinit = true; return BT_STATUS_FAIL; } @@ -1050,7 +1028,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; return BT_STATUS_SUCCESS; } @@ -1118,6 +1097,8 @@ static void clean_up(int service_id) osi_free(btc_av_cb_ptr); btc_av_cb_ptr = NULL; #endif + g_a2dp_on_init = false; + g_a2dp_on_deinit = true; } /******************************************************************************* @@ -1293,12 +1274,14 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable, UINT8 tsep) * auto-suspend av streaming on AG events(SCO or Call). The suspend shall * be initiated by the app/audioflinger layers */ if (g_av_with_rc) { + BTC_TRACE_WARNING("A2DP Enable with AVRC") BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD | BTA_AV_FEAT_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL, bte_av_callback); BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, &bta_avrc_cos, tsep); } else { + BTC_TRACE_WARNING("A2DP Enable without AVRC") BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD, bte_av_callback); BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, NULL, tsep); } diff --git a/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c b/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c index e7b94bfdd0..ff9621e7e1 100644 --- a/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c +++ b/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c @@ -1011,15 +1011,20 @@ static void btc_avrc_ct_init(void) return; } - // indicate that using A2DP with AVRC - g_av_with_rc = true; - /// initialize CT-specific resources s_rc_ct_init = BTC_RC_CT_INIT_MAGIC; /// initialize CT-TG shared resources if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) { memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t)); + + if (!g_av_with_rc) { + g_av_with_rc = true; + } + + if (g_a2dp_on_init) { + BTC_TRACE_WARNING("AVRC Controller is expected to be initialized in advance of A2DP !!!"); + } } } @@ -1037,20 +1042,24 @@ static void btc_avrc_ct_deinit(void) { BTC_TRACE_API("## %s ##", __FUNCTION__); + if (g_a2dp_on_deinit) { + BTC_TRACE_WARNING("A2DP already deinit, AVRC CT shuold deinit in advance of A2DP !!!"); + } + if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) { BTC_TRACE_WARNING("%s not initialized", __FUNCTION__); return; } - // indicate that using A2DP with AVRC - g_av_with_rc = true; - /// deinit CT-specific resources s_rc_ct_init = 0; /// deinit CT-TG shared resources if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) { memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t)); + if (g_av_with_rc) { + g_av_with_rc = false; + } } BTC_TRACE_API("## %s ## completed", __FUNCTION__); @@ -1285,6 +1294,14 @@ static void btc_avrc_tg_init(void) /// initialize CT-TG shared resources if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) { memset (&btc_rc_cb, 0, sizeof(btc_rc_cb)); + + if (!g_av_with_rc) { + g_av_with_rc = true; + } + + if (g_a2dp_on_init) { + BTC_TRACE_WARNING("AVRC Taget is expected to be initialized in advance of A2DP !!!"); + } } s_rc_tg_init = BTC_RC_TG_INIT_MAGIC; @@ -1304,6 +1321,10 @@ static void btc_avrc_tg_deinit(void) { BTC_TRACE_API("## %s ##", __FUNCTION__); + if (g_a2dp_on_deinit) { + BTC_TRACE_WARNING("A2DP already deinit, AVRC TG shuold deinit in advance of A2DP !!!"); + } + if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) { BTC_TRACE_WARNING("%s not initialized", __FUNCTION__); return; @@ -1317,6 +1338,9 @@ static void btc_avrc_tg_deinit(void) /// deinit CT-TG shared resources if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) { memset (&btc_rc_cb, 0, sizeof(btc_rc_cb)); + if (g_av_with_rc) { + g_av_with_rc = false; + } } BTC_TRACE_API("## %s ## completed", __FUNCTION__); 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 c68661c8f2..a4b695c538 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 @@ -33,8 +33,13 @@ #include "bta/bta_av_api.h" #if (BTC_AV_INCLUDED == TRUE) -extern bool g_av_open_fail; + +// global variable to inidcate avrc is initialized with a2dp extern bool g_av_with_rc; +// global variable to indicate a2dp is initialized +extern bool g_a2dp_on_init; +// global variable to indicate a2dp is deinitialized +extern bool g_a2dp_on_deinit; /******************************************************************************* ** Type definitions for callback functions ********************************************************************************/