diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 51a89b1..a96fb93 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
#define AVRCP_STATUS_PARAM_NOT_FOUND 0x02
#define AVRCP_STATUS_INTERNAL_ERROR 0x03
#define AVRCP_STATUS_SUCCESS 0x04
+#define AVRCP_STATUS_UID_CHANGED 0x05
+#define AVRCP_STATUS_DOES_NOT_EXIST 0x09
#define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b
#define AVRCP_STATUS_INVALID_PLAYER_ID 0x11
#define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12
return 0;
}
+static gboolean avrcp_play_item_rsp(struct avctp *conn, uint8_t code,
+ uint8_t subunit, uint8_t transaction,
+ uint8_t *operands, size_t operand_count,
+ void *user_data)
+{
+ struct avrcp_browsing_header *pdu = (void *) operands;
+ struct avrcp *session = (void *) user_data;
+ struct avrcp_player *player = session->controller->player;
+ struct media_player *mp = player->user_data;
+ int ret = 0;
+
+ if (pdu == NULL) {
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+
+ if (pdu->params[0] != AVRCP_STATUS_SUCCESS) {
+ switch (pdu->params[0]) {
+ case AVRCP_STATUS_UID_CHANGED:
+ case AVRCP_STATUS_DOES_NOT_EXIST:
+ ret = -ENOENT;
+ default:
+ ret = -EINVAL;
+ }
+ goto done;
+ }
+
+done:
+ media_player_play_item_complete(mp, ret);
+
+ return FALSE;
+}
+
static void avrcp_play_item(struct avrcp *session, uint64_t uid)
{
uint8_t buf[AVRCP_HEADER_LENGTH + 11];
avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
AVC_SUBUNIT_PANEL, buf, length,
- NULL, session);
+ avrcp_play_item_rsp, session);
}
static int ct_play_item(struct media_player *mp, const char *name,
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index 7944b49..72ebdfa 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
{
struct media_item *item = data;
struct media_player *mp = item->player;
+ struct media_folder *folder = mp->scope;
struct player_callback *cb = mp->cb;
const char *path;
int err;
if (!item->playable || !cb->cbs->play_item)
return btd_error_not_supported(msg);
- path = mp->search && mp->scope == mp->search ? "/Search" : item->path;
+ if (folder->msg)
+ return btd_error_failed(msg, strerror(EBUSY));
+
+ path = mp->search && folder == mp->search ? "/Search" : item->path;
err = cb->cbs->play_item(mp, path, item->uid, cb->user_data);
if (err < 0)
return btd_error_failed(msg, strerror(-err));
- return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+ folder->msg = dbus_message_ref(msg);
+
+ return NULL;
}
static DBusMessage *media_item_add_to_nowplaying(DBusConnection *conn,
{ }
};
+void media_player_play_item_complete(struct media_player *mp, int err)
+{
+ struct media_folder *folder = mp->scope;
+ DBusMessage *reply;
+
+ if (folder == NULL || folder->msg == NULL)
+ return;
+
+ if (err < 0) {
+ reply = btd_error_failed(folder->msg, strerror(-err));
+ goto done;
+ }
+
+ reply = g_dbus_create_reply(folder->msg, DBUS_TYPE_INVALID);
+
+done:
+ g_dbus_send_message(btd_get_dbus_connection(), reply);
+ dbus_message_unref(folder->msg);
+ folder->msg = NULL;
+}
+
void media_item_set_playable(struct media_item *item, bool value)
{
if (item->playable == value)
diff --git a/profiles/audio/player.h b/profiles/audio/player.h
index 54e395a..a7c7d2a 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
player_item_type_t type,
uint64_t uid);
+void media_player_play_item_complete(struct media_player *mp, int err);
void media_item_set_playable(struct media_item *item, bool value);
void media_player_list_complete(struct media_player *mp, GSList *items,
int err);