From: Andrei Emeltchenko <[email protected]>
This is rebased version of my previous patch set rebased after
latest modifications of avrcp-lib.
Andrei Emeltchenko (10):
avrcp: Fix possible buffer overflow
unit/avrcp: Add /TP/PAS/BV-06-C test
unit/avrcp: Add /TP/PAS/BV-08-C test
android/avrcp: Add avrcp_get_current_player_value() function
unit/avrcp: Add /TP/PAS/BV-09-C test
unit/avrcp: Add /TP/PAS/BV-10-C test
android/avrcp: Add avrcp_set_player_value() function
unit/avrcp: Add /TP/PAS/BV-11-C test
unit/avrcp: Add /TP/PAS/BI-01-C test
doc: Update test coverage document
android/avrcp-lib.c | 39 +++++++++++++
android/avrcp-lib.h | 14 +++++
doc/test-coverage.txt | 2 +-
profiles/audio/avrcp.c | 3 +
unit/test-avrcp.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 213 insertions(+), 1 deletion(-)
--
1.8.3.2
Hi Andrei,
On Tue, Mar 4, 2014 at 4:02 PM, Andrei Emeltchenko
<[email protected]> wrote:
> From: Andrei Emeltchenko <[email protected]>
>
> This is rebased version of my previous patch set rebased after
> latest modifications of avrcp-lib.
>
> Andrei Emeltchenko (10):
> avrcp: Fix possible buffer overflow
> unit/avrcp: Add /TP/PAS/BV-06-C test
> unit/avrcp: Add /TP/PAS/BV-08-C test
> android/avrcp: Add avrcp_get_current_player_value() function
> unit/avrcp: Add /TP/PAS/BV-09-C test
> unit/avrcp: Add /TP/PAS/BV-10-C test
> android/avrcp: Add avrcp_set_player_value() function
> unit/avrcp: Add /TP/PAS/BV-11-C test
> unit/avrcp: Add /TP/PAS/BI-01-C test
> doc: Update test coverage document
>
> android/avrcp-lib.c | 39 +++++++++++++
> android/avrcp-lib.h | 14 +++++
> doc/test-coverage.txt | 2 +-
> profiles/audio/avrcp.c | 3 +
> unit/test-avrcp.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 213 insertions(+), 1 deletion(-)
>
> --
> 1.8.3.2
Pushed, not that the first I did not apply since there already a check
if attributes are within the valid range before calling that function,
also change some parameter and code placement to be more consistent
and don't use VLA for buffers.
--
Luiz Augusto von Dentz
From: Andrei Emeltchenko <[email protected]>
Test verifies that get current player application setting value command
issued from the Controller.
---
unit/test-avrcp.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index a2f554c..a849be3 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -412,6 +412,14 @@ static void test_client(gconstpointer data)
avrcp_get_player_attribute_text(context->session, NULL, 0,
NULL, NULL);
+ if (g_str_equal(context->data->test_name, "/TP/PAS/BV-09-C")) {
+ uint8_t attributes[2] = { AVRCP_ATTRIBUTE_EQUALIZER,
+ AVRCP_ATTRIBUTE_REPEAT_MODE };
+
+ avrcp_get_current_player_value(context->session, attributes,
+ sizeof(attributes), NULL, NULL);
+ }
+
execute_context(context);
}
@@ -557,5 +565,13 @@ int main(int argc, char *argv[])
AVRCP_GET_PLAYER_VALUE_TEXT,
0x00, 0x00, 0x01, 0x00));
+ define_test("/TP/PAS/BV-09-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_CURRENT_PLAYER_VALUE,
+ 0x00, 0x00, 0x03, 0x02,
+ AVRCP_ATTRIBUTE_EQUALIZER,
+ AVRCP_ATTRIBUTE_REPEAT_MODE));
+
return g_test_run();
}
--
1.8.3.2
From: Andrei Emeltchenko <[email protected]>
Test verifies that the get player application setting values response
issued from the Target.
---
unit/test-avrcp.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index d33a459..a2f554c 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -349,6 +349,22 @@ static ssize_t avrcp_handle_list_player_values(struct avrcp *session,
return 1;
}
+static ssize_t avrcp_handle_get_player_value_text(struct avrcp *session,
+ uint8_t transaction,
+ uint16_t params_len,
+ uint8_t *params,
+ void *user_data)
+{
+ DBG("");
+
+ if (params_len != 1)
+ return -EINVAL;
+
+ params[0] = 0;
+
+ return 1;
+}
+
static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_CAPABILITIES,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -362,6 +378,9 @@ static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_LIST_PLAYER_VALUES,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
avrcp_handle_list_player_values },
+ { AVRCP_GET_PLAYER_VALUE_TEXT,
+ AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+ avrcp_handle_get_player_value_text },
{ },
};
@@ -528,5 +547,15 @@ int main(int argc, char *argv[])
AVRCP_LIST_PLAYER_VALUES,
0x00, 0x00, 0x01, 0x00));
+ define_test("/TP/PAS/BV-08-C", test_server,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_PLAYER_VALUE_TEXT,
+ 0x00, 0x00, 0x01, 0x00),
+ raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_PLAYER_VALUE_TEXT,
+ 0x00, 0x00, 0x01, 0x00));
+
return g_test_run();
}
--
1.8.3.2
From: Andrei Emeltchenko <[email protected]>
Test verifies that the set player application setting value command
issued from the Controller.
---
unit/test-avrcp.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index e7d37e0..6999d22 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -448,6 +448,16 @@ static void test_client(gconstpointer data)
sizeof(attributes), NULL, NULL);
}
+ if (g_str_equal(context->data->test_name, "/TP/PAS/BV-11-C")) {
+ uint8_t attributes[2] = { AVRCP_ATTRIBUTE_EQUALIZER,
+ AVRCP_ATTRIBUTE_REPEAT_MODE };
+ uint8_t values[] = { 0xaa, 0xff };
+
+ avrcp_set_player_value(context->session, attributes,
+ sizeof(attributes), values,
+ NULL, NULL);
+ }
+
execute_context(context);
}
@@ -615,5 +625,13 @@ int main(int argc, char *argv[])
AVRCP_ATTRIBUTE_EQUALIZER, 0x00,
AVRCP_ATTRIBUTE_REPEAT_MODE, 0x00));
+ define_test("/TP/PAS/BV-11-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_SET_PLAYER_VALUE,
+ 0x00, 0x00, 0x05, 0x02,
+ AVRCP_ATTRIBUTE_EQUALIZER, 0xaa,
+ AVRCP_ATTRIBUTE_REPEAT_MODE, 0xff));
+
return g_test_run();
}
--
1.8.3.2
From: Andrei Emeltchenko <[email protected]>
Update AVRCP test numbers.
---
doc/test-coverage.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/test-coverage.txt b/doc/test-coverage.txt
index ce73b9d..6568286 100644
--- a/doc/test-coverage.txt
+++ b/doc/test-coverage.txt
@@ -18,7 +18,7 @@ test-ringbuf 3 Ring buffer functionality
test-queue 1 Queue handling functionality
test-avdtp 60 AVDTP qualification test cases
test-avctp 9 AVCTP qualification test cases
-test-avrcp 7 AVRCP qualification test cases
+test-avrcp 24 AVRCP qualification test cases
test-gobex 31 Generic OBEX functionality
test-gobex-packet 9 OBEX packet handling
test-gobex-header 28 OBEX header handling
--
1.8.3.2
From: Andrei Emeltchenko <[email protected]>
Test verifies that the get current player application setting value
response issued from the Target.
---
unit/test-avrcp.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index a849be3..e7d37e0 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -365,6 +365,31 @@ static ssize_t avrcp_handle_get_player_value_text(struct avrcp *session,
return 1;
}
+static ssize_t avrcp_handle_get_current_player_value(struct avrcp *session,
+ uint8_t transaction,
+ uint16_t params_len,
+ uint8_t *params,
+ void *user_data)
+{
+ uint8_t *attributes;
+ int i;
+
+ DBG("params[0] %d params_len %d", params[0], params_len);
+
+ attributes = g_memdup(¶ms[1], params[0]);
+
+ for (i = 0; i < params[0]; i++) {
+ params[i * 2 + 1] = attributes[i];
+ params[i * 2 + 2] = 0; /* value */
+ }
+
+ g_free(attributes);
+
+ params[0] = i;
+
+ return params[0] * 2 + 1;
+}
+
static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_CAPABILITIES,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -381,6 +406,9 @@ static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_PLAYER_VALUE_TEXT,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
avrcp_handle_get_player_value_text },
+ { AVRCP_GET_CURRENT_PLAYER_VALUE,
+ AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+ avrcp_handle_get_current_player_value },
{ },
};
@@ -573,5 +601,19 @@ int main(int argc, char *argv[])
AVRCP_ATTRIBUTE_EQUALIZER,
AVRCP_ATTRIBUTE_REPEAT_MODE));
+ define_test("/TP/PAS/BV-10-C", test_server,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_CURRENT_PLAYER_VALUE,
+ 0x00, 0x00, 0x03, 0x02,
+ AVRCP_ATTRIBUTE_EQUALIZER,
+ AVRCP_ATTRIBUTE_REPEAT_MODE),
+ raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_CURRENT_PLAYER_VALUE,
+ 0x00, 0x00, 0x05, 0x02,
+ AVRCP_ATTRIBUTE_EQUALIZER, 0x00,
+ AVRCP_ATTRIBUTE_REPEAT_MODE, 0x00));
+
return g_test_run();
}
--
1.8.3.2
From: Andrei Emeltchenko <[email protected]>
---
android/avrcp-lib.c | 20 ++++++++++++++++++++
android/avrcp-lib.h | 11 +++++++++++
2 files changed, 31 insertions(+)
diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index dfd6fa3..8f18b9c 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -384,3 +384,23 @@ int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
AVC_SUBUNIT_PANEL, AVRCP_REGISTER_NOTIFICATION,
params, params_len);
}
+
+int avrcp_get_current_player_value(struct avrcp *session, uint8_t *attributes,
+ uint8_t attr_count, avctp_rsp_cb func,
+ void *user_data)
+
+{
+ uint8_t buf[AVRCP_ATTRIBUTE_LAST + 1];
+
+ if (attr_count > AVRCP_ATTRIBUTE_LAST)
+ return -EINVAL;
+
+ if (attributes && attr_count) {
+ buf[0] = attr_count;
+ memcpy(buf + 1, attributes, attr_count);
+ }
+
+ return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
+ AVRCP_GET_CURRENT_PLAYER_VALUE, buf,
+ attr_count + 1, func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 7185fb6..5e396bb 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -75,6 +75,14 @@
#define CAP_COMPANY_ID 0x02
#define CAP_EVENTS_SUPPORTED 0x03
+/* Player Attributes */
+#define AVRCP_ATTRIBUTE_ILEGAL 0x00
+#define AVRCP_ATTRIBUTE_EQUALIZER 0x01
+#define AVRCP_ATTRIBUTE_REPEAT_MODE 0x02
+#define AVRCP_ATTRIBUTE_SHUFFLE 0x03
+#define AVRCP_ATTRIBUTE_SCAN 0x04
+#define AVRCP_ATTRIBUTE_LAST AVRCP_ATTRIBUTE_SCAN
+
/* Company IDs for vendor dependent commands */
#define IEEEID_BTSIG 0x001958
@@ -138,3 +146,6 @@ int avrcp_get_element_attrs_rsp(struct avrcp *session, uint8_t transaction,
int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
uint8_t code, uint8_t *params,
size_t params_len);
+int avrcp_get_current_player_value(struct avrcp *session, uint8_t *attributes,
+ uint8_t attr_count, avctp_rsp_cb func,
+ void *user_data);
--
1.8.3.2
From: Andrei Emeltchenko <[email protected]>
Test verifies that the list player application setting values response
issued from the Target.
---
unit/test-avrcp.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 8119b53..d33a459 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -333,6 +333,22 @@ static ssize_t avrcp_handle_get_player_attr_text(struct avrcp *session,
return 1;
}
+static ssize_t avrcp_handle_list_player_values(struct avrcp *session,
+ uint8_t transaction,
+ uint16_t params_len,
+ uint8_t *params,
+ void *user_data)
+{
+ DBG("params[0] %d params_len %d", params[0], params_len);
+
+ if (params_len != 1)
+ return -EINVAL;
+
+ params[0] = 0;
+
+ return 1;
+}
+
static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_CAPABILITIES,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -343,6 +359,9 @@ static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
avrcp_handle_get_player_attr_text },
+ { AVRCP_LIST_PLAYER_VALUES,
+ AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+ avrcp_handle_list_player_values },
{ },
};
@@ -499,5 +518,15 @@ int main(int argc, char *argv[])
AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
0x00, 0x00, 0x01, 0x00));
+ define_test("/TP/PAS/BV-06-C", test_server,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_LIST_PLAYER_VALUES,
+ 0x00, 0x00, 0x01, 0x00),
+ raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_LIST_PLAYER_VALUES,
+ 0x00, 0x00, 0x01, 0x00));
+
return g_test_run();
}
--
1.8.3.2
From: Andrei Emeltchenko <[email protected]>
---
android/avrcp-lib.c | 19 +++++++++++++++++++
android/avrcp-lib.h | 3 +++
2 files changed, 22 insertions(+)
diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 8f18b9c..865a3f9 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -404,3 +404,22 @@ int avrcp_get_current_player_value(struct avrcp *session, uint8_t *attributes,
AVRCP_GET_CURRENT_PLAYER_VALUE, buf,
attr_count + 1, func, user_data);
}
+
+int avrcp_set_player_value(struct avrcp *session, uint8_t *attributes,
+ uint8_t attr_count, uint8_t *values,
+ avctp_rsp_cb func, void *user_data)
+{
+ uint8_t buf[2 * attr_count + 1];
+ int i;
+
+ buf[0] = attr_count;
+
+ for (i = 0; i < attr_count; i++) {
+ buf[i * 2 + 1] = attributes[i];
+ buf[i * 2 + 2] = values[i];
+ }
+
+ return avrcp_send_req(session, AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL,
+ AVRCP_SET_PLAYER_VALUE, buf, 2 * attr_count + 1,
+ func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 5e396bb..554e064 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -149,3 +149,6 @@ int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
int avrcp_get_current_player_value(struct avrcp *session, uint8_t *attributes,
uint8_t attr_count, avctp_rsp_cb func,
void *user_data);
+int avrcp_set_player_value(struct avrcp *session, uint8_t *attributes,
+ uint8_t attr_count, uint8_t *values,
+ avctp_rsp_cb func, void *user_data);
--
1.8.3.2
From: Andrei Emeltchenko <[email protected]>
Test verifies that Get player app setting attribute text returns error
given invalid attribute id.
---
unit/test-avrcp.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 6999d22..803dd6b 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -326,7 +326,16 @@ static ssize_t avrcp_handle_get_player_attr_text(struct avrcp *session,
uint8_t *params,
void *user_data)
{
- DBG("");
+ int i;
+
+ DBG("params[0] %d params_len %d", params[0], params_len);
+
+ for (i = 1; i <= params[0]; i++) {
+ DBG("params[%d] = 0x%02x", i, params[i]);
+ if (params[i] > AVRCP_ATTRIBUTE_LAST ||
+ params[i] == AVRCP_ATTRIBUTE_ILEGAL)
+ return -EINVAL;
+ }
params[0] = 0;
@@ -633,5 +642,18 @@ int main(int argc, char *argv[])
AVRCP_ATTRIBUTE_EQUALIZER, 0xaa,
AVRCP_ATTRIBUTE_REPEAT_MODE, 0xff));
+ /* Get player app setting attribute text invalid behavior - TG */
+ define_test("/TP/PAS/BI-01-C", test_server,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
+ 0x00, 0x00, 0x02, 0x01,
+ /* Invalid attribute id */
+ 0x7f),
+ raw_pdu(0x02, 0x11, 0x0e, AVC_CTYPE_REJECTED,
+ 0x48, 0x00, 0x00, 0x19, 0x58,
+ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
+ 0x00, 0x00, 0x01, AVRCP_STATUS_INVALID_PARAM));
+
return g_test_run();
}
--
1.8.3.2
From: Andrei Emeltchenko <[email protected]>
This fixes static analysers warnings.
---
profiles/audio/avrcp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index bca2fc8..aa932e0 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1909,6 +1909,9 @@ static void avrcp_get_current_player_value(struct avrcp *session,
struct avrcp_header *pdu = (void *) buf;
uint16_t length = AVRCP_HEADER_LENGTH + count + 1;
+ if (count > AVRCP_ATTRIBUTE_LAST)
+ return;
+
memset(buf, 0, sizeof(buf));
set_company_id(pdu->company_id, IEEEID_BTSIG);
--
1.8.3.2