From: Bharat Bhusan Panda <bharat.panda@samsung.com>
To: 'Luiz Augusto von Dentz' <luiz.dentz@gmail.com>
Cc: linux-bluetooth@vger.kernel.org, cpgs@samsung.com
Subject: RE: [PATCH 1/2] audio/avrcp: Add support for Set Browsed Player
Date: Wed, 07 Oct 2015 10:15:36 +0530 [thread overview]
Message-ID: <01c901d100bb$1536c3d0$3fa44b70$@samsung.com> (raw)
In-Reply-To: <CABBYNZJ5XE41CL0N22TuTU2M5RiCQh+E9pw1r3rjhfjk3GV1Ow@mail.gmail.com>
Hi Luiz,
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-
> owner@vger.kernel.org] On Behalf Of Luiz Augusto von Dentz
> Sent: Thursday, October 01, 2015 8:06 PM
> To: Bharat Panda
> Cc: linux-bluetooth@vger.kernel.org; cpgs@samsung.com
> Subject: Re: [PATCH 1/2] audio/avrcp: Add support for Set Browsed Player
>
> Hi Bharat,
>
> On Thu, Oct 1, 2015 at 2:48 PM, Bharat Panda <bharat.panda@samsung.com>
> wrote:
> > Support added to handle SetBrowsedPlayer cmd in AVRCP TG role.
> > Added a new player callback get_playlist to retrieve available
> > playlists on org.moris.MediPlayer2.Playlists interface.
> >
> > btmon:
> > AVCTP Browsing: Response: type 0x00 label 13 PID 0x110e
> > AVRCP: SetBrowsedPlayer: len 0x000a
> > Status: 0x04 (Success)
> > UIDCounter: 0x0000 (0)
> > Number of Items: 0x00000007 (7)
> > CharsetID: 0x006a (UTF-8)
> > Folder Depth: 0x00 (0)
> > ---
> > profiles/audio/avrcp.c | 71 ++++++++++++++++++++++++++++++++++++
> > profiles/audio/avrcp.h | 4 +++
> > profiles/audio/media.c | 98
> > ++++++++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 173 insertions(+)
> >
> > diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c index
> > 24deac5..b2198e3 100644
> > --- a/profiles/audio/avrcp.c
> > +++ b/profiles/audio/avrcp.c
> > @@ -207,6 +207,15 @@ struct player_item {
> > char name[0];
> > } __attribute__ ((packed));
> >
> > +struct avrcp_set_browsed_player_rsp {
> > + uint8_t status;
> > + uint16_t uid_counter;
> > + uint32_t num_of_items;
> > + uint16_t charset_id;
> > + uint8_t folder_depth;
> > + uint8_t data[0];
> > +} __attribute__ ((packed));
> > +
> > struct avrcp_server {
> > struct btd_adapter *adapter;
> > uint32_t tg_record_id;
> > @@ -1873,6 +1882,67 @@ err_metadata:
> > return AVRCP_HEADER_LENGTH + 1; }
> >
> > +static void avrcp_handle_set_browsed_player(struct avrcp *session,
> > + struct avrcp_browsing_header *pdu,
> > + uint8_t transaction) {
> > + struct avrcp_player *player;
> > + struct media_player *mp;
> > + uint16_t len = ntohs(pdu->param_len);
> > + uint16_t player_id = 0;
> > + uint8_t status;
> > +
> > + if (len < 1) {
> > + status = AVRCP_STATUS_INVALID_PARAM;
> > + goto failed;
> > + }
> > +
> > + player_id = bt_get_be16(&pdu->params[0]);
> > + player = find_tg_player(session, player_id);
> > +
> > + if (player) {
> > + struct avrcp_set_browsed_player_rsp *resp;
> > + uint32_t num_of_items = 0;
> > +
> > + mp = player->user_data;
> > + player->browsed = true;
> > +
> > + resp = (struct avrcp_set_browsed_player_rsp *)
> > + pdu->params;
> > +
> > + resp->status = AVRCP_STATUS_SUCCESS;
> > + resp->uid_counter = htons(player_get_uid_counter(player));
> > + resp->num_of_items = 0;
> > + resp->charset_id = htons(AVRCP_CHARSET_UTF8);
> > + resp->folder_depth = 0;
> > + pdu->param_len = htons(sizeof(*resp));
> > +
> > + if (!player->cb->get_playlists(0x0000, 0xFFFF,
> > + "Alphabetical",
> > + NULL,
> > + &num_of_items, mp)) {
>
> Design the callback based in AVRCP interface not MPRIS, it is up to media.c to
> convert this.
>
> > + status = AVRCP_STATUS_INVALID_PARAM;
> > + goto failed;
> > + }
> > +
> > + resp->num_of_items = htonl(num_of_items);
> > +
> > + /*
> > + * MPRIS player returns a flat hierarchy playlist structure,
> > + * where the folder depth will always considered to be 0.
> > + */
> > + resp->folder_depth = 0;
>
> It seems you are assigning this twice, also it probably make sense to split this
> into player_set_browsed and let it return the number of items.
>
> > + } else {
> > + status = AVRCP_STATUS_INVALID_PLAYER_ID;
> > + goto failed;
> > + }
> > +
> > + return;
> > +
> > +failed:
> > + pdu->params[0] = status;
> > + pdu->param_len = htons(1);
> > +}
> > +
> > static void avrcp_handle_media_player_list(struct avrcp *session,
> > struct avrcp_browsing_header *pdu,
> > uint32_t start_item, uint32_t
> > end_item) @@ -1989,6 +2059,7 @@ static struct browsing_pdu_handler {
> > uint8_t
> > transaction); } browsing_handlers[] = {
> > { AVRCP_GET_FOLDER_ITEMS,
> > avrcp_handle_get_folder_items },
> > + { AVRCP_SET_BROWSED_PLAYER,
> > + avrcp_handle_set_browsed_player},
> > { },
> > };
> >
> > diff --git a/profiles/audio/avrcp.h b/profiles/audio/avrcp.h index
> > 86d310c..87e591d 100644
> > --- a/profiles/audio/avrcp.h
> > +++ b/profiles/audio/avrcp.h
> > @@ -101,6 +101,10 @@ struct avrcp_player_cb {
> > bool (*pause) (void *user_data);
> > bool (*next) (void *user_data);
> > bool (*previous) (void *user_data);
> > + int (*get_playlists) (uint32_t start, uint32_t end,
> > + char *ordering, uint8_t *pdu,
> > + uint32_t *num_of_items,
> > + void *user_data);
> > };
> >
> > int avrcp_set_volume(struct btd_device *dev, uint8_t volume, bool
> > notify); diff --git a/profiles/audio/media.c b/profiles/audio/media.c
> > index 69070bf..2835f93 100644
> > --- a/profiles/audio/media.c
> > +++ b/profiles/audio/media.c
> > @@ -58,6 +58,7 @@
> > #define MEDIA_INTERFACE "org.bluez.Media1"
> > #define MEDIA_ENDPOINT_INTERFACE "org.bluez.MediaEndpoint1"
> > #define MEDIA_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player"
> > +#define MEDIA_PLAYER_PLAYLIST_INTERFACE
> "org.mpris.MediaPlayer2.Playlists"
> >
> > #define REQUEST_TIMEOUT (3 * 1000) /* 3 seconds */
> >
> > @@ -115,6 +116,14 @@ struct media_player {
> > char *name;
> > };
> >
> > +struct media_playlist {
> > + char *name;
> > + char *id;
> > + char *icon;
> > + uint32_t num_of_items;
> > + uint8_t data[0];
> > +} __attribute__ ((packed));
> > +
> > static GSList *adapters = NULL;
> >
> > static void endpoint_request_free(struct endpoint_request *request)
> > @@ -1270,6 +1279,94 @@ static bool previous(void *user_data)
> >
> > return media_player_send(mp, "Previous"); }
> > +static int get_playlists(uint32_t start_index, uint32_t end_index,
> > + char *ordering, uint8_t *pdu,
> > + uint32_t *num_of_items,
> > + void *user_data) {
> > + struct media_player *mp = user_data;
> > + struct media_playlist *playlist;
> > + DBusMessage *msg;
> > + DBusMessage *reply;
> > + DBusMessageIter array_iter;
> > + DBusMessageIter value;
> > + DBusMessageIter struct_iter;
> > + DBusError err;
> > + gboolean reverse_order = FALSE;
> > + int type;
> > + uint32_t total_items = 0;
> > + uint32_t max_count = (end_index - start_index);
> > +
> > + msg = dbus_message_new_method_call(mp->sender, mp->path,
> > + MEDIA_PLAYER_PLAYLIST_INTERFACE,
> > + "GetPlaylists");
> > +
> > + if (msg == NULL) {
> > + error("Couldn't allocate D-Bus message");
> > + return -ENOMEM;
> > + }
> > +
> > + dbus_message_append_args(msg,
> > + DBUS_TYPE_UINT32, &start_index,
> > + DBUS_TYPE_UINT32, &max_count,
> > + DBUS_TYPE_STRING, &ordering,
> > + DBUS_TYPE_BOOLEAN, &reverse_order,
> > + DBUS_TYPE_INVALID);
> > +
> > + dbus_error_init(&err);
> > +
> > + /* Make Dbus sync call to get available playlists */
> > + reply = dbus_connection_send_with_reply_and_block(
> > + btd_get_dbus_connection(), msg, -1,
> > + &err);
>
> You should never do blocking call in the daemon, this would make it
> unresponsive until the player respond. We should either add the
> PlaylistCount and Playlists properties in the registration or try to read them as
> soon the player register, and since they are properties we can probably
> cache it and subscribe to PropertiesChanged interface that way we never
> have to call anything blocking.
Thanks, I have incorporated above review comments and added 3 separate patches for,
- Getting Playlists after player registration.
- Add watch on playlist details changes
- Set Browsed Player response.
TODO: properties changed watch needs to be added, with playlist properties parser.
>
> --
> Luiz Augusto von Dentz
> --
Regards,
Bharat
prev parent reply other threads:[~2015-10-07 4:45 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-01 11:48 [PATCH 1/2] audio/avrcp: Add support for Set Browsed Player Bharat Panda
2015-10-01 11:49 ` [PATCH 2/2] tools: Fix Invalid return Bharat Panda
2015-10-02 7:33 ` Luiz Augusto von Dentz
2015-10-01 14:35 ` [PATCH 1/2] audio/avrcp: Add support for Set Browsed Player Luiz Augusto von Dentz
2015-10-07 4:45 ` Bharat Bhusan Panda [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='01c901d100bb$1536c3d0$3fa44b70$@samsung.com' \
--to=bharat.panda@samsung.com \
--cc=cpgs@samsung.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=luiz.dentz@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).