AVRCP
This manual describes the AVRCP API definition. AVRCP defines the features and procedures required in order to ensure interoperability between Bluetooth devices with audio/video control functions in the audio/video distribution scenarios.
Terminology and Concepts
AVRCP Roles
The following roles are defined for devices that implement this profile:
Controller (CT) - A device that initiates a transaction by sending a command frame to a target. Examples for CT are a personal computer, a PDA, a mobile phone, a remote controller, or an AV device (such as an in car system, headphone, player/recorder, timer, tuner, monitor, etc.).
Target (TG) - A device that receives a command frame and accordingly generates a response frame. Examples for TG are an audio player/recorder, a video player/recorder, a TV, a tuner, an amplifier, or a headphone.
AVRCP SDP Record
AVRCP local record avrcp_ct_sdp_record
and avrcp_tg_sdp_record
should be registered by bt_sdp_record_add()
.
static const uint8_t avrcp_ct_sdp_record[] =
{
//Total length
SDP_DATA_ELEM_SEQ_HDR,
0x3B,//0x49,//0x62,
//Attribute SDP_ATTR_SRV_CLASS_ID_LIST
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_ATTR_SRV_CLASS_ID_LIST >> 8),
(uint8_t)SDP_ATTR_SRV_CLASS_ID_LIST,
SDP_DATA_ELEM_SEQ_HDR,
0x06, //Attribute length: 6 bytes
//Service Class #0: A/V Remote Control
SDP_UUID16_HDR,
(uint8_t)(UUID_AV_REMOTE_CONTROL >> 8),
(uint8_t)(UUID_AV_REMOTE_CONTROL),
//Service Class #1: A/V Remote Control Controller
SDP_UUID16_HDR,
(uint8_t)(UUID_AV_REMOTE_CONTROL_CONTROLLER >> 8),
(uint8_t)(UUID_AV_REMOTE_CONTROL_CONTROLLER),
//Attribute SDP_ATTR_PROTO_DESC_LIST
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_ATTR_PROTO_DESC_LIST >> 8),
(uint8_t)SDP_ATTR_PROTO_DESC_LIST,
SDP_DATA_ELEM_SEQ_HDR,
0x10, //Attribute length: 12 bytes
//Protocol #0: L2CAP
SDP_DATA_ELEM_SEQ_HDR,
0x06, //Element length: 3 bytes
SDP_UUID16_HDR,
(uint8_t)(UUID_L2CAP >> 8),
(uint8_t)(UUID_L2CAP),
//Parameter #0 for Protocol #0: PSM = AVCTP
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(PSM_AVCTP >> 8),
(uint8_t)PSM_AVCTP,
//Protocol #1: AVCTP
SDP_DATA_ELEM_SEQ_HDR,
0x06, //Element length: 5 bytes
SDP_UUID16_HDR,
(uint8_t)(UUID_AVCTP >> 8),
(uint8_t)(UUID_AVCTP),
//Parameter #0 for Protocol #1: 0x0104 (v1.4)
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(0x0104 >> 8),
(uint8_t)(0x0104),
//Attribute SDP_ATTR_PROFILE_DESC_LIST
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_ATTR_PROFILE_DESC_LIST >> 8),
(uint8_t)SDP_ATTR_PROFILE_DESC_LIST,
SDP_DATA_ELEM_SEQ_HDR,
0x08, //Attribute length: 8 bytes
//Profile #0: A/V Remote Control
SDP_DATA_ELEM_SEQ_HDR,
0x06, //Element length: 6 bytes
SDP_UUID16_HDR,
(uint8_t)(UUID_AV_REMOTE_CONTROL >> 8),
(uint8_t)(UUID_AV_REMOTE_CONTROL),
//Parameter #0 for Profile #0: 0x0106 (v1.6)
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(0x0106 >> 8),
(uint8_t)(0x0106),
//Attribute SDP_ATTR_SUPPORTED_FEATURES
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)((SDP_ATTR_SUPPORTED_FEATURES) >> 8),
(uint8_t)(SDP_ATTR_SUPPORTED_FEATURES),
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(0x0001 >> 8), //Category 1 Player / Recorder //Supported Features
(uint8_t)(0x0001),
//Attribute SDP_ATTR_BROWSE_GROUP_LIST
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_ATTR_BROWSE_GROUP_LIST >> 8),
(uint8_t)SDP_ATTR_BROWSE_GROUP_LIST,
SDP_DATA_ELEM_SEQ_HDR,
0x03,
SDP_UUID16_HDR,
(uint8_t)(UUID_PUBLIC_BROWSE_GROUP >> 8),
(uint8_t)UUID_PUBLIC_BROWSE_GROUP
};
static const uint8_t avrcp_tg_sdp_record[] =
{
//Total length
SDP_DATA_ELEM_SEQ_HDR,
0x38,//0x46,//0x5F,
//Attribute SDP_ATTR_SRV_CLASS_ID_LIST
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_ATTR_SRV_CLASS_ID_LIST >> 8),
(uint8_t)SDP_ATTR_SRV_CLASS_ID_LIST,
SDP_DATA_ELEM_SEQ_HDR,
0x03, //Attribute length: 6 bytes
//Service Class #0: A/V Remote Control Target
SDP_UUID16_HDR,
(uint8_t)(UUID_AV_REMOTE_CONTROL_TARGET >> 8),
(uint8_t)(UUID_AV_REMOTE_CONTROL_TARGET),
//Attribute SDP_ATTR_PROTO_DESC_LIST
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_ATTR_PROTO_DESC_LIST >> 8),
(uint8_t)SDP_ATTR_PROTO_DESC_LIST,
SDP_DATA_ELEM_SEQ_HDR,
0x10, //Attribute length: 12 bytes
//Protocol #0: L2CAP
SDP_DATA_ELEM_SEQ_HDR,
0x06, //Element length: 3 bytes
SDP_UUID16_HDR,
(uint8_t)(UUID_L2CAP >> 8),
(uint8_t)(UUID_L2CAP),
//Parameter #0 for Protocol #0: PSM = AVCTP
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(PSM_AVCTP >> 8),
(uint8_t)PSM_AVCTP,
//Protocol #1: AVCTP
SDP_DATA_ELEM_SEQ_HDR,
0x06, //Element length: 5 bytes
SDP_UUID16_HDR,
(uint8_t)(UUID_AVCTP >> 8),
(uint8_t)(UUID_AVCTP),
//Parameter #0 for Protocol #1: 0x0104 (v1.4)
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(0x0104 >> 8),
(uint8_t)(0x0104),
//Attribute SDP_ATTR_PROFILE_DESC_LIST
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_ATTR_PROFILE_DESC_LIST >> 8),
(uint8_t)SDP_ATTR_PROFILE_DESC_LIST,
SDP_DATA_ELEM_SEQ_HDR,
0x08, //Attribute length: 8 bytes
//Profile #0: A/V Remote Control
SDP_DATA_ELEM_SEQ_HDR,
0x06, //Element length: 6 bytes
SDP_UUID16_HDR,
(uint8_t)(UUID_AV_REMOTE_CONTROL >> 8),
(uint8_t)(UUID_AV_REMOTE_CONTROL),
//Parameter #0 for Profile #0: 0x0106 (v1.6)
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(0x0106 >> 8),
(uint8_t)(0x0106),
//Attribute SDP_ATTR_SUPPORTED_FEATURES
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)((SDP_ATTR_SUPPORTED_FEATURES) >> 8),
(uint8_t)(SDP_ATTR_SUPPORTED_FEATURES),
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(0x0002 >> 8), //Category 2 Amplifier
(uint8_t)(0x0002),
//Attribute SDP_ATTR_BROWSE_GROUP_LIST
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_ATTR_BROWSE_GROUP_LIST >> 8),
(uint8_t)SDP_ATTR_BROWSE_GROUP_LIST,
SDP_DATA_ELEM_SEQ_HDR,
0x03,
SDP_UUID16_HDR,
(uint8_t)(UUID_PUBLIC_BROWSE_GROUP >> 8),
(uint8_t)UUID_PUBLIC_BROWSE_GROUP
/*
//Attribute SDP_ATTR_LANG_BASE_ATTR_ID_LIST...it is used for SDP_ATTR_SRV_NAME
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_ATTR_LANG_BASE_ATTR_ID_LIST >> 8),
(uint8_t)SDP_ATTR_LANG_BASE_ATTR_ID_LIST,
SDP_DATA_ELEM_SEQ_HDR,
0x09,
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_LANG_ENGLISH >> 8),
(uint8_t)SDP_LANG_ENGLISH,
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_CHARACTER_UTF8 >> 8),
(uint8_t)SDP_CHARACTER_UTF8,
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)(SDP_BASE_LANG_OFFSET >> 8),
(uint8_t)SDP_BASE_LANG_OFFSET,
//Attribute SDP_ATTR_PROVIDER_NAME
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)((SDP_ATTR_PROVIDER_NAME + SDP_BASE_LANG_OFFSET) >> 8),
(uint8_t)(SDP_ATTR_PROVIDER_NAME + SDP_BASE_LANG_OFFSET),
SDP_STRING_HDR,
0x07, //Attribute length: 7 bytes
0x52, 0x65, 0x61, 0x6C, 0x54, 0x65, 0x6B, //RealTek
//Attribute SDP_ATTR_SRV_NAME
SDP_UNSIGNED_TWO_BYTE,
(uint8_t)((SDP_ATTR_SRV_NAME + SDP_BASE_LANG_OFFSET) >> 8),
(uint8_t)(SDP_ATTR_SRV_NAME + SDP_BASE_LANG_OFFSET),
SDP_STRING_HDR,
0x08, //Attribute length: 8 bytes
0x41, 0x56, 0x52, 0x43, 0x50, 0x20, 0x54, 0x47, //AVRCP TG
*/
};
The bits for supported features are set to 1. Others are set to 0.
Bit |
Description |
---|---|
0 |
Category 1 Player / Recorder |
1 |
Category 2 Monitor/Amplifier |
2 |
Category 3 Tuner |
3 |
Category 4 Menu |
4-5 |
RFA |
6 |
Supports browsing |
7 |
Supports Cover Art GetImageProperties feature |
8 |
Supports Cover Art GetImage feature |
9 |
Supports Cover Art GetLinkedThumbnail feature |
10-15 |
RFA |
Feature Set
The functions provided by AVRCP API are as below.
Connecting and Disconnecting: Including functions to connect/disconnect AVRCP.
AVRCP Control APIs: Including functions to play/pause music, etc.
AVRCP Browsing APIs: Including functions to retrieve information about the available browsable items.
Cover Art APIs: Including functions to retrieve images associated with the media on the TG.
Provided APIs
This figure shows the relationship between applications, AVRCP, and Bluetooth Protocol Stack. Above the horizon line is developed by the applications. Below the horizon line is developed by Realtek.
The table below shows a simple description of AVRCP APIs. AVRCP related APIs are provided in the sdk\inc\framework\bt\bt_avrcp.h
.
Header file |
Description |
API Reference |
---|---|---|
bt_avrcp.h |
Connect AVRCP, send and receive data, etc. |
Functions
AVRCP Init
AVRCP initialization procedure involves profile initialization and supported features setting.
bt_avrcp_init() - Initialize AVRCP profile, and set AVRCP supported features for both CT and TG. The features set by this API shall be in accordance with these in AVRCP SDP record.
Note
If Absolute Volume is supported, Category 2 in Controller shall be checked for A2DP source device. And for A2DP sink device, Category 2 in Target shall be checked.
void app_avrcp_init(void)
{
if (app_cfg_const.supported_profile_mask & AVRCP_PROFILE_MASK)
{
uint8_t ct_features;
uint8_t tg_features;
ct_features = (app_cfg_const.avrcp_features_ct.features_value & 0x0F);
tg_features = (app_cfg_const.avrcp_features_tg.features_value & 0x0F);
if (ct_features != 0)
{
bt_sdp_record_add((void *)avrcp_ct_sdp_record);
}
if (tg_features != 0)
{
bt_sdp_record_add((void *)avrcp_tg_sdp_record);
}
bt_avrcp_init(app_cfg_const.avrcp_link_number);
bt_avrcp_supported_features_set(ct_features, tg_features);
bt_mgr_cback_register(app_avrcp_bt_cback);
}
}
AVRCP Control
AVRCP Control Connect
bt_avrcp_connect_req() - Initiate an AVRCP connection to a remote device.
Note
If both devices initiate a connection at the same time, both channels shall be closed and each device shall wait a random time (not more than 1s and not less than 100ms) and then try to initiate the connection again.
bt_avrcp_disconnect_req() - Request an AVRCP disconnection.
bt_avrcp_connect_cfm() - Accept or reject the incoming connection from the remote device.
static void app_avrcp_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case BT_EVENT_AVRCP_CONN_IND:
{
p_link = app_find_br_link(param->avrcp_conn_ind.bd_addr);
if (p_link != NULL)
{
bt_avrcp_connect_cfm(p_link->bd_addr, true);
}
}
break;
case BT_EVENT_AVRCP_CONN_CMPL:
break;
case BT_EVENT_AVRCP_CONN_FAIL:
break;
}
}
AVRCP Control Key
bt_avrcp_play() - Start playing an item on remote device.
bt_avrcp_pause() - Pause an item on remote device.
void app_avrcp_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case BT_EVENT_AVRCP_PLAY_STATUS_RSP:
case BT_EVENT_AVRCP_PLAY_STATUS_CHANGED:
{
if (app_db.avrcp_play_status == param->avrcp_play_status_changed.play_status)
{
break;
}
app_db.avrcp_play_status = param->avrcp_play_status_changed.play_status;
//job to do
}
break;
}
}
Note
BT_EVENT_AVRCP_PLAY_STATUS_RSP is reported after AVRCP play/pause CMD is accepted by phone.
BT_EVENT_AVRCP_PLAY_STATUS_CHANGED is reported only when receiving status changed event from phone.
The play_status in BT_EVENT_AVRCP_PLAY_STATUS_CHANGED is the real play status of phone, but play_status in BT_EVENT_AVRCP_PLAY_STATUS_RSP is related to the CMD sent to phone.
For example, if AVRCP pause is sent, the play_status in BT_EVENT_AVRCP_PLAY_STATUS_RSP is paused.
bt_avrcp_stop() - Stop playing an item on remote device.
bt_avrcp_forward() - Change the media which is playing to next one on remote device.
bt_avrcp_backward() - Change the media which is playing to last one on remote device.
bt_avrcp_rewind_start() - Start rewinding the media which is playing on remote device.
bt_avrcp_rewind_stop() - Stop rewinding the media which is playing on remote device.
bt_avrcp_fast_forward_start() - Start fast forward the media which is playing on remote device.
bt_avrcp_fast_forward_stop() - Stop fast forward the media which is playing on remote device.
AVRCP Control Volume
bt_avrcp_volume_change_register_rsp() - Send an AVRCP volume change response after received register notification volume change command.
bt_avrcp_volume_change_req() - Notify remote device that the volume has been changed locally.
void app_avrcp_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case BT_EVENT_AVRCP_REG_VOLUME_CHANGED:
{
p_link = app_find_br_link(param->avrcp_reg_volume_changed.bd_addr);
if (p_link != NULL)
{
bt_avrcp_volume_change_register_rsp(p_link->bd_addr, vol);
}
}
break;
}
}
void app_mmi_handle_action(uint8_t action)
{
switch (action)
{
case MMI_DEV_SPK_VOL_UP:
{
...
bt_avrcp_volume_change_req(app_db.br_link[active_idx].bd_addr, level);
}
break;
}
}
Volume adjustment flow is introduced below when absolute volume is supported by both sides.
AVRCP Control Miscellaneous
bt_avrcp_get_element_attr_req() - Get the attributes of the element of the currently playing track from the Addressed Player, if bt_avrcp_browsing_item_attrs_get() is not supported.
void app_avrcp_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case BT_EVENT_AVRCP_TRACK_CHANGED:
{
uint8_t attr_list[7] = {1, 2, 3, 4, 5, 6, 7};
uint8_t num_of_attr = 7;
p_link = app_find_br_link(param->avrcp_track_changed.bd_addr);
if (p_link != NULL)
{
bt_avrcp_get_element_attr_req(p_link->bd_addr, num_of_attr, attr_list);
}
}
break;
case BT_EVENT_AVRCP_ELEM_ATTR:
{
int i = 0;
for(i = 0; i < param->avrcp_elem_attr.num_of_attr; i++)
{
//deal with param->avrcp_elem_attr.attr[i]
switch(param->avrcp_elem_attr.attr[i].attribute_id)
{
case BT_AVRCP_ELEM_ATTR_TITLE:
{
...
}
break;
case BT_AVRCP_ELEM_ATTR_ARTIST:
break;
...
}
}
}
break;
}
}
bt_avrcp_get_play_status_req() - Get the status of the currently playing media, including song length and current position.
void app_avrcp_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case BT_EVENT_AVRCP_GET_PLAY_STATUS_RSP:
{
uint8_t play_status = param->avrcp_get_play_status_rsp.play_status;
uint32_t song_length = param->avrcp_get_play_status_rsp.length_ms;
uint32_t song_pos = param->avrcp_get_play_status_rsp.position_ms;
}
break;
}
}
AVRCP Browsing
This section describes the AVRCP browsing API definition. These APIs enable the CT to navigate the media on the target device, and perform operations on a specific media item. Browsing commands are used to retrieve information about the available browsable items.
AVRCP Browsing Connect
bt_avrcp_browsing_connect_req() - Create an AVRCP browsing connection.
bt_avrcp_browsing_disconnect_req() - Disconnect an AVRCP browsing connection.
bt_avrcp_browsing_connect_cfm() - Respond to the AVRCP connection request from remote device.
void app_test_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case BT_EVENT_AVRCP_BROWSING_CONN_IND:
{
p_link = app_find_br_link(param->avrcp_browsing_conn_ind.bd_addr);
if (p_link != NULL)
{
bt_avrcp_browsing_connect_cfm(p_link->bd_addr, true);
}
}
break;
case BT_EVENT_AVRCP_BROWSING_CONN_CMPL:
break;
}
}
AVRCP Browsing Application Setting
bt_avrcp_app_setting_attrs_list() - Request the target device to provide target supported player application setting attributes. The player application setting attributes are defined in
avrcp.h
.bt_avrcp_app_setting_values_list() - Request the target device to list the set of possible values for the requested player application setting attribute. The list of reserved player application setting attributes and their values are defined in
avrcp.h
.bt_avrcp_app_setting_value_get() - Request the target device to provide the current set values on the target for the provided player application setting attributes list.
void app_test_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
uint8_t i = 0;
switch (event_type)
{
case BT_EVENT_AVRCP_APP_SETTING_ATTRS_LIST_RSP:
{
if (param->avrcp_app_setting_attrs_list_rsp.state == 0)
{
for(i = 0; i < param->avrcp_app_setting_attrs_list_rsp.num_of_attr; i++)
{
APP_PRINT_INFO2("BT_EVENT_AVRCP_APP_SETTING_ATTRS_LIST_RSP: index %d, id %d",
i, param->avrcp_app_setting_attrs_list_rsp.p_attr_id[i]);
}
}
}
break;
case BT_EVENT_AVRCP_APP_SETTING_VALUES_LIST_RSP:
{
if (param->avrcp_app_setting_values_list_rsp.state == 0)
{
for(i = 0; i < param->avrcp_app_setting_values_list_rsp.num_of_value; i++)
{
APP_PRINT_INFO3("BT_EVENT_AVRCP_APP_SETTING_VALUES_LIST_RSP: index %d, value %d",
i, param->avrcp_app_setting_values_list_rsp.p_value[i]);
}
}
}
break;
case BT_EVENT_AVRCP_APP_SETTING_GET_RSP:
{
if (param->avrcp_app_setting_get_rsp.state == 0)
{
for(i = 0; i < param->avrcp_app_setting_get_rsp.num_of_attr; i++)
{
APP_PRINT_INFO3("BT_EVENT_AVRCP_APP_SETTING_GET_RSP: index %d, attr %d, value %d",
i, param->avrcp_app_setting_get_rsp.p_app_setting[i].attr,
param->avrcp_app_setting_get_rsp.p_app_setting[i].value);
}
}
}
break;
}
}
bt_avrcp_app_setting_value_set() - Request to set the player application setting list of player application setting values on the target device.
{
uint8_t attr_list[4];
attr_list[0] = APP_SETTING_ATTR_EQUALIZER;
attr_list[1] = EQUALIZER_STATUS_OFF;
attr_list[2] = APP_SETTING_ATTR_REPEAT_MODE;
attr_list[3] = REPEAT_MODE_STATUS_SINGLE;
bt_avrcp_app_setting_value_set(bd_addr, 2, attr_list);
}
AVRCP Browsing Search
The search procedure is shown below.
bt_avrcp_browsing_folder_items_get() - This command is used to retrieve a listing of the contents of a folder.
bt_avrcp_browsing_item_attrs_get() - This command is used to retrieve the metadata attributes for a particular media element item, or folder item.
bt_avrcp_browsing_search() - This provides basic search functionality. Regular expressions shall not be supported. Searches are performed from the current folder in the Browsed Players virtual filesystem. The search applies to the current folder and all folders below that.
void app_test_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case BT_EVENT_AVRCP_SEARCH_RSP:
{
uint8_t num_of_items;
num_of_items = param->avrcp_search_rsp.num_of_items;
bt_avrcp_browsing_folder_items_get(param->avrcp_search_rsp.bd_addr, 2, 0, num_of_items-1, 0, NULL);
}
break;
case BT_EVENT_AVRCP_FOLDER_ITEMS_GET_RSP:
{
uint8_t item_type;
if (param->avrcp_folder_items_get_rsp.num_of_items > 0)
{
item_type = param->avrcp_folder_items_get_rsp.item_type;
if (item_type == 0x1)
{
//media player item, refer to T_BT_AVRCP_MEDIA_PLAYER_ITEM
//param->avrcp_folder_items_get_rsp.u.p_media_player_items
}
else if (item_type == 0x2)
{
//folder item, refer to T_BT_AVRCP_FOLDER_ITEM
//param->avrcp_folder_items_get_rsp.u.p_folder_items
}
else if (item_type == 0x3)
{
//media element item, refer to T_BT_AVRCP_MEDIA_ELEMENT_ITEM
//param->avrcp_folder_items_get_rsp.u.p_media_element_items
}
}
}
break;
case BT_EVENT_AVRCP_ITEM_ATTR_GET_RSP:
{
T_BT_AVRCP_ITEM_ATTR *attr;
uint8_t i;
for (i = 0; i < param->avrcp_item_attr_get_rsp.num_of_attr; i++)
{
attr = event->p_attr + i;
switch(attr->attribute_id)
{
case BT_AVRCP_ELEM_ATTR_TITLE:
{
...
}
break;
...
}
}
}
break;
}
}
AVRCP Browsing Miscellaneous
bt_avrcp_addressed_player_set() - Inform the TG of which media player the CT wishes to control.
bt_avrcp_browsing_browsed_player_set() - This command is used to control to which player browsing commands should be routed.
Note
Some players may not support browsing of the media player tree or search results unless the Browsed Player is set to the Addressed Player. This is indicated in the player feature bitmask.
void app_avrcp_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case T_BT_EVENT_PARAM_AVRCP_ADDRESSED_PLAYER_SET_RSP:
{
...
}
break;
case T_BT_EVENT_PARAM_AVRCP_BROWSED_PLAYER_SET_RSP:
{
...
}
break;
}
}
bt_avrcp_item_play() - Start playing an item indicated by the UID. It is routed to the Addressed Player.
bt_avrcp_group_navigate() - Move to the first song in the next/previous group.
bt_avrcp_browsing_path_change() - This command is used to navigate the virtual filesystem, and allows the CT to navigate one level up or down in the virtual filesystem.
bt_avrcp_continuing_rsp_req() - Request for continuing response packets for the sent PDU command that has not completed.
bt_avrcp_continuing_rsp_abort() - Abort continuing response.
Cover Art
The CT uses the Cover Art feature to retrieve the cover art associated with the browsed or played media items, as shown below:
This section describes the Cover Art API definition and how to retrieve images associated with the media on the TG.
These APIs are used over an OBEX connection, as shown below:
Cover Art Retrieve Procedure
AVRCP Cover Art Connect
bt_avrcp_cover_art_connect_req() - Create a cover art connection.
void app_avrcp_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case BT_EVENT_SDP_ATTR_INFO:
{
T_BT_SDP_ATTR_INFO *sdp_info = ¶m->sdp_attr_info.info;
if (sdp_info->srv_class_uuid_data.uuid_16 == UUID_AV_REMOTE_CONTROL_TARGET)
{
bt_avrcp_cover_art_connect_req(bd_addr, sdp_info->l2c_psm);
}
}
break;
}
}
Note
There is no restriction when this API shall be called. However, as BIP image handles are valid only during the lifetime of a Cover Art connection, an OBEX level connection shall exist before the BIP image handle can be successfully retrieved and the handles retrieved can only be used during that Cover Art connection.
AVRCP Cover Art Retrieve
bt_avrcp_cover_art_get() - Retrieve the cover art.
uint8_t image_handle[16];
void app_avrcp_bt_cback(T_BT_EVENT event_type, void *event_buf, uint16_t buf_len)
{
switch (event_type)
{
case BT_EVENT_AVRCP_TRACK_CHANGED:
{
bt_avrcp_get_element_attr_req(param->avrcp_track_changed.bd_addr, 0, NULL);
}
break;
case BT_EVENT_AVRCP_ELEM_ATTR:
{
uint8_t num_of_attr = param->avrcp_elem_attr.num_of_attr;
uint8_t i;
for (i = 0; i < num_of_attr; i++)
{
if(param->avrcp_elem_attr.attr[i].attribute_id == BT_AVRCP_ELEM_ATTR_DEFAULT_COVER_ART)
{
utf8_to_unicode(param->avrcp_elem_attr.attr[i].p_buf, 7, image_handle);
image_handle[14] = '\0';
image_handle[15] = '\0';
bt_avrcp_cover_art_get(param->avrcp_elem_attr.bd_addr, image_handle);
break;
}
}
}
break;
case BT_EVENT_AVRCP_COVER_ART_DATA_IND:
{
if (!param->avrcp_cover_art_data_ind.data_end)
{
bt_avrcp_cover_art_get(param->avrcp_cover_art_data_ind.bd_addr, image_handle);
}
//deal with data
}
break;
}
}
Image Handle can be retrieved by bt_avrcp_get_element_attr_req() or bt_avrcp_browsing_item_attrs_get().
Note
The image handle retrieved is a 7-character UTF-8 string and should be converted to a NULL-terminated UTF-16 string.
AVRCP Cover Art Disconnect
bt_avrcp_cover_art_disconnect_req() - Disconnect a cover art connection. When the OBEX level connection is closed, the BIP image handles retrieved during that OBEX connection will no longer be valid.
Sample Projects
SDK provides a corresponding demo application for developers’ reference in development. The BR/EDR Audio gives a simple example on how to use AVRCP.