Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function
@ 2014-03-02 18:48 Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 02/16] android/avctp: Make handler return ssize_t Luiz Augusto von Dentz
                   ` (13 more replies)
  0 siblings, 14 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds avrcp_send function which can be used to response to
outstanding requests.
---
 android/avrcp-lib.c | 27 +++++++++++++++++++++++++++
 android/avrcp-lib.h |  4 +++-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 34eea66..6fed825 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -253,6 +253,33 @@ int avrcp_init_uinput(struct avrcp *session, const char *name,
 	return avctp_init_uinput(session->conn, name, address);
 }
 
+int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code,
+					uint8_t subunit, uint8_t pdu_id,
+					uint8_t *params, size_t params_len)
+{
+	struct avrcp_header *pdu = (void *) session->tx_buf;
+	size_t len = sizeof(*pdu);
+
+	memset(pdu, 0, len);
+
+	hton24(pdu->company_id, IEEEID_BTSIG);
+	pdu->pdu_id = pdu_id;
+	pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
+
+	if (params_len > 0) {
+		len += params_len;
+
+		if (len > session->tx_mtu)
+			return -ENOBUFS;
+
+		memcpy(pdu->params, params, params_len);
+		pdu->params_len = htons(params_len);
+	}
+
+	return avctp_send_vendordep(session->conn, transaction, code, subunit,
+							session->tx_buf, len);
+}
+
 static int avrcp_send_req(struct avrcp *session, uint8_t code, uint8_t subunit,
 					uint8_t pdu_id, uint8_t *params,
 					size_t params_len, avctp_rsp_cb func,
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 0407cb4..a33bdfe 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -102,7 +102,9 @@ void avrcp_set_passthrough_handlers(struct avrcp *session,
 			void *user_data);
 int avrcp_init_uinput(struct avrcp *session, const char *name,
 							const char *address);
-
+int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code,
+					uint8_t subunit, uint8_t pdu_id,
+					uint8_t *params, size_t params_len);
 int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
 					avctp_rsp_cb func, void *user_data);
 int avrcp_list_player_attributes(struct avrcp *session, avctp_rsp_cb func,
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 02/16] android/avctp: Make handler return ssize_t
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 03/16] android/avrcp-lib: Rework handler callback parameters Luiz Augusto von Dentz
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This makes possible to return errors such as -EAGAIN to indicate the
request would block and a response will be sent asynchronously.
---
 android/avctp.c     | 17 ++++++++++++-----
 android/avctp.h     |  2 +-
 android/avrcp-lib.c |  2 +-
 unit/test-avctp.c   |  2 +-
 4 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/android/avctp.c b/android/avctp.c
index bc1bd80..aa5abc9 100644
--- a/android/avctp.c
+++ b/android/avctp.c
@@ -311,7 +311,7 @@ static gboolean auto_release(gpointer user_data)
 	return FALSE;
 }
 
-static size_t handle_panel_passthrough(struct avctp *session,
+static ssize_t handle_panel_passthrough(struct avctp *session,
 					uint8_t transaction, uint8_t *code,
 					uint8_t *subunit, uint8_t *operands,
 					size_t operand_count, void *user_data)
@@ -402,7 +402,7 @@ done:
 	return operand_count;
 }
 
-static size_t handle_unit_info(struct avctp *session,
+static ssize_t handle_unit_info(struct avctp *session,
 					uint8_t transaction, uint8_t *code,
 					uint8_t *subunit, uint8_t *operands,
 					size_t operand_count, void *user_data)
@@ -428,7 +428,7 @@ static size_t handle_unit_info(struct avctp *session,
 	return operand_count;
 }
 
-static size_t handle_subunit_info(struct avctp *session,
+static ssize_t handle_subunit_info(struct avctp *session,
 					uint8_t transaction, uint8_t *code,
 					uint8_t *subunit, uint8_t *operands,
 					size_t operand_count, void *user_data)
@@ -849,8 +849,9 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
 	uint8_t *operands, code, subunit;
 	struct avctp_header *avctp;
 	struct avc_header *avc;
-	int ret, packet_size, operand_count, sock;
+	int packet_size, operand_count, sock;
 	struct avctp_pdu_handler *handler;
+	ssize_t ret;
 
 	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
 		goto failed;
@@ -910,10 +911,16 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
 	code = avc->code;
 	subunit = avc->subunit_type;
 
-	packet_size += handler->cb(session, avctp->transaction, &code,
+	ret = handler->cb(session, avctp->transaction, &code,
 					&subunit, operands, operand_count,
 					handler->user_data);
+	if (ret < 0) {
+		if (ret == -EAGAIN)
+			return TRUE;
+		goto failed;
+	}
 
+	packet_size += ret;
 	avc->code = code;
 	avc->subunit_type = subunit;
 
diff --git a/android/avctp.h b/android/avctp.h
index dfa0ca6..2f419a2 100644
--- a/android/avctp.h
+++ b/android/avctp.h
@@ -113,7 +113,7 @@ struct avctp;
 typedef bool (*avctp_passthrough_cb) (struct avctp *session,
 					uint8_t op, bool pressed,
 					void *user_data);
-typedef size_t (*avctp_control_pdu_cb) (struct avctp *session,
+typedef ssize_t (*avctp_control_pdu_cb) (struct avctp *session,
 					uint8_t transaction, uint8_t *code,
 					uint8_t *subunit, uint8_t *operands,
 					size_t operand_count, void *user_data);
diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 6fed825..cdad6ac 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -115,7 +115,7 @@ void avrcp_shutdown(struct avrcp *session)
 	g_free(session);
 }
 
-static size_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
+static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
 					uint8_t *code, uint8_t *subunit,
 					uint8_t *operands, size_t operand_count,
 					void *user_data)
diff --git a/unit/test-avctp.c b/unit/test-avctp.c
index be1dfd7..0759731 100644
--- a/unit/test-avctp.c
+++ b/unit/test-avctp.c
@@ -227,7 +227,7 @@ static void execute_context(struct context *context)
 	destroy_context(context);
 }
 
-static size_t handler(struct avctp *session,
+static ssize_t handler(struct avctp *session,
 					uint8_t transaction, uint8_t *code,
 					uint8_t *subunit, uint8_t *operands,
 					size_t operand_count, void *user_data)
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 03/16] android/avrcp-lib: Rework handler callback parameters
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 02/16] android/avctp: Make handler return ssize_t Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-03  9:52   ` Andrei Emeltchenko
  2014-03-02 18:48 ` [PATCH BlueZ 04/16] android/avrcp-lib: Embed response code into handler table Luiz Augusto von Dentz
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This rework handler callback parameters to make it able to return
proper error such as -EAGAIN to implement asynchronous responses.
---
 android/avrcp-lib.c | 12 +++++++++---
 android/avrcp-lib.h |  5 +++--
 unit/test-avrcp.c   | 42 +++++++++++++++++++++---------------------
 3 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index cdad6ac..339be16 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -125,6 +125,7 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
 	struct avrcp_header *pdu = (void *) operands;
 	uint32_t company_id = ntoh24(pdu->company_id);
 	uint16_t params_len = ntohs(pdu->params_len);
+	ssize_t ret;
 
 	if (company_id != IEEEID_BTSIG) {
 		*code = AVC_CTYPE_NOT_IMPLEMENTED;
@@ -159,12 +160,17 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
 		goto reject;
 	}
 
-	*code = handler->func(session, transaction, &params_len,
+	ret = handler->func(session, transaction, code, params_len,
 					pdu->params, session->control_data);
+	if (ret < 0) {
+		if (ret == -EAGAIN)
+			return ret;
+		goto reject;
+	}
 
-	pdu->params_len = htons(params_len);
+	pdu->params_len = htons(ret);
 
-	return AVRCP_HEADER_LENGTH + params_len;
+	return AVRCP_HEADER_LENGTH + ret;
 
 reject:
 	pdu->params_len = htons(1);
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index a33bdfe..d7a805b 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -79,8 +79,9 @@ struct avrcp;
 struct avrcp_control_handler {
 	uint8_t id;
 	uint8_t code;
-	uint8_t (*func) (struct avrcp *session, uint8_t transaction,
-			uint16_t *params_len, uint8_t *params, void *user_data);
+	ssize_t (*func) (struct avrcp *session, uint8_t transaction,
+			uint8_t *code, uint16_t params_len, uint8_t *params,
+			void *user_data);
 };
 
 struct avrcp_passthrough_handler {
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 302c331..2d5711b 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -292,54 +292,54 @@ static const struct avrcp_passthrough_handler passthrough_handlers[] = {
 		{ },
 };
 
-static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
-				uint8_t transaction, uint16_t *params_len,
-				uint8_t *params, void *user_data)
+static ssize_t avrcp_handle_get_capabilities(struct avrcp *session,
+					uint8_t transaction, uint8_t *code,
+					uint16_t params_len, uint8_t *params,
+					void *user_data)
 {
 	uint32_t id = 0x001958;
 
-	DBG("params[0] %d params_len %d", params[0], *params_len);
-
-	if (*params_len != 1)
+	if (params_len != 1)
 		goto fail;
 
 	switch (params[0]) {
 	case CAP_COMPANY_ID:
-		*params_len = 5;
 		params[1] = 1;
 		hton24(&params[2], id);
-		return AVC_CTYPE_STABLE;
+		*code = AVC_CTYPE_STABLE;
+		return 5;
 	}
 
 fail:
-	*params_len = 1;
 	params[0] = AVRCP_STATUS_INVALID_PARAM;
-
-	return AVC_CTYPE_REJECTED;
+	*code = AVC_CTYPE_REJECTED;
+	return 1;
 }
 
-static uint8_t avrcp_handle_list_attributes(struct avrcp *session,
-				uint8_t transaction, uint16_t *params_len,
-				uint8_t *params, void *user_data)
+static ssize_t avrcp_handle_list_attributes(struct avrcp *session,
+					uint8_t transaction, uint8_t *code,
+					uint16_t params_len, uint8_t *params,
+					void *user_data)
 {
 	DBG("");
 
-	*params_len = 1;
 	params[0] = 0;
+	*code = AVC_CTYPE_STABLE;
 
-	return AVC_CTYPE_STABLE;
+	return 1;
 }
 
-static uint8_t avrcp_handle_get_player_attr_text(struct avrcp *session,
-				uint8_t transaction, uint16_t *params_len,
-				uint8_t *params, void *user_data)
+static ssize_t avrcp_handle_get_player_attr_text(struct avrcp *session,
+					uint8_t transaction, uint8_t *code,
+					uint16_t params_len, uint8_t *params,
+					void *user_data)
 {
 	DBG("");
 
-	*params_len = 1;
 	params[0] = 0;
+	*code = AVC_CTYPE_STABLE;
 
-	return AVC_CTYPE_STABLE;
+	return 1;
 }
 
 static const struct avrcp_control_handler control_handlers[] = {
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 04/16] android/avrcp-lib: Embed response code into handler table
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 02/16] android/avctp: Make handler return ssize_t Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 03/16] android/avrcp-lib: Rework handler callback parameters Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 05/16] android/avrcp-lib: Fix not passing user data of passthrough callback Luiz Augusto von Dentz
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This makes the handlers code simpler as they don't need to care about
the response or reject opcode.
---
 android/avrcp-lib.c | 16 ++++++++++++----
 android/avrcp-lib.h |  4 ++--
 unit/test-avrcp.c   | 41 +++++++++++++++++++++--------------------
 3 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 339be16..7b89ee2 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -160,14 +160,22 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
 		goto reject;
 	}
 
-	ret = handler->func(session, transaction, code, params_len,
-					pdu->params, session->control_data);
+	ret = handler->func(session, transaction, params_len, pdu->params,
+							session->control_data);
 	if (ret < 0) {
-		if (ret == -EAGAIN)
+		switch (ret) {
+		case -EAGAIN:
 			return ret;
-		goto reject;
+		case -EINVAL:
+			pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
+			goto reject;
+		default:
+			pdu->params[0] = AVRCP_STATUS_INTERNAL_ERROR;
+			goto reject;
+		}
 	}
 
+	*code = handler->rsp;
 	pdu->params_len = htons(ret);
 
 	return AVRCP_HEADER_LENGTH + ret;
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index d7a805b..df9f1c6 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -79,9 +79,9 @@ struct avrcp;
 struct avrcp_control_handler {
 	uint8_t id;
 	uint8_t code;
+	uint8_t rsp;
 	ssize_t (*func) (struct avrcp *session, uint8_t transaction,
-			uint8_t *code, uint16_t params_len, uint8_t *params,
-			void *user_data);
+			uint16_t params_len, uint8_t *params, void *user_data);
 };
 
 struct avrcp_passthrough_handler {
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 2d5711b..d8484cd 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -31,6 +31,7 @@
 #include <inttypes.h>
 #include <string.h>
 #include <fcntl.h>
+#include <errno.h>
 #include <sys/socket.h>
 
 #include <glib.h>
@@ -293,61 +294,61 @@ static const struct avrcp_passthrough_handler passthrough_handlers[] = {
 };
 
 static ssize_t avrcp_handle_get_capabilities(struct avrcp *session,
-					uint8_t transaction, uint8_t *code,
-					uint16_t params_len, uint8_t *params,
-					void *user_data)
+						uint8_t transaction,
+						uint16_t params_len,
+						uint8_t *params,
+						void *user_data)
 {
 	uint32_t id = 0x001958;
 
 	if (params_len != 1)
-		goto fail;
+		return -EINVAL;
 
 	switch (params[0]) {
 	case CAP_COMPANY_ID:
 		params[1] = 1;
 		hton24(&params[2], id);
-		*code = AVC_CTYPE_STABLE;
 		return 5;
 	}
 
-fail:
-	params[0] = AVRCP_STATUS_INVALID_PARAM;
-	*code = AVC_CTYPE_REJECTED;
-	return 1;
+	return -EINVAL;
 }
 
 static ssize_t avrcp_handle_list_attributes(struct avrcp *session,
-					uint8_t transaction, uint8_t *code,
-					uint16_t params_len, uint8_t *params,
-					void *user_data)
+						uint8_t transaction,
+						uint16_t params_len,
+						uint8_t *params,
+						void *user_data)
 {
 	DBG("");
 
 	params[0] = 0;
-	*code = AVC_CTYPE_STABLE;
 
 	return 1;
 }
 
 static ssize_t avrcp_handle_get_player_attr_text(struct avrcp *session,
-					uint8_t transaction, uint8_t *code,
-					uint16_t params_len, uint8_t *params,
-					void *user_data)
+						uint8_t transaction,
+						uint16_t params_len,
+						uint8_t *params,
+						void *user_data)
 {
 	DBG("");
 
 	params[0] = 0;
-	*code = AVC_CTYPE_STABLE;
 
 	return 1;
 }
 
 static const struct avrcp_control_handler control_handlers[] = {
-		{ AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS,
+		{ AVRCP_GET_CAPABILITIES,
+					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
 					avrcp_handle_get_capabilities },
-		{ AVRCP_LIST_PLAYER_ATTRIBUTES, AVC_CTYPE_STATUS,
+		{ AVRCP_LIST_PLAYER_ATTRIBUTES,
+					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
 					avrcp_handle_list_attributes },
-		{ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT, AVC_CTYPE_STATUS,
+		{ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
+					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
 					avrcp_handle_get_player_attr_text },
 		{ },
 };
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 05/16] android/avrcp-lib: Fix not passing user data of passthrough callback
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 04/16] android/avrcp-lib: Embed response code into handler table Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 06/16] android/avrcp-lib: Add pressed status to passthrough handler callback Luiz Augusto von Dentz
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/avrcp-lib.c | 2 +-
 android/avrcp-lib.h | 2 +-
 unit/test-avrcp.c   | 8 ++++----
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 7b89ee2..8854263 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -209,7 +209,7 @@ static bool handle_passthrough_pdu(struct avctp *conn, uint8_t op,
 	if (!pressed)
 		return true;
 
-	return handler->func(session);
+	return handler->func(session, session->passthrough_data);
 }
 
 struct avrcp *avrcp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index df9f1c6..430f545 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -86,7 +86,7 @@ struct avrcp_control_handler {
 
 struct avrcp_passthrough_handler {
 	uint8_t op;
-	bool (*func) (struct avrcp *session);
+	bool (*func) (struct avrcp *session, void *user_data);
 };
 
 typedef void (*avrcp_destroy_cb_t) (void *user_data);
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index d8484cd..ac267bb 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -257,28 +257,28 @@ static void execute_context(struct context *context)
 	destroy_context(context);
 }
 
-static bool handle_play(struct avrcp *session)
+static bool handle_play(struct avrcp *session, void *user_data)
 {
 	DBG("");
 
 	return true;
 }
 
-static bool handle_volume_up(struct avrcp *session)
+static bool handle_volume_up(struct avrcp *session, void *user_data)
 {
 	DBG("");
 
 	return true;
 }
 
-static bool handle_channel_up(struct avrcp *session)
+static bool handle_channel_up(struct avrcp *session, void *user_data)
 {
 	DBG("");
 
 	return true;
 }
 
-static bool handle_select(struct avrcp *session)
+static bool handle_select(struct avrcp *session, void *user_data)
 {
 	DBG("");
 
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 06/16] android/avrcp-lib: Add pressed status to passthrough handler callback
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (3 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 05/16] android/avrcp-lib: Fix not passing user data of passthrough callback Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 07/16] android/avrcp: Add passthrough handler for fast forward Luiz Augusto von Dentz
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds pressed status to passthrough handler callback which is
required by Android HAL for certain keys such as fast forward and rewind.
---
 android/avrcp-lib.c |  6 +-----
 android/avrcp-lib.h |  2 +-
 unit/test-avrcp.c   | 10 ++++++----
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 8854263..40ff7b3 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -205,11 +205,7 @@ static bool handle_passthrough_pdu(struct avctp *conn, uint8_t op,
 	if (handler->func == NULL)
 		return false;
 
-	/* Do not trigger handler on release */
-	if (!pressed)
-		return true;
-
-	return handler->func(session, session->passthrough_data);
+	return handler->func(session, pressed, session->passthrough_data);
 }
 
 struct avrcp *avrcp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 430f545..3df5897 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -86,7 +86,7 @@ struct avrcp_control_handler {
 
 struct avrcp_passthrough_handler {
 	uint8_t op;
-	bool (*func) (struct avrcp *session, void *user_data);
+	bool (*func) (struct avrcp *session, bool pressed, void *user_data);
 };
 
 typedef void (*avrcp_destroy_cb_t) (void *user_data);
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index ac267bb..0294973 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -257,28 +257,30 @@ static void execute_context(struct context *context)
 	destroy_context(context);
 }
 
-static bool handle_play(struct avrcp *session, void *user_data)
+static bool handle_play(struct avrcp *session, bool pressed, void *user_data)
 {
 	DBG("");
 
 	return true;
 }
 
-static bool handle_volume_up(struct avrcp *session, void *user_data)
+static bool handle_volume_up(struct avrcp *session, bool pressed,
+							void *user_data)
 {
 	DBG("");
 
 	return true;
 }
 
-static bool handle_channel_up(struct avrcp *session, void *user_data)
+static bool handle_channel_up(struct avrcp *session, bool pressed,
+							void *user_data)
 {
 	DBG("");
 
 	return true;
 }
 
-static bool handle_select(struct avrcp *session, void *user_data)
+static bool handle_select(struct avrcp *session, bool pressed, void *user_data)
 {
 	DBG("");
 
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 07/16] android/avrcp: Add passthrough handler for fast forward
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (4 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 06/16] android/avrcp-lib: Add pressed status to passthrough handler callback Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 08/16] android/avrcp: Add passthrough handler for rewind Luiz Augusto von Dentz
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Fast forward should be send via HAL not handled directly by uinput
otherwise Android media player might not interpret it correctly.
---
 android/avrcp.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/android/avrcp.c b/android/avrcp.c
index 678c321..3d56ccf 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -301,6 +301,27 @@ static void disconnect_cb(void *data)
 	avrcp_device_remove(dev);
 }
 
+static bool handle_fast_forward(struct avrcp *session, bool pressed,
+							void *user_data)
+{
+	struct hal_ev_avrcp_passthrough_cmd ev;
+
+	DBG("pressed %s", pressed ? "true" : "false");
+
+	ev.id = AVC_FAST_FORWARD;
+	ev.state = pressed;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_EV_AVRCP_PASSTHROUGH_CMD, sizeof(ev), &ev);
+
+	return true;
+}
+
+static const struct avrcp_passthrough_handler passthrough_handlers[] = {
+		{ AVC_FAST_FORWARD, handle_fast_forward },
+		{ },
+};
+
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	struct avrcp_device *dev;
@@ -350,6 +371,8 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	}
 
 	avrcp_set_destroy_cb(dev->session, disconnect_cb, dev);
+	avrcp_set_passthrough_handlers(dev->session, passthrough_handlers,
+									dev);
 
 	/* FIXME: get the real name of the device */
 	avrcp_init_uinput(dev->session, "bluetooth", address);
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 08/16] android/avrcp: Add passthrough handler for rewind
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (5 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 07/16] android/avrcp: Add passthrough handler for fast forward Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 09/16] android/avrcp-lib: Make hton24 and ntoh24 public Luiz Augusto von Dentz
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Rewind should be send via HAL not handled directly by uinput otherwise
Android media player might not interpret it correctly.
---
 android/avrcp.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/android/avrcp.c b/android/avrcp.c
index 3d56ccf..9d86803 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -317,8 +317,25 @@ static bool handle_fast_forward(struct avrcp *session, bool pressed,
 	return true;
 }
 
+static bool handle_rewind(struct avrcp *session, bool pressed,
+							void *user_data)
+{
+	struct hal_ev_avrcp_passthrough_cmd ev;
+
+	DBG("pressed %s", pressed ? "true" : "false");
+
+	ev.id = AVC_REWIND;
+	ev.state = pressed;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
+			HAL_EV_AVRCP_PASSTHROUGH_CMD, sizeof(ev), &ev);
+
+	return true;
+}
+
 static const struct avrcp_passthrough_handler passthrough_handlers[] = {
 		{ AVC_FAST_FORWARD, handle_fast_forward },
+		{ AVC_REWIND, handle_rewind },
 		{ },
 };
 
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 09/16] android/avrcp-lib: Make hton24 and ntoh24 public
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (6 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 08/16] android/avrcp: Add passthrough handler for rewind Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 10/16] android/avrcp: Add handler for GetCapabilities command Luiz Augusto von Dentz
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This avoids duplicating those function everytime.
---
 android/avrcp-lib.c | 12 ------------
 android/avrcp-lib.h | 12 ++++++++++++
 unit/test-avrcp.c   |  7 -------
 3 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 40ff7b3..60c8ba3 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -73,18 +73,6 @@ struct avrcp_header {
 #error "Unknown byte order"
 #endif
 
-static inline uint32_t ntoh24(const uint8_t src[3])
-{
-	return src[0] << 16 | src[1] << 8 | src[2];
-}
-
-static inline void hton24(uint8_t dst[3], uint32_t src)
-{
-	dst[0] = (src & 0xff0000) >> 16;
-	dst[1] = (src & 0x00ff00) >> 8;
-	dst[2] = (src & 0x0000ff);
-}
-
 struct avrcp {
 	struct avctp *conn;
 
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 3df5897..8625425 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -91,6 +91,18 @@ struct avrcp_passthrough_handler {
 
 typedef void (*avrcp_destroy_cb_t) (void *user_data);
 
+static inline uint32_t ntoh24(const uint8_t src[3])
+{
+	return src[0] << 16 | src[1] << 8 | src[2];
+}
+
+static inline void hton24(uint8_t dst[3], uint32_t src)
+{
+	dst[0] = (src & 0xff0000) >> 16;
+	dst[1] = (src & 0x00ff00) >> 8;
+	dst[2] = (src & 0x0000ff);
+}
+
 struct avrcp *avrcp_new(int fd, size_t imtu, size_t omtu, uint16_t version);
 void avrcp_shutdown(struct avrcp *session);
 void avrcp_set_destroy_cb(struct avrcp *session, avrcp_destroy_cb_t cb,
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 0294973..695f62c 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -94,13 +94,6 @@ struct context {
 		g_test_add_data_func(name, &data, function);		\
 	} while (0)
 
-static inline void hton24(uint8_t dst[3], uint32_t src)
-{
-	dst[0] = (src & 0xff0000) >> 16;
-	dst[1] = (src & 0x00ff00) >> 8;
-	dst[2] = (src & 0x0000ff);
-}
-
 static void test_debug(const char *str, void *user_data)
 {
 	const char *prefix = user_data;
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 10/16] android/avrcp: Add handler for GetCapabilities command
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (7 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 09/16] android/avrcp-lib: Make hton24 and ntoh24 public Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-03 10:10   ` Andrei Emeltchenko
  2014-03-02 18:48 ` [PATCH BlueZ 11/16] android/avrcp: Add handler for GetPlayStatus command Luiz Augusto von Dentz
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/avrcp-lib.h |  1 +
 android/avrcp.c     | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 8625425..dda1d28 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -51,6 +51,7 @@
 #define AVRCP_EVENT_TRACK_CHANGED		0x02
 #define AVRCP_EVENT_TRACK_REACHED_END		0x03
 #define AVRCP_EVENT_TRACK_REACHED_START		0x04
+#define AVRCP_EVENT_PLAYBACK_POS_CHANGED	0x05
 #define AVRCP_EVENT_SETTINGS_CHANGED		0x08
 #define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED	0x0a
 #define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED	0x0b
diff --git a/android/avrcp.c b/android/avrcp.c
index 9d86803..bcaa66c 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -26,6 +26,7 @@
 #endif
 
 #include <stdbool.h>
+#include <errno.h>
 #include <glib.h>
 
 #include "btio/btio.h"
@@ -339,6 +340,46 @@ static const struct avrcp_passthrough_handler passthrough_handlers[] = {
 		{ },
 };
 
+static ssize_t handle_get_capabilities(struct avrcp *session,
+						uint8_t transaction,
+						uint16_t params_len,
+						uint8_t *params,
+						void *user_data)
+{
+	uint32_t id = 0x001958;
+
+	if (params_len != 1)
+		return -EINVAL;
+
+	switch (params[0]) {
+	case CAP_COMPANY_ID:
+		params[params_len++] = 1;
+		hton24(&params[params_len], id);
+		return params_len + 3;
+	case CAP_EVENTS_SUPPORTED:
+		/* Android do not provide this info via HAL so the list most
+		 * be hardcoded according to what RegisterNotification can
+		 * actually handle */
+		params[params_len++] = 6;
+		params[params_len++] = AVRCP_EVENT_STATUS_CHANGED;
+		params[params_len++] = AVRCP_EVENT_TRACK_CHANGED;
+		params[params_len++] = AVRCP_EVENT_TRACK_REACHED_END;
+		params[params_len++] = AVRCP_EVENT_TRACK_REACHED_START;
+		params[params_len++] = AVRCP_EVENT_PLAYBACK_POS_CHANGED;
+		params[params_len++] = AVRCP_EVENT_SETTINGS_CHANGED;
+		return params_len;
+	}
+
+	return -EINVAL;
+}
+
+static const struct avrcp_control_handler control_handlers[] = {
+		{ AVRCP_GET_CAPABILITIES,
+					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+					handle_get_capabilities },
+		{ },
+};
+
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	struct avrcp_device *dev;
@@ -390,6 +431,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	avrcp_set_destroy_cb(dev->session, disconnect_cb, dev);
 	avrcp_set_passthrough_handlers(dev->session, passthrough_handlers,
 									dev);
+	avrcp_set_control_handlers(dev->session, control_handlers, dev);
 
 	/* FIXME: get the real name of the device */
 	avrcp_init_uinput(dev->session, "bluetooth", address);
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 11/16] android/avrcp: Add handler for GetPlayStatus command
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (8 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 10/16] android/avrcp: Add handler for GetCapabilities command Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 12/16] android/avrcp: Add handler for GetElementAttributes command Luiz Augusto von Dentz
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/avrcp.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 93 insertions(+), 1 deletion(-)

diff --git a/android/avrcp.c b/android/avrcp.c
index bcaa66c..3ac8223 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -37,6 +37,7 @@
 #include "avctp.h"
 #include "avrcp-lib.h"
 #include "hal-msg.h"
+#include "ipc-common.h"
 #include "ipc.h"
 #include "bluetooth.h"
 #include "avrcp.h"
@@ -54,18 +55,76 @@ static GSList *devices = NULL;
 static GIOChannel *server = NULL;
 static struct ipc *hal_ipc = NULL;
 
+struct avrcp_request {
+	struct avrcp_device *dev;
+	uint8_t pdu_id;
+	uint8_t transaction;
+};
+
 struct avrcp_device {
 	bdaddr_t	dst;
 	struct avrcp	*session;
 	GIOChannel	*io;
+	GQueue		*queue;
 };
 
+static struct avrcp_request *pop_request(uint8_t pdu_id)
+{
+	GSList *l;
+
+	for (l = devices; l; l = g_slist_next(l)) {
+		struct avrcp_device *dev = l->data;
+		GList *reqs = g_queue_peek_head_link(dev->queue);
+		int i;
+
+		for (i = 0; reqs; reqs = g_list_next(reqs), i++) {
+			struct avrcp_request *req = reqs->data;
+
+			if (req->pdu_id == pdu_id) {
+				g_queue_pop_nth(dev->queue, i);
+				return req;
+			}
+		}
+	}
+
+	return NULL;
+}
+
 static void handle_get_play_status(const void *buf, uint16_t len)
 {
+	const struct hal_cmd_avrcp_get_play_status *cmd = buf;
+	uint8_t status;
+	struct avrcp_request *req;
+	uint8_t pdu[9];
+	int ret;
+
 	DBG("");
 
+	req = pop_request(AVRCP_GET_PLAY_STATUS);
+	if (!req) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	bt_put_be32(cmd->position, &pdu[0]);
+	bt_put_be32(cmd->duration, &pdu[4]);
+	pdu[8] = cmd->status;
+
+	ret = avrcp_send(req->dev->session, req->transaction, AVC_CTYPE_STABLE,
+					AVC_SUBUNIT_PANEL, req->pdu_id,
+					pdu, sizeof(pdu));
+	if (ret < 0) {
+		status = HAL_STATUS_FAILED;
+		g_free(req);
+		goto done;
+	}
+
+	status = HAL_STATUS_SUCCESS;
+	g_free(req);
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
-			HAL_OP_AVRCP_GET_PLAY_STATUS, HAL_STATUS_FAILED);
+				HAL_OP_AVRCP_GET_PLAY_STATUS, status);
 }
 
 static void handle_list_player_attrs(const void *buf, uint16_t len)
@@ -244,6 +303,9 @@ static void avrcp_device_free(void *data)
 {
 	struct avrcp_device *dev = data;
 
+	g_queue_foreach(dev->queue, (GFunc) g_free, NULL);
+	g_queue_free(dev->queue);
+
 	if (dev->session)
 		avrcp_shutdown(dev->session);
 
@@ -373,10 +435,38 @@ static ssize_t handle_get_capabilities(struct avrcp *session,
 	return -EINVAL;
 }
 
+static ssize_t handle_get_play_status_cmd(struct avrcp *session,
+						uint8_t transaction,
+						uint16_t params_len,
+						uint8_t *params,
+						void *user_data)
+{
+	struct avrcp_device *dev = user_data;
+	struct avrcp_request *req;
+
+	if (params_len != 0)
+		return -EINVAL;
+
+	req = g_new0(struct avrcp_request, 1);
+	req->dev = dev;
+	req->pdu_id = AVRCP_GET_CAPABILITIES;
+	req->transaction = transaction;
+
+	g_queue_push_tail(dev->queue, req);
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
+					HAL_EV_AVRCP_GET_PLAY_STATUS, 0, NULL);
+
+	return -EAGAIN;
+}
+
 static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_CAPABILITIES,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
 					handle_get_capabilities },
+		{ AVRCP_GET_PLAY_STATUS,
+					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+					handle_get_play_status_cmd },
 		{ },
 };
 
@@ -433,6 +523,8 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 									dev);
 	avrcp_set_control_handlers(dev->session, control_handlers, dev);
 
+	dev->queue = g_queue_new();
+
 	/* FIXME: get the real name of the device */
 	avrcp_init_uinput(dev->session, "bluetooth", address);
 
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 12/16] android/avrcp: Add handler for GetElementAttributes command
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (9 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 11/16] android/avrcp: Add handler for GetPlayStatus command Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 13/16] android/avrcp: Add handler for RegisterNotification command Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/avrcp.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 112 insertions(+), 1 deletion(-)

diff --git a/android/avrcp.c b/android/avrcp.c
index 3ac8223..6ef8d0a 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -167,12 +167,79 @@ static void handle_get_player_values_text(const void *buf, uint16_t len)
 			HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT, HAL_STATUS_FAILED);
 }
 
+static void write_element_text(uint8_t id, uint8_t text_len, uint8_t *text,
+						uint8_t *pdu, size_t *len)
+{
+	uint16_t charset = 106;
+
+	bt_put_be32(id, pdu);
+	pdu += 4;
+	*len += 4;
+
+	bt_put_be16(charset, pdu);
+	pdu += 2;
+	*len += 2;
+
+	bt_put_be16(text_len, pdu);
+	pdu += 2;
+	*len += 2;
+
+	memcpy(pdu, text, text_len);
+	*len += text_len;
+}
+
+static void write_element_attrs(uint8_t *ptr, uint8_t number, uint8_t *pdu,
+								size_t *len)
+{
+	int i;
+
+	for (i = 0; i < number; i++) {
+		struct hal_avrcp_player_setting_text *text = (void *) ptr;
+
+		write_element_text(text->id, text->len, text->text, pdu, len);
+
+		ptr += sizeof(*text) + text->len;
+		pdu += *len;
+	}
+}
+
 static void handle_get_element_attrs_text(const void *buf, uint16_t len)
 {
+	struct hal_cmd_avrcp_get_element_attrs_text *cmd = (void *) buf;
+	uint8_t status;
+	struct avrcp_request *req;
+	uint8_t pdu[IPC_MTU];
+	uint8_t *ptr;
+	size_t pdu_len;
+	int ret;
+
 	DBG("");
 
+	req = pop_request(AVRCP_GET_ELEMENT_ATTRIBUTES);
+	if (!req) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	ptr = (uint8_t *) &cmd->values[0];
+	pdu_len = 0;
+	write_element_attrs(ptr, cmd->number, pdu, &pdu_len);
+
+	ret = avrcp_send(req->dev->session, req->transaction, AVC_CTYPE_STABLE,
+					AVC_SUBUNIT_PANEL, req->pdu_id,
+					pdu, pdu_len);
+	if (ret < 0) {
+		status = HAL_STATUS_FAILED;
+		g_free(req);
+		goto done;
+	}
+
+	status = HAL_STATUS_SUCCESS;
+	g_free(req);
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
-			HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT, HAL_STATUS_FAILED);
+			HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT, status);
 }
 
 static void handle_set_player_attrs_value(const void *buf, uint16_t len)
@@ -460,6 +527,47 @@ static ssize_t handle_get_play_status_cmd(struct avrcp *session,
 	return -EAGAIN;
 }
 
+static ssize_t handle_get_element_attrs_cmd(struct avrcp *session,
+						uint8_t transaction,
+						uint16_t params_len,
+						uint8_t *params,
+						void *user_data)
+{
+	struct avrcp_device *dev = user_data;
+	struct avrcp_request *req;
+	uint8_t buf[IPC_MTU];
+	struct hal_ev_avrcp_get_element_attrs *ev = (void *) buf;
+	int i;
+
+	if (params_len < 9)
+		return -EINVAL;
+
+	ev->number = params[8];
+
+	if (params_len < ev->number * sizeof(uint32_t) + 1)
+		return -EINVAL;
+
+	params += 9;
+	for (i = 0; i < ev->number; i++) {
+		ev->attrs[i] = bt_get_be32(params);
+		params += 4;
+	}
+
+	req = g_new0(struct avrcp_request, 1);
+	req->dev = dev;
+	req->pdu_id = AVRCP_GET_ELEMENT_ATTRIBUTES;
+	req->transaction = transaction;
+
+	g_queue_push_tail(dev->queue, req);
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
+					HAL_EV_AVRCP_GET_ELEMENT_ATTRS,
+					sizeof(*ev) + ev->number, ev);
+
+	return -EAGAIN;
+
+}
+
 static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_CAPABILITIES,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -467,6 +575,9 @@ static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_PLAY_STATUS,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
 					handle_get_play_status_cmd },
+		{ AVRCP_GET_ELEMENT_ATTRIBUTES,
+					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+					handle_get_element_attrs_cmd },
 		{ },
 };
 
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 13/16] android/avrcp: Add handler for RegisterNotification command
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (10 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 12/16] android/avrcp: Add handler for GetElementAttributes command Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-02 18:48 ` [PATCH BlueZ 14/16] android/avrcp: Bump version to 1.3 Luiz Augusto von Dentz
  2014-03-04 11:47 ` [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/avrcp.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 83 insertions(+), 1 deletion(-)

diff --git a/android/avrcp.c b/android/avrcp.c
index 6ef8d0a..875c6e2 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -252,10 +252,58 @@ static void handle_set_player_attrs_value(const void *buf, uint16_t len)
 
 static void handle_register_notification(const void *buf, uint16_t len)
 {
+	struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
+	uint8_t status;
+	struct avrcp_request *req;
+	uint8_t pdu[IPC_MTU];
+	size_t pdu_len = 1;
+	int ret;
+
 	DBG("");
 
+	req = pop_request(AVRCP_REGISTER_NOTIFICATION);
+	if (!req) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	pdu[0] = cmd->event;
+
+	switch (cmd->event) {
+	case AVRCP_EVENT_STATUS_CHANGED:
+	case AVRCP_EVENT_TRACK_CHANGED:
+	case AVRCP_EVENT_TRACK_REACHED_END:
+	case AVRCP_EVENT_TRACK_REACHED_START:
+	case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
+		if (cmd->len > 0) {
+			memcpy(&pdu[1], cmd->data, cmd->len);
+			pdu_len += cmd->len;
+		}
+		break;
+	case AVRCP_EVENT_SETTINGS_CHANGED:
+		pdu[1] = cmd->len / sizeof(struct hal_avrcp_player_attr_value);
+		memcpy(&pdu[2], cmd->data, cmd->len);
+		break;
+	default:
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	ret = avrcp_send(req->dev->session, req->transaction, cmd->type,
+					AVC_SUBUNIT_PANEL, req->pdu_id,
+					pdu, pdu_len);
+	if (ret < 0) {
+		status = HAL_STATUS_FAILED;
+		g_free(req);
+		goto done;
+	}
+
+	status = HAL_STATUS_SUCCESS;
+	g_free(req);
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP,
-			HAL_OP_AVRCP_REGISTER_NOTIFICATION, HAL_STATUS_FAILED);
+			HAL_OP_AVRCP_REGISTER_NOTIFICATION, status);
 }
 
 static void handle_set_volume(const void *buf, uint16_t len)
@@ -568,6 +616,37 @@ static ssize_t handle_get_element_attrs_cmd(struct avrcp *session,
 
 }
 
+static ssize_t handle_register_notification_cmd(struct avrcp *session,
+						uint8_t transaction,
+						uint16_t params_len,
+						uint8_t *params,
+						void *user_data)
+{
+	struct avrcp_device *dev = user_data;
+	struct avrcp_request *req;
+	struct hal_ev_avrcp_register_notification ev;
+
+	if (params_len != 5)
+		return -EINVAL;
+
+	req = g_new0(struct avrcp_request, 1);
+	req->dev = dev;
+	req->pdu_id = AVRCP_REGISTER_NOTIFICATION;
+	req->transaction = transaction;
+
+	g_queue_push_tail(dev->queue, req);
+
+	ev.event = params[0];
+	ev.param = bt_get_be32(&params[1]);
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
+					HAL_EV_AVRCP_REGISTER_NOTIFICATION,
+					sizeof(ev), &ev);
+
+	return -EAGAIN;
+
+}
+
 static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_CAPABILITIES,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -578,6 +657,9 @@ static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_ELEMENT_ATTRIBUTES,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
 					handle_get_element_attrs_cmd },
+		{ AVRCP_REGISTER_NOTIFICATION,
+					AVC_CTYPE_NOTIFY, AVC_CTYPE_INTERIM,
+					handle_register_notification_cmd },
 		{ },
 };
 
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH BlueZ 14/16] android/avrcp: Bump version to 1.3
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (11 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 13/16] android/avrcp: Add handler for RegisterNotification command Luiz Augusto von Dentz
@ 2014-03-02 18:48 ` Luiz Augusto von Dentz
  2014-03-04 11:47 ` [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-02 18:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/avrcp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/avrcp.c b/android/avrcp.c
index 875c6e2..268c1b1 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -355,7 +355,7 @@ static sdp_record_t *avrcp_record(void)
 	sdp_record_t *record;
 	sdp_data_t *psm, *version, *features;
 	uint16_t lp = L2CAP_PSM_AVCTP;
-	uint16_t avrcp_ver = 0x0100, avctp_ver = 0x0103;
+	uint16_t avrcp_ver = 0x0103, avctp_ver = 0x0103;
 	uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
 					AVRCP_FEATURE_CATEGORY_2 |
 					AVRCP_FEATURE_CATEGORY_3 |
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH BlueZ 03/16] android/avrcp-lib: Rework handler callback parameters
  2014-03-02 18:48 ` [PATCH BlueZ 03/16] android/avrcp-lib: Rework handler callback parameters Luiz Augusto von Dentz
@ 2014-03-03  9:52   ` Andrei Emeltchenko
  2014-03-03 12:41     ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 19+ messages in thread
From: Andrei Emeltchenko @ 2014-03-03  9:52 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hi Luiz,

On Sun, Mar 02, 2014 at 08:48:18PM +0200, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> This rework handler callback parameters to make it able to return
> proper error such as -EAGAIN to implement asynchronous responses.
> ---
>  android/avrcp-lib.c | 12 +++++++++---
>  android/avrcp-lib.h |  5 +++--
>  unit/test-avrcp.c   | 42 +++++++++++++++++++++---------------------
>  3 files changed, 33 insertions(+), 26 deletions(-)
> 
> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
> index cdad6ac..339be16 100644
> --- a/android/avrcp-lib.c
> +++ b/android/avrcp-lib.c
> @@ -125,6 +125,7 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
>  	struct avrcp_header *pdu = (void *) operands;
>  	uint32_t company_id = ntoh24(pdu->company_id);
>  	uint16_t params_len = ntohs(pdu->params_len);
> +	ssize_t ret;
>  
>  	if (company_id != IEEEID_BTSIG) {
>  		*code = AVC_CTYPE_NOT_IMPLEMENTED;
> @@ -159,12 +160,17 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
>  		goto reject;
>  	}
>  
> -	*code = handler->func(session, transaction, &params_len,
> +	ret = handler->func(session, transaction, code, params_len,
>  					pdu->params, session->control_data);
> +	if (ret < 0) {
> +		if (ret == -EAGAIN)
> +			return ret;
> +		goto reject;
> +	}
>  
> -	pdu->params_len = htons(params_len);
> +	pdu->params_len = htons(ret);
>  
> -	return AVRCP_HEADER_LENGTH + params_len;
> +	return AVRCP_HEADER_LENGTH + ret;
>  
>  reject:
>  	pdu->params_len = htons(1);
> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
> index a33bdfe..d7a805b 100644
> --- a/android/avrcp-lib.h
> +++ b/android/avrcp-lib.h
> @@ -79,8 +79,9 @@ struct avrcp;
>  struct avrcp_control_handler {
>  	uint8_t id;
>  	uint8_t code;
> -	uint8_t (*func) (struct avrcp *session, uint8_t transaction,
> -			uint16_t *params_len, uint8_t *params, void *user_data);
> +	ssize_t (*func) (struct avrcp *session, uint8_t transaction,
> +			uint8_t *code, uint16_t params_len, uint8_t *params,
> +			void *user_data);
>  };
>  
>  struct avrcp_passthrough_handler {
> diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
> index 302c331..2d5711b 100644
> --- a/unit/test-avrcp.c
> +++ b/unit/test-avrcp.c
> @@ -292,54 +292,54 @@ static const struct avrcp_passthrough_handler passthrough_handlers[] = {
>  		{ },
>  };
>  
> -static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
> -				uint8_t transaction, uint16_t *params_len,
> -				uint8_t *params, void *user_data)
> +static ssize_t avrcp_handle_get_capabilities(struct avrcp *session,
> +					uint8_t transaction, uint8_t *code,
> +					uint16_t params_len, uint8_t *params,
> +					void *user_data)
>  {
>  	uint32_t id = 0x001958;
>  
> -	DBG("params[0] %d params_len %d", params[0], *params_len);
> -
> -	if (*params_len != 1)
> +	if (params_len != 1)
>  		goto fail;
>  
>  	switch (params[0]) {
>  	case CAP_COMPANY_ID:
> -		*params_len = 5;
>  		params[1] = 1;
>  		hton24(&params[2], id);
> -		return AVC_CTYPE_STABLE;
> +		*code = AVC_CTYPE_STABLE;
> +		return 5;

What is 5? Shall we define constants or use formulas?

Best regards 
Andrei Emeltchenko 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH BlueZ 10/16] android/avrcp: Add handler for GetCapabilities command
  2014-03-02 18:48 ` [PATCH BlueZ 10/16] android/avrcp: Add handler for GetCapabilities command Luiz Augusto von Dentz
@ 2014-03-03 10:10   ` Andrei Emeltchenko
  0 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2014-03-03 10:10 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hi Luiz,

On Sun, Mar 02, 2014 at 08:48:25PM +0200, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> ---
>  android/avrcp-lib.h |  1 +
>  android/avrcp.c     | 42 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
> index 8625425..dda1d28 100644
> --- a/android/avrcp-lib.h
> +++ b/android/avrcp-lib.h
> @@ -51,6 +51,7 @@
>  #define AVRCP_EVENT_TRACK_CHANGED		0x02
>  #define AVRCP_EVENT_TRACK_REACHED_END		0x03
>  #define AVRCP_EVENT_TRACK_REACHED_START		0x04
> +#define AVRCP_EVENT_PLAYBACK_POS_CHANGED	0x05
>  #define AVRCP_EVENT_SETTINGS_CHANGED		0x08
>  #define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED	0x0a
>  #define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED	0x0b
> diff --git a/android/avrcp.c b/android/avrcp.c
> index 9d86803..bcaa66c 100644
> --- a/android/avrcp.c
> +++ b/android/avrcp.c
> @@ -26,6 +26,7 @@
>  #endif
>  
>  #include <stdbool.h>
> +#include <errno.h>
>  #include <glib.h>
>  
>  #include "btio/btio.h"
> @@ -339,6 +340,46 @@ static const struct avrcp_passthrough_handler passthrough_handlers[] = {
>  		{ },
>  };
>  
> +static ssize_t handle_get_capabilities(struct avrcp *session,
> +						uint8_t transaction,
> +						uint16_t params_len,
> +						uint8_t *params,
> +						void *user_data)
> +{
> +	uint32_t id = 0x001958;

Don't we have it defined?

Best regards 
Andrei Emeltchenko 

> +
> +	if (params_len != 1)
> +		return -EINVAL;
> +
> +	switch (params[0]) {
> +	case CAP_COMPANY_ID:
> +		params[params_len++] = 1;
> +		hton24(&params[params_len], id);
> +		return params_len + 3;
> +	case CAP_EVENTS_SUPPORTED:
> +		/* Android do not provide this info via HAL so the list most
> +		 * be hardcoded according to what RegisterNotification can
> +		 * actually handle */
> +		params[params_len++] = 6;
> +		params[params_len++] = AVRCP_EVENT_STATUS_CHANGED;
> +		params[params_len++] = AVRCP_EVENT_TRACK_CHANGED;
> +		params[params_len++] = AVRCP_EVENT_TRACK_REACHED_END;
> +		params[params_len++] = AVRCP_EVENT_TRACK_REACHED_START;
> +		params[params_len++] = AVRCP_EVENT_PLAYBACK_POS_CHANGED;
> +		params[params_len++] = AVRCP_EVENT_SETTINGS_CHANGED;
> +		return params_len;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct avrcp_control_handler control_handlers[] = {
> +		{ AVRCP_GET_CAPABILITIES,
> +					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
> +					handle_get_capabilities },
> +		{ },
> +};
> +
>  static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
>  {
>  	struct avrcp_device *dev;
> @@ -390,6 +431,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
>  	avrcp_set_destroy_cb(dev->session, disconnect_cb, dev);
>  	avrcp_set_passthrough_handlers(dev->session, passthrough_handlers,
>  									dev);
> +	avrcp_set_control_handlers(dev->session, control_handlers, dev);
>  
>  	/* FIXME: get the real name of the device */
>  	avrcp_init_uinput(dev->session, "bluetooth", address);
> -- 
> 1.8.5.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH BlueZ 03/16] android/avrcp-lib: Rework handler callback parameters
  2014-03-03  9:52   ` Andrei Emeltchenko
@ 2014-03-03 12:41     ` Luiz Augusto von Dentz
  2014-03-04  8:05       ` Andrei Emeltchenko
  0 siblings, 1 reply; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-03 12:41 UTC (permalink / raw)
  To: Andrei Emeltchenko, Luiz Augusto von Dentz,
	linux-bluetooth@vger.kernel.org

Hi Andrei,

On Mon, Mar 3, 2014 at 11:52 AM, Andrei Emeltchenko
<andrei.emeltchenko.news@gmail.com> wrote:
> Hi Luiz,
>
> On Sun, Mar 02, 2014 at 08:48:18PM +0200, Luiz Augusto von Dentz wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> This rework handler callback parameters to make it able to return
>> proper error such as -EAGAIN to implement asynchronous responses.
>> ---
>>  android/avrcp-lib.c | 12 +++++++++---
>>  android/avrcp-lib.h |  5 +++--
>>  unit/test-avrcp.c   | 42 +++++++++++++++++++++---------------------
>>  3 files changed, 33 insertions(+), 26 deletions(-)
>>
>> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
>> index cdad6ac..339be16 100644
>> --- a/android/avrcp-lib.c
>> +++ b/android/avrcp-lib.c
>> @@ -125,6 +125,7 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
>>       struct avrcp_header *pdu = (void *) operands;
>>       uint32_t company_id = ntoh24(pdu->company_id);
>>       uint16_t params_len = ntohs(pdu->params_len);
>> +     ssize_t ret;
>>
>>       if (company_id != IEEEID_BTSIG) {
>>               *code = AVC_CTYPE_NOT_IMPLEMENTED;
>> @@ -159,12 +160,17 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
>>               goto reject;
>>       }
>>
>> -     *code = handler->func(session, transaction, &params_len,
>> +     ret = handler->func(session, transaction, code, params_len,
>>                                       pdu->params, session->control_data);
>> +     if (ret < 0) {
>> +             if (ret == -EAGAIN)
>> +                     return ret;
>> +             goto reject;
>> +     }
>>
>> -     pdu->params_len = htons(params_len);
>> +     pdu->params_len = htons(ret);
>>
>> -     return AVRCP_HEADER_LENGTH + params_len;
>> +     return AVRCP_HEADER_LENGTH + ret;
>>
>>  reject:
>>       pdu->params_len = htons(1);
>> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
>> index a33bdfe..d7a805b 100644
>> --- a/android/avrcp-lib.h
>> +++ b/android/avrcp-lib.h
>> @@ -79,8 +79,9 @@ struct avrcp;
>>  struct avrcp_control_handler {
>>       uint8_t id;
>>       uint8_t code;
>> -     uint8_t (*func) (struct avrcp *session, uint8_t transaction,
>> -                     uint16_t *params_len, uint8_t *params, void *user_data);
>> +     ssize_t (*func) (struct avrcp *session, uint8_t transaction,
>> +                     uint8_t *code, uint16_t params_len, uint8_t *params,
>> +                     void *user_data);
>>  };
>>
>>  struct avrcp_passthrough_handler {
>> diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
>> index 302c331..2d5711b 100644
>> --- a/unit/test-avrcp.c
>> +++ b/unit/test-avrcp.c
>> @@ -292,54 +292,54 @@ static const struct avrcp_passthrough_handler passthrough_handlers[] = {
>>               { },
>>  };
>>
>> -static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
>> -                             uint8_t transaction, uint16_t *params_len,
>> -                             uint8_t *params, void *user_data)
>> +static ssize_t avrcp_handle_get_capabilities(struct avrcp *session,
>> +                                     uint8_t transaction, uint8_t *code,
>> +                                     uint16_t params_len, uint8_t *params,
>> +                                     void *user_data)
>>  {
>>       uint32_t id = 0x001958;
>>
>> -     DBG("params[0] %d params_len %d", params[0], *params_len);
>> -
>> -     if (*params_len != 1)
>> +     if (params_len != 1)
>>               goto fail;
>>
>>       switch (params[0]) {
>>       case CAP_COMPANY_ID:
>> -             *params_len = 5;
>>               params[1] = 1;
>>               hton24(&params[2], id);
>> -             return AVC_CTYPE_STABLE;
>> +             *code = AVC_CTYPE_STABLE;
>> +             return 5;
>
> What is 5? Shall we define constants or use formulas?

This is the param length, ideally we should define structs for all the PDUs.


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH BlueZ 03/16] android/avrcp-lib: Rework handler callback parameters
  2014-03-03 12:41     ` Luiz Augusto von Dentz
@ 2014-03-04  8:05       ` Andrei Emeltchenko
  0 siblings, 0 replies; 19+ messages in thread
From: Andrei Emeltchenko @ 2014-03-04  8:05 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org

Hi Luiz,

On Mon, Mar 03, 2014 at 02:41:19PM +0200, Luiz Augusto von Dentz wrote:
> Hi Andrei,
> 
> On Mon, Mar 3, 2014 at 11:52 AM, Andrei Emeltchenko
> <andrei.emeltchenko.news@gmail.com> wrote:
> > Hi Luiz,
> >
> > On Sun, Mar 02, 2014 at 08:48:18PM +0200, Luiz Augusto von Dentz wrote:
> >> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> >>
> >> This rework handler callback parameters to make it able to return
> >> proper error such as -EAGAIN to implement asynchronous responses.
> >> ---
> >>  android/avrcp-lib.c | 12 +++++++++---
> >>  android/avrcp-lib.h |  5 +++--
> >>  unit/test-avrcp.c   | 42 +++++++++++++++++++++---------------------
> >>  3 files changed, 33 insertions(+), 26 deletions(-)
> >>
> >> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
> >> index cdad6ac..339be16 100644
> >> --- a/android/avrcp-lib.c
> >> +++ b/android/avrcp-lib.c
> >> @@ -125,6 +125,7 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
> >>       struct avrcp_header *pdu = (void *) operands;
> >>       uint32_t company_id = ntoh24(pdu->company_id);
> >>       uint16_t params_len = ntohs(pdu->params_len);
> >> +     ssize_t ret;
> >>
> >>       if (company_id != IEEEID_BTSIG) {
> >>               *code = AVC_CTYPE_NOT_IMPLEMENTED;
> >> @@ -159,12 +160,17 @@ static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
> >>               goto reject;
> >>       }
> >>
> >> -     *code = handler->func(session, transaction, &params_len,
> >> +     ret = handler->func(session, transaction, code, params_len,
> >>                                       pdu->params, session->control_data);
> >> +     if (ret < 0) {
> >> +             if (ret == -EAGAIN)
> >> +                     return ret;
> >> +             goto reject;
> >> +     }
> >>
> >> -     pdu->params_len = htons(params_len);
> >> +     pdu->params_len = htons(ret);
> >>
> >> -     return AVRCP_HEADER_LENGTH + params_len;
> >> +     return AVRCP_HEADER_LENGTH + ret;
> >>
> >>  reject:
> >>       pdu->params_len = htons(1);
> >> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
> >> index a33bdfe..d7a805b 100644
> >> --- a/android/avrcp-lib.h
> >> +++ b/android/avrcp-lib.h
> >> @@ -79,8 +79,9 @@ struct avrcp;
> >>  struct avrcp_control_handler {
> >>       uint8_t id;
> >>       uint8_t code;
> >> -     uint8_t (*func) (struct avrcp *session, uint8_t transaction,
> >> -                     uint16_t *params_len, uint8_t *params, void *user_data);
> >> +     ssize_t (*func) (struct avrcp *session, uint8_t transaction,
> >> +                     uint8_t *code, uint16_t params_len, uint8_t *params,
> >> +                     void *user_data);
> >>  };
> >>
> >>  struct avrcp_passthrough_handler {
> >> diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
> >> index 302c331..2d5711b 100644
> >> --- a/unit/test-avrcp.c
> >> +++ b/unit/test-avrcp.c
> >> @@ -292,54 +292,54 @@ static const struct avrcp_passthrough_handler passthrough_handlers[] = {
> >>               { },
> >>  };
> >>
> >> -static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
> >> -                             uint8_t transaction, uint16_t *params_len,
> >> -                             uint8_t *params, void *user_data)
> >> +static ssize_t avrcp_handle_get_capabilities(struct avrcp *session,
> >> +                                     uint8_t transaction, uint8_t *code,
> >> +                                     uint16_t params_len, uint8_t *params,
> >> +                                     void *user_data)
> >>  {
> >>       uint32_t id = 0x001958;
> >>
> >> -     DBG("params[0] %d params_len %d", params[0], *params_len);
> >> -
> >> -     if (*params_len != 1)
> >> +     if (params_len != 1)
> >>               goto fail;
> >>
> >>       switch (params[0]) {
> >>       case CAP_COMPANY_ID:
> >> -             *params_len = 5;
> >>               params[1] = 1;
> >>               hton24(&params[2], id);
> >> -             return AVC_CTYPE_STABLE;
> >> +             *code = AVC_CTYPE_STABLE;
> >> +             return 5;
> >
> > What is 5? Shall we define constants or use formulas?
> 
> This is the param length, ideally we should define structs for all the
> PDUs.

I do agree here, currently the pointer magic generates warnings from
static analyzers so they are not useful much.

Best regards 
Andrei Emeltchenko 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function
  2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
                   ` (12 preceding siblings ...)
  2014-03-02 18:48 ` [PATCH BlueZ 14/16] android/avrcp: Bump version to 1.3 Luiz Augusto von Dentz
@ 2014-03-04 11:47 ` Luiz Augusto von Dentz
  13 siblings, 0 replies; 19+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-04 11:47 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org

Hi,

On Sun, Mar 2, 2014 at 8:48 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This adds avrcp_send function which can be used to response to
> outstanding requests.
> ---
>  android/avrcp-lib.c | 27 +++++++++++++++++++++++++++
>  android/avrcp-lib.h |  4 +++-
>  2 files changed, 30 insertions(+), 1 deletion(-)
>
> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
> index 34eea66..6fed825 100644
> --- a/android/avrcp-lib.c
> +++ b/android/avrcp-lib.c
> @@ -253,6 +253,33 @@ int avrcp_init_uinput(struct avrcp *session, const char *name,
>         return avctp_init_uinput(session->conn, name, address);
>  }
>
> +int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code,
> +                                       uint8_t subunit, uint8_t pdu_id,
> +                                       uint8_t *params, size_t params_len)
> +{
> +       struct avrcp_header *pdu = (void *) session->tx_buf;
> +       size_t len = sizeof(*pdu);
> +
> +       memset(pdu, 0, len);
> +
> +       hton24(pdu->company_id, IEEEID_BTSIG);
> +       pdu->pdu_id = pdu_id;
> +       pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
> +
> +       if (params_len > 0) {
> +               len += params_len;
> +
> +               if (len > session->tx_mtu)
> +                       return -ENOBUFS;
> +
> +               memcpy(pdu->params, params, params_len);
> +               pdu->params_len = htons(params_len);
> +       }
> +
> +       return avctp_send_vendordep(session->conn, transaction, code, subunit,
> +                                                       session->tx_buf, len);
> +}
> +
>  static int avrcp_send_req(struct avrcp *session, uint8_t code, uint8_t subunit,
>                                         uint8_t pdu_id, uint8_t *params,
>                                         size_t params_len, avctp_rsp_cb func,
> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
> index 0407cb4..a33bdfe 100644
> --- a/android/avrcp-lib.h
> +++ b/android/avrcp-lib.h
> @@ -102,7 +102,9 @@ void avrcp_set_passthrough_handlers(struct avrcp *session,
>                         void *user_data);
>  int avrcp_init_uinput(struct avrcp *session, const char *name,
>                                                         const char *address);
> -
> +int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code,
> +                                       uint8_t subunit, uint8_t pdu_id,
> +                                       uint8_t *params, size_t params_len);
>  int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
>                                         avctp_rsp_cb func, void *user_data);
>  int avrcp_list_player_attributes(struct avrcp *session, avctp_rsp_cb func,
> --
> 1.8.5.3

I went ahead and pushed this sets with a few fixes suggested.


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2014-03-04 11:47 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-02 18:48 [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 02/16] android/avctp: Make handler return ssize_t Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 03/16] android/avrcp-lib: Rework handler callback parameters Luiz Augusto von Dentz
2014-03-03  9:52   ` Andrei Emeltchenko
2014-03-03 12:41     ` Luiz Augusto von Dentz
2014-03-04  8:05       ` Andrei Emeltchenko
2014-03-02 18:48 ` [PATCH BlueZ 04/16] android/avrcp-lib: Embed response code into handler table Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 05/16] android/avrcp-lib: Fix not passing user data of passthrough callback Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 06/16] android/avrcp-lib: Add pressed status to passthrough handler callback Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 07/16] android/avrcp: Add passthrough handler for fast forward Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 08/16] android/avrcp: Add passthrough handler for rewind Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 09/16] android/avrcp-lib: Make hton24 and ntoh24 public Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 10/16] android/avrcp: Add handler for GetCapabilities command Luiz Augusto von Dentz
2014-03-03 10:10   ` Andrei Emeltchenko
2014-03-02 18:48 ` [PATCH BlueZ 11/16] android/avrcp: Add handler for GetPlayStatus command Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 12/16] android/avrcp: Add handler for GetElementAttributes command Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 13/16] android/avrcp: Add handler for RegisterNotification command Luiz Augusto von Dentz
2014-03-02 18:48 ` [PATCH BlueZ 14/16] android/avrcp: Bump version to 1.3 Luiz Augusto von Dentz
2014-03-04 11:47 ` [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox