diff --git a/components/bt/host/bluedroid/api/esp_a2dp_api.c b/components/bt/host/bluedroid/api/esp_a2dp_api.c index 0151b72ec3..a5ae32fa42 100644 --- a/components/bt/host/bluedroid/api/esp_a2dp_api.c +++ b/components/bt/host/bluedroid/api/esp_a2dp_api.c @@ -131,6 +131,53 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda) return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } +esp_err_t esp_a2d_sink_set_delay_value(uint16_t delay_value) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + 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; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SINK_API_SET_DELAY_VALUE_EVT; + + memset(&arg, 0, sizeof(btc_av_args_t)); + arg.delay_value = delay_value; + + /* Switch to BTC context */ + stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + +esp_err_t esp_a2d_sink_get_delay_value(void) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + 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_msg_t msg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_A2DP; + msg.act = BTC_AV_SINK_API_GET_DELAY_VALUE_EVT; + + /* Switch to BTC context */ + stat = btc_transfer_context(&msg, NULL, 0, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} #endif /* BTC_AV_SINK_INCLUDED */ esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback) 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 85ce6a4fdc..1ff85c2efe 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 @@ -23,6 +23,12 @@ extern "C" { typedef uint8_t esp_a2d_mct_t; +/** + * @brief Protocol service capabilities. This value is a mask. + */ +#define ESP_A2D_PSC_DELAY_RPT (1<<0) /*!< Delay Report */ +typedef uint16_t esp_a2d_psc_t; + /** A2DP media codec capabilities union */ typedef struct { @@ -82,6 +88,12 @@ typedef enum { ESP_A2D_INIT_SUCCESS /*!< A2DP profile deinit successful event */ } esp_a2d_init_state_t; +/// Bluetooth A2DP set delay report value states +typedef enum { + ESP_A2D_SET_SUCCESS = 0, /*!< A2DP profile set delay report value successful */ + ESP_A2D_SET_INVALID_PARAMS /*!< A2DP profile set delay report value is invalid parameter */ +} esp_a2d_set_delay_value_state_t; + /// A2DP callback events typedef enum { ESP_A2D_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */ @@ -89,6 +101,10 @@ typedef enum { ESP_A2D_AUDIO_CFG_EVT, /*!< audio codec is configured, only used for A2DP SINK */ ESP_A2D_MEDIA_CTRL_ACK_EVT, /*!< acknowledge event in response to media control commands */ ESP_A2D_PROF_STATE_EVT, /*!< indicate a2dp init&deinit complete */ + ESP_A2D_SNK_PSC_CFG_EVT, /*!< protocol service capabilities configured,only used for A2DP SINK */ + ESP_A2D_SNK_SET_DELAY_VALUE_EVT, /*!< indicate a2dp sink set delay report value complete, only used for A2DP SINK */ + ESP_A2D_SNK_GET_DELAY_VALUE_EVT, /*!< indicate a2dp sink get delay report value complete, only used for A2DP SINK */ + ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT, /*!< report delay value, only used for A2DP SRC */ } esp_a2d_cb_event_t; /// A2DP state callback parameters @@ -125,12 +141,36 @@ typedef union { esp_a2d_media_ctrl_t cmd; /*!< media control commands to acknowledge */ esp_a2d_media_ctrl_ack_t status; /*!< acknowledgement to media control commands */ } media_ctrl_stat; /*!< status in acknowledgement to media control commands */ + /** * @brief ESP_A2D_PROF_STATE_EVT */ struct a2d_prof_stat_param { esp_a2d_init_state_t init_state; /*!< a2dp profile state param */ } a2d_prof_stat; /*!< status to indicate a2d prof init or deinit */ + + /** + * @brief ESP_A2D_SNK_PSC_CFG_EVT + */ + struct a2d_psc_cfg_param { + esp_a2d_psc_t psc_mask; /*!< protocol service capabilities configured */ + } a2d_psc_cfg_stat; /*!< status to indicate protocol service capabilities configured */ + + /** + * @brief ESP_A2D_SNK_SET_DELAY_VALUE_EVT + */ + struct a2d_set_stat_param { + esp_a2d_set_delay_value_state_t set_state; /*!< a2dp profile state param */ + uint16_t delay_value; /*!< delay report value */ + } a2d_set_delay_value_stat; /*!< A2DP sink set delay report value status */ + + /** + * @brief ESP_A2D_SNK_GET_DELAY_VALUE_EVT + */ + struct a2d_get_stat_param { + uint16_t delay_value; /*!< delay report value */ + } a2d_get_delay_value_stat; /*!< A2DP sink get delay report value status */ + } esp_a2d_cb_param_t; /** @@ -261,6 +301,36 @@ esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda); */ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda); +/** + * + * @brief Set delay reporting value. The delay value of sink is caused by buffering (including + * protocol stack and application layer), decoding and rendering. The default delay + * value is 120ms, if the set value is less than 120ms, the setting will fail. This API + * must be called after esp_a2d_sink_init() and before esp_a2d_sink_deinit(). + * + * @param[in] delay_value: reporting value is in 1/10 millisecond + * + * @return + * - ESP_OK: delay value is sent to lower layer successfully + * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_sink_set_delay_value(uint16_t delay_value); + +/** + * + * @brief Get delay reporting value. This API must be called after + * esp_a2d_sink_init() and before esp_a2d_sink_deinit(). + * + * @return + * - ESP_OK: if the request is sent successfully + * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_a2d_sink_get_delay_value(void); + /** * diff --git a/components/bt/host/bluedroid/bta/av/bta_av_aact.c b/components/bt/host/bluedroid/bta/av/bta_av_aact.c index 60f7cdfa1c..6eca9b1dc8 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_aact.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_aact.c @@ -125,6 +125,7 @@ const tBTA_AV_SACT bta_av_a2d_action[] = { bta_av_delay_co, /* BTA_AV_DELAY_CO */ bta_av_open_at_inc, /* BTA_AV_OPEN_AT_INC */ bta_av_open_fail_sdp, /* BTA_AV_OPEN_FAIL_SDP */ + bta_av_set_delay_value, /* BTA_AV_SET_DELAY_VALUE */ NULL }; @@ -499,6 +500,9 @@ static void bta_av_proc_stream_evt(UINT8 handle, BD_ADDR bd_addr, UINT8 event, t case AVDT_DISCONNECT_IND_EVT: p_msg->hdr.offset = p_data->hdr.err_param; break; + case AVDT_DELAY_REPORT_CFM_EVT: + APPL_TRACE_DEBUG("%s: AVDT_DELAY_REPORT_CFM_EVT", __func__); + return; default: break; } @@ -1250,16 +1254,24 @@ void bta_av_setconfig_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) UINT8 *p_seid = p_data->ci_setconfig.p_seid; int i; UINT8 local_sep; + tBTA_AV_SNK_PSC_CFG psc_cfg = {0}; /* we like this codec_type. find the sep_idx */ local_sep = bta_av_get_scb_sep_type(p_scb, avdt_handle); bta_av_adjust_seps_idx(p_scb, avdt_handle); APPL_TRACE_DEBUG("bta_av_setconfig_rsp: sep_idx: %d cur_psc_mask:0x%x", p_scb->sep_idx, p_scb->cur_psc_mask); - if ((AVDT_TSEP_SNK == local_sep) && (p_data->ci_setconfig.err_code == AVDT_SUCCESS) && - (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL)) - p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT, - (tBTA_AV_MEDIA *)p_scb->cfg.codec_info); + if (AVDT_TSEP_SNK == local_sep) { + if ((p_data->ci_setconfig.err_code == AVDT_SUCCESS) && + (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL)) { + p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT, + (tBTA_AV_MEDIA *)p_scb->cfg.codec_info); + } + if (p_scb->cur_psc_mask & AVDT_PSC_DELAY_RPT) { + psc_cfg.psc_mask |= BTA_AV_PSC_DEALY_RPT; + } + (*bta_av_cb.p_cback)(BTA_AV_SNK_PSC_CFG_EVT, (tBTA_AV *)&psc_cfg); + } AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, p_data->ci_setconfig.err_code, @@ -1818,6 +1830,7 @@ void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) UINT8 media_type; tAVDT_SEP_INFO *p_info = &p_scb->sep_info[p_scb->sep_info_idx]; UINT16 uuid_int; /* UUID for which connection was initiatied */ + tBTA_AV_SNK_PSC_CFG psc_cfg = {0}; memcpy(&cfg, &p_scb->cfg, sizeof(tAVDT_CFG)); cfg.num_codec = 1; @@ -1858,11 +1871,16 @@ void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) cfg.psc_mask &= p_scb->p_cap->psc_mask; p_scb->cur_psc_mask = cfg.psc_mask; - if ((uuid_int == UUID_SERVCLASS_AUDIO_SINK) && - (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL)) { - APPL_TRACE_DEBUG(" Configure Deoder for Sink Connection "); - p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT, - (tBTA_AV_MEDIA *)p_scb->cfg.codec_info); + if (uuid_int == UUID_SERVCLASS_AUDIO_SINK) { + if (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL) { + APPL_TRACE_DEBUG(" Configure Deoder for Sink Connection "); + p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT, + (tBTA_AV_MEDIA *)p_scb->cfg.codec_info); + } + if (p_scb->cur_psc_mask & AVDT_PSC_DELAY_RPT) { + psc_cfg.psc_mask |= BTA_AV_PSC_DEALY_RPT; + } + (*bta_av_cb.p_cback)(BTA_AV_SNK_PSC_CFG_EVT, (tBTA_AV *)&psc_cfg); } /* open the stream */ @@ -1878,7 +1896,6 @@ void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) p_scb->sep_info_idx++; bta_av_next_getcap(p_scb, p_data); } - } /******************************************************************************* @@ -2956,4 +2973,31 @@ void bta_av_open_at_inc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) } } +/******************************************************************************* +** +** Function bta_av_set_delay_value +** +** Description This function is called if application layer +** call the API set_delay_value +** +** Returns void +** +*******************************************************************************/ +void bta_av_set_delay_value (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) +{ + tBTA_AV_DELAY delay = {0}; + + AVDT_SetDelayValue(p_data->api_set_delay_vlaue.delay_value); + delay.delay_value = p_data->api_set_delay_vlaue.delay_value; + + if (p_scb->state == BTA_AV_OPEN_SST) { + if (AVDT_DelayReport(p_scb->avdt_handle, 0, delay.delay_value) != AVDT_SUCCESS) { + delay.status = BTA_AV_FAIL; + } + } + + /* call callback with set delay value event */ + (*bta_av_cb.p_cback)(BTA_AV_SET_DELAY_VALUE_EVT, (tBTA_AV *)&delay); +} + #endif /* BTA_AV_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/av/bta_av_api.c b/components/bt/host/bluedroid/bta/av/bta_av_api.c index 284cd8c523..eadb30085f 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_api.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_api.c @@ -373,6 +373,45 @@ void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data, UINT16 } } +/******************************************************************************* +** +** Function BTA_SetDelayValue +** +** Description Set delay report value +** +** Returns void +** +*******************************************************************************/ +void BTA_SetDelayValue(UINT16 delay_value) +{ + tBTA_AV_API_SET_DELAY_VALUE *p_buf; + + if ((p_buf = (tBTA_AV_API_SET_DELAY_VALUE *) osi_malloc(sizeof(tBTA_AV_API_SET_DELAY_VALUE))) != NULL) { + p_buf->hdr.event = BTA_AV_API_SET_DELAY_VALUE_EVT; + p_buf->delay_value = delay_value; + bta_sys_sendmsg(p_buf); + } +} + +/******************************************************************************* +** +** Function BTA_GetDelayValue +** +** Description Get delay report value +** +** Returns void +** +*******************************************************************************/ +void BTA_GetDelayValue(void) +{ + tBTA_AV_API_GET_DELAY_VALUE *p_buf; + + if ((p_buf = (tBTA_AV_API_GET_DELAY_VALUE *) osi_malloc(sizeof(tBTA_AV_API_GET_DELAY_VALUE))) != NULL) { + p_buf->hdr.event = BTA_AV_API_GET_DELAY_VALUE_EVT; + bta_sys_sendmsg(p_buf); + } +} + /******************************************************************************* ** ** Function BTA_AvRemoteCmd 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 561f0b60d0..f3813a4d03 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_main.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_main.c @@ -35,6 +35,7 @@ #include "stack/l2c_api.h" #include "stack/l2cdefs.h" #include "bta/bta_av_co.h" +#include "stack/a2d_api.h" #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) #include "bta/bta_ar_api.h" #endif @@ -152,6 +153,7 @@ static void bta_av_api_enable(tBTA_AV_DATA *p_data); static void bta_av_api_register(tBTA_AV_DATA *p_data); #if (BTA_AV_SINK_INCLUDED == TRUE) static void bta_av_api_sink_enable(tBTA_AV_DATA *p_data); +static void bta_av_api_get_delay_value(tBTA_AV_DATA *p_data); #endif static void bta_av_ci_data(tBTA_AV_DATA *p_data); #if (AVDT_REPORTING == TRUE) @@ -179,12 +181,14 @@ const tBTA_AV_NSM_ACT bta_av_nsm_act[] = { bta_av_dereg_comp, /* BTA_AV_DEREG_COMP_EVT */ #if (BTA_AV_SINK_INCLUDED == TRUE) bta_av_api_sink_enable, /* BTA_AV_API_SINK_ENABLE_EVT */ + bta_av_api_get_delay_value, /* BTA_AV_API_GET_DELAY_VALUE_EVT */ #endif #if (AVDT_REPORTING == TRUE) bta_av_rpc_conn, /* BTA_AV_AVDT_RPT_CONN_EVT */ #endif bta_av_api_to_ssm, /* BTA_AV_API_START_EVT */ bta_av_api_to_ssm, /* BTA_AV_API_STOP_EVT */ + bta_av_api_to_ssm, /* BTA_AV_API_SET_DELAY_VALUE_EVT */ }; /***************************************************************************** @@ -488,6 +492,27 @@ static void bta_av_api_sink_enable(tBTA_AV_DATA *p_data) } } } + +/******************************************************************************* +** +** Function bta_av_api_get_delay_value +** +** Description Get delay reporting value +** +** +** Returns void +** +*******************************************************************************/ +static void bta_av_api_get_delay_value(tBTA_AV_DATA *p_data) +{ + UNUSED(p_data); + tBTA_AV_DELAY delay; + + delay.delay_value = AVDT_GetDelayValue(); + + /* call callback with get delay value event */ + (*bta_av_cb.p_cback)(BTA_AV_GET_DELAY_VALUE_EVT, (tBTA_AV *)&delay); +} #endif /******************************************************************************* ** @@ -625,6 +650,8 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data) #endif if (bta_av_cb.features & BTA_AV_FEAT_DELAY_RPT) { cs.cfg.psc_mask |= AVDT_PSC_DELAY_RPT; + a2d_set_avdt_sdp_ver(AVDT_VERSION_SYNC); + a2d_set_a2dp_sdp_ver(A2D_VERSION_SYC); } /* keep the configuration in the stream control block */ @@ -1259,6 +1286,7 @@ char *bta_av_evt_code(UINT16 evt_code) case BTA_AV_API_CLOSE_EVT: return "API_CLOSE"; case BTA_AV_AP_START_EVT: return "AP_START"; case BTA_AV_AP_STOP_EVT: return "AP_STOP"; + case BTA_AV_AP_SET_DELAY_VALUE_EVT: return "AP_SET_DELAY_VALUE"; case BTA_AV_API_RECONFIG_EVT: return "API_RECONFIG"; case BTA_AV_API_PROTECT_REQ_EVT: return "API_PROTECT_REQ"; case BTA_AV_API_PROTECT_RSP_EVT: return "API_PROTECT_RSP"; @@ -1303,12 +1331,14 @@ char *bta_av_evt_code(UINT16 evt_code) case BTA_AV_DEREG_COMP_EVT: return "DEREG_COMP"; #if (BTA_AV_SINK_INCLUDED == TRUE) case BTA_AV_API_SINK_ENABLE_EVT: return "SINK_ENABLE"; + case BTA_AV_API_GET_DELAY_VALUE_EVT: return "GET_DELAY_VALUE"; #endif #if (AVDT_REPORTING == TRUE) case BTA_AV_AVDT_RPT_CONN_EVT: return "RPT_CONN"; #endif case BTA_AV_API_START_EVT: return "API_START"; case BTA_AV_API_STOP_EVT: return "API_STOP"; + case BTA_AV_API_SET_DELAY_VALUE_EVT: return "API_SET_DELAY_VALUE"; default: return "unknown"; } } diff --git a/components/bt/host/bluedroid/bta/av/bta_av_ssm.c b/components/bt/host/bluedroid/bta/av/bta_av_ssm.c index c633f3adf6..15acf51386 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_ssm.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_ssm.c @@ -96,6 +96,7 @@ enum { BTA_AV_DELAY_CO, BTA_AV_OPEN_AT_INC, BTA_AV_OPEN_FAIL_SDP, + BTA_AV_SET_DELAY_VALUE, BTA_AV_NUM_SACTIONS }; @@ -115,6 +116,7 @@ static const UINT8 bta_av_sst_init[][BTA_AV_NUM_COLS] = { /* AP_CLOSE_EVT */ {BTA_AV_CLEANUP, BTA_AV_SIGNORE, BTA_AV_INIT_SST }, /* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST }, /* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST }, + /* AP_SET_DELAY_VALUE_EVT */{BTA_AV_SET_DELAY_VALUE,BTA_AV_SIGNORE, BTA_AV_INIT_SST }, /* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST }, /* API_PROTECT_REQ_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST }, /* API_PROTECT_RSP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST }, @@ -154,6 +156,7 @@ static const UINT8 bta_av_sst_incoming[][BTA_AV_NUM_COLS] = { /* AP_CLOSE_EVT */ {BTA_AV_CCO_CLOSE, BTA_AV_DISCONNECT_REQ, BTA_AV_CLOSING_SST }, /* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }, /* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }, + /* AP_SET_DELAY_VALUE_EVT */{BTA_AV_SET_DELAY_VALUE,BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }, /* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }, /* API_PROTECT_REQ_EVT */ {BTA_AV_SECURITY_REQ, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }, /* API_PROTECT_RSP_EVT */ {BTA_AV_SECURITY_RSP, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }, @@ -193,6 +196,7 @@ static const UINT8 bta_av_sst_opening[][BTA_AV_NUM_COLS] = { /* AP_CLOSE_EVT */ {BTA_AV_DO_CLOSE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, /* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST }, /* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST }, + /* AP_SET_DELAY_VALUE_EVT */{BTA_AV_SET_DELAY_VALUE,BTA_AV_SIGNORE, BTA_AV_OPENING_SST }, /* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST }, /* API_PROTECT_REQ_EVT */ {BTA_AV_SECURITY_REQ, BTA_AV_SIGNORE, BTA_AV_OPENING_SST }, /* API_PROTECT_RSP_EVT */ {BTA_AV_SECURITY_RSP, BTA_AV_SIGNORE, BTA_AV_OPENING_SST }, @@ -232,6 +236,7 @@ static const UINT8 bta_av_sst_open[][BTA_AV_NUM_COLS] = { /* AP_CLOSE_EVT */ {BTA_AV_DO_CLOSE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, /* AP_START_EVT */ {BTA_AV_DO_START, BTA_AV_SIGNORE, BTA_AV_OPEN_SST }, /* AP_STOP_EVT */ {BTA_AV_STR_STOPPED, BTA_AV_SIGNORE, BTA_AV_OPEN_SST }, + /* AP_SET_DELAY_VALUE_EVT */{BTA_AV_SET_DELAY_VALUE,BTA_AV_SIGNORE, BTA_AV_OPEN_SST }, /* API_RECONFIG_EVT */ {BTA_AV_RECONFIG, BTA_AV_SIGNORE, BTA_AV_RCFG_SST }, /* API_PROTECT_REQ_EVT */ {BTA_AV_SECURITY_REQ, BTA_AV_SIGNORE, BTA_AV_OPEN_SST }, /* API_PROTECT_RSP_EVT */ {BTA_AV_SECURITY_RSP, BTA_AV_SIGNORE, BTA_AV_OPEN_SST }, @@ -271,6 +276,7 @@ static const UINT8 bta_av_sst_rcfg[][BTA_AV_NUM_COLS] = { /* AP_CLOSE_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, /* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST }, /* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST }, + /* AP_SET_DELAY_VALUE_EVT */{BTA_AV_SET_DELAY_VALUE,BTA_AV_SIGNORE, BTA_AV_RCFG_SST }, /* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST }, /* API_PROTECT_REQ_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST }, /* API_PROTECT_RSP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST }, @@ -310,6 +316,7 @@ static const UINT8 bta_av_sst_closing[][BTA_AV_NUM_COLS] = { /* AP_CLOSE_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, /* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, /* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, + /* AP_SET_DELAY_VALUE_EVT */{BTA_AV_SET_DELAY_VALUE,BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, /* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, /* API_PROTECT_REQ_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, /* API_PROTECT_RSP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }, diff --git a/components/bt/host/bluedroid/bta/av/include/bta_av_int.h b/components/bt/host/bluedroid/bta/av/include/bta_av_int.h index 342a3d1437..36aa0b32d9 100644 --- a/components/bt/host/bluedroid/bta/av/include/bta_av_int.h +++ b/components/bt/host/bluedroid/bta/av/include/bta_av_int.h @@ -52,8 +52,9 @@ enum { /* these events are handled by the AV stream state machine */ BTA_AV_API_OPEN_EVT, BTA_AV_API_CLOSE_EVT, - BTA_AV_AP_START_EVT, /* the following 2 events must be in the same order as the *API_*EVT */ + BTA_AV_AP_START_EVT, /* the following 3 events must be in the same order as the *API_*EVT */ BTA_AV_AP_STOP_EVT, + BTA_AV_AP_SET_DELAY_VALUE_EVT, BTA_AV_API_RECONFIG_EVT, BTA_AV_API_PROTECT_REQ_EVT, BTA_AV_API_PROTECT_RSP_EVT, @@ -99,12 +100,15 @@ enum { BTA_AV_DEREG_COMP_EVT, #if (BTA_AV_SINK_INCLUDED == TRUE) BTA_AV_API_SINK_ENABLE_EVT, + // add + BTA_AV_API_GET_DELAY_VALUE_EVT, #endif #if (AVDT_REPORTING == TRUE) BTA_AV_AVDT_RPT_CONN_EVT, #endif - BTA_AV_API_START_EVT, /* the following 2 events must be in the same order as the *AP_*EVT */ - BTA_AV_API_STOP_EVT + BTA_AV_API_START_EVT, /* the following 3 events must be in the same order as the *AP_*EVT */ + BTA_AV_API_STOP_EVT, + BTA_AV_API_SET_DELAY_VALUE_EVT, }; /* events for AV control block state machine */ @@ -116,13 +120,13 @@ enum { /* events that do not go through state machine */ #define BTA_AV_FIRST_NSM_EVT BTA_AV_API_ENABLE_EVT -#define BTA_AV_LAST_NSM_EVT BTA_AV_API_STOP_EVT +#define BTA_AV_LAST_NSM_EVT BTA_AV_API_SET_DELAY_VALUE_EVT /* API events passed to both SSMs (by bta_av_api_to_ssm) */ #define BTA_AV_FIRST_A2S_API_EVT BTA_AV_API_START_EVT #define BTA_AV_FIRST_A2S_SSM_EVT BTA_AV_AP_START_EVT -#define BTA_AV_LAST_EVT BTA_AV_API_STOP_EVT +#define BTA_AV_LAST_EVT BTA_AV_API_SET_DELAY_VALUE_EVT /* maximum number of SEPS in stream discovery results */ #define BTA_AV_NUM_SEPS 32 @@ -333,6 +337,16 @@ typedef struct { tBTA_AV_DATA_CBACK *p_app_data_cback; /* Application callback for media packets */ } tBTA_AV_SEP; +/* data type for BTA_AV_API_SET_DELAY_VALUE_EVT */ +typedef struct { + BT_HDR hdr; + UINT16 delay_value; +} tBTA_AV_API_SET_DELAY_VALUE; + +/* data type for BTA_AV_API_GET_DELAY_VALUE_EVT */ +typedef struct { + BT_HDR hdr; +} tBTA_AV_API_GET_DELAY_VALUE; /* initiator/acceptor role for adaption */ #define BTA_AV_ROLE_AD_INT 0x00 /* initiator */ @@ -366,6 +380,8 @@ typedef union { tBTA_AV_ROLE_RES role_res; tBTA_AV_SDP_RES sdp_res; tBTA_AV_API_META_RSP api_meta_rsp; + tBTA_AV_API_SET_DELAY_VALUE api_set_delay_vlaue; + tBTA_AV_API_GET_DELAY_VALUE api_get_delay_value; } tBTA_AV_DATA; typedef void (tBTA_AV_VDP_DATA_ACT)(void *p_scb); @@ -682,6 +698,7 @@ extern void bta_av_role_res (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data); extern void bta_av_delay_co (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data); extern void bta_av_open_at_inc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data); extern void bta_av_open_fail_sdp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data); +extern void bta_av_set_delay_value (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data); /* ssm action functions - vdp specific */ extern void bta_av_do_disc_vdp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data); 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 65d7e35cae..443871ceb0 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 @@ -64,6 +64,9 @@ typedef UINT8 tBTA_AV_STATUS; /* Internal features */ #define BTA_AV_FEAT_NO_SCO_SSPD 0x8000 /* Do not suspend av streaming as to AG events(SCO or Call) */ +/* Protocol service capabilities mask*/ +#define BTA_AV_PSC_DEALY_RPT (1<<0) /* Delay Report */ + typedef UINT16 tBTA_AV_FEAT; /* AV channel values */ @@ -247,8 +250,11 @@ typedef UINT8 tBTA_AV_ERR; #define BTA_AV_RC_FEAT_EVT 19 /* remote control channel peer supported features update */ #define BTA_AV_MEDIA_SINK_CFG_EVT 20 /* command to configure codec */ #define BTA_AV_MEDIA_DATA_EVT 21 /* sending data to Media Task */ +#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. */ /* Max BTA event */ -#define BTA_AV_MAX_EVT 22 +#define BTA_AV_MAX_EVT 25 /* function types for call-out functions */ @@ -461,6 +467,17 @@ typedef struct { tBTA_AV_HNDL hndl; /* Handle associated with the stream that rejected the connection. */ } tBTA_AV_REJECT; +/* data associated with BTA_AV_SET_DELAY_VALUE_EVT/BTA_AV_GET_DELAY_VALUE_EVT */ +typedef struct { + tBTA_AV_STATUS status; + UINT16 delay_value; +} tBTA_AV_DELAY; + +/* data associated with BTA_AV_SNK_PSC_CFG_EVT */ +typedef struct { + UINT16 psc_mask; +} tBTA_AV_SNK_PSC_CFG; + /* union of data associated with AV callback */ typedef union { @@ -484,6 +501,8 @@ typedef union { tBTA_AV_META_MSG meta_msg; tBTA_AV_REJECT reject; tBTA_AV_RC_FEAT rc_feat; + tBTA_AV_DELAY delay; + tBTA_AV_SNK_PSC_CFG psc; } tBTA_AV; /* union of data associated with AV Media callback */ @@ -723,6 +742,28 @@ void BTA_AvProtectReq(tBTA_AV_HNDL hndl, UINT8 *p_data, UINT16 len); void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data, UINT16 len); +/******************************************************************************* +** +** Function BTA_SetDelayValue +** +** Description Set delay report value +** +** Returns void +** +*******************************************************************************/ +void BTA_SetDelayValue(UINT16 delay_value); + +/******************************************************************************* +** +** Function BTA_GetDelayValue +** +** Description Get delay report value +** +** Returns void +** +*******************************************************************************/ +void BTA_GetDelayValue(void); + /******************************************************************************* ** ** Function BTA_AvRemoteCmd diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c index a3250cdac5..5a006e8411 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c @@ -979,6 +979,7 @@ void bta_av_co_audio_drop(tBTA_AV_HNDL hndl) *******************************************************************************/ void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, UINT16 delay) { + // todo FUNC_TRACE(); APPL_TRACE_ERROR("bta_av_co_audio_delay handle: x%x, delay:0x%x", hndl, delay); 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 f198294d50..7ab8c78320 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 @@ -52,6 +52,9 @@ bool g_a2dp_sink_ongoing_deinit; #define BTC_AV_SERVICE_NAME "Advanced Audio" #define BTC_TIMEOUT_AV_OPEN_ON_RC_SECS 2 +/* Max audio per 3-DH5 EDR packet: 23.2ms + jitter buffer: 5(JITTER_BUFFER_WATER_LEVEL) */ +#define BTC_DELAY_REPORT_DFT_VALUE 1200 // 120ms typedef enum { BTC_AV_STATE_IDLE = 0x0, @@ -144,6 +147,8 @@ static void btc_a2d_src_deinit(void); #if BTC_AV_SINK_INCLUDED static bt_status_t btc_a2d_sink_init(void); static bt_status_t btc_a2d_sink_connect(bt_bdaddr_t *remote_bda); +static void btc_a2d_sink_set_delay_value(UINT16 delay_value); +static void btc_a2d_sink_get_delay_value(void); static void btc_a2d_sink_deinit(void); #endif /* BTC_AV_SINK_INCLUDED */ @@ -299,6 +304,8 @@ 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) { + esp_a2d_cb_param_t param; + BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); @@ -389,6 +396,26 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) btc_rc_handler(event, p_data); break; + case BTA_AV_SNK_PSC_CFG_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_psc_cfg_stat.psc_mask = ((tBTA_AV *)p_data)->psc.psc_mask; + btc_a2d_cb_to_app(ESP_A2D_SNK_PSC_CFG_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + case BTA_AV_SET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status; + btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + case BTA_AV_GET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + default: BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event)); @@ -410,6 +437,8 @@ 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) { + esp_a2d_cb_param_t param; + BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); @@ -507,6 +536,27 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) CHECK_RC_EVENT(event, p_data); + case BTA_AV_SNK_PSC_CFG_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_psc_cfg_stat.psc_mask = ((tBTA_AV *)p_data)->psc.psc_mask; + btc_a2d_cb_to_app(ESP_A2D_SNK_PSC_CFG_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + case BTA_AV_SET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status; + btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + + case BTA_AV_GET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + default: BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event)); return FALSE; @@ -528,6 +578,8 @@ 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) { + esp_a2d_cb_param_t param; + BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); @@ -579,6 +631,23 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data) btc_rc_handler(event, (tBTA_AV *)p_data); break; + case BTA_AV_SNK_PSC_CFG_EVT: + break; + case BTA_AV_SET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status; + btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + + case BTA_AV_GET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + default: BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event)); return FALSE; @@ -597,6 +666,7 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data) *******************************************************************************/ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) { + esp_a2d_cb_param_t param; tBTA_AV *p_av = (tBTA_AV *)p_data; BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, @@ -739,6 +809,23 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) CHECK_RC_EVENT(event, p_data); + case BTA_AV_SNK_PSC_CFG_EVT: + break; + case BTA_AV_SET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status; + btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + + case BTA_AV_GET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + default: BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event)); @@ -761,6 +848,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) { tBTA_AV *p_av = (tBTA_AV *)p_data; + esp_a2d_cb_param_t param; BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__, dump_av_sm_event_name(event), btc_av_cb.flags); @@ -909,6 +997,23 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) CHECK_RC_EVENT(event, p_data); + case BTA_AV_SNK_PSC_CFG_EVT: + break; + case BTA_AV_SET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status; + btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + + case BTA_AV_GET_DELAY_VALUE_EVT: +#if BTC_AV_SINK_INCLUDED + param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value; + btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, ¶m); +#endif /* BTC_AV_SINK_INCLUDED */ + break; + default: BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event)); @@ -1307,12 +1412,12 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable, UINT8 tsep) 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, + BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_DELAY_RPT, 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_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD | BTA_AV_FEAT_DELAY_RPT, 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 { @@ -1474,6 +1579,14 @@ void btc_a2dp_call_handler(btc_msg_t *msg) btc_a2dp_sink_reg_data_cb(arg->data_cb); break; } + case BTC_AV_SINK_API_SET_DELAY_VALUE_EVT: { + btc_a2d_sink_set_delay_value(arg->delay_value); + break; + } + case BTC_AV_SINK_API_GET_DELAY_VALUE_EVT: { + btc_a2d_sink_get_delay_value(); + break; + } #endif /* BTC_AV_SINK_INCLUDED */ #if BTC_AV_SRC_INCLUDED case BTC_AV_SRC_API_INIT_EVT: { @@ -1551,6 +1664,24 @@ static bt_status_t btc_a2d_sink_connect(bt_bdaddr_t *remote_bda) return btc_queue_connect(UUID_SERVCLASS_AUDIO_SINK, remote_bda, connect_int); } +static void btc_a2d_sink_set_delay_value(UINT16 delay_value) +{ + esp_a2d_cb_param_t param; + + if (delay_value <= BTC_DELAY_REPORT_DFT_VALUE) { + param.a2d_set_delay_value_stat.delay_value = 0; + param.a2d_set_delay_value_stat.set_state = ESP_A2D_SET_INVALID_PARAMS; + btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, ¶m); + } else { + BTA_SetDelayValue(delay_value); + } +} + +static void btc_a2d_sink_get_delay_value(void) +{ + BTA_GetDelayValue(); +} + static void btc_a2d_sink_deinit(void) { g_a2dp_sink_ongoing_deinit = true; 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 c4fd1ac16b..c097ff008f 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 @@ -62,6 +62,8 @@ typedef enum { BTC_AV_SINK_API_CONNECT_EVT, BTC_AV_SINK_API_DISCONNECT_EVT, BTC_AV_SINK_API_REG_DATA_CB_EVT, + BTC_AV_SINK_API_SET_DELAY_VALUE_EVT, + BTC_AV_SINK_API_GET_DELAY_VALUE_EVT, #endif /* BTC_AV_SINK_INCLUDED */ #if BTC_AV_SRC_INCLUDED BTC_AV_SRC_API_INIT_EVT, @@ -84,6 +86,8 @@ typedef union { bt_bdaddr_t disconn; // BTC_AV_SINK_API_REG_DATA_CB_EVT esp_a2d_sink_data_cb_t data_cb; + // BTC_AV_SINK_API_SET_DELAY_VALUE_EVT + uint16_t delay_value; #endif /* BTC_AV_SINK_INCLUDED */ #if BTC_AV_SRC_INCLUDED // BTC_AV_SRC_API_REG_DATA_CB_EVT diff --git a/components/bt/host/bluedroid/stack/a2dp/a2d_api.c b/components/bt/host/bluedroid/stack/a2dp/a2d_api.c index 8adb200dcd..87ff14c39b 100644 --- a/components/bt/host/bluedroid/stack/a2dp/a2d_api.c +++ b/components/bt/host/bluedroid/stack/a2dp/a2d_api.c @@ -128,11 +128,26 @@ static void a2d_sdp_cback(UINT16 status) ** Returns None ** *******************************************************************************/ -void a2d_set_avdt_sdp_ver (UINT16 avdt_sdp_ver) +void a2d_set_avdt_sdp_ver(UINT16 avdt_sdp_ver) { a2d_cb.avdt_sdp_ver = avdt_sdp_ver; } +/******************************************************************************* + * + * Function a2d_set_a2dp_sdp_ver + * + * Description This function allows the script wrapper to change the + * a2dp version + * + * Returns None + * + ******************************************************************************/ +void a2d_set_a2dp_sdp_ver(UINT16 a2dp_sdp_ver) +{ + a2d_cb.a2dp_sdp_ver = a2dp_sdp_ver; +} + /****************************************************************************** ** ** Function A2D_AddRecord @@ -195,7 +210,7 @@ tA2D_STATUS A2D_AddRecord(UINT16 service_uuid, char *p_service_name, char *p_pro result &= SDP_AddProtocolList(sdp_handle, A2D_NUM_PROTO_ELEMS, proto_list); /* add profile descriptor list */ - result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION, A2D_VERSION); + result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION, a2d_cb.a2dp_sdp_ver); /* add supported feature */ if (features != 0) { @@ -386,6 +401,7 @@ bt_status_t A2D_Init(void) memset(&a2d_cb, 0, sizeof(tA2D_CB)); a2d_cb.avdt_sdp_ver = AVDT_VERSION; + a2d_cb.a2dp_sdp_ver = A2D_VERSION; #if defined(A2D_INITIAL_TRACE_LEVEL) a2d_cb.trace_level = A2D_INITIAL_TRACE_LEVEL; diff --git a/components/bt/host/bluedroid/stack/a2dp/include/a2d_int.h b/components/bt/host/bluedroid/stack/a2dp/include/a2d_int.h index 0791a975f9..e1ec7b441c 100644 --- a/components/bt/host/bluedroid/stack/a2dp/include/a2d_int.h +++ b/components/bt/host/bluedroid/stack/a2dp/include/a2d_int.h @@ -29,7 +29,6 @@ /***************************************************************************** ** Constants *****************************************************************************/ -#define A2D_VERSION 0x0102 /* Number of attributes in A2D SDP record. */ #define A2D_NUM_ATTR 6 @@ -52,6 +51,7 @@ typedef struct { tA2D_FIND_CB find; /* find service control block */ UINT8 trace_level; UINT16 avdt_sdp_ver; /* AVDTP version */ + UINT16 a2dp_sdp_ver; /* A2DP version */ } tA2D_CB; @@ -70,9 +70,6 @@ extern tA2D_CB *a2d_cb_ptr; #define a2d_cb (*a2d_cb_ptr) #endif -/* Used only for conformance testing */ -extern void a2d_set_avdt_sdp_ver (UINT16 avdt_sdp_ver); - #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/stack/avdt/avdt_api.c b/components/bt/host/bluedroid/stack/avdt/avdt_api.c index 1d1637108f..f37db81654 100644 --- a/components/bt/host/bluedroid/stack/avdt/avdt_api.c +++ b/components/bt/host/bluedroid/stack/avdt/avdt_api.c @@ -63,6 +63,9 @@ void avdt_process_timeout(TIMER_LIST_ENT *p_tle) UINT8 err_code = AVDT_ERR_TIMEOUT; switch (p_tle->event) { + case BTU_TTYPE_AVDT_SCB_DELAY_RPT: + event = AVDT_SCB_DELAY_RPT_RSP_TOUT_EVT; + break; case BTU_TTYPE_AVDT_CCB_RET: event = AVDT_CCB_RET_TOUT_EVT + AVDT_CCB_MKR; break; @@ -474,6 +477,9 @@ UINT16 AVDT_DelayReport(UINT8 handle, UINT8 seid, UINT16 delay) tAVDT_SCB *p_scb; UINT16 result = AVDT_SUCCESS; tAVDT_SCB_EVT evt; + UNUSED(seid); + + AVDT_TRACE_DEBUG("%s: delay value: 0x%04x\n", __func__, delay); /* map handle to scb */ if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) { @@ -481,9 +487,14 @@ UINT16 AVDT_DelayReport(UINT8 handle, UINT8 seid, UINT16 delay) } else /* send event to scb */ { - evt.apidelay.hdr.seid = seid; - evt.apidelay.delay = delay; - avdt_scb_event(p_scb, AVDT_SCB_API_DELAY_RPT_REQ_EVT, &evt); + if ((p_scb->cs.tsep == AVDT_TSEP_SNK) && (p_scb->curr_cfg.psc_mask & AVDT_PSC_DELAY_RPT)) { + evt.apidelay.hdr.seid = p_scb->peer_seid; + evt.apidelay.delay = delay; + avdt_scb_event(p_scb, AVDT_SCB_API_DELAY_RPT_REQ_EVT, &evt); + } else { + AVDT_TRACE_WARNING("%s: peer device does not supported\n", __func__); + result = AVDT_BAD_PARAMS; + } } return result; @@ -1261,4 +1272,32 @@ UINT8 AVDT_SetTraceLevel (UINT8 new_level) return (avdt_cb.trace_level); } +/******************************************************************************* +** +** Function AVDT_SetDelayValue +** +** Description Set delay reporting value. +** +** Returns void +** +*******************************************************************************/ +void AVDT_SetDelayValue(UINT16 delay_value) +{ + avdt_cb.delay_value = delay_value; +} + +/******************************************************************************* +** +** Function AVDT_GetDelayValue +** +** Description Get delay reporting value. +** +** Returns delay value +** +*******************************************************************************/ +UINT16 AVDT_GetDelayValue(void) +{ + return avdt_cb.delay_value; +} + #endif /* #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE) */ diff --git a/components/bt/host/bluedroid/stack/avdt/avdt_scb.c b/components/bt/host/bluedroid/stack/avdt/avdt_scb.c index ac6cbce388..43bc4452c9 100644 --- a/components/bt/host/bluedroid/stack/avdt/avdt_scb.c +++ b/components/bt/host/bluedroid/stack/avdt/avdt_scb.c @@ -100,7 +100,8 @@ const char *const avdt_scb_evt_str[] = { "TC_CLOSE_EVT", "TC_CONG_EVT", "TC_DATA_EVT", - "CC_CLOSE_EVT" + "CC_CLOSE_EVT", + "DELAY_RPT_RSP_TOUT_EVT" }; #endif @@ -170,7 +171,10 @@ const tAVDT_SCB_ACTION avdt_scb_action[] = { avdt_scb_chk_snd_pkt, avdt_scb_tc_timer, avdt_scb_clr_vars, - avdt_scb_dealloc + avdt_scb_dealloc, + avdt_scb_hdl_delay_rpt_tout, + avdt_scb_init_open_req, + avdt_scb_send_delay_report_cmd }; /* state table information */ @@ -192,7 +196,7 @@ const UINT8 avdt_scb_st_idle[][AVDT_SCB_NUM_COLS] = { /* API_SECURITY_REQ_EVT */ {AVDT_SCB_CB_ERR, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* API_ABORT_REQ_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* API_GETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, - /* API_SETCONFIG_RSP_EVT */ {AVDT_SCB_SND_SETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST}, + /* API_SETCONFIG_RSP_EVT */ {AVDT_SCB_SND_SETCONFIG_RSP, AVDT_SCB_SEND_DELAY_REPORT_CMD_EVT, AVDT_SCB_CONF_ST}, /* API_SETCONFIG_REJ_EVT */ {AVDT_SCB_SND_SETCONFIG_REJ, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* API_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* API_CLOSE_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, @@ -210,7 +214,7 @@ const UINT8 avdt_scb_st_idle[][AVDT_SCB_NUM_COLS] = { /* MSG_SECURITY_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* MSG_DELAY_RPT_CMD_EVT */ {AVDT_SCB_REJ_STATE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* MSG_DELAY_RPT_RSP_EVT */ {AVDT_SCB_HDL_DELAY_RPT_RSP, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, - /* MSG_SETCONFIG_RSP_EVT */ {AVDT_SCB_HDL_SETCONFIG_RSP, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST}, + /* MSG_SETCONFIG_RSP_EVT */ {AVDT_SCB_HDL_SETCONFIG_RSP, AVDT_SCB_INIT_OPEN_REQ_EVT, AVDT_SCB_CONF_ST}, /* MSG_GETCONFIG_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* MSG_OPEN_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* MSG_START_RSP_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, @@ -228,7 +232,8 @@ const UINT8 avdt_scb_st_idle[][AVDT_SCB_NUM_COLS] = { /* TC_CLOSE_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* TC_CONG_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, - /* CC_CLOSE_EVT */ {AVDT_SCB_CLR_VARS, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST} + /* CC_CLOSE_EVT */ {AVDT_SCB_CLR_VARS, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, + /* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST} }; /* state table for configured state */ @@ -281,7 +286,8 @@ const UINT8 avdt_scb_st_conf[][AVDT_SCB_NUM_COLS] = { /* TC_CLOSE_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST}, /* TC_CONG_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST}, /* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST}, - /* CC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST} + /* CC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, + /* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_HDL_DELAY_RPT_TOUT, AVDT_SCB_IGNORE, AVDT_SCB_CONF_ST} }; /* state table for opening state */ @@ -334,7 +340,8 @@ const UINT8 avdt_scb_st_opening[][AVDT_SCB_NUM_COLS] = { /* TC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* TC_CONG_EVT */ {AVDT_SCB_CONG_STATE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST}, /* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST}, - /* CC_CLOSE_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST} + /* CC_CLOSE_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST}, + /* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPENING_ST} }; /* state table for open state */ @@ -392,7 +399,8 @@ const UINT8 avdt_scb_st_open[][AVDT_SCB_NUM_COLS] = { #endif /* TC_CONG_EVT */ {AVDT_SCB_CONG_STATE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST}, /* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST}, - /* CC_CLOSE_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST} + /* CC_CLOSE_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST}, + /* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_OPEN_ST} }; /* state table for streaming state */ @@ -445,7 +453,8 @@ const UINT8 avdt_scb_st_stream[][AVDT_SCB_NUM_COLS] = { /* TC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* TC_CONG_EVT */ {AVDT_SCB_CONG_STATE, AVDT_SCB_CHK_SND_PKT, AVDT_SCB_STREAM_ST}, /* TC_DATA_EVT */ {AVDT_SCB_HDL_PKT, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST}, - /* CC_CLOSE_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST} + /* CC_CLOSE_EVT */ {AVDT_SCB_SND_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST}, + /* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_STREAM_ST} }; /* state table for closing state */ @@ -498,7 +507,8 @@ const UINT8 avdt_scb_st_closing[][AVDT_SCB_NUM_COLS] = { /* TC_CLOSE_EVT */ {AVDT_SCB_HDL_TC_CLOSE, AVDT_SCB_IGNORE, AVDT_SCB_IDLE_ST}, /* TC_CONG_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST}, /* TC_DATA_EVT */ {AVDT_SCB_DROP_PKT, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST}, - /* CC_CLOSE_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST} + /* CC_CLOSE_EVT */ {AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST}, + /* DELAY_RPT_RSP_TOUT_EVT */{AVDT_SCB_IGNORE, AVDT_SCB_IGNORE, AVDT_SCB_CLOSING_ST} }; /* type for state table */ @@ -570,6 +580,7 @@ void avdt_scb_init(void) { memset(&avdt_cb.scb[0], 0, sizeof(tAVDT_SCB) * AVDT_NUM_SEPS); avdt_cb.p_scb_act = (tAVDT_SCB_ACTION *) avdt_scb_action; + avdt_cb.delay_value = AVDT_DELAY_RPT_DFT_VALUE; } diff --git a/components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c b/components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c index 4cdc5a2e36..44ff388878 100644 --- a/components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c +++ b/components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c @@ -837,6 +837,50 @@ void avdt_scb_hdl_setconfig_rej(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) (tAVDT_CTRL *) &p_data->msg.hdr); } +/******************************************************************************* +** +** Function avdt_scb_send_delay_report_cmd +** +** Description This function is to initiate the delay reporting command. +** +** Returns Nothing. +** +*******************************************************************************/ +void avdt_scb_send_delay_report_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) +{ + UINT16 delay_value; + UNUSED(p_data); + + if ((p_scb->cs.tsep == AVDT_TSEP_SNK) && (p_scb->curr_cfg.psc_mask & AVDT_PSC_DELAY_RPT)) { + delay_value = AVDT_GetDelayValue(); + AVDT_DelayReport(avdt_scb_to_hdl(p_scb), p_scb->peer_seid, delay_value); + } +} + +/******************************************************************************* +** +** Function avdt_scb_init_open_req +** +** Description This function sends the SCB an AVDT_SCB_API_OPEN_REQ_EVT +** to initiate sending of an open command message. +** +** Returns Nothing. +** +*******************************************************************************/ +void avdt_scb_init_open_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) +{ + tAVDT_EVT_HDR single; + UNUSED(p_data); + + if (!(p_scb->curr_cfg.psc_mask & AVDT_PSC_DELAY_RPT)) { + /* initiate open */ + single.seid = p_scb->peer_seid; + avdt_scb_event(p_scb, AVDT_SCB_API_OPEN_REQ_EVT, (tAVDT_SCB_EVT *) &single); + } else { + btu_start_timer(&p_scb->timer_entry, BTU_TTYPE_AVDT_SCB_DELAY_RPT, AVDT_SCB_TC_DELAY_RPT_TOUT); + } +} + /******************************************************************************* ** ** Function avdt_scb_hdl_setconfig_rsp @@ -849,16 +893,15 @@ void avdt_scb_hdl_setconfig_rej(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) *******************************************************************************/ void avdt_scb_hdl_setconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) { - tAVDT_EVT_HDR single; UNUSED(p_data); if (p_scb->p_ccb != NULL) { /* save configuration */ memcpy(&p_scb->curr_cfg, &p_scb->req_cfg, sizeof(tAVDT_CFG)); + p_scb->role = AVDT_CONF_INT; - /* initiate open */ - single.seid = p_scb->peer_seid; - avdt_scb_event(p_scb, AVDT_SCB_API_OPEN_REQ_EVT, (tAVDT_SCB_EVT *) &single); + /* send delay reporting command */ + avdt_scb_send_delay_report_cmd(p_scb, p_data); } } @@ -1029,6 +1072,8 @@ void avdt_scb_snd_delay_rpt_req (tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) *******************************************************************************/ void avdt_scb_hdl_delay_rpt_cmd (tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) { + tAVDT_EVT_HDR single; + (*p_scb->cs.p_ctrl_cback)(avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL, AVDT_DELAY_REPORT_EVT, @@ -1036,6 +1081,12 @@ void avdt_scb_hdl_delay_rpt_cmd (tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) if (p_scb->p_ccb) { avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_DELAY_RPT, &p_data->msg); + if(p_scb->role == AVDT_CONF_INT) { + btu_stop_timer(&p_scb->timer_entry); + /* initiate open */ + single.seid = p_scb->peer_seid; + avdt_scb_event(p_scb, AVDT_SCB_API_OPEN_REQ_EVT, (tAVDT_SCB_EVT *) &single); + } } else { avdt_scb_rej_not_in_use(p_scb, p_data); } @@ -1053,6 +1104,16 @@ void avdt_scb_hdl_delay_rpt_cmd (tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) *******************************************************************************/ void avdt_scb_hdl_delay_rpt_rsp (tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) { + tAVDT_EVT_HDR single; + + if ((p_scb->cs.tsep == AVDT_TSEP_SNK) && + (p_scb->state == AVDT_SCB_CONF_ST) && (p_scb->role == AVDT_CONF_INT)) { + btu_stop_timer(&p_scb->timer_entry); + /* initiate open */ + single.seid = p_scb->peer_seid; + avdt_scb_event(p_scb, AVDT_SCB_API_OPEN_REQ_EVT, (tAVDT_SCB_EVT *) &single); + } + (*p_scb->cs.p_ctrl_cback)(avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL, AVDT_DELAY_REPORT_CFM_EVT, @@ -1093,6 +1154,26 @@ void avdt_scb_hdl_tc_close_sto(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) } #endif +/******************************************************************************* + * + * Function avdt_scb_hdl_delay_rpt_tout + * + * Description The timer triggers the sending of AVDT open_req. + * This function is theoretically not called. + * + * Returns Nothing. + * + ******************************************************************************/ +void avdt_scb_hdl_delay_rpt_tout(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) +{ + tAVDT_EVT_HDR single; + UNUSED(p_data); + + /* initiate open */ + single.seid = p_scb->peer_seid; + avdt_scb_event(p_scb, AVDT_SCB_API_OPEN_REQ_EVT, (tAVDT_SCB_EVT *) &single); +} + /******************************************************************************* ** ** Function avdt_scb_hdl_tc_open @@ -1654,6 +1735,7 @@ void avdt_scb_snd_setconfig_rsp(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) { if (p_scb->p_ccb != NULL) { memcpy(&p_scb->curr_cfg, &p_scb->req_cfg, sizeof(tAVDT_CFG)); + p_scb->role = AVDT_CONF_ACP; avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_SETCONFIG, &p_data->msg); } diff --git a/components/bt/host/bluedroid/stack/avdt/include/avdt_int.h b/components/bt/host/bluedroid/stack/avdt/include/avdt_int.h index 06bedc3573..3b850c17e5 100644 --- a/components/bt/host/bluedroid/stack/avdt/include/avdt_int.h +++ b/components/bt/host/bluedroid/stack/avdt/include/avdt_int.h @@ -80,6 +80,8 @@ enum { #define AVDT_CLOSE_INT 1 #define AVDT_OPEN_ACP 2 #define AVDT_OPEN_INT 3 +#define AVDT_CONF_ACP 4 +#define AVDT_CONF_INT 5 /* states for avdt_scb_verify */ #define AVDT_VERIFY_OPEN 0 @@ -109,6 +111,9 @@ enum { /* scb transport channel disconnect timeout value */ #define AVDT_SCB_TC_DISC_TOUT 10 +/* scb transport delay reporting command timeout value */ +#define AVDT_SCB_TC_DELAY_RPT_TOUT 5 + /* maximum number of command retransmissions */ #ifndef AVDT_RET_MAX #define AVDT_RET_MAX 1 @@ -276,6 +281,9 @@ enum { AVDT_SCB_TC_TIMER, AVDT_SCB_CLR_VARS, AVDT_SCB_DEALLOC, + AVDT_SCB_HDL_DELAY_RPT_TOUT, + AVDT_SCB_INIT_OPEN_REQ_EVT, + AVDT_SCB_SEND_DELAY_REPORT_CMD_EVT, AVDT_SCB_NUM_ACTIONS }; @@ -330,7 +338,8 @@ enum { AVDT_SCB_TC_CLOSE_EVT, AVDT_SCB_TC_CONG_EVT, AVDT_SCB_TC_DATA_EVT, - AVDT_SCB_CC_CLOSE_EVT + AVDT_SCB_CC_CLOSE_EVT, + AVDT_SCB_DELAY_RPT_RSP_TOUT_EVT }; /* adaption layer number of stream routing table entries */ @@ -550,6 +559,7 @@ typedef struct { tAVDT_SCB_ACTION *p_scb_act; /* pointer to SCB action functions */ tAVDT_CTRL_CBACK *p_conn_cback; /* connection callback function */ UINT8 trace_level; /* trace level */ + UINT16 delay_value; /* delay reporting value */ } tAVDT_CB; @@ -674,6 +684,9 @@ extern void avdt_scb_clr_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); extern void avdt_scb_tc_timer(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); extern void avdt_scb_clr_vars(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); extern void avdt_scb_queue_frags(tAVDT_SCB *p_scb, UINT8 **pp_data, UINT32 *p_data_len, fixed_queue_t *pq); +extern void avdt_scb_hdl_delay_rpt_tout(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); +extern void avdt_scb_init_open_req(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); +extern void avdt_scb_send_delay_report_cmd(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data); /* msg function declarations */ extern BOOLEAN avdt_msg_send(tAVDT_CCB *p_ccb, BT_HDR *p_msg); diff --git a/components/bt/host/bluedroid/stack/btu/btu_task.c b/components/bt/host/bluedroid/stack/btu/btu_task.c index 83d4219542..a305e76fea 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_task.c +++ b/components/bt/host/bluedroid/stack/btu/btu_task.c @@ -334,6 +334,7 @@ static void btu_general_alarm_process(void *param) #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE) + case BTU_TTYPE_AVDT_SCB_DELAY_RPT: case BTU_TTYPE_AVDT_CCB_RET: case BTU_TTYPE_AVDT_CCB_RSP: case BTU_TTYPE_AVDT_CCB_IDLE: diff --git a/components/bt/host/bluedroid/stack/include/stack/a2d_api.h b/components/bt/host/bluedroid/stack/include/stack/a2d_api.h index 47ed61f31a..4680996ee1 100644 --- a/components/bt/host/bluedroid/stack/include/stack/a2d_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/a2d_api.h @@ -29,6 +29,8 @@ /***************************************************************************** ** constants *****************************************************************************/ +#define A2D_VERSION 0x0102 +#define A2D_VERSION_SYC 0x0103 /* Profile supported features */ #define A2D_SUPF_PLAYER 0x0001 @@ -262,6 +264,28 @@ extern bt_status_t A2D_Init(void); *******************************************************************************/ extern void A2D_Deinit(void); +/******************************************************************************* +** +** Function a2d_set_avdt_sdp_ver +** +** Description Used for change version of avdtp +** +** Returns void +** +*******************************************************************************/ +extern void a2d_set_avdt_sdp_ver(UINT16 avdt_sdp_ver); + +/******************************************************************************* +** +** Function a2d_set_a2dp_sdp_ver +** +** Description Used for change version of a2dp +** +** Returns void +** +*******************************************************************************/ +extern void a2d_set_a2dp_sdp_ver(UINT16 a2dp_sdp_ver); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/avdt_api.h b/components/bt/host/bluedroid/stack/include/stack/avdt_api.h index 26919697b4..42a1f85570 100644 --- a/components/bt/host/bluedroid/stack/include/stack/avdt_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/avdt_api.h @@ -109,6 +109,12 @@ typedef UINT8 AVDT_REPORT_TYPE; #define AVDT_PSC_MUX (1<<6) /* Multiplexing */ #define AVDT_PSC_DELAY_RPT (1<<8) /* Delay Report */ +/* Max audio per 3-DH5 EDR packet: 23.2ms +** jitter buffer: 5(JITTER_BUFFER_WATER_LEVEL) +*/ +#define AVDT_DELAY_RPT_DFT_VALUE 1200 /* 120 ms */ +#define AVDT_DELAY_RPT_TIMER_TICK_MS 2000 /* 2000 ms */ + /* Recovery type. This indicates the recovery type. */ #define AVDT_RECOV_RFC2733 1 /* RFC2733 recovery */ @@ -980,6 +986,28 @@ extern UINT16 AVDT_SendReport(UINT8 handle, AVDT_REPORT_TYPE type, ******************************************************************************/ extern UINT8 AVDT_SetTraceLevel (UINT8 new_level); +/******************************************************************************* +** +** Function AVDT_SetDelayValue +** +** Description Set delay reporting value. +** +** Returns void +** +*******************************************************************************/ +extern void AVDT_SetDelayValue(UINT16 delay_value); + +/******************************************************************************* +** +** Function AVDT_GetDelayValue +** +** Description Get delay reporting value. +** +** Returns delay value +** +*******************************************************************************/ +extern UINT16 AVDT_GetDelayValue(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/btu.h b/components/bt/host/bluedroid/stack/include/stack/btu.h index b3b0bc3a43..fd284c9090 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btu.h +++ b/components/bt/host/bluedroid/stack/include/stack/btu.h @@ -118,12 +118,11 @@ typedef void (*tBTU_EVENT_CALLBACK)(BT_HDR *p_hdr); #define BTU_TTYPE_HSP2_SDP_RTRY_TO 56 /* BTU internal */ -/* unused 60 */ - -#define BTU_TTYPE_AVDT_CCB_RET 61 -#define BTU_TTYPE_AVDT_CCB_RSP 62 -#define BTU_TTYPE_AVDT_CCB_IDLE 63 -#define BTU_TTYPE_AVDT_SCB_TC 64 +#define BTU_TTYPE_AVDT_SCB_DELAY_RPT 60 +#define BTU_TTYPE_AVDT_CCB_RET 61 +#define BTU_TTYPE_AVDT_CCB_RSP 62 +#define BTU_TTYPE_AVDT_CCB_IDLE 63 +#define BTU_TTYPE_AVDT_SCB_TC 64 #define BTU_TTYPE_HID_DEV_REPAGE_TO 65 #define BTU_TTYPE_HID_HOST_REPAGE_TO 66 diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c index dddcd2d3c7..d087c992d1 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c @@ -304,6 +304,34 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) } break; } + /* When the bottom layer knows whether the peer device support delay reporting, this event comes */ + case ESP_A2D_SUPPORT_DELAY_RPT_EVT: { + a2d = (esp_a2d_cb_param_t *)(p_param); + if (a2d->a2d_support_delay_rpt_stat.is_support_delay_rpt) { + ESP_LOGI(BT_AV_TAG, "Peer device support delay reporting"); + } else { + ESP_LOGI(BT_AV_TAG, "Peer device unsupport delay reporting"); + } + break; + } + /* when set delay value completed, this event comes */ + case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: { + a2d = (esp_a2d_cb_param_t *)(p_param); + if (ESP_A2D_SET_INVALID_PARAMS == a2d->a2d_set_delay_value_stat.set_state) { + ESP_LOGI(BT_AV_TAG, "Set delay report value: fail"); + } else { + ESP_LOGI(BT_AV_TAG, "Set delay report value: success, delay_value:0x%x * 1/10 ms\n", a2d->a2d_set_delay_value_stat.delay_value); + } + break; + } + /* when get delay value completed, this event comes */ + case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { + a2d = (esp_a2d_cb_param_t *)(p_param); + ESP_LOGI(BT_AV_TAG, "Get delay report value: delay_value:0x%x * 1/10 ms\n", a2d->a2d_get_delay_value_stat.delay_value); + /* Default delay value plus delay caused by application layer */ + esp_a2d_sink_set_delay_value(a2d->a2d_get_delay_value_stat.delay_value + APP_DELAY_VALUE); + break; + } /* others */ default: ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); @@ -437,7 +465,10 @@ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) case ESP_A2D_CONNECTION_STATE_EVT: case ESP_A2D_AUDIO_STATE_EVT: case ESP_A2D_AUDIO_CFG_EVT: - case ESP_A2D_PROF_STATE_EVT: { + case ESP_A2D_PROF_STATE_EVT: + case ESP_A2D_SUPPORT_DELAY_RPT_EVT: + case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: + case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { bt_app_work_dispatch(bt_av_hdl_a2d_evt, event, param, sizeof(esp_a2d_cb_param_t), NULL); break; }