2014-03-14 15:17:42

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 00/16] AVRCP code and test cases

From: Andrei Emeltchenko <[email protected]>

Set of unapplied test cases and code so far.

Andrei Emeltchenko (16):
android/avrcp: Add avrcp_connect_browsing()
android/avrcp: Add avrcp_set_browsed_player() function
unit/avrcp: Add browsing channel support in unit testing
unit/avrcp: Add /TP/MPS/BV-03-C test
android/avrcp: Use defined constant instead of magic number
android/avrcp: Add avrcp_get_folder_items() function
unit/avrcp: Add /TP/MPS/BV-08-C test
unit/avrcp: Add /TP/MPS/BV-01-I test
unit/avrcp: Add Connection establishment and release tests
unit/avrcp: Add /TP/MCN/CB/BV-01-C test
android/avrcp: Add avrcp_change_path() function
unit/avrcp: Add /TP/MCN/CB/BV-04-C test
android/avrcp: Add avrcp_get_item_attributes() function
unit/avrcp: Add /TP/MCN/CB/BV-07-C test
android/avrcp: Add avrcp_search() function
unit/avrcp: Add /TP/MCN/SRC/BV-01-C test

.gitignore | 2 +
android/avrcp-lib.c | 124 ++++++++++++++++++++++++++++++++-
android/avrcp-lib.h | 32 +++++++++
unit/test-avrcp.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 352 insertions(+), 3 deletions(-)

--
1.8.3.2



2014-03-14 15:17:48

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 06/16] android/avrcp: Add avrcp_get_folder_items() function

From: Andrei Emeltchenko <[email protected]>

---
android/avrcp-lib.c | 29 +++++++++++++++++++++++++++++
android/avrcp-lib.h | 10 ++++++++++
2 files changed, 39 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index fe6d7b4..e9220b7 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -521,3 +521,32 @@ int avrcp_set_browsed_player(struct avrcp *session, uint16_t player_id,
return avctp_send_browsing_req(session->conn, buf, sizeof(buf),
func, user_data);
}
+
+int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
+ uint32_t start, uint32_t end, uint32_t *attr,
+ size_t attr_count, avctp_browsing_rsp_cb func,
+ void *user_data)
+{
+ uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 10 +
+ attr_count * sizeof(uint32_t)];
+ struct avrcp_browsing_header *pdu = (void *) buf;
+
+ memset(buf, 0, sizeof(buf));
+
+ pdu->pdu_id = AVRCP_GET_FOLDER_ITEMS;
+ pdu->param_len = htons(10 + attr_count * sizeof(uint32_t));
+
+ /* Scope */
+ pdu->params[0] = scope;
+
+ bt_put_be32(start, &pdu->params[1]);
+ bt_put_be32(end, &pdu->params[5]);
+
+ /* attr count */
+ pdu->params[9] = attr_count;
+
+ memcpy(&pdu->params[10], attr, attr_count);
+
+ return avctp_send_browsing_req(session->conn, buf, sizeof(buf),
+ func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 88d2126..72fd89a 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -84,6 +84,12 @@
#define AVRCP_ATTRIBUTE_SCAN 0x04
#define AVRCP_ATTRIBUTE_LAST AVRCP_ATTRIBUTE_SCAN

+/* Media Scope */
+#define AVRCP_MEDIA_PLAYER_LIST 0x00
+#define AVRCP_MEDIA_PLAYER_VFS 0x01
+#define AVRCP_MEDIA_SEARCH 0x02
+#define AVRCP_MEDIA_NOW_PLAYING 0x03
+
/* Company IDs for vendor dependent commands */
#define IEEEID_BTSIG 0x001958

@@ -179,3 +185,7 @@ int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
int avrcp_send_passthrough(struct avrcp *session, uint32_t vendor, uint8_t op);
int avrcp_set_browsed_player(struct avrcp *session, uint16_t player_id,
avctp_browsing_rsp_cb func, void *user_data);
+int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
+ uint32_t start, uint32_t end, uint32_t *attr,
+ size_t attr_count, avctp_browsing_rsp_cb func,
+ void *user_data);
--
1.8.3.2


2014-03-14 15:17:50

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 08/16] unit/avrcp: Add /TP/MPS/BV-01-I test

From: Andrei Emeltchenko <[email protected]>

Test verifies that Controller is able to request the list of available
Media Players.
---
unit/test-avrcp.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index b173e8d..3a7e0d1 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -718,6 +718,11 @@ static void test_client(gconstpointer data)
AVRCP_MEDIA_PLAYER_LIST, 0, 2, NULL, 0,
NULL, NULL);

+ if (g_str_equal(context->data->test_name, "/TP/MPS/BV-01-I"))
+ avrcp_get_folder_items(context->session,
+ AVRCP_MEDIA_PLAYER_LIST, 0, 2, NULL, 0,
+ NULL, NULL);
+
if (g_str_equal(context->data->test_name, "/TP/CFG/BV-01-C"))
avrcp_get_capabilities(context->session, CAP_EVENTS_SUPPORTED,
NULL, NULL);
@@ -807,6 +812,16 @@ int main(int argc, char *argv[])
0x00, 0x00, 0x00, 0x02, /* end */
0x00));

+ /* Media Player Selection IOP tests */
+
+ /* Listing of available media players */
+ define_test("/TP/MPS/BV-01-I", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, AVRCP_GET_FOLDER_ITEMS,
+ 0x00, 0x0a, AVRCP_MEDIA_PLAYER_LIST,
+ 0x00, 0x00, 0x00, 0x00, /* start */
+ 0x00, 0x00, 0x00, 0x02, /* end */
+ 0x00));
+
/* Connection Establishment for Control tests */

/*
--
1.8.3.2


2014-03-14 15:17:52

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 10/16] unit/avrcp: Add /TP/MCN/CB/BV-01-C test

From: Andrei Emeltchenko <[email protected]>

Test verifies that the GetFolderItems command issued by the Controller
with VFS parameter.
---
unit/test-avrcp.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index c5aa32c..f948a8c 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -723,6 +723,11 @@ static void test_client(gconstpointer data)
AVRCP_MEDIA_PLAYER_LIST, 0, 2, NULL, 0,
NULL, NULL);

+ if (g_str_equal(context->data->test_name, "/TP/MCN/CB/BV-01-C"))
+ avrcp_get_folder_items(context->session,
+ AVRCP_MEDIA_PLAYER_VFS, 0, 2, NULL, 0,
+ NULL, NULL);
+
if (g_str_equal(context->data->test_name, "/TP/CFG/BV-01-C"))
avrcp_get_capabilities(context->session, CAP_EVENTS_SUPPORTED,
NULL, NULL);
@@ -812,6 +817,19 @@ int main(int argc, char *argv[])
0x00, 0x00, 0x00, 0x02, /* end */
0x00));

+ /*
+ * Media Content Navigation Commands and Notifications for Content
+ * Browsing.
+ */
+
+ /* GetFolderItems - Virtual FS - CT */
+ define_test("/TP/MCN/CB/BV-01-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, AVRCP_GET_FOLDER_ITEMS,
+ 0x00, 0x0a, AVRCP_MEDIA_PLAYER_VFS,
+ 0x00, 0x00, 0x00, 0x00, /* start */
+ 0x00, 0x00, 0x00, 0x02, /* end */
+ 0x00));
+
/* Media Player Selection IOP tests */

/* Listing of available media players */
--
1.8.3.2


2014-03-14 15:17:58

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 16/16] unit/avrcp: Add /TP/MCN/SRC/BV-01-C test

From: Andrei Emeltchenko <[email protected]>

Test verifies that Search command issued by the Controller.
---
unit/test-avrcp.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index ddd20f7..15cba1c 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -737,6 +737,10 @@ static void test_client(gconstpointer data)
AVRCP_MEDIA_PLAYER_VFS, 0x01, 0xaabb,
NULL, 0, NULL, NULL);

+ if (g_str_equal(context->data->test_name, "/TP/MCN/SRC/BV-01-C"))
+ avrcp_search(context->session, AVRCP_CHARSET_UTF8, "Country",
+ NULL, NULL);
+
if (g_str_equal(context->data->test_name, "/TP/CFG/BV-01-C"))
avrcp_get_capabilities(context->session, CAP_EVENTS_SUPPORTED,
NULL, NULL);
@@ -857,6 +861,16 @@ int main(int argc, char *argv[])
0xaa, 0xbb, /* counter */
0x00)); /* num attr */

+ /* Media Content Navigation Commands and Notifications for Search */
+
+ /* Search - CT */
+ define_test("/TP/MCN/SRC/BV-01-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, AVRCP_SEARCH,
+ 0x00, 0x0b, 0x00, AVRCP_CHARSET_UTF8,
+ 0x00, 0x07,
+ 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79));
+
+
/* Media Player Selection IOP tests */

/* Listing of available media players */
--
1.8.3.2


2014-03-14 15:17:55

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 13/16] android/avrcp: Add avrcp_get_item_attributes() function

From: Andrei Emeltchenko <[email protected]>

---
android/avrcp-lib.c | 28 ++++++++++++++++++++++++++++
android/avrcp-lib.h | 4 ++++
2 files changed, 32 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index cf4aeab..b3f3975 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -570,3 +570,31 @@ int avrcp_change_path(struct avrcp *session, uint8_t direction, uint64_t uid,
return avctp_send_browsing_req(session->conn, buf, sizeof(buf),
func, user_data);
}
+
+int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope,
+ uint64_t uid, uint16_t counter, uint32_t *attr,
+ size_t attr_count, avctp_browsing_rsp_cb func,
+ void *user_data)
+{
+ uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 12 +
+ attr_count * sizeof(uint32_t)];
+ struct avrcp_browsing_header *pdu = (void *) buf;
+
+ memset(buf, 0, sizeof(buf));
+
+ pdu->pdu_id = AVRCP_GET_ITEM_ATTRIBUTES;
+ pdu->param_len = htons(12 + attr_count * sizeof(uint32_t));
+
+ /* Scope */
+ pdu->params[0] = scope;
+
+ bt_put_be64(uid, &pdu->params[1]);
+ bt_put_be16(counter, &pdu->params[9]);
+
+ pdu->params[11] = attr_count;
+
+ memcpy(&pdu->params[12], attr, attr_count * sizeof(uint32_t));
+
+ return avctp_send_browsing_req(session->conn, buf, sizeof(buf),
+ func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 575cd2d..8188dad 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -192,3 +192,7 @@ int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
int avrcp_change_path(struct avrcp *session, uint8_t direction, uint64_t uid,
uint16_t counter, avctp_browsing_rsp_cb func,
void *user_data);
+int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope,
+ uint64_t uid, uint16_t counter, uint32_t *attr,
+ size_t attr_count, avctp_browsing_rsp_cb func,
+ void *user_data);
--
1.8.3.2


2014-03-14 15:17:51

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 09/16] unit/avrcp: Add Connection establishment and release tests

From: Andrei Emeltchenko <[email protected]>

Tests are checking connection establishment and release for browsing
channel. Since we are connected through socketpair the tests are dummy.
---
unit/test-avrcp.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 3a7e0d1..c5aa32c 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -822,6 +822,19 @@ int main(int argc, char *argv[])
0x00, 0x00, 0x00, 0x02, /* end */
0x00));

+ /* Connection Establishment for Browsing tests */
+
+ /*
+ * Tests are checking connection establishment and release
+ * for browsing channel. Since we are connected through socketpair
+ * the tests are dummy
+ */
+ define_test("/TP/CON/BV-01-C", test_dummy, raw_pdu(0x00));
+ define_test("/TP/CON/BV-02-C", test_dummy, raw_pdu(0x00));
+ define_test("/TP/CON/BV-03-C", test_dummy, raw_pdu(0x00));
+ define_test("/TP/CON/BV-04-C", test_dummy, raw_pdu(0x00));
+ define_test("/TP/CON/BV-05-C", test_dummy, raw_pdu(0x00));
+
/* Connection Establishment for Control tests */

/*
--
1.8.3.2


2014-03-14 15:17:54

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 12/16] unit/avrcp: Add /TP/MCN/CB/BV-04-C test

From: Andrei Emeltchenko <[email protected]>

Test verifies that the ChangePath command issued by the Controller.
---
unit/test-avrcp.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index f948a8c..171a44b 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -728,6 +728,10 @@ static void test_client(gconstpointer data)
AVRCP_MEDIA_PLAYER_VFS, 0, 2, NULL, 0,
NULL, NULL);

+ if (g_str_equal(context->data->test_name, "/TP/MCN/CB/BV-04-C"))
+ avrcp_change_path(context->session, 0x01, 0x01, 0xaabb,
+ NULL, NULL);
+
if (g_str_equal(context->data->test_name, "/TP/CFG/BV-01-C"))
avrcp_get_capabilities(context->session, CAP_EVENTS_SUPPORTED,
NULL, NULL);
@@ -830,6 +834,15 @@ int main(int argc, char *argv[])
0x00, 0x00, 0x00, 0x02, /* end */
0x00));

+ /* ChangePath - CT */
+ define_test("/TP/MCN/CB/BV-04-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, AVRCP_CHANGE_PATH,
+ 0x00, 0x0b,
+ 0xaa, 0xbb, /* counter */
+ 0x01, /* direction */
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01 /* Folder UID */));
+
/* Media Player Selection IOP tests */

/* Listing of available media players */
--
1.8.3.2


2014-03-14 15:17:49

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 07/16] unit/avrcp: Add /TP/MPS/BV-08-C test

From: Andrei Emeltchenko <[email protected]>

Test verifies that GetFolderItems cmd for the Media Player List
issued by the Controller.
---
unit/test-avrcp.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 22b3e4a..b173e8d 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -713,6 +713,11 @@ static void test_client(gconstpointer data)
if (g_str_equal(context->data->test_name, "/TP/MPS/BV-03-C"))
avrcp_set_browsed_player(context->session, 0xabcd, NULL, NULL);

+ if (g_str_equal(context->data->test_name, "/TP/MPS/BV-08-C"))
+ avrcp_get_folder_items(context->session,
+ AVRCP_MEDIA_PLAYER_LIST, 0, 2, NULL, 0,
+ NULL, NULL);
+
if (g_str_equal(context->data->test_name, "/TP/CFG/BV-01-C"))
avrcp_get_capabilities(context->session, CAP_EVENTS_SUPPORTED,
NULL, NULL);
@@ -794,6 +799,14 @@ int main(int argc, char *argv[])
raw_pdu(0x00, 0x11, 0x0e, 0x70, 0x00, 0x02,
0xab, 0xcd));

+ /* GetFolderItems - CT */
+ define_test("/TP/MPS/BV-08-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, AVRCP_GET_FOLDER_ITEMS,
+ 0x00, 0x0a, AVRCP_MEDIA_PLAYER_LIST,
+ 0x00, 0x00, 0x00, 0x00, /* start */
+ 0x00, 0x00, 0x00, 0x02, /* end */
+ 0x00));
+
/* Connection Establishment for Control tests */

/*
--
1.8.3.2


2014-03-14 15:17:47

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 05/16] android/avrcp: Use defined constant instead of magic number

From: Andrei Emeltchenko <[email protected]>

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

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 0e9f0df..fe6d7b4 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -346,7 +346,7 @@ int avrcp_register_notification(struct avrcp *session, uint8_t event,
uint32_t interval, avctp_rsp_cb func,
void *user_data)
{
- uint8_t params[5];
+ uint8_t params[AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH];

params[0] = event;
bt_put_be32(interval, &params[1]);
--
1.8.3.2


2014-03-14 15:17:57

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 15/16] android/avrcp: Add avrcp_search() function

From: Andrei Emeltchenko <[email protected]>

---
android/avrcp-lib.c | 21 +++++++++++++++++++++
android/avrcp-lib.h | 4 ++++
2 files changed, 25 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index b3f3975..ab7f915 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -28,6 +28,7 @@
#include <stdbool.h>
#include <glib.h>
#include <errno.h>
+#include <string.h>

#include "lib/bluetooth.h"

@@ -598,3 +599,23 @@ int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope,
return avctp_send_browsing_req(session->conn, buf, sizeof(buf),
func, user_data);
}
+
+int avrcp_search(struct avrcp *session, uint16_t charset, const char *string,
+ avctp_browsing_rsp_cb func, void *user_data)
+{
+ size_t str_len = strnlen(string, 255 - 4);
+ uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + str_len + 4];
+ struct avrcp_browsing_header *pdu = (void *) buf;
+
+ memset(buf, 0, sizeof(buf));
+
+ pdu->pdu_id = AVRCP_SEARCH;
+ pdu->param_len = htons(str_len + 4);
+
+ bt_put_be16(charset, &pdu->params[0]);
+ bt_put_be16(str_len, &pdu->params[2]);
+ memcpy(&pdu->params[4], string, str_len);
+
+ return avctp_send_browsing_req(session->conn, buf, sizeof(buf),
+ func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 8188dad..81e4ab1 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -93,6 +93,8 @@
/* Company IDs for vendor dependent commands */
#define IEEEID_BTSIG 0x001958

+#define AVRCP_CHARSET_UTF8 0x006a
+
/* Parameters legths */
#define AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH 5

@@ -196,3 +198,5 @@ int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope,
uint64_t uid, uint16_t counter, uint32_t *attr,
size_t attr_count, avctp_browsing_rsp_cb func,
void *user_data);
+int avrcp_search(struct avrcp *session, uint16_t charset, const char *string,
+ avctp_browsing_rsp_cb func, void *user_data);
--
1.8.3.2


2014-03-14 15:17:53

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 11/16] android/avrcp: Add avrcp_change_path() function

From: Andrei Emeltchenko <[email protected]>

---
android/avrcp-lib.c | 20 ++++++++++++++++++++
android/avrcp-lib.h | 3 +++
2 files changed, 23 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index e9220b7..cf4aeab 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -550,3 +550,23 @@ int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
return avctp_send_browsing_req(session->conn, buf, sizeof(buf),
func, user_data);
}
+
+int avrcp_change_path(struct avrcp *session, uint8_t direction, uint64_t uid,
+ uint16_t counter, avctp_browsing_rsp_cb func,
+ void *user_data)
+{
+ uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 11];
+ struct avrcp_browsing_header *pdu = (void *) buf;
+
+ memset(buf, 0, sizeof(buf));
+
+ pdu->pdu_id = AVRCP_CHANGE_PATH;
+ pdu->param_len = htons(11);
+
+ bt_put_be16(counter, &pdu->params[0]);
+ pdu->params[2] = direction;
+ bt_put_be64(uid, &pdu->params[3]);
+
+ return avctp_send_browsing_req(session->conn, buf, sizeof(buf),
+ func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 72fd89a..575cd2d 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -189,3 +189,6 @@ int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
uint32_t start, uint32_t end, uint32_t *attr,
size_t attr_count, avctp_browsing_rsp_cb func,
void *user_data);
+int avrcp_change_path(struct avrcp *session, uint8_t direction, uint64_t uid,
+ uint16_t counter, avctp_browsing_rsp_cb func,
+ void *user_data);
--
1.8.3.2


2014-03-14 15:17:56

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 14/16] unit/avrcp: Add /TP/MCN/CB/BV-07-C test

From: Andrei Emeltchenko <[email protected]>

Test verifies that GetItemAttributes command issued by the Controller.
---
unit/test-avrcp.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 171a44b..ddd20f7 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -732,6 +732,11 @@ static void test_client(gconstpointer data)
avrcp_change_path(context->session, 0x01, 0x01, 0xaabb,
NULL, NULL);

+ if (g_str_equal(context->data->test_name, "/TP/MCN/CB/BV-07-C"))
+ avrcp_get_item_attributes(context->session,
+ AVRCP_MEDIA_PLAYER_VFS, 0x01, 0xaabb,
+ NULL, 0, NULL, NULL);
+
if (g_str_equal(context->data->test_name, "/TP/CFG/BV-01-C"))
avrcp_get_capabilities(context->session, CAP_EVENTS_SUPPORTED,
NULL, NULL);
@@ -843,6 +848,15 @@ int main(int argc, char *argv[])
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01 /* Folder UID */));

+ /* GetItemAttributes - CT */
+ define_test("/TP/MCN/CB/BV-07-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, AVRCP_GET_ITEM_ATTRIBUTES,
+ 0x00, 0x0c, AVRCP_MEDIA_PLAYER_VFS,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, /* uuid */
+ 0xaa, 0xbb, /* counter */
+ 0x00)); /* num attr */
+
/* Media Player Selection IOP tests */

/* Listing of available media players */
--
1.8.3.2


2014-03-14 15:17:43

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 01/16] android/avrcp: Add avrcp_connect_browsing()

From: Andrei Emeltchenko <[email protected]>

Add support for browsing channel
---
android/avrcp-lib.c | 6 ++++++
android/avrcp-lib.h | 2 ++
2 files changed, 8 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index f5ae5a3..39fc748 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -244,6 +244,12 @@ struct avrcp *avrcp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
return session;
}

+int avrcp_connect_browsing(struct avrcp *session, int fd, size_t imtu,
+ size_t omtu)
+{
+ return avctp_connect_browsing(session->conn, fd, imtu, omtu);
+}
+
void avrcp_set_destroy_cb(struct avrcp *session, avrcp_destroy_cb_t cb,
void *user_data)
{
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 4adf4bf..7f82d7d 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -123,6 +123,8 @@ 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,
void *user_data);
+int avrcp_connect_browsing(struct avrcp *session, int fd, size_t imtu,
+ size_t omtu);
void avrcp_set_control_handlers(struct avrcp *session,
const struct avrcp_control_handler *handlers,
void *user_data);
--
1.8.3.2


2014-03-14 15:17:46

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 04/16] unit/avrcp: Add /TP/MPS/BV-03-C test

From: Andrei Emeltchenko <[email protected]>

Test verifies that SetBrowsedPlayer command issued by the Controller.
---
unit/test-avrcp.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 623e62e..22b3e4a 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -710,6 +710,9 @@ static void test_client(gconstpointer data)
avrcp_set_addressed_player(context->session, 0xabcd, NULL,
NULL);

+ if (g_str_equal(context->data->test_name, "/TP/MPS/BV-03-C"))
+ avrcp_set_browsed_player(context->session, 0xabcd, NULL, NULL);
+
if (g_str_equal(context->data->test_name, "/TP/CFG/BV-01-C"))
avrcp_get_capabilities(context->session, CAP_EVENTS_SUPPORTED,
NULL, NULL);
@@ -786,6 +789,11 @@ int main(int argc, char *argv[])
AVRCP_SET_ADDRESSED_PLAYER,
0x00, 0x00, 0x01, 0x00));

+ /* SetBrowsedPlayer - CT */
+ define_test("/TP/MPS/BV-03-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, 0x70, 0x00, 0x02,
+ 0xab, 0xcd));
+
/* Connection Establishment for Control tests */

/*
--
1.8.3.2


2014-03-14 15:17:45

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 03/16] unit/avrcp: Add browsing channel support in unit testing

From: Andrei Emeltchenko <[email protected]>

---
.gitignore | 2 ++
unit/test-avrcp.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index 7a2af5a..0a66fec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -127,3 +127,5 @@ android/bluetoothd-snoop
android/test-ipc
android/test-*.log
android/test-*.trs
+
+patches/
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index b86d572..623e62e 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -46,6 +46,7 @@
struct test_pdu {
bool valid;
bool fragmented;
+ bool browse;
const uint8_t *data;
size_t size;
};
@@ -59,8 +60,10 @@ struct context {
GMainLoop *main_loop;
struct avrcp *session;
guint source;
+ guint browse_source;
guint process;
int fd;
+ int browse_fd;
unsigned int pdu_offset;
const struct test_data *data;
};
@@ -74,6 +77,14 @@ struct context {
.size = sizeof(data(args)), \
}

+#define brs_pdu(args...) \
+ { \
+ .valid = true, \
+ .browse = true, \
+ .data = data(args), \
+ .size = sizeof(data(args)), \
+ }
+
#define frg_pdu(args...) \
{ \
.valid = true, \
@@ -129,7 +140,10 @@ static gboolean send_pdu(gpointer user_data)

pdu = &context->data->pdu_list[context->pdu_offset++];

- len = write(context->fd, pdu->data, pdu->size);
+ if (pdu->browse)
+ len = write(context->browse_fd, pdu->data, pdu->size);
+ else
+ len = write(context->fd, pdu->data, pdu->size);

if (g_test_verbose())
util_hexdump('<', pdu->data, len, test_debug, "AVRCP: ");
@@ -162,6 +176,8 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
ssize_t len;
int fd;

+ DBG("");
+
pdu = &context->data->pdu_list[context->pdu_offset++];

if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
@@ -189,17 +205,59 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
return TRUE;
}

+static gboolean browse_test_handler(GIOChannel *channel, GIOCondition cond,
+ gpointer user_data)
+{
+ struct context *context = user_data;
+ const struct test_pdu *pdu;
+ unsigned char buf[512];
+ ssize_t len;
+ int fd;
+
+ DBG("");
+
+ pdu = &context->data->pdu_list[context->pdu_offset++];
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+ context->browse_source = 0;
+ g_print("%s: cond %x\n", __func__, cond);
+ return FALSE;
+ }
+
+ fd = g_io_channel_unix_get_fd(channel);
+
+ len = read(fd, buf, sizeof(buf));
+
+ g_assert(len > 0);
+
+ if (g_test_verbose())
+ util_hexdump('>', buf, len, test_debug, "AVCTP: ");
+
+ g_assert_cmpint(len, ==, pdu->size);
+
+ g_assert(memcmp(buf, pdu->data, pdu->size) == 0);
+
+ if (!pdu->fragmented)
+ context_process(context);
+
+ return TRUE;
+}
+
static struct context *create_context(uint16_t version, gconstpointer data)
{
struct context *context = g_new0(struct context, 1);
GIOChannel *channel;
int err, sv[2];

+ DBG("");
+
context->main_loop = g_main_loop_new(NULL, FALSE);
g_assert(context->main_loop);

+ /* Control channel setup */
+
err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
- g_assert(err == 0);
+ g_assert(!err);

context->session = avrcp_new(sv[0], 672, 672, version);
g_assert(context->session != NULL);
@@ -218,6 +276,30 @@ static struct context *create_context(uint16_t version, gconstpointer data)
g_io_channel_unref(channel);

context->fd = sv[1];
+
+ /* Browsing channel setup */
+
+ err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
+ g_assert(!err);
+
+ err = avrcp_connect_browsing(context->session, sv[0], 672, 672);
+ g_assert(!err);
+
+ channel = g_io_channel_unix_new(sv[1]);
+
+ g_io_channel_set_close_on_unref(channel, TRUE);
+ g_io_channel_set_encoding(channel, NULL, NULL);
+ g_io_channel_set_buffered(channel, FALSE);
+
+ context->browse_source = g_io_add_watch(channel,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ browse_test_handler, context);
+ g_assert(context->browse_source > 0);
+
+ g_io_channel_unref(channel);
+
+ context->browse_fd = sv[1];
+
context->data = data;

return context;
@@ -230,6 +312,9 @@ static void destroy_context(struct context *context)

avrcp_shutdown(context->session);

+ if (context->browse_source > 0)
+ g_source_remove(context->browse_source);
+
g_main_loop_unref(context->main_loop);

test_free(context->data);
--
1.8.3.2


2014-03-14 15:17:44

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCHv2 02/16] android/avrcp: Add avrcp_set_browsed_player() function

From: Andrei Emeltchenko <[email protected]>

---
android/avrcp-lib.c | 18 ++++++++++++++++++
android/avrcp-lib.h | 9 +++++++++
2 files changed, 27 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 39fc748..0e9f0df 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -503,3 +503,21 @@ int avrcp_send_passthrough(struct avrcp *session, uint32_t vendor, uint8_t op)
return avctp_send_passthrough(session->conn, AVC_VENDOR_UNIQUE, params,
sizeof(params));
}
+
+int avrcp_set_browsed_player(struct avrcp *session, uint16_t player_id,
+ avctp_browsing_rsp_cb func, void *user_data)
+{
+ uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 2];
+ struct avrcp_browsing_header *pdu = (void *) buf;
+
+ DBG("");
+
+ memset(buf, 0, sizeof(buf));
+
+ pdu->pdu_id = AVRCP_SET_BROWSED_PLAYER;
+ bt_put_be16(player_id, pdu->params);
+ pdu->param_len = htons(2);
+
+ return avctp_send_browsing_req(session->conn, buf, sizeof(buf),
+ func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 7f82d7d..88d2126 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -90,6 +90,13 @@
/* Parameters legths */
#define AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH 5

+struct avrcp_browsing_header {
+ uint8_t pdu_id;
+ uint16_t param_len;
+ uint8_t params[0];
+} __attribute__ ((packed));
+#define AVRCP_BROWSING_HEADER_LENGTH 3
+
struct avrcp;

struct avrcp_control_handler {
@@ -170,3 +177,5 @@ int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
uint8_t code, uint8_t *params,
size_t params_len);
int avrcp_send_passthrough(struct avrcp *session, uint32_t vendor, uint8_t op);
+int avrcp_set_browsed_player(struct avrcp *session, uint16_t player_id,
+ avctp_browsing_rsp_cb func, void *user_data);
--
1.8.3.2