From 36a74daa0a3058d3135b8280ef82b42e1fe4eab8 Mon Sep 17 00:00:00 2001 From: wangmengyang Date: Thu, 19 Jan 2017 15:23:46 +0800 Subject: [PATCH] component/bt: clean up AVRCP API and example code --- .../bt/bluedroid/api/include/esp_avrc_api.h | 121 +++++++++++++ components/bt/bluedroid/btif/btif_rc.c | 170 ++++++++++-------- components/bt/bluedroid/btif/include/bt_rc.h | 30 ---- .../bluedroid_demos/app_project/SampleAV.c | 139 ++++---------- 4 files changed, 254 insertions(+), 206 deletions(-) create mode 100755 components/bt/bluedroid/api/include/esp_avrc_api.h 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 index 000000000..e6df84878 --- /dev/null +++ b/components/bt/bluedroid/api/include/esp_avrc_api.h @@ -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 +#include + +/// 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__ */ diff --git a/components/bt/bluedroid/btif/btif_rc.c b/components/bt/bluedroid/btif/btif_rc.c index 841faed44..07a15d22b 100755 --- a/components/bt/bluedroid/btif/btif_rc.c +++ b/components/bt/bluedroid/btif/btif_rc.c @@ -38,6 +38,7 @@ #include "btif_av.h" #include "bt_rc.h" #include "uinput.h" +#include "esp_avrc_api.h" /***************************************************************************** ** Constants & Macros @@ -70,6 +71,14 @@ 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(¶m, 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, ¶m); } #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(¶m, 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, ¶m); } #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(¶m, 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, ¶m); + } 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; + esp_err_t result = ESP_OK; - if (bt_rc_ctrl_callbacks) - return BT_STATUS_DONE; - - 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 ** diff --git a/components/bt/bluedroid/btif/include/bt_rc.h b/components/bt/bluedroid/btif/include/bt_rc.h index 72e407bcc..a0e7345ec 100755 --- a/components/bt/bluedroid/btif/include/bt_rc.h +++ b/components/bt/bluedroid/btif/include/bt_rc.h @@ -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__ */ diff --git a/examples/09_a2dp/components/bluedroid_demos/app_project/SampleAV.c b/examples/09_a2dp/components/bluedroid_demos/app_project/SampleAV.c index de2f1573b..3bf8cf7f8 100644 --- a/examples/09_a2dp/components/bluedroid_demos/app_project/SampleAV.c +++ b/examples/09_a2dp/components/bluedroid_demos/app_project/SampleAV.c @@ -15,77 +15,24 @@ #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(¶m, 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, ¶m, 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) -{ - bt_app_evt_arg param; - memset(¶m, 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, ¶m, sizeof(bt_app_evt_arg), NULL); -} - -static void btrc_conn_state_cb(bool state, bt_bdaddr_t *bd_addr) -{ - bt_app_evt_arg param; - memset(¶m, 0, sizeof(bt_app_evt_arg)); - param.avrc_state.state = state; - memcpy(¶m.avrc_state.bd_addr, bd_addr, sizeof(bt_bdaddr_t)); - bt_app_transfer_context(bt_app_handle_evt, ESP_AVRC_CONNECTION_STATE_EVT, ¶m, sizeof(bt_app_evt_arg), NULL); -} - -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_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) +{ + 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 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)