Diff between f1af5592645a20c6705eb8b30b5e5b4f1cc1d1ce and 4f45ed811a27c173c2f70d87bff7bb9c8bb46ee4

Changed Files

File Additions Deletions Status
profiles/audio/avrcp.c +48 -0 modified
profiles/audio/player.h +2 -0 modified

Full Patch

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index a35477e..632cd64 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -105,6 +105,7 @@
 #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,
diff --git a/profiles/audio/player.h b/profiles/audio/player.h
index 151cabd..7d4344c 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
@@ -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,