mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/btdm_avrc_metadata' into 'master'
Feature/btdm avrc metadata: implemented AVRCP metadata and notification register commands See merge request !1624
This commit is contained in:
commit
08048ff76a
@ -27,7 +27,7 @@ esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback)
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@ -43,7 +43,7 @@ esp_err_t esp_avrc_ct_init(void)
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_CTRL_API_INIT_EVT;
|
||||
@ -60,7 +60,7 @@ esp_err_t esp_avrc_ct_deinit(void)
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_CTRL_API_DEINIT_EVT;
|
||||
@ -70,12 +70,97 @@ esp_err_t esp_avrc_ct_deinit(void)
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (tl >= 16 || attr_id > ESP_AVRC_PS_MAX_ATTR - 1) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_CTRL_API_SET_PLAYER_SETTING_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
|
||||
arg.ps_cmd.tl = tl;
|
||||
arg.ps_cmd.attr_id = attr_id;
|
||||
arg.ps_cmd.value_id = value_id;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (tl >= 16 || event_id > ESP_AVRC_RN_MAX_EVT - 1) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
|
||||
arg.rn_cmd.tl = tl;
|
||||
arg.rn_cmd.event_id = event_id;
|
||||
arg.rn_cmd.event_parameter = event_parameter;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (tl >= 16) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_STATUS_API_SND_META_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
|
||||
arg.md_cmd.tl = tl;
|
||||
arg.md_cmd.attr_mask = attr_mask;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (tl >= 16 || key_state > ESP_AVRC_PT_CMD_STATE_RELEASED) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
@ -87,7 +172,7 @@ esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t
|
||||
arg.pt_cmd.tl = tl;
|
||||
arg.pt_cmd.key_code = key_code;
|
||||
arg.pt_cmd.key_state = key_state;
|
||||
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
|
@ -40,7 +40,9 @@ typedef enum {
|
||||
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 */
|
||||
ESP_AVRC_PT_CMD_BACKWARD = 0x4C, /*!< backward */
|
||||
ESP_AVRC_PT_CMD_REWIND = 0x48, /*!< rewind */
|
||||
ESP_AVRC_PT_CMD_FAST_FORWARD = 0x49 /*!< fast forward */
|
||||
} esp_avrc_pt_cmd_t;
|
||||
|
||||
/// AVRC passthrough command state
|
||||
@ -53,9 +55,73 @@ typedef enum {
|
||||
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_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_cb_event_t;
|
||||
|
||||
//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 */
|
||||
ESP_AVRC_MD_ATTR_ALBUM = 0x4, /*!< album name */
|
||||
ESP_AVRC_MD_ATTR_TRACK_NUM = 0x8, /*!< track position on the album */
|
||||
ESP_AVRC_MD_ATTR_NUM_TRACKS = 0x10, /*!< number of tracks on the album */
|
||||
ESP_AVRC_MD_ATTR_GENRE = 0x20, /*!< track genre */
|
||||
ESP_AVRC_MD_ATTR_PLAYING_TIME = 0x40 /*!< total album playing time in miliseconds */
|
||||
} esp_avrc_md_attr_mask_t;
|
||||
|
||||
//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 */
|
||||
ESP_AVRC_RN_TRACK_REACHED_END = 0x03, /*!< current track reached end */
|
||||
ESP_AVRC_RN_TRACK_REACHED_START = 0x04, /*!< current track reached start position */
|
||||
ESP_AVRC_RN_PLAY_POS_CHANGED = 0x05, /*!< track playing position changed */
|
||||
ESP_AVRC_RN_BATTERY_STATUS_CHANGE = 0x06, /*!< battery status changed */
|
||||
ESP_AVRC_RN_SYSTEM_STATUS_CHANGE = 0x07, /*!< system status changed */
|
||||
ESP_AVRC_RN_APP_SETTING_CHANGE = 0x08, /*!< application settings changed */
|
||||
ESP_AVRC_RN_MAX_EVT
|
||||
} esp_avrc_rn_event_ids_t;
|
||||
|
||||
//AVRC player setting ids
|
||||
typedef enum {
|
||||
ESP_AVRC_PS_EQUALIZER = 0x01, /*!< equalizer, on or off */
|
||||
ESP_AVRC_PS_REPEAT_MODE = 0x02, /*!< repeat mode */
|
||||
ESP_AVRC_PS_SHUFFLE_MODE = 0x03, /*!< shuffle mode */
|
||||
ESP_AVRC_PS_SCAN_MODE = 0x04, /*!< scan mode on or off */
|
||||
ESP_AVRC_PS_MAX_ATTR
|
||||
} esp_avrc_ps_attr_ids_t;
|
||||
|
||||
//AVRC equalizer modes
|
||||
typedef enum {
|
||||
ESP_AVRC_PS_EQUALIZER_OFF = 0x1,
|
||||
ESP_AVRC_PS_EQUALIZER_ON = 0x2
|
||||
} esp_avrc_ps_eq_value_ids_t;
|
||||
|
||||
//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_rpt_value_ids_t;
|
||||
|
||||
|
||||
//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_shf_value_ids_t;
|
||||
|
||||
//AVRC scan modes
|
||||
typedef enum {
|
||||
ESP_AVRC_PS_SCAN_OFF = 0x1,
|
||||
ESP_AVRC_PS_SCAN_ALL = 0x2,
|
||||
ESP_AVRC_PS_SCAN_GROUP = 0x3
|
||||
} esp_avrc_ps_scn_value_ids_t;
|
||||
|
||||
/// AVRC controller callback parameters
|
||||
typedef union {
|
||||
/**
|
||||
@ -63,10 +129,10 @@ typedef union {
|
||||
*/
|
||||
struct avrc_ct_conn_stat_param {
|
||||
bool connected; /*!< whether AVRC connection is set up */
|
||||
uint32_t feat_mask; /*!< AVRC feature mask of remote device */
|
||||
uint32_t feat_mask; /*!< AVRC feature mask of remote device */
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
} conn_stat; /*!< AVRC connection status */
|
||||
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_PASSTHROUGH_RSP_EVT
|
||||
*/
|
||||
@ -75,6 +141,24 @@ typedef union {
|
||||
uint8_t key_code; /*!< passthrough command code */
|
||||
uint8_t key_state; /*!< 0 for PRESSED, 1 for RELEASED */
|
||||
} psth_rsp; /*!< passthrough command response */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_METADATA_RSP_EVT
|
||||
*/
|
||||
struct avrc_ct_meta_rsp_param {
|
||||
uint8_t attr_id; /*!< id of metadata attribute */
|
||||
uint8_t *attr_text; /*!< attribute itself */
|
||||
int attr_length; /*!< attribute character length */
|
||||
} meta_rsp; /*!< metadata attributes response */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_CHANGE_NOTIFY_EVT
|
||||
*/
|
||||
struct avrc_ct_change_notify_param {
|
||||
uint8_t event_id; /*!< id of AVRC event notification */
|
||||
uint32_t event_parameter; /*!< event notification parameter */
|
||||
} change_ntf; /*!< notifications */
|
||||
|
||||
} esp_avrc_ct_cb_param_t;
|
||||
|
||||
|
||||
@ -88,9 +172,9 @@ typedef void (* esp_avrc_ct_cb_t)(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_p
|
||||
|
||||
/**
|
||||
* @brief Register application callbacks to AVRCP module; for now only AVRCP Controller
|
||||
* role is supported. This function should be called after esp_bluedroid_enable()
|
||||
* role is supported. This function should be called after esp_bluedroid_enable()
|
||||
* completes successfully
|
||||
*
|
||||
*
|
||||
* @param[in] callback: AVRCP controller callback function
|
||||
*
|
||||
* @return
|
||||
@ -107,7 +191,7 @@ esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback);
|
||||
* @brief Initialize the bluetooth AVRCP controller module, This function should be called
|
||||
* after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
@ -121,13 +205,45 @@ esp_err_t esp_avrc_ct_init(void);
|
||||
* @brief De-initialize AVRCP controller module. This function should be called after
|
||||
* after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_deinit(void);
|
||||
|
||||
/* add description */
|
||||
esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id);
|
||||
|
||||
/**
|
||||
* @brief Send register notification 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] event_id : id of events, e.g. ESP_AVRC_RN_PLAY_STATUS_CHANGE, ESP_AVRC_RN_TRACK_CHANGE, etc.
|
||||
* @param[in] event_parameter : special parameters, eg. playback interval for ESP_AVRC_RN_PLAY_POS_CHANGED
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send metadata 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_mask : mask of attributes, e.g. ESP_AVRC_MD_ATTR_ID_TITLE | ESP_AVRC_MD_ATTR_ID_ARTIST.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send passthrough command to AVRCP target, This function should be called after
|
||||
@ -138,7 +254,7 @@ esp_err_t esp_avrc_ct_deinit(void);
|
||||
* @param[in] key_state : passthrough command key state, ESP_AVRC_PT_CMD_STATE_PRESSED or
|
||||
* ESP_AVRC_PT_CMD_STATE_RELEASED
|
||||
*
|
||||
* @return
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
|
@ -1120,7 +1120,7 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable)
|
||||
* auto-suspend av streaming on AG events(SCO or Call). The suspend shall
|
||||
* be initiated by the app/audioflinger layers */
|
||||
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_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR
|
||||
| BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL,
|
||||
bte_av_callback);
|
||||
BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos);
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "btc_manage.h"
|
||||
#include "esp_avrc_api.h"
|
||||
#include "mutex.h"
|
||||
#include "allocator.h"
|
||||
|
||||
#if BTC_AV_INCLUDED
|
||||
|
||||
@ -96,6 +97,7 @@ rc_device_t device;
|
||||
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_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp);
|
||||
static void handle_rc_metadata_rsp ( tBTA_AV_META_MSG *p_remote_rsp);
|
||||
|
||||
/*****************************************************************************
|
||||
** Static variables
|
||||
@ -250,6 +252,86 @@ static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void handle_rc_attributes_rsp ( tAVRC_MSG_VENDOR *vendor_msg)
|
||||
{
|
||||
uint8_t attr_count = vendor_msg->p_vendor_data[4];
|
||||
int attr_index = 5;
|
||||
int attr_length = 0;
|
||||
uint32_t attr_id = 0;
|
||||
|
||||
//Check if there are any attributes
|
||||
if (attr_count < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
esp_avrc_ct_cb_param_t param[attr_count];
|
||||
memset(¶m[0], 0, sizeof(esp_avrc_ct_cb_param_t) * attr_count);
|
||||
|
||||
for (int i = 0; i < attr_count; i++) {
|
||||
attr_length = (int) vendor_msg->p_vendor_data[7 + attr_index] | vendor_msg->p_vendor_data[6 + attr_index] << 8;
|
||||
|
||||
//Received attribute text is not null terminated, so it's useful to know it's length
|
||||
param[i].meta_rsp.attr_length = attr_length;
|
||||
param[i].meta_rsp.attr_text = &vendor_msg->p_vendor_data[8 + attr_index];
|
||||
|
||||
attr_id = vendor_msg->p_vendor_data[3 + attr_index] |
|
||||
vendor_msg->p_vendor_data[2 + attr_index] << 8 | vendor_msg->p_vendor_data[1 + attr_index] << 16 |
|
||||
vendor_msg->p_vendor_data[attr_index] << 24;
|
||||
|
||||
//Convert to mask id
|
||||
param[i].meta_rsp.attr_id = (1 << (attr_id - 1));
|
||||
|
||||
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_METADATA_RSP_EVT, ¶m[i]);
|
||||
|
||||
attr_index += (int) vendor_msg->p_vendor_data[7 + attr_index] + 8;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_rc_notification_rsp ( tAVRC_MSG_VENDOR *vendor_msg)
|
||||
{
|
||||
esp_avrc_ct_cb_param_t param;
|
||||
|
||||
param.change_ntf.event_id = vendor_msg->p_vendor_data[4];
|
||||
|
||||
param.change_ntf.event_parameter = vendor_msg->p_vendor_data[5] << 24 | vendor_msg->p_vendor_data[6] << 16 |
|
||||
vendor_msg->p_vendor_data[7] << 8 | vendor_msg->p_vendor_data[8];
|
||||
|
||||
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CHANGE_NOTIFY_EVT, ¶m);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function handle_rc_metadata_rsp
|
||||
*
|
||||
* - Argument: tBTA_AV_META_MSG metadata command response
|
||||
*
|
||||
* - Description: Vendor metadata response handler
|
||||
*
|
||||
***************************************************************************/
|
||||
static void handle_rc_metadata_rsp ( tBTA_AV_META_MSG *p_remote_rsp)
|
||||
{
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
tAVRC_MSG *avrc_msg = p_remote_rsp->p_msg;
|
||||
tAVRC_MSG_VENDOR *vendor_msg = &avrc_msg->vendor;
|
||||
|
||||
//Check what type of metadata was received
|
||||
switch (vendor_msg->hdr.ctype) {
|
||||
case AVRC_RSP_CHANGED:
|
||||
if (vendor_msg->p_vendor_data[0] == AVRC_PDU_REGISTER_NOTIFICATION) {
|
||||
handle_rc_notification_rsp(vendor_msg);
|
||||
}
|
||||
break;
|
||||
|
||||
case AVRC_RSP_IMPL_STBL:
|
||||
if (vendor_msg->p_vendor_data[0] == AVRC_PDU_GET_ELEMENT_ATTR) {
|
||||
handle_rc_attributes_rsp(vendor_msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#else
|
||||
LOG_ERROR("%s AVRCP metadata is not enabled", __FUNCTION__);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function handle_rc_passthrough_rsp
|
||||
*
|
||||
@ -326,8 +408,12 @@ void btc_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
|
||||
}
|
||||
break;
|
||||
|
||||
case BTA_AV_META_MSG_EVT: {
|
||||
handle_rc_metadata_rsp(&(p_data->meta_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
// below events are not handled for now
|
||||
case BTA_AV_META_MSG_EVT:
|
||||
case BTA_AV_REMOTE_CMD_EVT:
|
||||
default:
|
||||
LOG_DEBUG("Unhandled RC event : 0x%x", event);
|
||||
@ -390,13 +476,124 @@ static void btc_avrc_ct_deinit(void)
|
||||
LOG_INFO("## %s ## completed", __FUNCTION__);
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
tAVRC_APP_SETTING values = {0};
|
||||
|
||||
values.attr_id = attr_id;
|
||||
values.attr_val = value_id;
|
||||
|
||||
avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR;
|
||||
avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR;
|
||||
avrc_cmd.set_app_val.num_val = 1;
|
||||
avrc_cmd.set_app_val.p_vals = &values;
|
||||
avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
|
||||
|
||||
status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (status == AVRC_STS_NO_ERROR) {
|
||||
if (btc_rc_vb.rc_features & BTA_AV_FEAT_METADATA) {
|
||||
BTA_AvMetaCmd(btc_rc_vb.rc_handle, tl, BTA_AV_CMD_CTRL, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
LOG_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
LOG_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
|
||||
avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
|
||||
avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
|
||||
avrc_cmd.reg_notif.event_id = event_id;
|
||||
avrc_cmd.reg_notif.param = event_parameter;
|
||||
avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
|
||||
|
||||
status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (status == AVRC_STS_NO_ERROR) {
|
||||
if (btc_rc_vb.rc_features & BTA_AV_FEAT_METADATA) {
|
||||
BTA_AvMetaCmd(btc_rc_vb.rc_handle, tl, AVRC_CMD_NOTIF, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
LOG_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
LOG_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_metadata_cmd (uint8_t tl, uint8_t attr_mask)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
uint32_t index = 0;
|
||||
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
|
||||
avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
|
||||
avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
|
||||
avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
|
||||
|
||||
for (int count = 0; count < AVRC_MAX_ELEM_ATTR_SIZE; count++) {
|
||||
if ((attr_mask & (1 << count)) > 0) {
|
||||
avrc_cmd.get_elem_attrs.attrs[index] = count + 1;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
avrc_cmd.get_elem_attrs.num_attr = index;
|
||||
|
||||
status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (status == AVRC_STS_NO_ERROR) {
|
||||
if (btc_rc_vb.rc_features & BTA_AV_FEAT_METADATA) {
|
||||
BTA_AvMetaCmd(btc_rc_vb.rc_handle, tl, AVRC_CMD_STATUS, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
LOG_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
LOG_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bt_status_t btc_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_ESP_RC_CONNECTED;
|
||||
LOG_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
|
||||
@ -436,6 +633,18 @@ void btc_avrc_call_handler(btc_msg_t *msg)
|
||||
// todo: callback to application
|
||||
break;
|
||||
}
|
||||
case BTC_AVRC_STATUS_API_SND_META_EVT: {
|
||||
btc_avrc_ct_send_metadata_cmd(arg->md_cmd.tl, arg->md_cmd.attr_mask);
|
||||
break;
|
||||
}
|
||||
case BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT: {
|
||||
btc_avrc_ct_send_register_notification_cmd(arg->rn_cmd.tl, arg->rn_cmd.event_id, arg->rn_cmd.event_parameter);
|
||||
break;
|
||||
}
|
||||
case BTC_AVRC_CTRL_API_SET_PLAYER_SETTING_EVT: {
|
||||
btc_avrc_ct_send_set_player_value_cmd(arg->ps_cmd.tl, arg->ps_cmd.attr_id, arg->ps_cmd.value_id);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_WARN("%s : unhandled event: %d\n", __FUNCTION__, msg->act);
|
||||
}
|
||||
|
@ -39,7 +39,11 @@ typedef enum {
|
||||
typedef enum {
|
||||
BTC_AVRC_CTRL_API_INIT_EVT = 0,
|
||||
BTC_AVRC_CTRL_API_DEINIT_EVT,
|
||||
BTC_AVRC_CTRL_API_SND_PTCMD_EVT
|
||||
BTC_AVRC_CTRL_API_SND_PTCMD_EVT,
|
||||
BTC_AVRC_STATUS_API_SND_META_EVT,
|
||||
BTC_AVRC_STATUS_API_SND_PLAY_STATUS_EVT,
|
||||
BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT,
|
||||
BTC_AVRC_CTRL_API_SET_PLAYER_SETTING_EVT
|
||||
} btc_avrc_act_t;
|
||||
|
||||
typedef struct {
|
||||
@ -48,14 +52,29 @@ typedef struct {
|
||||
uint8_t key_state;
|
||||
} pt_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t tl;
|
||||
uint8_t attr_mask;
|
||||
} md_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t tl;
|
||||
uint8_t event_id;
|
||||
uint32_t event_parameter;
|
||||
} rn_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t tl;
|
||||
uint8_t attr_id;
|
||||
uint8_t value_id;
|
||||
} ps_cmd_t;
|
||||
|
||||
/* btc_avrc_args_t */
|
||||
typedef union {
|
||||
// BTC_AVRC_CTRL_API_SND_PT_CMD_EVT
|
||||
struct {
|
||||
uint8_t tl;
|
||||
uint8_t key_code;
|
||||
uint8_t key_state;
|
||||
} pt_cmd;
|
||||
pt_cmd_t pt_cmd;
|
||||
md_cmd_t md_cmd;
|
||||
rn_cmd_t rn_cmd;
|
||||
ps_cmd_t ps_cmd;
|
||||
} btc_avrc_args_t;
|
||||
|
||||
/** BT-RC Controller callback structure. */
|
||||
|
@ -98,7 +98,7 @@ static tAVRC_STS avrc_bld_set_abs_volume_cmd (tAVRC_SET_VOLUME_CMD *p_cmd, BT_HD
|
||||
** Otherwise, the error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static tAVRC_STS avrc_bld_vol_change_notfn(BT_HDR *p_pkt)
|
||||
static tAVRC_STS avrc_bld_register_change_notfn(UINT8 event_id, UINT32 event_parameter, BT_HDR *p_pkt)
|
||||
{
|
||||
UINT8 *p_data, *p_start;
|
||||
|
||||
@ -109,8 +109,8 @@ static tAVRC_STS avrc_bld_vol_change_notfn(BT_HDR *p_pkt)
|
||||
p_data = p_start + 2; /* pdu + rsvd */
|
||||
/* add fixed length 5 -*/
|
||||
UINT16_TO_BE_STREAM(p_data, 5);
|
||||
UINT8_TO_BE_STREAM(p_data, AVRC_EVT_VOLUME_CHANGE);
|
||||
UINT32_TO_BE_STREAM(p_data, 0);
|
||||
UINT8_TO_BE_STREAM(p_data, event_id);
|
||||
UINT32_TO_BE_STREAM(p_data, event_parameter);
|
||||
p_pkt->len = (p_data - p_start);
|
||||
return AVRC_STS_NO_ERROR;
|
||||
}
|
||||
@ -132,8 +132,7 @@ static BT_HDR *avrc_bld_init_cmd_buffer(tAVRC_COMMAND *p_cmd)
|
||||
AVRC_TRACE_API("avrc_bld_init_cmd_buffer: pdu=%x, opcode=%x", p_cmd->pdu, opcode);
|
||||
|
||||
UINT16 offset = 0;
|
||||
switch (opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case AVRC_OP_PASS_THRU:
|
||||
offset = AVRC_MSG_PASS_THRU_OFFSET;
|
||||
break;
|
||||
@ -148,7 +147,7 @@ static BT_HDR *avrc_bld_init_cmd_buffer(tAVRC_COMMAND *p_cmd)
|
||||
if (p_pkt) {
|
||||
UINT8 *p_data, *p_start;
|
||||
|
||||
p_pkt->layer_specific = AVCT_DATA_CTRL;
|
||||
p_pkt->layer_specific = AVCT_DATA_CTRL;
|
||||
p_pkt->event = opcode;
|
||||
p_pkt->offset = offset;
|
||||
p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
|
||||
@ -175,6 +174,69 @@ static BT_HDR *avrc_bld_init_cmd_buffer(tAVRC_COMMAND *p_cmd)
|
||||
return p_pkt;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function avrc_bld_set_player_value_cmd
|
||||
**
|
||||
** Description This function builds the Set Player Application Value command.
|
||||
**
|
||||
** Returns AVRC_STS_NO_ERROR, if the command is built successfully
|
||||
** Otherwise, the error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static tAVRC_STS avrc_bld_set_player_value_cmd(tAVRC_SET_APP_VALUE_CMD *p_cmd, BT_HDR *p_pkt)
|
||||
{
|
||||
UINT8 *p_data, *p_start;
|
||||
|
||||
/* get the existing length, if any, and also the num attributes */
|
||||
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
|
||||
p_data = p_start + 2; /* pdu + rsvd */
|
||||
/* add length */
|
||||
UINT16_TO_BE_STREAM(p_data, 3);
|
||||
/* Number of attributes */
|
||||
UINT8_TO_BE_STREAM(p_data, 1);
|
||||
UINT8_TO_BE_STREAM(p_data, p_cmd->p_vals->attr_id);
|
||||
UINT8_TO_BE_STREAM(p_data, p_cmd->p_vals->attr_val);
|
||||
|
||||
p_pkt->len = (p_data - p_start);
|
||||
return AVRC_STS_NO_ERROR;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function avrc_bld_get_element_attr_cmd
|
||||
**
|
||||
** Description This function builds the Get Element Attribute command.
|
||||
**
|
||||
** Returns AVRC_STS_NO_ERROR, if the command is built successfully
|
||||
** Otherwise, the error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static tAVRC_STS avrc_bld_get_element_attr_cmd (tAVRC_GET_ELEM_ATTRS_CMD *p_cmd, BT_HDR *p_pkt)
|
||||
{
|
||||
int i;
|
||||
UINT8 *p_data, *p_start;
|
||||
|
||||
AVRC_TRACE_API("avrc_bld_get_element_attr_cmd num_attr: %d", p_cmd->num_attr);
|
||||
/* get the existing length, if any, and also the num attributes */
|
||||
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
|
||||
p_data = p_start + 2; /* pdu + rsvd */
|
||||
/* add length */
|
||||
UINT16_TO_BE_STREAM(p_data, 8 + 1 /* id + attr count */ + p_cmd->num_attr * sizeof(UINT32));
|
||||
/* Identifier 0x0 (PLAYING) */
|
||||
UINT64_TO_BE_STREAM(p_data, (UINT64)(0));
|
||||
/* Attribute count */
|
||||
UINT8_TO_BE_STREAM(p_data, p_cmd->num_attr);
|
||||
|
||||
for (i = 0; i < p_cmd->num_attr; i++) {
|
||||
AVRC_TRACE_API("avrc_bld_get_element_attr_cmd attr_id: %d", p_cmd->attrs[i]);
|
||||
UINT32_TO_BE_STREAM(p_data, p_cmd->attrs[i]);
|
||||
}
|
||||
|
||||
p_pkt->len = (p_data - p_start);
|
||||
return AVRC_STS_NO_ERROR;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function AVRC_BldCommand
|
||||
@ -223,14 +285,17 @@ tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt)
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
|
||||
#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
|
||||
if (AVRC_EVT_VOLUME_CHANGE == p_cmd->reg_notif.event_id) {
|
||||
status = avrc_bld_vol_change_notfn(p_pkt);
|
||||
}
|
||||
#endif
|
||||
case AVRC_PDU_SET_PLAYER_APP_VALUE: /* 0x14 */
|
||||
status = avrc_bld_set_player_value_cmd(&p_cmd->set_app_val, p_pkt);
|
||||
break;
|
||||
|
||||
case AVRC_PDU_GET_ELEMENT_ATTR: /* 0x20 */
|
||||
status = avrc_bld_get_element_attr_cmd(&p_cmd->get_elem_attrs, p_pkt);
|
||||
break;
|
||||
|
||||
case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
|
||||
status = avrc_bld_register_change_notfn(p_cmd->reg_notif.event_id, p_cmd->reg_notif.param, p_pkt);
|
||||
break;
|
||||
}
|
||||
|
||||
if (alloc && (status != AVRC_STS_NO_ERROR) ) {
|
||||
|
@ -276,6 +276,7 @@ typedef struct {
|
||||
/********************************************************************************
|
||||
** Macros to get and put bytes to and from a stream (Big Endian format)
|
||||
*/
|
||||
#define UINT64_TO_BE_STREAM(p, u64) {*(p)++ = (UINT8)((u64) >> 56); *(p)++ = (UINT8)((u64) >> 48); *(p)++ = (UINT8)((u64) >> 40); *(p)++ = (UINT8)((u64) >> 32); *(p)++ = (UINT8)((u64) >> 24); *(p)++ = (UINT8)((u64) >> 16); *(p)++ = (UINT8)((u64) >> 8); *(p)++ = (UINT8)(u64); }
|
||||
#define UINT32_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 24); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
|
||||
#define UINT24_TO_BE_STREAM(p, u24) {*(p)++ = (UINT8)((u24) >> 16); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)(u24);}
|
||||
#define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);}
|
||||
|
@ -35,7 +35,6 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param);
|
||||
/* avrc event handler */
|
||||
static void bt_av_hdl_avrc_evt(uint16_t event, void *p_param);
|
||||
|
||||
|
||||
static uint32_t m_pkt_cnt = 0;
|
||||
static esp_a2d_audio_state_t m_audio_state = ESP_A2D_AUDIO_STATE_STOPPED;
|
||||
|
||||
@ -63,11 +62,24 @@ void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
|
||||
}
|
||||
}
|
||||
|
||||
void bt_app_alloc_meta_buffer(esp_avrc_ct_cb_param_t *param)
|
||||
{
|
||||
esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param);
|
||||
uint8_t *attr_text = (uint8_t *) malloc (rc->meta_rsp.attr_length + 1);
|
||||
memcpy(attr_text, rc->meta_rsp.attr_text, rc->meta_rsp.attr_length);
|
||||
attr_text[rc->meta_rsp.attr_length] = 0;
|
||||
|
||||
rc->meta_rsp.attr_text = attr_text;
|
||||
}
|
||||
|
||||
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_METADATA_RSP_EVT:
|
||||
bt_app_alloc_meta_buffer(param);
|
||||
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: {
|
||||
bt_app_work_dispatch(bt_av_hdl_avrc_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
|
||||
break;
|
||||
}
|
||||
@ -127,6 +139,22 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param)
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_av_new_track()
|
||||
{
|
||||
//Register notifications and request metadata
|
||||
esp_avrc_ct_send_metadata_cmd(0, ESP_AVRC_MD_ATTR_TITLE | ESP_AVRC_MD_ATTR_ARTIST | ESP_AVRC_MD_ATTR_ALBUM | ESP_AVRC_MD_ATTR_GENRE);
|
||||
esp_avrc_ct_send_register_notification_cmd(1, ESP_AVRC_RN_TRACK_CHANGE, 0);
|
||||
}
|
||||
|
||||
void bt_av_notify_evt_handler(uint8_t event_id, uint32_t event_parameter)
|
||||
{
|
||||
switch (event_id) {
|
||||
case ESP_AVRC_RN_TRACK_CHANGE:
|
||||
bt_av_new_track();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_av_hdl_avrc_evt(uint16_t event, void *p_param)
|
||||
{
|
||||
ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event);
|
||||
@ -135,13 +163,27 @@ static void bt_av_hdl_avrc_evt(uint16_t event, void *p_param)
|
||||
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]);
|
||||
rc->conn_stat.connected, rc->conn_stat.feat_mask, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
|
||||
|
||||
if (rc->conn_stat.connected) {
|
||||
bt_av_new_track();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: {
|
||||
ESP_LOGI(BT_AV_TAG, "avrc passthrough rsp: key_code 0x%x, key_state %d", rc->psth_rsp.key_code, rc->psth_rsp.key_state);
|
||||
break;
|
||||
}
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT: {
|
||||
ESP_LOGI(BT_AV_TAG, "avrc metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text);
|
||||
free(rc->meta_rsp.attr_text);
|
||||
break;
|
||||
}
|
||||
case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: {
|
||||
ESP_LOGI(BT_AV_TAG, "avrc event notification: %d, param: %d", 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;
|
||||
}
|
||||
default:
|
||||
ESP_LOGE(BT_AV_TAG, "%s unhandled evt %d", __func__, event);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user