Răsfoiți Sursa

Merge branch 'feature/add_avdtp_delay_reporting' into 'master'

component_bt: add avdtp delay reporting

Closes BT-2308

See merge request espressif/esp-idf!17475
Jiang Jiang Jian 3 ani în urmă
părinte
comite
ffbc25056c
26 a modificat fișierele cu 831 adăugiri și 64 ștergeri
  1. 47 0
      components/bt/host/bluedroid/api/esp_a2dp_api.c
  2. 109 12
      components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h
  3. 54 10
      components/bt/host/bluedroid/bta/av/bta_av_aact.c
  4. 39 0
      components/bt/host/bluedroid/bta/av/bta_av_api.c
  5. 30 0
      components/bt/host/bluedroid/bta/av/bta_av_main.c
  6. 7 0
      components/bt/host/bluedroid/bta/av/bta_av_ssm.c
  7. 22 5
      components/bt/host/bluedroid/bta/av/include/bta_av_int.h
  8. 42 1
      components/bt/host/bluedroid/bta/include/bta/bta_av_api.h
  9. 3 1
      components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c
  10. 24 1
      components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c
  11. 133 2
      components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c
  12. 9 0
      components/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_source.h
  13. 4 0
      components/bt/host/bluedroid/btc/profile/std/include/btc_av.h
  14. 18 2
      components/bt/host/bluedroid/stack/a2dp/a2d_api.c
  15. 1 4
      components/bt/host/bluedroid/stack/a2dp/include/a2d_int.h
  16. 42 3
      components/bt/host/bluedroid/stack/avdt/avdt_api.c
  17. 21 10
      components/bt/host/bluedroid/stack/avdt/avdt_scb.c
  18. 94 5
      components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c
  19. 14 1
      components/bt/host/bluedroid/stack/avdt/include/avdt_int.h
  20. 1 0
      components/bt/host/bluedroid/stack/btu/btu_task.c
  21. 24 0
      components/bt/host/bluedroid/stack/include/stack/a2d_api.h
  22. 28 0
      components/bt/host/bluedroid/stack/include/stack/avdt_api.h
  23. 5 6
      components/bt/host/bluedroid/stack/include/stack/btu.h
  24. 36 1
      examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c
  25. 3 0
      examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c
  26. 21 0
      examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c

+ 47 - 0
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)

+ 109 - 12
components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h

@@ -14,16 +14,24 @@
 extern "C" {
 #endif
 
-/// Media codec types supported by A2DP
+/**
+ * @brief Media codec types supported by A2DP.
+ */
 #define ESP_A2D_MCT_SBC         (0)             /*!< SBC */
 #define ESP_A2D_MCT_M12         (0x01)          /*!< MPEG-1, 2 Audio */
 #define ESP_A2D_MCT_M24         (0x02)          /*!< MPEG-2, 4 AAC */
 #define ESP_A2D_MCT_ATRAC       (0x04)          /*!< ATRAC family */
-#define ESP_A2D_MCT_NON_A2DP    (0xff)
-
+#define ESP_A2D_MCT_NON_A2DP    (0xff)          /*!< NON-A2DP */
 typedef uint8_t esp_a2d_mct_t;
 
-/** A2DP media codec capabilities union
+/**
+ * @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;
+
+/**
+ * @brief A2DP media codec capabilities union
  */
 typedef struct {
     esp_a2d_mct_t type;                        /*!< A2DP media codec type */
@@ -39,7 +47,9 @@ typedef struct {
     } cie;                                     /*!< A2DP codec information element */
 } __attribute__((packed)) esp_a2d_mcc_t;
 
-/// Bluetooth A2DP connection states
+/**
+ * @brief Bluetooth A2DP connection states
+ */
 typedef enum {
     ESP_A2D_CONNECTION_STATE_DISCONNECTED = 0, /*!< connection released  */
     ESP_A2D_CONNECTION_STATE_CONNECTING,       /*!< connecting remote device */
@@ -47,27 +57,35 @@ typedef enum {
     ESP_A2D_CONNECTION_STATE_DISCONNECTING     /*!< disconnecting remote device */
 } esp_a2d_connection_state_t;
 
-/// Bluetooth A2DP disconnection reason
+/**
+ * @brief Bluetooth A2DP disconnection reason
+ */
 typedef enum {
     ESP_A2D_DISC_RSN_NORMAL = 0,               /*!< Finished disconnection that is initiated by local or remote device */
     ESP_A2D_DISC_RSN_ABNORMAL                  /*!< Abnormal disconnection caused by signal loss */
 } esp_a2d_disc_rsn_t;
 
-/// Bluetooth A2DP datapath states
+/**
+ * @brief Bluetooth A2DP datapath states
+ */
 typedef enum {
     ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND = 0,    /*!< audio stream datapath suspended by remote device */
     ESP_A2D_AUDIO_STATE_STOPPED,               /*!< audio stream datapath stopped */
     ESP_A2D_AUDIO_STATE_STARTED,               /*!< audio stream datapath started */
 } esp_a2d_audio_state_t;
 
-/// A2DP media control command acknowledgement code
+/**
+ * @brief A2DP media control command acknowledgement code
+ */
 typedef enum {
     ESP_A2D_MEDIA_CTRL_ACK_SUCCESS = 0,        /*!< media control command is acknowledged with success */
     ESP_A2D_MEDIA_CTRL_ACK_FAILURE,            /*!< media control command is acknowledged with failure */
     ESP_A2D_MEDIA_CTRL_ACK_BUSY,               /*!< media control command is rejected, as previous command is not yet acknowledged */
 } esp_a2d_media_ctrl_ack_t;
 
-/// A2DP media control commands
+/**
+ * @brief A2DP media control commands
+ */
 typedef enum {
     ESP_A2D_MEDIA_CTRL_NONE = 0,               /*!< Not for application use, use inside stack only. */
     ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY,          /*!< check whether AVDTP is connected, only used in A2DP source */
@@ -76,22 +94,40 @@ typedef enum {
     ESP_A2D_MEDIA_CTRL_SUSPEND,                /*!< command to suspend media transmission  */
 } esp_a2d_media_ctrl_t;
 
-/// Bluetooth A2DP Initiation states
+/**
+ * @brief Bluetooth A2DP Initiation states
+ */
 typedef enum {
     ESP_A2D_DEINIT_SUCCESS = 0,                /*!< A2DP profile deinit successful event */
     ESP_A2D_INIT_SUCCESS                       /*!< A2DP profile deinit successful event */
 } esp_a2d_init_state_t;
 
-/// A2DP callback events
+/**
+ * @brief 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;
+
+/**
+ * @brief A2DP callback events
+ */
 typedef enum {
     ESP_A2D_CONNECTION_STATE_EVT = 0,          /*!< connection state changed event */
     ESP_A2D_AUDIO_STATE_EVT,                   /*!< audio stream transmission state changed event */
     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
+/**
+ * @brief A2DP state callback parameters
+ */
 typedef union {
     /**
      * @brief  ESP_A2D_CONNECTION_STATE_EVT
@@ -125,12 +161,43 @@ 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 */
+
+    /**
+     * @brief ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT
+     */
+    struct a2d_report_delay_stat_param {
+        uint16_t delay_value;                  /*!< delay report value */
+    } a2d_report_delay_value_stat;             /*!< A2DP source received sink report value status */
+
 } esp_a2d_cb_param_t;
 
 /**
@@ -261,6 +328,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);
+
 
 /**
  *

+ 54 - 10
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 */

+ 39 - 0
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

+ 30 - 0
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";
     }
 }

+ 7 - 0
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 },

+ 22 - 5
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);

+ 42 - 1
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

+ 3 - 1
components/bt/host/bluedroid/btc/profile/std/a2dp/bta_av_co.c

@@ -981,7 +981,9 @@ void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, UINT16 delay)
 {
     FUNC_TRACE();
 
-    APPL_TRACE_ERROR("bta_av_co_audio_delay handle: x%x, delay:0x%x", hndl, delay);
+    btc_source_report_delay_value(delay);
+
+    APPL_TRACE_DEBUG("bta_av_co_audio_delay handle: x%x, delay:0x%x", hndl, delay);
 }
 
 

+ 24 - 1
components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c

@@ -424,7 +424,6 @@ void btc_a2dp_source_set_tx_flush(BOOLEAN enable)
 ** Returns
 **
 *******************************************************************************/
-
 void btc_a2dp_source_setup_codec(void)
 {
     tBTC_AV_MEDIA_FEEDINGS media_feeding;
@@ -617,6 +616,30 @@ BOOLEAN btc_a2dp_source_tx_flush_req(void)
     return TRUE;
 }
 
+/*****************************************************************************
+**
+** Function        btc_source_report_delay_value
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+void btc_source_report_delay_value(UINT16 delay_value)
+{
+    esp_a2d_cb_param_t param;
+
+#if A2D_DYNAMIC_MEMORY == TRUE
+    if (a2dp_source_local_param_ptr == NULL) {
+        return;
+    }
+#endif
+
+    param.a2d_report_delay_value_stat.delay_value = delay_value;
+
+    btc_aa_cb_to_app(ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT, &param);
+}
+
 /*****************************************************************************
  **  BTC ADAPTATION
  *****************************************************************************/

+ 133 - 2
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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+#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, &param);
+    } 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;

+ 9 - 0
components/bt/host/bluedroid/btc/profile/std/include/btc_a2dp_source.h

@@ -231,6 +231,15 @@ void btc_a2dp_source_set_tx_flush(BOOLEAN enable);
  *******************************************************************************/
 void btc_a2dp_source_encoder_update(void);
 
+/*****************************************************************************
+**
+** Function        btc_source_report_delay_value
+**
+** Description     Report sink delay report value
+**
+*******************************************************************************/
+void btc_source_report_delay_value(UINT16 delay_value);
+
 #endif /* #if BTC_AV_SRC_INCLUDED */
 
 #endif /* __BTC_A2DP_SOURCE_H__ */

+ 4 - 0
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

+ 18 - 2
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;

+ 1 - 4
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

+ 42 - 3
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) */

+ 21 - 10
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;
 }
 
 

+ 94 - 5
components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c

@@ -837,6 +837,52 @@ 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->p_ccb != NULL && p_scb->role == AVDT_CONF_INT) {
+        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 +895,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,13 +1074,26 @@ 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,
                               (tAVDT_CTRL *) &p_data->msg.hdr);
 
     if (p_scb->p_ccb) {
-        avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_DELAY_RPT, &p_data->msg);
+        if (p_scb->cs.cfg.psc_mask & AVDT_PSC_DELAY_RPT) {
+            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 {
+            p_data->msg.hdr.err_code = AVDT_ERR_NSC;
+            avdt_msg_send_rej(p_scb->p_ccb, AVDT_SIG_DELAY_RPT, &p_data->msg);
+        }
     } else {
         avdt_scb_rej_not_in_use(p_scb, p_data);
     }
@@ -1053,6 +1111,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 +1161,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 +1742,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);
     }

+ 14 - 1
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);

+ 1 - 0
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:

+ 24 - 0
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

+ 28 - 0
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

+ 5 - 6
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

+ 36 - 1
examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c

@@ -31,6 +31,9 @@
 #define APP_RC_CT_TL_RN_PLAYBACK_CHANGE  (3)
 #define APP_RC_CT_TL_RN_PLAY_POS_CHANGE  (4)
 
+/* Application layer causes delay value */
+#define APP_DELAY_VALUE                  50  // 5ms
+
 /*******************************
  * STATIC FUNCTION DECLARATIONS
  ******************************/
@@ -304,6 +307,35 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param)
         }
         break;
     }
+    /* When protocol service capabilities configured, this event comes */
+    case ESP_A2D_SNK_PSC_CFG_EVT: {
+        a2d = (esp_a2d_cb_param_t *)(p_param);
+        ESP_LOGI(BT_AV_TAG, "protocol service capabilities configured: 0x%x ", a2d->a2d_psc_cfg_stat.psc_mask);
+        if (a2d->a2d_psc_cfg_stat.psc_mask & ESP_A2D_PSC_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: %u * 1/10 ms", 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: %u * 1/10 ms", 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 +469,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_SNK_PSC_CFG_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;
     }

+ 3 - 0
examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c

@@ -111,6 +111,9 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
         esp_a2d_register_callback(&bt_app_a2d_cb);
         esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb);
 
+        /* Get the default value of the delay value */
+        esp_a2d_sink_get_delay_value();
+
         /* set discoverable and connectable mode, wait to be connected */
         esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
         break;

+ 21 - 0
examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c

@@ -393,6 +393,7 @@ static void bt_app_av_sm_hdlr(uint16_t event, void *param)
 
 static void bt_app_av_state_unconnected_hdlr(uint16_t event, void *param)
 {
+    esp_a2d_cb_param_t *a2d = NULL;
     /* handle the events of intrest in unconnected state */
     switch (event) {
     case ESP_A2D_CONNECTION_STATE_EVT:
@@ -409,6 +410,11 @@ static void bt_app_av_state_unconnected_hdlr(uint16_t event, void *param)
         s_connecting_intv = 0;
         break;
     }
+    case ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT: {
+        a2d = (esp_a2d_cb_param_t *)(param);
+        ESP_LOGI(BT_AV_TAG, "%s, delay value: %u * 1/10 ms", __func__, a2d->a2d_report_delay_value_stat.delay_value);
+        break;
+    }
     default: {
         ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
         break;
@@ -448,6 +454,11 @@ static void bt_app_av_state_connecting_hdlr(uint16_t event, void *param)
             s_connecting_intv = 0;
         }
         break;
+    case ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT: {
+        a2d = (esp_a2d_cb_param_t *)(param);
+        ESP_LOGI(BT_AV_TAG, "%s, delay value: %u * 1/10 ms", __func__, a2d->a2d_report_delay_value_stat.delay_value);
+        break;
+    }
     default:
         ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
         break;
@@ -554,6 +565,11 @@ static void bt_app_av_state_connected_hdlr(uint16_t event, void *param)
         bt_app_av_media_proc(event, param);
         break;
     }
+    case ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT: {
+        a2d = (esp_a2d_cb_param_t *)(param);
+        ESP_LOGI(BT_AV_TAG, "%s, delay value: %u * 1/10 ms", __func__, a2d->a2d_report_delay_value_stat.delay_value);
+        break;
+    }
     default: {
         ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
         break;
@@ -581,6 +597,11 @@ static void bt_app_av_state_disconnecting_hdlr(uint16_t event, void *param)
     case ESP_A2D_MEDIA_CTRL_ACK_EVT:
     case BT_APP_HEART_BEAT_EVT:
         break;
+    case ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT: {
+        a2d = (esp_a2d_cb_param_t *)(param);
+        ESP_LOGI(BT_AV_TAG, "%s, delay value: 0x%u * 1/10 ms", __func__, a2d->a2d_report_delay_value_stat.delay_value);
+        break;
+    }
     default: {
         ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
         break;