diff mbox series

[Bluez,v1] avrcp: Add handler for GET_TOTAL_NUMBER_OF_ITEMS

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

Commit Message

Archie Pusaka Sept. 2, 2020, 4:57 a.m. UTC
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(+)

Comments

Archie Pusaka Sept. 11, 2020, 12:50 p.m. UTC | #1
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
>
Luiz Augusto von Dentz Sept. 11, 2020, 3:43 p.m. UTC | #2
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 mbox series

Patch

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