From e07b43e924ae32aa13de4ffb48a8ef6e48457384 Mon Sep 17 00:00:00 2001 From: wangmengyang Date: Wed, 27 Dec 2017 19:49:11 +0800 Subject: [PATCH] component/bt: add AVRC event for remote features indication 1. remove the feature mask parameter from AVRC connection state event, as the AVCTP connection can be initiated by remote device before service discovery to remote device is performed. \ In this case, AVRCP connection state event may not be reported after connection initated by remote device is established. 2. remove ESP_AVRC_CT_MAX_EVT 3. add more documentations to AVRC APIs --- .../bt/bluedroid/api/include/esp_avrc_api.h | 61 +++++++++----- components/bt/bluedroid/bta/av/bta_av_act.c | 3 + .../bt/bluedroid/bta/include/bta_av_api.h | 1 + .../bluedroid/btc/profile/std/avrc/btc_avrc.c | 82 ++++++------------- .../btc/profile/std/include/btc_avrc.h | 8 -- examples/bluetooth/a2dp_sink/main/bt_app_av.c | 11 ++- 6 files changed, 77 insertions(+), 89 deletions(-) diff --git a/components/bt/bluedroid/api/include/esp_avrc_api.h b/components/bt/bluedroid/api/include/esp_avrc_api.h index df320b80a..228beb8ae 100644 --- a/components/bt/bluedroid/api/include/esp_avrc_api.h +++ b/components/bt/bluedroid/api/include/esp_avrc_api.h @@ -58,10 +58,10 @@ typedef enum { ESP_AVRC_CT_METADATA_RSP_EVT = 2, /*!< metadata response event */ ESP_AVRC_CT_PLAY_STATUS_RSP_EVT = 3, /*!< play status response event */ ESP_AVRC_CT_CHANGE_NOTIFY_EVT = 4, /*!< notification event */ - ESP_AVRC_CT_MAX_EVT + ESP_AVRC_CT_REMOTE_FEATURES_EVT = 5, /*!< feature of remote device indication event */ } esp_avrc_ct_cb_event_t; -//AVRC metadata attribute mask +/// AVRC metadata attribute mask typedef enum { ESP_AVRC_MD_ATTR_TITLE = 0x1, /*!< title of the playing track */ ESP_AVRC_MD_ATTR_ARTIST = 0x2, /*!< track artist */ @@ -72,7 +72,7 @@ typedef enum { ESP_AVRC_MD_ATTR_PLAYING_TIME = 0x40 /*!< total album playing time in miliseconds */ } esp_avrc_md_attr_mask_t; -//AVRC event notification ids +/// AVRC event notification ids typedef enum { ESP_AVRC_RN_PLAY_STATUS_CHANGE = 0x01, /*!< track status change, eg. from playing to paused */ ESP_AVRC_RN_TRACK_CHANGE = 0x02, /*!< new track is loaded */ @@ -85,7 +85,7 @@ typedef enum { ESP_AVRC_RN_MAX_EVT } esp_avrc_rn_event_ids_t; -//AVRC player setting ids +/// AVRC player setting ids typedef enum { ESP_AVRC_PS_EQUALIZER = 0x01, /*!< equalizer, on or off */ ESP_AVRC_PS_REPEAT_MODE = 0x02, /*!< repeat mode */ @@ -94,32 +94,32 @@ typedef enum { ESP_AVRC_PS_MAX_ATTR } esp_avrc_ps_attr_ids_t; -//AVRC equalizer modes +/// AVRC equalizer modes typedef enum { - ESP_AVRC_PS_EQUALIZER_OFF = 0x1, - ESP_AVRC_PS_EQUALIZER_ON = 0x2 + ESP_AVRC_PS_EQUALIZER_OFF = 0x1, /*!< equalizer OFF */ + ESP_AVRC_PS_EQUALIZER_ON = 0x2 /*!< equalizer ON */ } esp_avrc_ps_eq_value_ids_t; -//AVRC repeat modes +/// AVRC repeat modes typedef enum { - ESP_AVRC_PS_REPEAT_OFF = 0x1, - ESP_AVRC_PS_REPEAT_SINGLE = 0x2, - ESP_AVRC_PS_REPEAT_GROUP = 0x3 + ESP_AVRC_PS_REPEAT_OFF = 0x1, /*!< repeat mode off */ + ESP_AVRC_PS_REPEAT_SINGLE = 0x2, /*!< single track repeat */ + ESP_AVRC_PS_REPEAT_GROUP = 0x3 /*!< group repeat */ } esp_avrc_ps_rpt_value_ids_t; -//AVRC shuffle modes +/// AVRC shuffle modes typedef enum { - ESP_AVRC_PS_SHUFFLE_OFF = 0x1, - ESP_AVRC_PS_SHUFFLE_ALL = 0x2, - ESP_AVRC_PS_SHUFFLE_GROUP = 0x3 + ESP_AVRC_PS_SHUFFLE_OFF = 0x1, /*rc_conn_chg.peer_addr); rc_open.peer_features = p_cb->rcb[i].peer_features; + rc_open.sdp_disc_done = TRUE; rc_open.status = BTA_AV_SUCCESS; APPL_TRACE_DEBUG("local features:x%x peer_features:x%x", p_cb->features, rc_open.peer_features); @@ -536,6 +537,7 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) /* we have not done SDP on peer RC capabilities. * peer must have initiated the RC connection */ rc_open.peer_features = BTA_AV_FEAT_RCCT; + rc_open.sdp_disc_done = FALSE; bta_av_rc_disc(disc); } (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open); @@ -1610,6 +1612,7 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data) p_scb->use_rc = FALSE; bdcpy(rc_open.peer_addr, p_scb->peer_addr); rc_open.peer_features = 0; + rc_open.sdp_disc_done = FALSE; rc_open.status = BTA_AV_FAIL_SDP; (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open); } diff --git a/components/bt/bluedroid/bta/include/bta_av_api.h b/components/bt/bluedroid/bta/include/bta_av_api.h index 24c359910..a7560c9eb 100644 --- a/components/bt/bluedroid/bta/include/bta_av_api.h +++ b/components/bt/bluedroid/bta/include/bta_av_api.h @@ -375,6 +375,7 @@ typedef struct { /* data associated with BTA_AV_RC_OPEN_EVT */ typedef struct { UINT8 rc_handle; + BOOLEAN sdp_disc_done; tBTA_AV_FEAT peer_features; BD_ADDR peer_addr; tBTA_AV_STATUS status; diff --git a/components/bt/bluedroid/btc/profile/std/avrc/btc_avrc.c b/components/bt/bluedroid/btc/profile/std/avrc/btc_avrc.c index 8c4462357..cb884e270 100644 --- a/components/bt/bluedroid/btc/profile/std/avrc/btc_avrc.c +++ b/components/bt/bluedroid/btc/profile/std/avrc/btc_avrc.c @@ -120,30 +120,11 @@ static inline void btc_avrc_ct_cb_to_app(esp_avrc_ct_cb_event_t event, esp_avrc_ static void handle_rc_features(void) { - btrc_remote_features_t rc_features = BTRC_FEAT_NONE; - bt_bdaddr_t rc_addr; - bdcpy(rc_addr.address, btc_rc_vb.rc_addr); - - // TODO(eisenbach): If devices need to be blacklisted for absolute - // volume, it should be added to device/include/interop_database.h - // For now, everything goes... If blacklisting is necessary, exclude - // the following bit here: - // btc_rc_vb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL; - - if (btc_rc_vb.rc_features & BTA_AV_FEAT_BROWSE) { - rc_features |= BTRC_FEAT_BROWSE; - } - - if ( (btc_rc_vb.rc_features & BTA_AV_FEAT_ADV_CTRL) && - (btc_rc_vb.rc_features & BTA_AV_FEAT_RCTG)) { - rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME; - } - - if (btc_rc_vb.rc_features & BTA_AV_FEAT_METADATA) { - rc_features |= BTRC_FEAT_METADATA; - } - - LOG_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features); + esp_avrc_ct_cb_param_t param; + memset(¶m, 0, sizeof(esp_avrc_ct_cb_param_t)); + param.rmt_feats.feat_mask = btc_rc_vb.rc_features; + memcpy(param.rmt_feats.remote_bda, btc_rc_vb.rc_addr, sizeof(esp_bd_addr_t)); + btc_avrc_ct_cb_to_app(ESP_AVRC_CT_REMOTE_FEATURES_EVT, ¶m); } @@ -158,9 +139,7 @@ static void handle_rc_features(void) static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open) { LOG_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle); -#if (AVRC_CTLR_INCLUDED == TRUE) bt_bdaddr_t rc_addr; -#endif if (p_rc_open->status == BTA_AV_SUCCESS) { //check if already some RC is connected @@ -182,22 +161,18 @@ static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open) btc_rc_vb.rc_connected = TRUE; btc_rc_vb.rc_handle = p_rc_open->rc_handle; + bdcpy(rc_addr.address, btc_rc_vb.rc_addr); + + esp_avrc_ct_cb_param_t param; + memset(¶m, 0, sizeof(esp_avrc_ct_cb_param_t)); + param.conn_stat.connected = true; + memcpy(param.conn_stat.remote_bda, &rc_addr, sizeof(esp_bd_addr_t)); + btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, ¶m); + /* on locally initiated connection we will get remote features as part of connect */ - if (btc_rc_vb.rc_features != 0) { + if (p_rc_open->sdp_disc_done == TRUE) { handle_rc_features(); } -#if (AVRC_CTLR_INCLUDED == TRUE) - bdcpy(rc_addr.address, btc_rc_vb.rc_addr); - /* report connection state if device is AVRCP target */ - if (btc_rc_vb.rc_features & BTA_AV_FEAT_RCTG) { - 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 = btc_rc_vb.rc_features; - memcpy(param.conn_stat.remote_bda, &rc_addr, sizeof(esp_bd_addr_t)); - btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, ¶m); - } -#endif } else { LOG_ERROR("%s Connect failed with error code: %d", __FUNCTION__, p_rc_open->status); @@ -215,10 +190,8 @@ static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open) ***************************************************************************/ static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close) { -#if (AVRC_CTLR_INCLUDED == TRUE) bt_bdaddr_t rc_addr; - tBTA_AV_FEAT features; -#endif + LOG_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle); if ((p_rc_close->rc_handle != btc_rc_vb.rc_handle) && (bdcmp(btc_rc_vb.rc_addr, p_rc_close->peer_addr))) { @@ -230,26 +203,21 @@ static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close) btc_rc_vb.rc_connected = FALSE; memset(btc_rc_vb.rc_addr, 0, sizeof(BD_ADDR)); memset(btc_rc_vb.rc_notif, 0, sizeof(btc_rc_vb.rc_notif)); -#if (AVRC_CTLR_INCLUDED == TRUE) - features = btc_rc_vb.rc_features; -#endif + btc_rc_vb.rc_features = 0; btc_rc_vb.rc_vol_label = MAX_LABEL; btc_rc_vb.rc_volume = MAX_VOLUME; -#if (AVRC_CTLR_INCLUDED == TRUE) + bdcpy(rc_addr.address, btc_rc_vb.rc_addr); -#endif + memset(btc_rc_vb.rc_addr, 0, sizeof(BD_ADDR)); -#if (AVRC_CTLR_INCLUDED == TRUE) - /* report connection state if device is AVRCP target */ - if (features & BTA_AV_FEAT_RCTG) { - 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)); - btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, ¶m); - } -#endif + + /* report connection state */ + 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)); + btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, ¶m); } static void handle_rc_attributes_rsp ( tAVRC_MSG_VENDOR *vendor_msg) diff --git a/components/bt/bluedroid/btc/profile/std/include/btc_avrc.h b/components/bt/bluedroid/btc/profile/std/include/btc_avrc.h index 1ea3c2dbb..836696433 100644 --- a/components/bt/bluedroid/btc/profile/std/include/btc_avrc.h +++ b/components/bt/bluedroid/btc/profile/std/include/btc_avrc.h @@ -28,14 +28,6 @@ #define BTC_AVRC_TGT_INCLUDED FALSE #endif -/* Macros */ -typedef enum { - BTRC_FEAT_NONE = 0x00, /* AVRCP 1.0 */ - BTRC_FEAT_METADATA = 0x01, /* AVRCP 1.3 */ - BTRC_FEAT_ABSOLUTE_VOLUME = 0x02, /* Supports TG role and volume sync */ - BTRC_FEAT_BROWSE = 0x04, /* AVRCP 1.4 and up, with Browsing support */ -} btrc_remote_features_t; - typedef enum { BTC_AVRC_CTRL_API_INIT_EVT = 0, BTC_AVRC_CTRL_API_DEINIT_EVT, diff --git a/examples/bluetooth/a2dp_sink/main/bt_app_av.c b/examples/bluetooth/a2dp_sink/main/bt_app_av.c index f041787fb..2698d4a5a 100644 --- a/examples/bluetooth/a2dp_sink/main/bt_app_av.c +++ b/examples/bluetooth/a2dp_sink/main/bt_app_av.c @@ -79,7 +79,8 @@ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param bt_app_alloc_meta_buffer(param); case ESP_AVRC_CT_CONNECTION_STATE_EVT: case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: - case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { bt_app_work_dispatch(bt_av_hdl_avrc_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); break; } @@ -162,8 +163,8 @@ static void bt_av_hdl_avrc_evt(uint16_t event, void *p_param) switch (event) { case ESP_AVRC_CT_CONNECTION_STATE_EVT: { uint8_t *bda = rc->conn_stat.remote_bda; - ESP_LOGI(BT_AV_TAG, "avrc conn_state evt: state %d, feature 0x%x, [%02x:%02x:%02x:%02x:%02x:%02x]", - rc->conn_stat.connected, rc->conn_stat.feat_mask, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + ESP_LOGI(BT_AV_TAG, "avrc conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", + rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); if (rc->conn_stat.connected) { bt_av_new_track(); @@ -184,6 +185,10 @@ static void bt_av_hdl_avrc_evt(uint16_t event, void *p_param) bt_av_notify_evt_handler(rc->change_ntf.event_id, rc->change_ntf.event_parameter); break; } + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { + ESP_LOGI(BT_AV_TAG, "avrc remote features %x", rc->rmt_feats.feat_mask); + break; + } default: ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event); break;