Message ID | 20200902125726.Bluez.v1.1.I732df55cd70d552fc48e87686fb53c3f8ccbefa5@changeid (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Luiz Von Dentz |
Headers | show |
Series | [Bluez,v1] avrcp: Add handler for GET_TOTAL_NUMBER_OF_ITEMS | expand |
Hi Bluez maintainers, Could you take another look at this patch? Thanks, Archie On Wed, 2 Sep 2020 at 12:57, Archie Pusaka <apusaka@google.com> wrote: > > From: Archie Pusaka <apusaka@chromium.org> > > 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@google.com> > Reviewed-by: Michael Sun <michaelfsun@google.com> > --- > > 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 >
Hi Archie, On Tue, Sep 1, 2020 at 9:57 PM Archie Pusaka <apusaka@google.com> wrote: > > From: Archie Pusaka <apusaka@chromium.org> > > 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@google.com> > Reviewed-by: Michael Sun <michaelfsun@google.com> > --- > > 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.
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 }, { }, };