OSDN Git Service

audio/AVRCP: Add support for PlayItem command
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 17 May 2013 12:43:49 +0000 (15:43 +0300)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 17 Jun 2013 15:13:54 +0000 (18:13 +0300)
This adds support for PlayItem command via player callback.

profiles/audio/avrcp.c
profiles/audio/player.h

index a35477e..632cd64 100644 (file)
 #define AVRCP_GET_FOLDER_ITEMS         0x71
 #define AVRCP_CHANGE_PATH              0x72
 #define AVRCP_GET_ITEM_ATTRIBUTES      0x73
+#define AVRCP_PLAY_ITEM                        0x74
 #define AVRCP_GENERAL_REJECT           0xA0
 
 /* Capabilities for AVRCP_GET_CAPABILITIES pdu */
@@ -2630,6 +2631,52 @@ static int ct_change_folder(struct media_player *mp, const char *path,
        return 0;
 }
 
+static void avrcp_play_item(struct avrcp *session, uint64_t uid)
+{
+       uint8_t buf[AVRCP_HEADER_LENGTH + 11];
+       struct avrcp_player *player = session->player;
+       struct avrcp_header *pdu = (void *) buf;
+       uint16_t length;
+
+       memset(buf, 0, sizeof(buf));
+
+       set_company_id(pdu->company_id, IEEEID_BTSIG);
+       pdu->pdu_id = AVRCP_PLAY_ITEM;
+       pdu->params_len = htons(11);
+       pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
+
+       pdu->params[0] = player->scope;
+       bt_put_be64(uid, &pdu->params[1]);
+       bt_put_be16(player->uid_counter, &pdu->params[9]);
+
+       length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
+
+       avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
+                                       AVC_SUBUNIT_PANEL, buf, length,
+                                       NULL, session);
+}
+
+static int ct_play_item(struct media_player *mp, const char *name,
+                                               uint64_t uid, void *user_data)
+{
+       struct avrcp_player *player = user_data;
+       struct avrcp *session;
+
+       if (player->p != NULL)
+               return -EBUSY;
+
+       session = player->sessions->data;
+
+       if (g_strrstr(name, "/NowPlaying"))
+               player->scope = 0x03;
+       else
+               player->scope = 0x01;
+
+       avrcp_play_item(session, uid);
+
+       return 0;
+}
+
 static const struct media_player_callback ct_cbs = {
        .set_setting    = ct_set_setting,
        .play           = ct_play,
@@ -2641,6 +2688,7 @@ static const struct media_player_callback ct_cbs = {
        .rewind         = ct_rewind,
        .list_items     = ct_list_items,
        .change_folder  = ct_change_folder,
+       .play_item      = ct_play_item,
 };
 
 static struct avrcp_player *create_ct_player(struct avrcp *session,
index 151cabd..7d4344c 100644 (file)
@@ -58,6 +58,8 @@ struct media_player_callback {
                                uint32_t start, uint32_t end, void *user_data);
        int (*change_folder) (struct media_player *mp, const char *path,
                                                uint64_t uid, void *user_data);
+       int (*play_item) (struct media_player *mp, const char *name,
+                                       uint64_t uid, void *user_data);
 };
 
 struct media_player *media_player_controller_create(const char *path,