Diff between 5071d7dd621b5d04720c2decec2325c5777b872d and 45aa22f0f3d672c66b9777317c12c4196a9efd86

Changed Files

File Additions Deletions Status
android/avrcp.c +40 -27 modified

Full Patch

diff --git a/android/avrcp.c b/android/avrcp.c
index 7bd6165..504ce2b 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -60,6 +60,7 @@ static struct ipc *hal_ipc = NULL;
 struct avrcp_request {
 	struct avrcp_device *dev;
 	uint8_t pdu_id;
+	uint8_t event_id;
 	uint8_t transaction;
 };
 
@@ -72,7 +73,8 @@ struct avrcp_device {
 	GQueue		*queue;
 };
 
-static struct avrcp_request *pop_request(uint8_t pdu_id)
+static struct avrcp_request *pop_request(uint8_t pdu_id, uint8_t event_id,
+								bool peek)
 {
 	GSList *l;
 
@@ -84,10 +86,13 @@ static struct avrcp_request *pop_request(uint8_t pdu_id)
 		for (i = 0; reqs; reqs = g_list_next(reqs), i++) {
 			struct avrcp_request *req = reqs->data;
 
-			if (req->pdu_id == pdu_id) {
+			if (req->pdu_id != pdu_id || req->event_id != event_id)
+				continue;
+
+			if (!peek)
 				g_queue_pop_nth(dev->queue, i);
-				return req;
-			}
+
+			return req;
 		}
 	}
 
@@ -103,7 +108,7 @@ static void handle_get_play_status(const void *buf, uint16_t len)
 
 	DBG("");
 
-	req = pop_request(AVRCP_GET_PLAY_STATUS);
+	req = pop_request(AVRCP_GET_PLAY_STATUS, 0, false);
 	if (!req) {
 		status = HAL_STATUS_FAILED;
 		goto done;
@@ -218,7 +223,7 @@ static void handle_get_element_attrs_text(const void *buf, uint16_t len)
 
 	DBG("");
 
-	req = pop_request(AVRCP_GET_ELEMENT_ATTRIBUTES);
+	req = pop_request(AVRCP_GET_ELEMENT_ATTRIBUTES, 0, false);
 	if (!req) {
 		status = HAL_STATUS_FAILED;
 		goto done;
@@ -260,11 +265,25 @@ static void handle_register_notification(const void *buf, uint16_t len)
 	uint8_t pdu[IPC_MTU];
 	size_t pdu_len;
 	uint8_t code;
+	bool peek = false;
 	int ret;
 
 	DBG("");
 
-	req = pop_request(AVRCP_REGISTER_NOTIFICATION);
+	switch (cmd->type) {
+	case HAL_AVRCP_EVENT_TYPE_INTERIM:
+		code = AVC_CTYPE_INTERIM;
+		peek = true;
+		break;
+	case HAL_AVRCP_EVENT_TYPE_CHANGED:
+		code = AVC_CTYPE_CHANGED;
+		break;
+	default:
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	req = pop_request(AVRCP_REGISTER_NOTIFICATION, cmd->event, peek);
 	if (!req) {
 		status = HAL_STATUS_FAILED;
 		goto done;
@@ -285,29 +304,19 @@ static void handle_register_notification(const void *buf, uint16_t len)
 		goto done;
 	}
 
-	switch (cmd->type) {
-	case HAL_AVRCP_EVENT_TYPE_INTERIM:
-		code = AVC_CTYPE_INTERIM;
-		break;
-	case HAL_AVRCP_EVENT_TYPE_CHANGED:
-		code = AVC_CTYPE_CHANGED;
-		break;
-	default:
-		status = HAL_STATUS_FAILED;
-		goto done;
-	}
-
 	ret = avrcp_register_notification_rsp(req->dev->session,
 						req->transaction, code,
 						pdu, pdu_len);
 	if (ret < 0) {
 		status = HAL_STATUS_FAILED;
-		g_free(req);
+		if (!peek)
+			g_free(req);
 		goto done;
 	}
 
 	status = HAL_STATUS_SUCCESS;
-	g_free(req);
+	if (!peek)
+		g_free(req);
 
 done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
@@ -556,13 +565,14 @@ static ssize_t handle_get_capabilities_cmd(struct avrcp *session,
 }
 
 static void push_request(struct avrcp_device *dev, uint8_t pdu_id,
-							uint8_t transaction)
+					uint8_t event_id, uint8_t transaction)
 {
 	struct avrcp_request *req;
 
 	req = g_new0(struct avrcp_request, 1);
 	req->dev = dev;
 	req->pdu_id = pdu_id;
+	req->event_id = event_id;
 	req->transaction = transaction;
 
 	g_queue_push_tail(dev->queue, req);
@@ -584,7 +594,7 @@ static ssize_t handle_get_play_status_cmd(struct avrcp *session,
 	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
 					HAL_EV_AVRCP_GET_PLAY_STATUS, 0, NULL);
 
-	push_request(dev, AVRCP_GET_PLAY_STATUS, transaction);
+	push_request(dev, AVRCP_GET_PLAY_STATUS, 0, transaction);
 
 	return -EAGAIN;
 }
@@ -620,7 +630,7 @@ static ssize_t handle_get_element_attrs_cmd(struct avrcp *session,
 					HAL_EV_AVRCP_GET_ELEMENT_ATTRS,
 					sizeof(*ev) + ev->number, ev);
 
-	push_request(dev, AVRCP_GET_ELEMENT_ATTRIBUTES, transaction);
+	push_request(dev, AVRCP_GET_ELEMENT_ATTRIBUTES, 0, transaction);
 
 	return -EAGAIN;
 
@@ -634,14 +644,17 @@ static ssize_t handle_register_notification_cmd(struct avrcp *session,
 {
 	struct avrcp_device *dev = user_data;
 	struct hal_ev_avrcp_register_notification ev;
+	uint8_t event_id;
 
 	DBG("");
 
 	if (params_len != 5)
 		return -EINVAL;
 
+	event_id = params[0];
+
 	/* TODO: Add any missing events supported by Android */
-	switch (params[0]) {
+	switch (event_id) {
 	case AVRCP_EVENT_STATUS_CHANGED:
 	case AVRCP_EVENT_TRACK_CHANGED:
 	case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
@@ -650,14 +663,14 @@ static ssize_t handle_register_notification_cmd(struct avrcp *session,
 		return -EINVAL;
 	}
 
-	ev.event = params[0];
+	ev.event = event_id;
 	ev.param = bt_get_be32(&params[1]);
 
 	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
 					HAL_EV_AVRCP_REGISTER_NOTIFICATION,
 					sizeof(ev), &ev);
 
-	push_request(dev, AVRCP_REGISTER_NOTIFICATION, transaction);
+	push_request(dev, AVRCP_REGISTER_NOTIFICATION, event_id, transaction);
 
 	return -EAGAIN;
 }