bluetooth: Need help with A2DP/AVRC Vendor Response to GetElementAttributes (0x20)

elliott
Posts: 2
Joined: Mon Jan 06, 2020 9:23 pm

bluetooth: Need help with A2DP/AVRC Vendor Response to GetElementAttributes (0x20)

Postby elliott » Mon Jan 06, 2020 9:46 pm

New ESP32 user here. I'm working on an ESP32 enabled device that acts as a A2DP-SRC/AVRC target that should send audio / media title to a remote AVRC controller display / A2DP sink. I'm using the V4 master branch source (to get the AVRC TARGET code). Starting with the A2DP/AVRC source, I have been able to get everything working as desired except for displaying metadata on a vehicle panel display. I only desire to display the TITLE of media via GetElementAttributes (0x20) and to response to GetPlayStatus (0x30). By default, the play status is always playing as desired (may be the default action of the controller). Monitoring the console output, I noticed that I was getting unhandled vendor commands for 0x20 and 0x30 PDUs. I've added code to try and get the response correct, but no luck so far. The controller (panel display) continues to send 0x20 when pressing track forward/back and continually sends 0x30 to check on the playing status.

In components/bt/host/bluedroid/bta/av/bta_av_act.c

I have added the following case inside the bta_av_proc_meta_cmd() function in an attempt to display "TEST" for the media TITLE in response to the 0x20 GetElementAttributes command from the controller. I also implemented a similar case for the GetPlayStatus (0x30)

Code: Select all

    uint8_t vendor_attr_resp[64];
    uint8_t *ptr;


        case  0x20  : //getelementattributes
            printf("\r\nRemote controller requested GetElementAttributes\r\n");

            ptr = vendor_attr_resp;
            *ptr++ = 0x00;
            *ptr++ = 0x00;
            *ptr++ = 0x00;
            *ptr++ = 0x01;  //int attrib 0x00000001 is TITLE of media attrib id
            *ptr++ = 0x00;
            *ptr++ = 0x6a;  //UTF-8 charset 
            *ptr++ = 0x00;
            *ptr++ = 0x04;  //uint16_t  len of attribute 
            *ptr++ = 'T';
            *ptr++ = 'E';
            *ptr++ = 'S';
            *ptr++ = 'T';

            *p_ctype = AVRC_RSP_CHANGED;
            p_rc_rsp->rsp.status = AVRC_STS_NO_ERROR;

            p_rc_rsp->get_elem_attrs.pdu = 0x20;
            p_rc_rsp->get_elem_attrs.opcode = AVRC_OP_VENDOR;
            p_rc_rsp->get_elem_attrs.num_attr = 0x01;   //single attribute
            p_rc_rsp->get_elem_attrs.p_attrs = vendor_attr_resp;

            evt = 1;  //true to send respond
The code does get called and I don't see any related errors in the console with related debug messages enabled, but the controller does not display the media TITLE (audio is working / playing). Would appreciate if someone can spot what is wrong / missing?

elliott
Posts: 2
Joined: Mon Jan 06, 2020 9:23 pm

Re: bluetooth: Need help with A2DP/AVRC Vendor Response to GetElementAttributes (0x20)

Postby elliott » Tue Jan 07, 2020 1:35 am

I finally got it figured it out. I wasn't seeing error messages because I had set the evt flag to 1. After setting that to zero, I started getting messages about invalid attribute id for the GetElementAttributes and noticed that I had passed the incorrect structure.

changes to components/bt/host/bluedroid/bta/av/bta_av_act.c to get the Vendor commands for meta data working look like this:

Code: Select all

static tavrc_attr_entry attr_entry;
static char title[64];

//////////////////////////////////////////////////
//////////////////////////////////////////////////
void set_track_title(char *str) {
  strncpy( title, str, 63);
  title[63]=0;
}

In  bta_av_proc_meta_cmd()  function,  the case 0x20  (GetElementAttributes)  was added


        case  0x20  : //getelementattributes
            printf("\r\nremote controller requested getelementattributes\r\n");

            #if 0
                typedef struct {
                    uint32              attr_id;        /* use avrc_media_attr_id_title, avrc_media_attr_id_artist, avrc_media_attr_id_album,
                                                           avrc_media_attr_id_track_num, avrc_media_attr_id_num_tracks,
                                                           avrc_media_attr_id_genre, avrc_media_attr_id_playing_time */
                    tavrc_full_name     name;           /* the attribute value, value length and character set id. */
                } tavrc_attr_entry;

                typedef struct {
                    uint16              charset_id;
                    uint16              str_len;
                    uint8               *p_str;
                } tavrc_full_name;
            #endif

            attr_ptr->attr_id = avrc_media_attr_id_title;
            attr_ptr->name.charset_id = 0x006a;
            attr_ptr->name.str_len = strlen(title);
            attr_ptr->name.p_str = (uint8_t *) title;

            *p_ctype = avrc_rsp_changed;
            p_rc_rsp->rsp.status = avrc_sts_no_error;

            p_rc_rsp->get_elem_attrs.pdu = 0x20;
            p_rc_rsp->get_elem_attrs.opcode = avrc_op_vendor;
            p_rc_rsp->get_elem_attrs.num_attr = 0x01;   //single attribute
            p_rc_rsp->get_elem_attrs.p_attrs = attr_ptr;

            evt = 0;  //process immediately after return and not in application event handler

Who is online

Users browsing this forum: Bing [Bot], cdollar and 117 guests