Merge branch 'bugfix/btdm_avrc_connect_state_evt' into 'master'

Bugfix/btdm avrc connect state evt

See merge request !1717
This commit is contained in:
Jiang Jiang Jian 2018-01-09 19:33:06 +08:00
commit 3452845063
6 changed files with 77 additions and 89 deletions

View file

@ -58,10 +58,10 @@ typedef enum {
ESP_AVRC_CT_METADATA_RSP_EVT = 2, /*!< metadata response event */ 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_PLAY_STATUS_RSP_EVT = 3, /*!< play status response event */
ESP_AVRC_CT_CHANGE_NOTIFY_EVT = 4, /*!< notification 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; } esp_avrc_ct_cb_event_t;
//AVRC metadata attribute mask /// AVRC metadata attribute mask
typedef enum { typedef enum {
ESP_AVRC_MD_ATTR_TITLE = 0x1, /*!< title of the playing track */ ESP_AVRC_MD_ATTR_TITLE = 0x1, /*!< title of the playing track */
ESP_AVRC_MD_ATTR_ARTIST = 0x2, /*!< track artist */ 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_PLAYING_TIME = 0x40 /*!< total album playing time in miliseconds */
} esp_avrc_md_attr_mask_t; } esp_avrc_md_attr_mask_t;
//AVRC event notification ids /// AVRC event notification ids
typedef enum { typedef enum {
ESP_AVRC_RN_PLAY_STATUS_CHANGE = 0x01, /*!< track status change, eg. from playing to paused */ 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 */ ESP_AVRC_RN_TRACK_CHANGE = 0x02, /*!< new track is loaded */
@ -85,7 +85,7 @@ typedef enum {
ESP_AVRC_RN_MAX_EVT ESP_AVRC_RN_MAX_EVT
} esp_avrc_rn_event_ids_t; } esp_avrc_rn_event_ids_t;
//AVRC player setting ids /// AVRC player setting ids
typedef enum { typedef enum {
ESP_AVRC_PS_EQUALIZER = 0x01, /*!< equalizer, on or off */ ESP_AVRC_PS_EQUALIZER = 0x01, /*!< equalizer, on or off */
ESP_AVRC_PS_REPEAT_MODE = 0x02, /*!< repeat mode */ ESP_AVRC_PS_REPEAT_MODE = 0x02, /*!< repeat mode */
@ -94,32 +94,32 @@ typedef enum {
ESP_AVRC_PS_MAX_ATTR ESP_AVRC_PS_MAX_ATTR
} esp_avrc_ps_attr_ids_t; } esp_avrc_ps_attr_ids_t;
//AVRC equalizer modes /// AVRC equalizer modes
typedef enum { typedef enum {
ESP_AVRC_PS_EQUALIZER_OFF = 0x1, ESP_AVRC_PS_EQUALIZER_OFF = 0x1, /*!< equalizer OFF */
ESP_AVRC_PS_EQUALIZER_ON = 0x2 ESP_AVRC_PS_EQUALIZER_ON = 0x2 /*!< equalizer ON */
} esp_avrc_ps_eq_value_ids_t; } esp_avrc_ps_eq_value_ids_t;
//AVRC repeat modes /// AVRC repeat modes
typedef enum { typedef enum {
ESP_AVRC_PS_REPEAT_OFF = 0x1, ESP_AVRC_PS_REPEAT_OFF = 0x1, /*!< repeat mode off */
ESP_AVRC_PS_REPEAT_SINGLE = 0x2, ESP_AVRC_PS_REPEAT_SINGLE = 0x2, /*!< single track repeat */
ESP_AVRC_PS_REPEAT_GROUP = 0x3 ESP_AVRC_PS_REPEAT_GROUP = 0x3 /*!< group repeat */
} esp_avrc_ps_rpt_value_ids_t; } esp_avrc_ps_rpt_value_ids_t;
//AVRC shuffle modes /// AVRC shuffle modes
typedef enum { typedef enum {
ESP_AVRC_PS_SHUFFLE_OFF = 0x1, ESP_AVRC_PS_SHUFFLE_OFF = 0x1, /*<! shuffle off */
ESP_AVRC_PS_SHUFFLE_ALL = 0x2, ESP_AVRC_PS_SHUFFLE_ALL = 0x2, /*<! all trackes shuffle */
ESP_AVRC_PS_SHUFFLE_GROUP = 0x3 ESP_AVRC_PS_SHUFFLE_GROUP = 0x3 /*<! group shuffle */
} esp_avrc_ps_shf_value_ids_t; } esp_avrc_ps_shf_value_ids_t;
//AVRC scan modes /// AVRC scan modes
typedef enum { typedef enum {
ESP_AVRC_PS_SCAN_OFF = 0x1, ESP_AVRC_PS_SCAN_OFF = 0x1, /*!< scan off */
ESP_AVRC_PS_SCAN_ALL = 0x2, ESP_AVRC_PS_SCAN_ALL = 0x2, /*!< all tracks scan */
ESP_AVRC_PS_SCAN_GROUP = 0x3 ESP_AVRC_PS_SCAN_GROUP = 0x3 /*!< group scan */
} esp_avrc_ps_scn_value_ids_t; } esp_avrc_ps_scn_value_ids_t;
/// AVRC controller callback parameters /// AVRC controller callback parameters
@ -129,7 +129,6 @@ typedef union {
*/ */
struct avrc_ct_conn_stat_param { struct avrc_ct_conn_stat_param {
bool connected; /*!< whether AVRC connection is set up */ bool connected; /*!< whether AVRC connection is set up */
uint32_t feat_mask; /*!< AVRC feature mask of remote device */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
} conn_stat; /*!< AVRC connection status */ } conn_stat; /*!< AVRC connection status */
@ -159,6 +158,14 @@ typedef union {
uint32_t event_parameter; /*!< event notification parameter */ uint32_t event_parameter; /*!< event notification parameter */
} change_ntf; /*!< notifications */ } change_ntf; /*!< notifications */
/**
* @brief ESP_AVRC_CT_REMOTE_FEATURES_EVT
*/
struct avrc_ct_rmt_feats_param {
uint32_t feat_mask; /*!< AVRC feature mask of remote device */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
} rmt_feats; /*!< AVRC features discovered from remote SDP server */
} esp_avrc_ct_cb_param_t; } esp_avrc_ct_cb_param_t;
@ -212,7 +219,19 @@ esp_err_t esp_avrc_ct_init(void);
*/ */
esp_err_t esp_avrc_ct_deinit(void); esp_err_t esp_avrc_ct_deinit(void);
/* add description */ /**
*
* @brief Send player application settings command to AVRCP target. This function should be called
* after ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established.
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
* @param[in] attr_id : player application setting attribute IDs from one of esp_avrc_ps_attr_ids_t
* @param[in] value_id : attribute value defined for the specific player application setting attribute
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*/
esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id); esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id);
/** /**

View file

@ -529,6 +529,7 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
bdcpy(rc_open.peer_addr, p_data->rc_conn_chg.peer_addr); bdcpy(rc_open.peer_addr, p_data->rc_conn_chg.peer_addr);
rc_open.peer_features = p_cb->rcb[i].peer_features; rc_open.peer_features = p_cb->rcb[i].peer_features;
rc_open.sdp_disc_done = TRUE;
rc_open.status = BTA_AV_SUCCESS; rc_open.status = BTA_AV_SUCCESS;
APPL_TRACE_DEBUG("local features:x%x peer_features:x%x", p_cb->features, APPL_TRACE_DEBUG("local features:x%x peer_features:x%x", p_cb->features,
rc_open.peer_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. /* we have not done SDP on peer RC capabilities.
* peer must have initiated the RC connection */ * peer must have initiated the RC connection */
rc_open.peer_features = BTA_AV_FEAT_RCCT; rc_open.peer_features = BTA_AV_FEAT_RCCT;
rc_open.sdp_disc_done = FALSE;
bta_av_rc_disc(disc); bta_av_rc_disc(disc);
} }
(*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open); (*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; p_scb->use_rc = FALSE;
bdcpy(rc_open.peer_addr, p_scb->peer_addr); bdcpy(rc_open.peer_addr, p_scb->peer_addr);
rc_open.peer_features = 0; rc_open.peer_features = 0;
rc_open.sdp_disc_done = FALSE;
rc_open.status = BTA_AV_FAIL_SDP; rc_open.status = BTA_AV_FAIL_SDP;
(*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open); (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open);
} }

View file

@ -375,6 +375,7 @@ typedef struct {
/* data associated with BTA_AV_RC_OPEN_EVT */ /* data associated with BTA_AV_RC_OPEN_EVT */
typedef struct { typedef struct {
UINT8 rc_handle; UINT8 rc_handle;
BOOLEAN sdp_disc_done;
tBTA_AV_FEAT peer_features; tBTA_AV_FEAT peer_features;
BD_ADDR peer_addr; BD_ADDR peer_addr;
tBTA_AV_STATUS status; tBTA_AV_STATUS status;

View file

@ -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) static void handle_rc_features(void)
{ {
btrc_remote_features_t rc_features = BTRC_FEAT_NONE; esp_avrc_ct_cb_param_t param;
bt_bdaddr_t rc_addr; memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
bdcpy(rc_addr.address, btc_rc_vb.rc_addr); 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));
// TODO(eisenbach): If devices need to be blacklisted for absolute btc_avrc_ct_cb_to_app(ESP_AVRC_CT_REMOTE_FEATURES_EVT, &param);
// 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);
} }
@ -158,9 +139,7 @@ static void handle_rc_features(void)
static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open) static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
{ {
LOG_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle); LOG_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
#if (AVRC_CTLR_INCLUDED == TRUE)
bt_bdaddr_t rc_addr; bt_bdaddr_t rc_addr;
#endif
if (p_rc_open->status == BTA_AV_SUCCESS) { if (p_rc_open->status == BTA_AV_SUCCESS) {
//check if already some RC is connected //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_connected = TRUE;
btc_rc_vb.rc_handle = p_rc_open->rc_handle; 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(&param, 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, &param);
/* on locally initiated connection we will get remote features as part of connect */ /* 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(); 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(&param, 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, &param);
}
#endif
} else { } else {
LOG_ERROR("%s Connect failed with error code: %d", LOG_ERROR("%s Connect failed with error code: %d",
__FUNCTION__, p_rc_open->status); __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) static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
{ {
#if (AVRC_CTLR_INCLUDED == TRUE)
bt_bdaddr_t rc_addr; bt_bdaddr_t rc_addr;
tBTA_AV_FEAT features;
#endif
LOG_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle); LOG_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
if ((p_rc_close->rc_handle != btc_rc_vb.rc_handle) if ((p_rc_close->rc_handle != btc_rc_vb.rc_handle)
&& (bdcmp(btc_rc_vb.rc_addr, p_rc_close->peer_addr))) { && (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; btc_rc_vb.rc_connected = FALSE;
memset(btc_rc_vb.rc_addr, 0, sizeof(BD_ADDR)); memset(btc_rc_vb.rc_addr, 0, sizeof(BD_ADDR));
memset(btc_rc_vb.rc_notif, 0, sizeof(btc_rc_vb.rc_notif)); 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_features = 0;
btc_rc_vb.rc_vol_label = MAX_LABEL; btc_rc_vb.rc_vol_label = MAX_LABEL;
btc_rc_vb.rc_volume = MAX_VOLUME; btc_rc_vb.rc_volume = MAX_VOLUME;
#if (AVRC_CTLR_INCLUDED == TRUE)
bdcpy(rc_addr.address, btc_rc_vb.rc_addr); bdcpy(rc_addr.address, btc_rc_vb.rc_addr);
#endif
memset(btc_rc_vb.rc_addr, 0, sizeof(BD_ADDR)); memset(btc_rc_vb.rc_addr, 0, sizeof(BD_ADDR));
#if (AVRC_CTLR_INCLUDED == TRUE)
/* report connection state if device is AVRCP target */ /* report connection state */
if (features & BTA_AV_FEAT_RCTG) { esp_avrc_ct_cb_param_t param;
esp_avrc_ct_cb_param_t param; memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t)); param.conn_stat.connected = false;
param.conn_stat.connected = false; memcpy(param.conn_stat.remote_bda, &rc_addr, sizeof(esp_bd_addr_t));
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, &param);
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, &param);
}
#endif
} }
static void handle_rc_attributes_rsp ( tAVRC_MSG_VENDOR *vendor_msg) static void handle_rc_attributes_rsp ( tAVRC_MSG_VENDOR *vendor_msg)

View file

@ -28,14 +28,6 @@
#define BTC_AVRC_TGT_INCLUDED FALSE #define BTC_AVRC_TGT_INCLUDED FALSE
#endif #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 { typedef enum {
BTC_AVRC_CTRL_API_INIT_EVT = 0, BTC_AVRC_CTRL_API_INIT_EVT = 0,
BTC_AVRC_CTRL_API_DEINIT_EVT, BTC_AVRC_CTRL_API_DEINIT_EVT,

View file

@ -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); bt_app_alloc_meta_buffer(param);
case ESP_AVRC_CT_CONNECTION_STATE_EVT: case ESP_AVRC_CT_CONNECTION_STATE_EVT:
case ESP_AVRC_CT_PASSTHROUGH_RSP_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); bt_app_work_dispatch(bt_av_hdl_avrc_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
break; break;
} }
@ -162,8 +163,8 @@ static void bt_av_hdl_avrc_evt(uint16_t event, void *p_param)
switch (event) { switch (event) {
case ESP_AVRC_CT_CONNECTION_STATE_EVT: { case ESP_AVRC_CT_CONNECTION_STATE_EVT: {
uint8_t *bda = rc->conn_stat.remote_bda; 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]", ESP_LOGI(BT_AV_TAG, "avrc conn_state evt: state %d, [%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]); rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
if (rc->conn_stat.connected) { if (rc->conn_stat.connected) {
bt_av_new_track(); 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); bt_av_notify_evt_handler(rc->change_ntf.event_id, rc->change_ntf.event_parameter);
break; break;
} }
case ESP_AVRC_CT_REMOTE_FEATURES_EVT: {
ESP_LOGI(BT_AV_TAG, "avrc remote features %x", rc->rmt_feats.feat_mask);
break;
}
default: default:
ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event); ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event);
break; break;