This allows user applications to display the playlist with Artist, Album, Track number, Duration and Cover art handle. --- profiles/audio/avrcp.c | 50 ++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c index cab9fb4b2..1622734b3 100644 --- a/profiles/audio/avrcp.c +++ b/profiles/audio/avrcp.c @@ -2414,16 +2414,12 @@ static void avrcp_list_player_attributes(struct avrcp *session) } static void avrcp_parse_attribute_list(struct avrcp_player *player, + struct media_item *item, uint8_t *operands, uint8_t count) { struct media_player *mp = player->user_data; - struct media_item *item; int i; - media_player_clear_metadata(mp); - - item = media_player_set_playlist_item(mp, player->uid); - for (i = 0; count > 0; count--) { uint32_t id; uint16_t charset, len; @@ -2448,8 +2444,6 @@ static void avrcp_parse_attribute_list(struct avrcp_player *player, i += len; } - - media_player_metadata_changed(mp); } static gboolean avrcp_get_element_attributes_rsp(struct avctp *conn, @@ -2462,6 +2456,8 @@ static gboolean avrcp_get_element_attributes_rsp(struct avctp *conn, struct avrcp *session = user_data; struct avrcp_player *player = session->controller->player; struct avrcp_header *pdu = (void *) operands; + struct media_player *mp = player->user_data; + struct media_item *item; uint8_t count; if (code == AVC_CTYPE_REJECTED) @@ -2474,7 +2470,13 @@ static gboolean avrcp_get_element_attributes_rsp(struct avctp *conn, return FALSE; } - avrcp_parse_attribute_list(player, &pdu->params[1], count); + media_player_clear_metadata(mp); + + item = media_player_set_playlist_item(mp, player->uid); + + avrcp_parse_attribute_list(player, item, &pdu->params[1], count); + + media_player_metadata_changed(mp); avrcp_get_play_status(session); @@ -2560,9 +2562,10 @@ static struct media_item *parse_media_element(struct avrcp *session, struct avrcp_player *player; struct media_player *mp; struct media_item *item; - uint16_t namelen; + uint16_t namelen, namesize; char name[255]; uint64_t uid; + uint8_t count; if (len < 13) return NULL; @@ -2570,10 +2573,13 @@ static struct media_item *parse_media_element(struct avrcp *session, uid = get_be64(&operands[0]); memset(name, 0, sizeof(name)); - namelen = MIN(get_be16(&operands[11]), sizeof(name) - 1); + namesize = get_be16(&operands[11]); + namelen = MIN(namesize, sizeof(name) - 1); if (namelen > 0) memcpy(name, &operands[13], namelen); + count = operands[13 + namesize]; + player = session->controller->player; mp = player->user_data; @@ -2583,6 +2589,9 @@ static struct media_item *parse_media_element(struct avrcp *session, media_item_set_playable(item, true); + avrcp_parse_attribute_list(player, item, &operands[14 + namesize], + count); + return item; } @@ -2717,20 +2726,25 @@ static void avrcp_list_items(struct avrcp *session, uint32_t start, memset(buf, 0, sizeof(buf)); pdu->pdu_id = AVRCP_GET_FOLDER_ITEMS; - pdu->param_len = cpu_to_be16(10 + sizeof(uint32_t)); + pdu->param_len = cpu_to_be16(10 + (6 * sizeof(uint32_t))); pdu->params[0] = player->scope; put_be32(start, &pdu->params[1]); put_be32(end, &pdu->params[5]); - pdu->params[9] = 1; + pdu->params[9] = 6; /* Only the title (0x01) is mandatory. This can be extended to * support AVRCP_MEDIA_ATTRIBUTE_* attributes */ put_be32(AVRCP_MEDIA_ATTRIBUTE_TITLE, &pdu->params[10]); + put_be32(AVRCP_MEDIA_ATTRIBUTE_ARTIST, &pdu->params[14]); + put_be32(AVRCP_MEDIA_ATTRIBUTE_ALBUM, &pdu->params[18]); + put_be32(AVRCP_MEDIA_ATTRIBUTE_TRACK, &pdu->params[22]); + put_be32(AVRCP_MEDIA_ATTRIBUTE_DURATION, &pdu->params[26]); + put_be32(AVRCP_MEDIA_ATTRIBUTE_IMG_HANDLE, &pdu->params[30]); - length += sizeof(uint32_t); + length += 6 * sizeof(uint32_t); avctp_send_browsing_req(session->conn, buf, length, avrcp_list_items_rsp, session); @@ -2855,6 +2869,8 @@ static gboolean avrcp_get_item_attributes_rsp(struct avctp *conn, struct avrcp *session = user_data; struct avrcp_player *player = session->controller->player; struct avrcp_browsing_header *pdu = (void *) operands; + struct media_player *mp = player->user_data; + struct media_item *item; uint8_t count; if (pdu == NULL) { @@ -2874,7 +2890,13 @@ static gboolean avrcp_get_item_attributes_rsp(struct avctp *conn, return FALSE; } - avrcp_parse_attribute_list(player, &pdu->params[2], count); + media_player_clear_metadata(mp); + + item = media_player_set_playlist_item(mp, player->uid); + + avrcp_parse_attribute_list(player, item, &pdu->params[2], count); + + media_player_metadata_changed(mp); avrcp_get_play_status(session); -- 2.34.1