Diff between 1453f159f2e05b2815d01e5e64e9a98a3ac8fd76 and 0da74a1afc2aec08ec225c925c78a2f6305f0418

Changed Files

File Additions Deletions Status
android/avrcp-lib.c +0 -16 modified
android/avrcp-lib.h +31 -0 modified
unit/test-avrcp.c +59 -0 modified

Full Patch

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index e620af5..05d651c 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -39,28 +39,12 @@
 /* Company IDs for vendor dependent commands */
 #define IEEEID_BTSIG		0x001958
 
-/* Status codes */
-#define AVRCP_STATUS_INVALID_COMMAND		0x00
-#define AVRCP_STATUS_INVALID_PARAM		0x01
-#define AVRCP_STATUS_PARAM_NOT_FOUND		0x02
-#define AVRCP_STATUS_INTERNAL_ERROR		0x03
-#define AVRCP_STATUS_SUCCESS			0x04
-#define AVRCP_STATUS_OUT_OF_BOUNDS		0x0b
-#define AVRCP_STATUS_INVALID_PLAYER_ID		0x11
-#define AVRCP_STATUS_PLAYER_NOT_BROWSABLE	0x12
-#define AVRCP_STATUS_NO_AVAILABLE_PLAYERS	0x15
-#define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED	0x16
-
 /* Packet types */
 #define AVRCP_PACKET_TYPE_SINGLE		0x00
 #define AVRCP_PACKET_TYPE_START			0x01
 #define AVRCP_PACKET_TYPE_CONTINUING		0x02
 #define AVRCP_PACKET_TYPE_END			0x03
 
-/* Capabilities for AVRCP_GET_CAPABILITIES pdu */
-#define CAP_COMPANY_ID				0x02
-#define CAP_EVENTS_SUPPORTED			0x03
-
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 struct avrcp_header {
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index f727632..75802b9 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -46,6 +46,37 @@
 #define AVRCP_ADD_TO_NOW_PLAYING	0x90
 #define AVRCP_GENERAL_REJECT		0xA0
 
+/* Notification events */
+#define AVRCP_EVENT_STATUS_CHANGED		0x01
+#define AVRCP_EVENT_TRACK_CHANGED		0x02
+#define AVRCP_EVENT_TRACK_REACHED_END		0x03
+#define AVRCP_EVENT_TRACK_REACHED_START		0x04
+#define AVRCP_EVENT_SETTINGS_CHANGED		0x08
+#define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED	0x0a
+#define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED	0x0b
+#define AVRCP_EVENT_UIDS_CHANGED		0x0c
+#define AVRCP_EVENT_VOLUME_CHANGED		0x0d
+#define AVRCP_EVENT_LAST			AVRCP_EVENT_VOLUME_CHANGED
+
+/* Status codes */
+#define AVRCP_STATUS_INVALID_COMMAND		0x00
+#define AVRCP_STATUS_INVALID_PARAM		0x01
+#define AVRCP_STATUS_PARAM_NOT_FOUND		0x02
+#define AVRCP_STATUS_INTERNAL_ERROR		0x03
+#define AVRCP_STATUS_SUCCESS			0x04
+#define AVRCP_STATUS_OUT_OF_BOUNDS		0x0b
+#define AVRCP_STATUS_INVALID_PLAYER_ID		0x11
+#define AVRCP_STATUS_PLAYER_NOT_BROWSABLE	0x12
+#define AVRCP_STATUS_NO_AVAILABLE_PLAYERS	0x15
+#define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED	0x16
+
+/* Capabilities for AVRCP_GET_CAPABILITIES pdu */
+#define CAP_COMPANY_ID				0x02
+#define CAP_EVENTS_SUPPORTED			0x03
+
+/* Company IDs for vendor dependent commands */
+#define IEEEID_BTSIG		0x001958
+
 struct avrcp;
 
 struct avrcp_control_handler {
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 2906ca2..bcd8f88 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -93,6 +93,26 @@ struct context {
 		g_test_add_data_func(name, &data, function);		\
 	} while (0)
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+static inline void hton24(uint8_t dst[3], uint32_t src)
+{
+	dst[0] = (src >> 16) & 0xff;
+	dst[1] = (src >> 8) & 0xff;
+	dst[2] = src & 0xff;
+}
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+static inline void hton24(uint8_t dst[3], uint32_t src)
+{
+	memcpy(&dst, src, sizeof(dst));
+}
+
+#else
+#error "Unknown byte order"
+#endif
+
 static void test_debug(const char *str, void *user_data)
 {
 	const char *prefix = user_data;
@@ -285,12 +305,43 @@ 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)
+{
+	uint32_t id = 0x001958;
+
+	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;
+	}
+
+fail:
+	*params_len = htons(1);
+	params[0] = AVRCP_STATUS_INVALID_PARAM;
+
+	return AVC_CTYPE_REJECTED;
+}
+
+static const struct avrcp_control_handler control_handlers[] = {
+		{ AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS,
+					avrcp_handle_get_capabilities },
+		{ },
+};
+
 static void test_server(gconstpointer data)
 {
 	struct context *context = create_context(0x0100, data);
 
 	avrcp_set_passthrough_handlers(context->session, passthrough_handlers,
 								context);
+	avrcp_set_control_handlers(context->session, control_handlers, NULL);
 
 	g_idle_add(send_pdu, context);
 
@@ -381,5 +432,13 @@ int main(int argc, char *argv[])
 				0x00, 0x19, 0x58, 0x10, 0x00, 0x00,
 				0x01, 0x03));
 
+	define_test("/TP/CFG/BV-02-C", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+				0x00, 0x19, 0x58, 0x10, 0x00, 0x00,
+				0x01, 0x02),
+			raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+				0x00, 0x19, 0x58, 0x10, 0x00, 0x00,
+				0x05, 0x02, 0x01, 0x00, 0x19, 0x58));
+
 	return g_test_run();
 }