Hi Archie, On Tue, Sep 1, 2020 at 9:57 PM Archie Pusaka <apusaka@xxxxxxxxxx> wrote: > > From: Archie Pusaka <apusaka@xxxxxxxxxxxx> > > According to the AVRCP spec, section 4.5, GetTotalNumberOfItems PDU > is mandatory for TG supporting category 1 or 3. > > Reviewed-by: Yun-Hao Chung <howardchung@xxxxxxxxxx> > Reviewed-by: Michael Sun <michaelfsun@xxxxxxxxxx> > --- > > profiles/audio/avrcp.c | 58 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 58 insertions(+) > > diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c > index 5d0256c52..6da73394f 100644 > --- a/profiles/audio/avrcp.c > +++ b/profiles/audio/avrcp.c > @@ -79,6 +79,7 @@ > #define AVRCP_STATUS_SUCCESS 0x04 > #define AVRCP_STATUS_UID_CHANGED 0x05 > #define AVRCP_STATUS_DOES_NOT_EXIST 0x09 > +#define AVRCP_STATUS_INVALID_SCOPE 0x0a > #define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b > #define AVRCP_STATUS_INVALID_PLAYER_ID 0x11 > #define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12 > @@ -211,6 +212,12 @@ struct player_item { > char name[0]; > } __attribute__ ((packed)); > > +struct get_total_number_of_items_rsp { > + uint8_t status; > + uint16_t uid_counter; > + uint32_t num_items; > +} __attribute__ ((packed)); > + > struct avrcp_server { > struct btd_adapter *adapter; > uint32_t tg_record_id; > @@ -566,6 +573,9 @@ static void populate_default_features(void) > > /* supports at least AVRCP 1.4 */ > default_features[7] |= (1 << 2); > + > + /* supports GetTotalNumberOfItems browsing command */ > + default_features[8] |= (1 << 3); > } > > static unsigned int attr_get_max_val(uint8_t attr) > @@ -2048,10 +2058,56 @@ static void avrcp_handle_get_folder_items(struct avrcp *session, > case AVRCP_SCOPE_SEARCH: > case AVRCP_SCOPE_NOW_PLAYING: > default: > + status = AVRCP_STATUS_INVALID_SCOPE; > + goto failed; > + } > + > + return; > + > +failed: > + pdu->params[0] = status; > + pdu->param_len = htons(1); > +} > + > +static void avrcp_handle_media_player_list_num_items(struct avrcp *session, > + struct avrcp_browsing_header *pdu) > +{ > + struct avrcp_player *player = target_get_player(session); > + struct get_total_number_of_items_rsp *rsp; > + > + rsp = (void *)pdu->params; > + rsp->status = AVRCP_STATUS_SUCCESS; > + rsp->uid_counter = htons(player_get_uid_counter(player)); > + rsp->num_items = htonl(g_slist_length(session->server->players)); > + pdu->param_len = htons(sizeof(*rsp)); > +} > + > +static void avrcp_handle_get_total_number_of_items(struct avrcp *session, > + struct avrcp_browsing_header *pdu, > + uint8_t transaction) > +{ > + uint8_t scope; > + uint8_t status = AVRCP_STATUS_SUCCESS; > + > + if (ntohs(pdu->param_len) != 1) { > status = AVRCP_STATUS_INVALID_PARAM; > goto failed; > } > > + scope = pdu->params[0]; > + > + switch (scope) { > + case AVRCP_SCOPE_MEDIA_PLAYER_LIST: > + avrcp_handle_media_player_list_num_items(session, pdu); > + break; > + case AVRCP_SCOPE_MEDIA_PLAYER_VFS: > + case AVRCP_SCOPE_SEARCH: > + case AVRCP_SCOPE_NOW_PLAYING: > + default: > + status = AVRCP_STATUS_INVALID_SCOPE; > + goto failed; > + } > + > return; > > failed: > @@ -2065,6 +2121,8 @@ static struct browsing_pdu_handler { > uint8_t transaction); > } browsing_handlers[] = { > { AVRCP_GET_FOLDER_ITEMS, avrcp_handle_get_folder_items }, > + { AVRCP_GET_TOTAL_NUMBER_OF_ITEMS, > + avrcp_handle_get_total_number_of_items }, > { }, > }; > > -- > 2.28.0.402.g5ffc5be6b7-goog > Applied, thanks. -- Luiz Augusto von Dentz