]> granicus.if.org Git - esp-idf/commitdiff
component/bt: clean up AVRCP API and example code
authorwangmengyang <wangmengyang@espressif.com>
Thu, 19 Jan 2017 07:23:46 +0000 (15:23 +0800)
committerwangmengyang <wangmengyang@espressif.com>
Thu, 19 Jan 2017 07:23:46 +0000 (15:23 +0800)
components/bt/bluedroid/api/include/esp_avrc_api.h [new file with mode: 0755]
components/bt/bluedroid/btif/btif_rc.c
components/bt/bluedroid/btif/include/bt_rc.h
examples/09_a2dp/components/bluedroid_demos/app_project/SampleAV.c

diff --git a/components/bt/bluedroid/api/include/esp_avrc_api.h b/components/bt/bluedroid/api/include/esp_avrc_api.h
new file mode 100755 (executable)
index 0000000..e6df848
--- /dev/null
@@ -0,0 +1,121 @@
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __ESP_AVRC_API_H__
+#define __ESP_AVRC_API_H__
+
+#include "esp_err.h"
+#include "esp_bt_defs.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+/// AVRC feature bit mask
+typedef enum {
+    ESP_AVRC_FEAT_RCTG = 0x0001,                 /*!< remote control target */
+    ESP_AVRC_FEAT_RCCT = 0x0002,                 /*!< remote control controller */
+    ESP_AVRC_FEAT_VENDOR = 0x0008,               /*!< remote control vendor dependent commands */
+    ESP_AVRC_FEAT_BROWSE = 0x0010,               /*!< use browsing channel */
+    ESP_AVRC_FEAT_META_DATA = 0x0040,            /*!< remote control metadata transfer command/response */
+    ESP_AVRC_FEAT_ADV_CTRL = 0x0200,             /*!< remote control advanced control commmand/response */
+} esp_avrc_features_t;
+
+/// AVRC passthrough command code
+enum {
+    ESP_AVRC_PT_CMD_PLAY = 0x44,                 /*!< play */
+    ESP_AVRC_PT_CMD_STOP = 0x45,                 /*!< stop */
+    ESP_AVRC_PT_CMD_PAUSE = 0x46,                /*!< pause */
+    ESP_AVRC_PT_CMD_FORWARD = 0x4B,              /*!< forward */
+    ESP_AVRC_PT_CMD_BACKWARD = 0x4C              /*!< backward */
+};
+
+/// AVRC passthrough command state
+enum {
+    ESP_AVRC_PT_CMD_STATE_PRESSED = 0,           /*!< key pressed */
+    ESP_AVRC_PT_CMD_STATE_RELEASED = 1           /*!< key released */
+};
+
+/// AVRC Controller callback events
+typedef enum {
+    ESP_AVRC_CT_CONNECTION_STATE_EVT = 0,        /*!< connection state changed event */
+    ESP_AVRC_CT_PASSTHROUGH_RSP_EVT = 1,         /*!< passthrough response event */
+    ESP_AVRC_CT_MAX_EVT
+} esp_avrc_ct_cb_event_t;
+
+/// AVRC controller callback parameters
+typedef union {
+    /*< ESP_AVRC_CT_CONNECTION_STATE_EVT */
+    struct avrc_ct_conn_stat_param {
+        bool connected;
+       uint32_t feat_mask;
+        esp_bd_addr_t remote_bda;
+    } conn_stat;
+    
+    /*< ESP_AVRC_CT_PASSTHROUGH_RSP_EVT */
+    struct avrc_ct_psth_rsp_param {
+        uint8_t tl;                               /*!< transaction label, 0 to 15 */
+        uint8_t key_code;
+        uint8_t key_state;                        /*!< 0 for  */
+    } psth_rsp;
+} esp_avrc_ct_cb_param_t;
+
+
+/**
+ * @brief AVRCP controler callback function type
+ * @param event : Event type
+ * @param param : Point to callback parameter, currently is union type
+ */
+typedef void (* esp_avrc_ct_cb_t)(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param);
+
+
+/**
+ * @brief           This function is called to register application callbacks
+ *                  to AVRCP module; callbacks will provide the upstream events
+ *                  (type esp_avrc_ct_cb_event_t) and paramters(type esp_avrc_ct_cb_param_t)
+ *                  
+ * @param[in]       callback: A2DP sink event callback function
+ *
+ * @return
+ *                  - ESP_OK: success
+ *                  - ESP_FAIL: others
+ *
+ */
+esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback);
+
+
+/**
+ *
+ * @brief           This function is called to initialize the bluetooth AVRCP controller module
+ *
+ * @return          
+ *                  - ESP_OK: success
+ *                  - ESP_FAIL: others
+ *
+ */
+esp_err_t esp_avrc_ct_init(void);
+
+
+/**
+ *
+ * @brief           This function is called to deinit AVRCP controller module
+ *
+ */
+void esp_avrc_ct_deinit(void);
+
+
+/**
+ * send pass through command to target
+ */
+esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state);
+
+#endif /* __ESP_AVRC_API_H__ */
index 841faed447f01d170ab773400cf2f0690840c744..07a15d22b2fef11ab9c68884a9dc322fcf182abc 100755 (executable)
@@ -38,6 +38,7 @@
 #include "btif_av.h"
 #include "bt_rc.h"
 #include "uinput.h"
+#include "esp_avrc_api.h"
 
 /*****************************************************************************
 **  Constants & Macros
         return BT_STATUS_NOT_READY;                                                         \
     }
 
+#define CHECK_ESP_RC_CONNECTED       do { \
+        BTIF_TRACE_DEBUG("## %s ##", __FUNCTION__); \
+        if (btif_rc_cb.rc_connected == FALSE) { \
+            BTIF_TRACE_WARNING("Function %s() called when RC is not connected", __FUNCTION__); \
+           return ESP_ERR_INVALID_STATE; \
+        } \
+    } while (0)
+
 #define FILL_PDU_QUEUE(index, ctype, label, pending)        \
 {                                                           \
     btif_rc_cb.rc_pdu_info[index].ctype = ctype;            \
@@ -187,7 +196,15 @@ static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp,
 ******************************************************************************/
 static btif_rc_cb_t btif_rc_cb;
 static btrc_callbacks_t *bt_rc_callbacks = NULL;
-static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL;
+// static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL;
+static esp_avrc_ct_cb_t bt_rc_ctrl_callback = NULL;
+
+// TODO: need protection against race
+#define BTIF_AVRC_CT_CB_TO_APP(_event, _param)    do { \
+       if (bt_rc_ctrl_callback) { \
+           bt_rc_ctrl_callback(_event, _param); \
+       } \
+    } while (0)
 
 /*****************************************************************************
 **  Static functions
@@ -372,15 +389,16 @@ void handle_rc_features()
     }
 
     BTIF_TRACE_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features);
-    HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
-
+    // todo: uncomment the following line when added the AVRC target role
+    // HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
+    
 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
      BTIF_TRACE_DEBUG("Checking for feature flags in btif_rc_handler with label %d",
                         btif_rc_cb.rc_vol_label);
      // Register for volume change on connect
-      if(btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL &&
-         btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
-      {
+     if(btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL &&
+       btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
+     {
          rc_transaction_t *p_transaction=NULL;
          bt_status_t status = BT_STATUS_NOT_READY;
          if(MAX_LABEL==btif_rc_cb.rc_vol_label)
@@ -405,7 +423,7 @@ void handle_rc_features()
             btif_rc_cb.rc_vol_label=p_transaction->lbl;
             register_volumechange(btif_rc_cb.rc_vol_label);
          }
-       }
+    }
 #endif
 }
 
@@ -461,9 +479,12 @@ void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
         bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
         /* report connection state if device is AVRCP target */
         if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) {
-            if (bt_rc_ctrl_callbacks != NULL) {
-                HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, TRUE, &rc_addr);
-            }
+           esp_avrc_ct_cb_param_t param;
+           memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
+           param.conn_stat.connected = true;
+           param.conn_stat.feat_mask = btif_rc_cb.rc_features;
+           memcpy(param.conn_stat.remote_bda, &rc_addr, sizeof(esp_bd_addr_t));
+           BTIF_AVRC_CT_CB_TO_APP(ESP_AVRC_CT_CONNECTION_STATE_EVT, &param);
         }
 #endif
     }
@@ -518,9 +539,11 @@ void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
 #if (AVRC_CTLR_INCLUDED == TRUE)
     /* report connection state if device is AVRCP target */
     if (features & BTA_AV_FEAT_RCTG) {
-        if (bt_rc_ctrl_callbacks != NULL) {
-            HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, FALSE, &rc_addr);
-        }
+       esp_avrc_ct_cb_param_t param;
+       memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
+       param.conn_stat.connected = false;
+       memcpy(param.conn_stat.remote_bda, &rc_addr, sizeof(esp_bd_addr_t));
+       BTIF_AVRC_CT_CB_TO_APP(ESP_AVRC_CT_CONNECTION_STATE_EVT, &param);
     }
 #endif
 }
@@ -663,10 +686,14 @@ void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
 
         BTIF_TRACE_DEBUG("%s: rc_id=%d status=%s", __FUNCTION__, p_remote_rsp->rc_id, status);
 
-        release_transaction(p_remote_rsp->label);
-        if (bt_rc_ctrl_callbacks != NULL) {
-            HAL_CBACK(bt_rc_ctrl_callbacks, passthrough_rsp_cb, p_remote_rsp->rc_id, key_state);
-        }
+       do {
+           esp_avrc_ct_cb_param_t param;
+           memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
+            param.psth_rsp.tl = p_remote_rsp->label;
+           param.psth_rsp.key_code = p_remote_rsp->rc_id;
+           param.psth_rsp.key_state = key_state;
+           BTIF_AVRC_CT_CB_TO_APP(ESP_AVRC_CT_PASSTHROUGH_RSP_EVT, &param);
+       } while (0);
     }
     else
     {
@@ -784,8 +811,8 @@ void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg)
             __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu));
 
         /* Since handle_rc_metamsg_cmd() itself is called from
-            *btif context, no context switching is required. Invoke
-            * btif_rc_upstreams_evt directly from here. */
+         btif context, no context switching is required. Invoke
+         * btif_rc_upstreams_evt directly from here. */
         btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code,
                                pmeta_msg->label);
     }
@@ -800,7 +827,7 @@ void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg)
  ***************************************************************************/
 void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
 {
-    BTIF_TRACE_EVENT ("%s event:%s", __FUNCTION__, dump_rc_event(event));
+    BTIF_TRACE_DEBUG ("%s event:%s", __FUNCTION__, dump_rc_event(event));
     switch (event)
     {
         case BTA_AV_RC_OPEN_EVT:
@@ -1267,25 +1294,40 @@ static bt_status_t init(btrc_callbacks_t* callbacks )
     return result;
 }
 
+
 /*******************************************************************************
 **
-** Function         init_ctrl
+** Function         esp_avrc_ct_register_callback
+**
+** Description      Register AVRCP controller callback function
+**
+** Returns          esp_err_t
+**
+*******************************************************************************/
+esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback)
+{
+    if (bt_rc_ctrl_callback)
+       return ESP_FAIL;
+
+    bt_rc_ctrl_callback = callback;
+    return ESP_OK;
+}
+
+
+/*******************************************************************************
+**
+** Function         esp_avrc_ct_init
 **
 ** Description      Initializes the AVRC interface
 **
-** Returns          bt_status_t
+** Returns          esp_err_t
 **
 *******************************************************************************/
-// static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks )
-bt_status_t btrc_ctrl_init(btrc_ctrl_callbacks_t *callbacks)
+esp_err_t esp_avrc_ct_init(void)
 {
     BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
-    bt_status_t result = BT_STATUS_SUCCESS;
-
-    if (bt_rc_ctrl_callbacks)
-        return BT_STATUS_DONE;
+    esp_err_t result = ESP_OK;
 
-    bt_rc_ctrl_callbacks = callbacks;
     memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
     btif_rc_cb.rc_vol_label=MAX_LABEL;
     btif_rc_cb.rc_volume=MAX_VOLUME;
@@ -1647,56 +1689,54 @@ static void cleanup()
 ** Returns          void
 **
 ***************************************************************************/
-void btrc_ctrl_cleanup(void)
-// static void cleanup_ctrl()
+void esp_avrc_ct_deinit(void)
 {
     BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
 
-    if (bt_rc_ctrl_callbacks)
+    if (bt_rc_ctrl_callback)
     {
-        bt_rc_ctrl_callbacks = NULL;
+        bt_rc_ctrl_callback = NULL;
     }
     memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
     lbl_destroy();
     BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
 }
 
-bt_status_t btrc_ctrl_send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
-// static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
+esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state)
 {
     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
+    if (tl >= 16 ||
+        key_state > ESP_AVRC_PT_CMD_STATE_RELEASED) {
+        return ESP_ERR_INVALID_ARG;
+    }
 #if (AVRC_CTLR_INCLUDED == TRUE)
-    CHECK_RC_CONNECTED
-    rc_transaction_t *p_transaction=NULL;
+    CHECK_ESP_RC_CONNECTED;
     BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
                                                     key_code, key_state);
     if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
     {
-        bt_status_t tran_status = get_transaction(&p_transaction);
-        if(BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
-        {
-            BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
-                (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
-            status =  BT_STATUS_SUCCESS;
-            BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
-        }
-        else
-        {
-            status =  BT_STATUS_FAIL;
-            BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
-        }
+        BTA_AvRemoteCmd(btif_rc_cb.rc_handle, tl,
+                        (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
+        status =  BT_STATUS_SUCCESS;
+        BTIF_TRACE_EVENT("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
     }
     else
     {
-        status =  BT_STATUS_FAIL;
+        status = BT_STATUS_FAIL;
         BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
     }
 #else
     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
 #endif
-    return status;
+
+    switch (status) {
+    case BT_STATUS_SUCCESS: return ESP_OK;
+    case BT_STATUS_UNSUPPORTED: return ESP_ERR_NOT_SUPPORTED;
+    default: return ESP_FAIL;
+    }
 }
 
+#if 0
 static const btrc_interface_t bt_rc_interface = {
     sizeof(bt_rc_interface),
     init,
@@ -1713,14 +1753,6 @@ static const btrc_interface_t bt_rc_interface = {
     cleanup,
 };
 
-#if 0
-static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
-    sizeof(bt_rc_ctrl_interface),
-    init_ctrl,
-    send_passthrough_cmd,
-    cleanup_ctrl,
-};
-#endif
 /*******************************************************************************
 **
 ** Function         btif_rc_get_interface
@@ -1736,22 +1768,8 @@ const btrc_interface_t *btif_rc_get_interface(void)
     return &bt_rc_interface;
 }
 
-/*******************************************************************************
-**
-** Function         btif_rc_ctrl_get_interface
-**
-** Description      Get the AVRCP Controller callback interface
-**
-** Returns          btav_interface_t
-**
-*******************************************************************************/
-#if 0
-const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void)
-{
-    BTIF_TRACE_EVENT("%s", __FUNCTION__);
-    return &bt_rc_ctrl_interface;
-}
-#endif
+#endif /* #if 0*/
+
 /*******************************************************************************
 **      Function         initialize_transaction
 **
index 72e407bcc60119d4278de0f731e31bae7e61e097..a0e7345ec474a75955387f0dbaa97ace7aba084a 100755 (executable)
@@ -276,34 +276,4 @@ typedef struct {
     btrc_connection_state_callback              connection_state_cb;
 } btrc_ctrl_callbacks_t;
 
-#if 0
-/** Represents the standard BT-RC AVRCP Controller interface. */
-typedef struct {
-
-    /** set to sizeof(BtRcInterface) */
-    size_t          size;
-    /**
-     * Register the BtRc callbacks
-     */
-    bt_status_t (*init)( btrc_ctrl_callbacks_t* callbacks );
-
-    /** send pass through command to target */
-    bt_status_t (*send_pass_through_cmd) ( bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state );
-
-    /** Closes the interface. */
-    void  (*cleanup)( void );
-} btrc_ctrl_interface_t;
-#endif
-
-/**
- * Register the BtRc callbacks
- */
-bt_status_t btrc_ctrl_init(btrc_ctrl_callbacks_t *callbacks);
-
-/** send pass through command to target */
-bt_status_t btrc_ctrl_send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state);
-
-/** Closes the interface. */
-void btrc_ctrl_cleanup(void);
-
 #endif /* __BT_RC_H__ */
index de2f1573b8e5b0e264b71fe881d87a6dfbd9374b..3bf8cf7f892c4ce359a000fbbc878e3158cb8e75 100644 (file)
 #include "esp_bt_stack_manager.h"
 #include "esp_gap_bt_api.h"
 #include "esp_a2dp_api.h"
-
-#include "bt_rc.h"
+#include "esp_avrc_api.h"
 
 typedef enum {
     BT_APP_EVT_STACK_ON = 0xa0,
     BT_APP_EVT_MAX
 } bt_app_evt_t;
 
-typedef struct {
-    bool state;
-    bt_bdaddr_t bd_addr;
-} esp_avrc_conn_state_t;
-
-typedef struct {
-    int id;
-    int key_state;
-} esp_avrc_passthrough_rsp_t;
-
-typedef struct {
-    int id;
-    int key_state;
-} esp_avrc_key_state_t;
 
 typedef union {
     esp_a2d_cb_param_t a2d;
-    esp_avrc_conn_state_t avrc_state;
-    esp_avrc_passthrough_rsp_t avrc_passthrough_rsp;
-    esp_avrc_key_state_t avrc_key;
+    esp_avrc_ct_cb_event_t rc;
 } bt_app_evt_arg;
 
-/// AVRC callback events
-typedef enum {
-    ESP_AVRC_CONNECTION_STATE_EVT = 5,           /*!< connection state changed event */
-    ESP_AVRC_PASSTHROUGH_RSP_EVT,                /*!< AVRC PASSTHROUGH commands */
-    ESP_AVRC_KEY_STATE_TO
-} esp_avrc_cb_event_t;
-
 static esp_a2d_audio_state_t m_audio_state = ESP_A2D_AUDIO_STATE_STOPPED;
-static TimerHandle_t m_key_tmr = 0;
-static int m_key_state = 1; // 0 for pressed, 1 for released
-static xTaskHandle  xKeyTaskHandle = 0;
 
 static void bt_app_handle_evt(uint16_t event, void *p_param);
 
-static void key_press_task_handler(void *arg)
-{
-    int key_id = 0x48; // rewind
-    for(;;) {
-        if (m_audio_state != ESP_A2D_AUDIO_STATE_STARTED) {
-            BT_APP_TRACE_EVENT("-----key_tmr_hdlr, return, audio state: %d\n", m_audio_state);
-            vTaskDelay(5000 / portTICK_PERIOD_MS);
-            continue;
-        }
-
-        bt_app_evt_arg param;
-        memset(&param, 0, sizeof(bt_app_evt_arg));
-        if (m_key_state == 1) {
-            param.avrc_key.key_state = 1;
-            m_key_state = 0;
-            vTaskDelay(5000 / portTICK_PERIOD_MS);
-        } else {
-            param.avrc_key.key_state = 0;
-            m_key_state = 1;
-            vTaskDelay(30 / portTICK_PERIOD_MS);
-        }
-        param.avrc_key.id = key_id; // 0x41 volume up, 0x4b FORWARD
-
-        BT_APP_TRACE_EVENT("-----key_task_hdlr: %d, key_id %d---\n", m_key_state, param.avrc_key.id);
-        bt_app_transfer_context(bt_app_handle_evt, ESP_AVRC_KEY_STATE_TO, &param, sizeof(bt_app_evt_arg), NULL);
-    }
-}
+static void bt_app_handle_rc_evt(uint16_t event, void *p_param);
 
 static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
 {
@@ -103,35 +50,25 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
     }
 }
 
-static void btrc_passthrough_rsp_cb(int id, int key_state)
+static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
 {
-    bt_app_evt_arg param;
-    memset(&param, 0, sizeof(bt_app_evt_arg));
-    param.avrc_passthrough_rsp.id = id;
-    param.avrc_passthrough_rsp.key_state = key_state;
-    bt_app_transfer_context(bt_app_handle_evt, ESP_AVRC_PASSTHROUGH_RSP_EVT, &param, sizeof(bt_app_evt_arg), NULL);
+    // EspAudioPlayerStreamWrite((uint8_t *)data, len, 10);
 }
 
-static void btrc_conn_state_cb(bool state, bt_bdaddr_t *bd_addr)
+static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param)
 {
-    bt_app_evt_arg param;
-    memset(&param, 0, sizeof(bt_app_evt_arg));
-    param.avrc_state.state = state;
-    memcpy(&param.avrc_state.bd_addr, bd_addr, sizeof(bt_bdaddr_t));
-    bt_app_transfer_context(bt_app_handle_evt, ESP_AVRC_CONNECTION_STATE_EVT, &param, sizeof(bt_app_evt_arg), NULL);
+    switch (event) {
+    case ESP_AVRC_CT_CONNECTION_STATE_EVT:
+    case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: {
+        bt_app_transfer_context(bt_app_handle_rc_evt, event, param, sizeof(bt_app_evt_arg), NULL);
+        break;
+    }
+    default:
+        BT_APP_TRACE_ERROR("===a2dp invalid cb event: %d\n", event);
+        break;
+    }
 }
 
-static btrc_ctrl_callbacks_t btrc_ctrl_cb = {
-    sizeof(btrc_ctrl_callbacks_t),
-    btrc_passthrough_rsp_cb,
-    btrc_conn_state_cb
-};
-
-static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
-{
-    // EspAudioPlayerStreamWrite((uint8_t *)data, len, 10);
-}
-                           
 static void bt_app_handle_evt(uint16_t event, void *p_param)
 {
     BT_APP_TRACE_DEBUG("bt_app_handle_evt 0x%x\n", event);
@@ -145,8 +82,10 @@ static void bt_app_handle_evt(uint16_t event, void *p_param)
         esp_a2d_register_data_callback(bt_app_a2d_data_cb);
 
         esp_a2d_sink_init();
-       
-       btrc_ctrl_init(&btrc_ctrl_cb);
+
+        esp_avrc_ct_init();
+        esp_avrc_ct_register_callback(bt_app_rc_ct_cb);
+        
         esp_bt_gap_set_scan_mode(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
         break;
     }
@@ -157,13 +96,8 @@ static void bt_app_handle_evt(uint16_t event, void *p_param)
     }
     case ESP_A2D_AUDIO_STATE_EVT: {
         a2d = (esp_a2d_cb_param_t *)(p_param);
-        BT_APP_TRACE_EVENT("===a2dp audio_state_cb %d, %d===\n", a2d->audio_stat.state, (int)m_key_tmr);
+        BT_APP_TRACE_EVENT("===a2dp audio_state_cb %d===\n", a2d->audio_stat.state);
         m_audio_state = a2d->audio_stat.state;
-        if (m_audio_state == ESP_A2D_AUDIO_STATE_STARTED &&
-            m_key_tmr == 0) {
-            BT_APP_TRACE_EVENT("mm1\n");
-            xTaskCreate(key_press_task_handler, "keyT", 2048, NULL, 10, &xKeyTaskHandle);
-        }
         break;
     }
     case ESP_A2D_AUDIO_CFG_EVT: {
@@ -178,27 +112,32 @@ static void bt_app_handle_evt(uint16_t event, void *p_param)
         }
         break;
     }
-    case ESP_AVRC_CONNECTION_STATE_EVT: {
-        esp_avrc_conn_state_t *conn_state = (esp_avrc_conn_state_t *)(p_param);
-        BT_APP_TRACE_EVENT("===avrc conn_state evt %d ===\n", conn_state->state);
+    default:
+        BT_APP_TRACE_ERROR("===application invalid event: %d\n", event);
         break;
     }
-    case ESP_AVRC_PASSTHROUGH_RSP_EVT: {
-        esp_avrc_passthrough_rsp_t *passthrough_rsp = (esp_avrc_passthrough_rsp_t *)(p_param);
-        BT_APP_TRACE_EVENT("===avrc passthrough evt id 0x%x, key_state %d===\n", passthrough_rsp->id, passthrough_rsp->key_state);
+    
+}
+
+void bt_app_handle_rc_evt(uint16_t event, void *p_param)
+{
+    BT_APP_TRACE_DEBUG("bt_app_handle_avrc_evt 0x%x\n", event);
+    esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(p_param);
+    switch (event) {
+    case ESP_AVRC_CT_CONNECTION_STATE_EVT: {
+        uint8_t *bda = rc->conn_stat.remote_bda;
+        BT_APP_TRACE_EVENT("===avrc conn_state evt: state %d, feature 0x%x, [%02x:%02x:%02x:%02x:%02x:%02x]===\n",
+                           rc->conn_stat.connected, rc->conn_stat.feat_mask, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
         break;
     }
-    case ESP_AVRC_KEY_STATE_TO: {
-        esp_avrc_key_state_t *key_s = (esp_avrc_key_state_t *)(p_param);
-        BT_APP_TRACE_EVENT("===avrc send key id 0x%x, state %d\n", key_s->id, key_s->key_state);
-        btrc_ctrl_send_passthrough_cmd(NULL, key_s->id, key_s->key_state);
+    case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: {
+        BT_APP_TRACE_EVENT("===avrc passthrough rsp: key_code 0x%x, key_state %d===\n", rc->psth_rsp.key_code, rc->psth_rsp.key_state);
         break;
     }
     default:
         BT_APP_TRACE_ERROR("===application invalid event: %d\n", event);
         break;
     }
-    
 }
 
 void app_main_entry(void)