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 Personal Digital Assistant, a mobile phone, a remote controller, or an audio/video 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.

AVRCP Support Feature

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:

  1. Connecting and Disconnecting: Including functions to connect/disconnect AVRCP.

  2. AVRCP Control APIs: Including functions to play/pause music, etc.

  3. AVRCP Browsing APIs: Including functions to retrieve information about the available browsable items.

  4. 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 host. Above the horizon line is developed by the applications. Below the horizon line is developed by Realtek.

../../../../../_images/bt_avrcp_struct.png

AVRCP Struct

The table below shows a simple description of AVRCP APIs. AVRCP related APIs are provided in the sdk\inc\framework\bt\bt_avrcp.h.

AVRCP API

Header File

Description

API Reference

bt_avrcp.h

ContConnect AVRCP, send and receive data etc.ents

Bluetooth AVRCP Profile

Functions

AVRCP Init

AVRCP initialization procedure involves profile initialization and supported features setting.

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.
../../../../../_images/avrcp_feature.png

AVRCP Feature

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

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.

Request an AVRCP disconnection.
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

Start playing an item on remote device.
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

For example, if AVRCP pause is sent, the play_status in BT_EVENT_AVRCP_PLAY_STATUS_RSP is paused.

../../../../../_images/avrcp_play_status.png

Avrcp Play Status

Stop playing an item on remote device.
Change the media which is playing to next one on remote device.
Change the media which is playing to last one on remote device.
Start rewinding the media which is playing on remote device.
Stop rewinding the media which is playing on remote device.
Start fast forward the media which is playing on remote device.
Stop fast forward the media which is playing on remote device.

AVRCP Control Volume

Send an AVRCP volume change response after received register notification volume change command.
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.

../../../../../_images/avrcp_volume_adjust_src.png

AVRCP Volume Adjust Src

../../../../../_images/avrcp_volume_adjust_snk.png

AVRCP Volume Adjust Snk

AVRCP Control Miscellaneous

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;
    }
}
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

Create an AVRCP browsing connection.
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

Request the target device to provide target supported player application setting attributes. The player application setting attributes are defined in avrcp.h.
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.
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;
    }
}
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 Miscellaneous

Inform the TG of which media player the CT wishes to control.
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;
    }
}
Start playing an item indicated by the UID. It is routed to the Addressed Player.
Move to the first song in the next/previous group.
This command is used to navigate the virtual filesystem, and allows the CT to navigate one level up or down in the virtual filesystem.
Request for continuing response packets for the sent PDU command that has not completed.
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:

../../../../../_images/cover_art.png

AVRCP Cover Art

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:

../../../../../_images/profile_avrcp.png

Profile AVRCP

Cover Art Retrieve Procedure

The procedure is shown below.

../../../../../_images/cover_art_retrieve_flow.png

Cover Art Retrieve Flow

AVRCP Cover Art Connect

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 = &param->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

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

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.