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.

  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 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.

Bluetooth AVRCP Profile

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

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.

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

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.

AVRCP Control Volume

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

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

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

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

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

The procedure is shown below.

AVRCP Cover Art Connect

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

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.