2014-09-16 08:49:29

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 0/8] android/tester: Unifying the way PDU is handled

This patchset makes all testers use common struct for using raw data (PDUs).
Also some helpers were added for pdu matching.

Jakub Tyszkowski (8):
android/tester: Expose gatt-tester's pdu definition to other testers
android/tester: Make AVRCP tests use generic pdu struct
android/tester: Make A2DP tests use generic pdu struct
android/tester: Make GATT tests use generic pdu struct
android/tester: Make HidHost tests use generic pdu struct
android/tester: Add helper functions for sending sdp responses
android/tester: Make avrcp use sdp pdu sending helper
android/tester: Expose pdu set and matching function to be reused

android/tester-a2dp.c | 74 ++++++++++++++++--------------------------
android/tester-avrcp.c | 84 ++++++++++++++++++++----------------------------
android/tester-gatt.c | 26 +++------------
android/tester-hidhost.c | 40 +++++++++--------------
android/tester-main.c | 50 ++++++++++++++++++++++++++++
android/tester-main.h | 30 +++++++++++++++++
6 files changed, 163 insertions(+), 141 deletions(-)

--
1.9.3



2014-09-16 10:12:16

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH 0/8] android/tester: Unifying the way PDU is handled

Hi Jakub,

On Tue, Sep 16, 2014 at 11:49 AM, Jakub Tyszkowski
<[email protected]> wrote:
> This patchset makes all testers use common struct for using raw data (PDUs).
> Also some helpers were added for pdu matching.
>
> Jakub Tyszkowski (8):
> android/tester: Expose gatt-tester's pdu definition to other testers
> android/tester: Make AVRCP tests use generic pdu struct
> android/tester: Make A2DP tests use generic pdu struct
> android/tester: Make GATT tests use generic pdu struct
> android/tester: Make HidHost tests use generic pdu struct
> android/tester: Add helper functions for sending sdp responses
> android/tester: Make avrcp use sdp pdu sending helper
> android/tester: Expose pdu set and matching function to be reused
>
> android/tester-a2dp.c | 74 ++++++++++++++++--------------------------
> android/tester-avrcp.c | 84 ++++++++++++++++++++----------------------------
> android/tester-gatt.c | 26 +++------------
> android/tester-hidhost.c | 40 +++++++++--------------
> android/tester-main.c | 50 ++++++++++++++++++++++++++++
> android/tester-main.h | 30 +++++++++++++++++
> 6 files changed, 163 insertions(+), 141 deletions(-)
>
> --
> 1.9.3


I think this PDU matching is so common that we should have it in
bthost to begin with, so Im planning to implement something like this:

diff --git a/emulator/bthost.h b/emulator/bthost.h
index 49a8649..c73ae6f 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -29,6 +29,17 @@ typedef void (*bthost_send_func) (const void *data,
uint16_t len,

struct bthost;

+struct bthost_pdu {
+ const uint8_t *data;
+ size_t len;
+ size_t offset;
+};
+
+struct bthost_pdu_set {
+ const struct bthost_pdu *req;
+ const struct bthost_pdu *rsp;
+};
+
struct bthost *bthost_create(void);
void bthost_destroy(struct bthost *bthost);

@@ -64,6 +75,9 @@ void bthost_add_cid_hook(struct bthost *bthost,
uint16_t handle, uint16_t cid,
void bthost_send_cid(struct bthost *bthost, uint16_t handle, uint16_t cid,
const void *data, uint16_t len);

+void bthost_add_cid_pdu(struct bthost *bthost, uint16_t handle, uint16_t cid,
+ const struct bthost_pdu_set *pdus);
+
typedef void (*bthost_l2cap_rsp_cb) (uint8_t code, const void *data,
uint16_t len, void *user_data);

With this I think we would be able to match intervals of a PDU and be
able to respond keeping the original data for the offsets.

--
Luiz Augusto von Dentz

2014-09-16 08:49:37

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 8/8] android/tester: Expose pdu set and matching function to be reused

So far this is used by avrcp and a2dp tests, but we could try to
implement this way of pdu matching and responding in other testers.
---
android/tester-a2dp.c | 22 +++-------------------
android/tester-avrcp.c | 22 +++-------------------
android/tester-gatt.c | 1 -
android/tester-hidhost.c | 1 -
android/tester-main.c | 24 +++++++++++++++++++++++-
android/tester-main.h | 10 ++++++++++
6 files changed, 39 insertions(+), 41 deletions(-)

diff --git a/android/tester-a2dp.c b/android/tester-a2dp.c
index 7e06ec4..35ba27f 100644
--- a/android/tester-a2dp.c
+++ b/android/tester-a2dp.c
@@ -18,7 +18,6 @@
#include <stdbool.h>

#include "emulator/bthost.h"
-#include "src/shared/util.h"

#include "tester-main.h"
#include "android/utils.h"
@@ -50,10 +49,7 @@ static struct emu_cid_data cid_data;
#define req_suspend 0x50, 0x09, 0x04
#define rsp_suspend 0x52, 0x09

-const struct pdu_set {
- struct pdu req;
- struct pdu rsp;
-} pdus[] = {
+const struct pdu_set pdus[] = {
{ raw_pdu(req_dsc), raw_pdu(rsp_dsc) },
{ raw_pdu(req_get), raw_pdu(rsp_get) },
{ raw_pdu(req_cfg), raw_pdu(rsp_cfg) },
@@ -74,23 +70,11 @@ static void a2dp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
struct emu_cid_data *cid_data = user_data;
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- int i;

util_hexdump('>', data, len, print_data, NULL);

- for (i = 0; pdus[i].req.data; i++) {
- if (pdus[i].req.size != len)
- continue;
-
- if (memcmp(pdus[i].req.data, data, len))
- continue;
-
- util_hexdump('<', pdus[i].rsp.data, pdus[i].rsp.size,
- print_data, NULL);
-
- bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
- pdus[i].rsp.data, pdus[i].rsp.size);
- }
+ tester_send_matching_pdu_resp(bthost, cid_data->handle, cid_data->cid,
+ pdus, data, len, print_data);
}

static void a2dp_connect_request_cb(uint16_t handle, uint16_t cid,
diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index 6beab7d..527fc25 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -18,7 +18,6 @@
#include <stdbool.h>

#include "emulator/bthost.h"
-#include "src/shared/util.h"

#include "tester-main.h"
#include "android/utils.h"
@@ -73,10 +72,7 @@ static struct pdu sdp_rsp_pdu = raw_pdu(
#define req_suspend 0x50, 0x09, 0x04
#define rsp_suspend 0x52, 0x09

-static const struct pdu_set {
- const struct pdu req;
- const struct pdu rsp;
-} pdus[] = {
+static const struct pdu_set pdus[] = {
{ raw_pdu(req_dsc), raw_pdu(rsp_dsc)},
{ raw_pdu(req_get), raw_pdu(rsp_get)},
{ raw_pdu(req_cfg), raw_pdu(rsp_cfg)},
@@ -126,23 +122,11 @@ static void a2dp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
struct emu_cid_data *cid_data = user_data;
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- int i;

util_hexdump('>', data, len, print_a2dp, NULL);

- for (i = 0; pdus[i].req.data; i++) {
- if (pdus[i].req.size != len)
- continue;
-
- if (memcmp(pdus[i].req.data, data, len))
- continue;
-
- util_hexdump('<', pdus[i].rsp.data, pdus[i].rsp.size,
- print_a2dp, NULL);
-
- bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
- pdus[i].rsp.data, pdus[i].rsp.size);
- }
+ tester_send_matching_pdu_resp(bthost, cid_data->handle, cid_data->cid,
+ pdus, data, len, print_a2dp);
}

static void a2dp_connect_request_cb(uint16_t handle, uint16_t cid,
diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index 5defce0..db6fede 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -19,7 +19,6 @@

#include "emulator/bthost.h"
#include "tester-main.h"
-#include "src/shared/util.h"

#define L2CAP_ATT_EXCHANGE_MTU_REQ 0x02
#define L2CAP_ATT_EXCHANGE_MTU_RSP 0x03
diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index 0fe9c0a..6f524f2 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -21,7 +21,6 @@
#include "tester-main.h"

#include "android/utils.h"
-#include "src/shared/util.h"

#define HID_GET_REPORT_PROTOCOL 0x60
#define HID_GET_BOOT_PROTOCOL 0x61
diff --git a/android/tester-main.c b/android/tester-main.c
index edbb35c..b254c89 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -20,7 +20,6 @@
#include "tester-main.h"

#include "monitor/bt.h"
-#include "src/shared/util.h"

static char exec_dir[PATH_MAX + 1];

@@ -2247,6 +2246,29 @@ void tester_send_sdp_pdu(struct bthost *bthost, uint16_t handle, uint16_t cid,
g_free(sdp_buf);
}

+void tester_send_matching_pdu_resp(struct bthost *bthost, uint16_t handle,
+ uint16_t cid, const struct pdu_set *pdus,
+ const uint8_t *data, uint16_t data_len,
+ util_debug_func_t function)
+{
+ int i;
+
+ for (i = 0; pdus[i].req.data; i++) {
+ if (pdus[i].req.size != data_len)
+ continue;
+
+ if (memcmp(pdus[i].req.data, data, data_len))
+ continue;
+
+ if (function)
+ util_hexdump('<', pdus[i].rsp.data, pdus[i].rsp.size,
+ function, NULL);
+
+ bthost_send_cid(bthost, handle, cid, pdus[i].rsp.data,
+ pdus[i].rsp.size);
+ }
+}
+
static void generic_test_function(const void *test_data)
{
struct test_data *data = tester_get_data();
diff --git a/android/tester-main.h b/android/tester-main.h
index e0b1693..e39e75e 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -41,6 +41,7 @@
#include "src/shared/hciemu.h"
#include "src/shared/mgmt.h"
#include "src/shared/queue.h"
+#include "src/shared/util.h"

#include <hardware/hardware.h>
#include <hardware/audio.h>
@@ -60,6 +61,11 @@ struct pdu {
uint16_t size;
};

+struct pdu_set {
+ const struct pdu req;
+ const struct pdu rsp;
+};
+
#define raw_data(args...) ((const unsigned char[]) { args })

#define raw_pdu(args...) \
@@ -472,6 +478,10 @@ bool tester_match_sdp_pdu(const uint8_t *pdu, uint16_t len,
const struct pdu *match_pdu);
void tester_send_sdp_pdu(struct bthost *bthost, uint16_t handle, uint16_t cid,
uint16_t trans_id, const struct pdu *pdu);
+void tester_send_matching_pdu_resp(struct bthost *bthost, uint16_t handle,
+ uint16_t cid, const struct pdu_set *pdus,
+ const uint8_t *data, uint16_t data_len,
+ util_debug_func_t function);

/* Get, remove test cases API */
struct queue *get_bluetooth_tests(void);
--
1.9.3


2014-09-16 08:49:36

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 7/8] android/tester: Make avrcp use sdp pdu sending helper

This fixes any potential issues with the sdp response transaction id not
matching the request.
---
android/tester-avrcp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index 46c92e3..6beab7d 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -173,8 +173,8 @@ static void sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
struct emu_cid_data *cid_data = user_data;

- bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
- sdp_rsp_pdu.data, sdp_rsp_pdu.size);
+ tester_send_sdp_pdu(bthost, cid_data->handle, cid_data->cid,
+ get_be16(data + 1), &sdp_rsp_pdu);
}
static void sdp_connect_request_cb(uint16_t handle, uint16_t cid,
void *user_data)
--
1.9.3


2014-09-16 08:49:32

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 3/8] android/tester: Make A2DP tests use generic pdu struct

---
android/tester-a2dp.c | 66 +++++++++++++++++++++++++--------------------------
1 file changed, 32 insertions(+), 34 deletions(-)

diff --git a/android/tester-a2dp.c b/android/tester-a2dp.c
index ab3936e..7e06ec4 100644
--- a/android/tester-a2dp.c
+++ b/android/tester-a2dp.c
@@ -32,37 +32,35 @@ struct emu_cid_data {

static struct emu_cid_data cid_data;

-static const uint8_t req_dsc[] = { 0x00, 0x01 };
-static const uint8_t rsp_dsc[] = { 0x02, 0x01, 0x04, 0x08 };
-static const uint8_t req_get[] = { 0x10, 0x02, 0x04 };
-static const uint8_t rsp_get[] = { 0x12, 0x02, 0x01, 0x00, 0x07, 0x06, 0x00,
- 0x00, 0xff, 0xff, 0x02, 0x40 };
-static const uint8_t req_cfg[] = { 0x20, 0x03, 0x04, 0x04, 0x01, 0x00, 0x07,
- 0x06, 0x00, 0x00, 0x21, 0x15, 0x02,
- 0x40 };
-static const uint8_t rsp_cfg[] = { 0x22, 0x03 };
-static const uint8_t req_open[] = { 0x30, 0x06, 0x04 };
-static const uint8_t rsp_open[] = { 0x32, 0x06 };
-static const uint8_t req_close[] = { 0x40, 0x08, 0x04 };
-static const uint8_t rsp_close[] = { 0x42, 0x08 };
-static const uint8_t req_start[] = { 0x40, 0x07, 0x04 };
-static const uint8_t rsp_start[] = { 0x42, 0x07 };
-static const uint8_t req_suspend[] = { 0x50, 0x09, 0x04 };
-static const uint8_t rsp_suspend[] = { 0x52, 0x09 };
+#define req_dsc 0x00, 0x01
+#define rsp_dsc 0x02, 0x01, 0x04, 0x08
+#define req_get 0x10, 0x02, 0x04
+#define rsp_get 0x12, 0x02, 0x01, 0x00, 0x07, 0x06, 0x00, \
+ 0x00, 0xff, 0xff, 0x02, 0x40
+#define req_cfg 0x20, 0x03, 0x04, 0x04, 0x01, 0x00, 0x07, \
+ 0x06, 0x00, 0x00, 0x21, 0x15, 0x02, \
+ 0x40
+#define rsp_cfg 0x22, 0x03
+#define req_open 0x30, 0x06, 0x04
+#define rsp_open 0x32, 0x06
+#define req_close 0x40, 0x08, 0x04
+#define rsp_close 0x42, 0x08
+#define req_start 0x40, 0x07, 0x04
+#define rsp_start 0x42, 0x07
+#define req_suspend 0x50, 0x09, 0x04
+#define rsp_suspend 0x52, 0x09

const struct pdu_set {
- const uint8_t *req;
- size_t req_len;
- const uint8_t *rsp;
- size_t rsp_len;
+ struct pdu req;
+ struct pdu rsp;
} pdus[] = {
- { req_dsc, sizeof(req_dsc), rsp_dsc, sizeof(rsp_dsc) },
- { req_get, sizeof(req_get), rsp_get, sizeof(rsp_get) },
- { req_cfg, sizeof(req_cfg), rsp_cfg, sizeof(rsp_cfg) },
- { req_open, sizeof(req_open), rsp_open, sizeof(rsp_open) },
- { req_close, sizeof(req_close), rsp_close, sizeof(rsp_close) },
- { req_start, sizeof(req_start), rsp_start, sizeof(rsp_start) },
- { req_suspend, sizeof(req_suspend), rsp_suspend, sizeof(rsp_start) },
+ { raw_pdu(req_dsc), raw_pdu(rsp_dsc) },
+ { raw_pdu(req_get), raw_pdu(rsp_get) },
+ { raw_pdu(req_cfg), raw_pdu(rsp_cfg) },
+ { raw_pdu(req_open), raw_pdu(rsp_open) },
+ { raw_pdu(req_close), raw_pdu(rsp_close) },
+ { raw_pdu(req_start), raw_pdu(rsp_start) },
+ { raw_pdu(req_suspend), raw_pdu(rsp_suspend) },
{ },
};

@@ -80,18 +78,18 @@ static void a2dp_cid_hook_cb(const void *data, uint16_t len, void *user_data)

util_hexdump('>', data, len, print_data, NULL);

- for (i = 0; pdus[i].req; i++) {
- if (pdus[i].req_len != len)
+ for (i = 0; pdus[i].req.data; i++) {
+ if (pdus[i].req.size != len)
continue;

- if (memcmp(pdus[i].req, data, len))
+ if (memcmp(pdus[i].req.data, data, len))
continue;

- util_hexdump('<', pdus[i].rsp, pdus[i].rsp_len, print_data,
- NULL);
+ util_hexdump('<', pdus[i].rsp.data, pdus[i].rsp.size,
+ print_data, NULL);

bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
- pdus[i].rsp, pdus[i].rsp_len);
+ pdus[i].rsp.data, pdus[i].rsp.size);
}
}

--
1.9.3


2014-09-16 08:49:34

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 5/8] android/tester: Make HidHost tests use generic pdu struct

---
android/tester-hidhost.c | 41 +++++++++++++++++------------------------
1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index c7e3a67..0fe9c0a 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -21,6 +21,7 @@
#include "tester-main.h"

#include "android/utils.h"
+#include "src/shared/util.h"

#define HID_GET_REPORT_PROTOCOL 0x60
#define HID_GET_BOOT_PROTOCOL 0x61
@@ -59,14 +60,16 @@ struct emu_cid_data {

static struct emu_cid_data cid_data;

-static const uint8_t did_req_pdu[] = { 0x06, /* PDU id */
+static struct pdu did_req_pdu = raw_pdu(
+ 0x06, /* PDU id */
0x00, 0x00, /* Transaction id */
0x00, 0x0f, /* Req length */
0x35, 0x03, /* Attributes length */
0x19, 0x12, 0x00, 0xff, 0xff, 0x35, 0x05, 0x0a, 0x00,
- 0x00, 0xff, 0xff, 0x00 }; /* no continuation */
+ 0x00, 0xff, 0xff, 0x00); /* no continuation */

-static const uint8_t did_rsp_pdu[] = { 0x07, /* PDU id */
+static struct pdu did_rsp_pdu = raw_pdu(
+ 0x07, /* PDU id */
0x00, 0x00, /* Transaction id */
0x00, 0x4f, /* Response length */
0x00, 0x4c, /* Attributes length */
@@ -79,9 +82,10 @@ static const uint8_t did_rsp_pdu[] = { 0x07, /* PDU id */
0x02, 0x02, 0x09, 0x02, 0x46, 0x09, 0x02, 0x03, 0x09,
0x05, 0x0e, 0x09, 0x02, 0x04, 0x28, 0x01, 0x09, 0x02,
0x05, 0x09, 0x00, 0x02,
- 0x00 }; /* no continuation */
+ 0x00); /* no continuation */

-static const uint8_t hid_rsp_pdu[] = { 0x07, /* PDU id */
+static struct pdu hid_rsp_pdu = raw_pdu(
+ 0x07, /* PDU id */
0x00, 0x01, /* Transaction id */
0x01, 0x71, /* Response length */
0x01, 0x6E, /* Attributes length */
@@ -126,7 +130,7 @@ static const uint8_t hid_rsp_pdu[] = { 0x07, /* PDU id */
0x28, 0x01, 0x09, 0x02, 0x0b, 0x09, 0x01, 0x00, 0x09,
0x02, 0x0c, 0x09, 0x0c, 0x80, 0x09, 0x02, 0x0d, 0x28,
0x00, 0x09, 0x02, 0x0e, 0x28, 0x01,
- 0x00 }; /* no continuation */
+ 0x00); /* no continuation */

static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
@@ -134,14 +138,14 @@ static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
struct emu_cid_data *cid_data = user_data;

- if (!memcmp(did_req_pdu, data, len)) {
+ if (!memcmp(did_req_pdu.data, data, len)) {
bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
- did_rsp_pdu, sizeof(did_rsp_pdu));
+ did_rsp_pdu.data, did_rsp_pdu.size);
return;
}

bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
- hid_rsp_pdu, sizeof(hid_rsp_pdu));
+ hid_rsp_pdu.data, hid_rsp_pdu.size);
}
static void hid_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
{
@@ -159,31 +163,20 @@ static void hid_prepare_reply_protocol_mode(struct emu_cid_data *cid_data)
{
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- uint8_t pdu[2] = { 0, 0 };
- uint16_t pdu_len = 0;
-
- pdu_len = 2;
- pdu[0] = 0xa0;
- pdu[1] = 0x00;
+ const struct pdu pdu = raw_pdu(0xa0, 0x00);

bthost_send_cid(bthost, cid_data->ctrl_handle, cid_data->ctrl_cid,
- (void *)pdu, pdu_len);
+ pdu.data, pdu.size);
}

static void hid_prepare_reply_report(struct emu_cid_data *cid_data)
{
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- uint8_t pdu[3] = { 0, 0, 0 };
- uint16_t pdu_len = 0;
-
- pdu_len = 3;
- pdu[0] = 0xa2;
- pdu[1] = 0x01;
- pdu[2] = 0x00;
+ const struct pdu pdu = raw_pdu(0xa2, 0x01, 0x00);

bthost_send_cid(bthost, cid_data->ctrl_handle, cid_data->ctrl_cid,
- (void *)pdu, pdu_len);
+ pdu.data, pdu.size);
}

static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
--
1.9.3


2014-09-16 08:49:35

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 6/8] android/tester: Add helper functions for sending sdp responses

These are to help comparing and sending sdp data.
---
android/tester-main.c | 28 ++++++++++++++++++++++++++++
android/tester-main.h | 5 +++++
2 files changed, 33 insertions(+)

diff --git a/android/tester-main.c b/android/tester-main.c
index 385c00d..edbb35c 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -20,6 +20,7 @@
#include "tester-main.h"

#include "monitor/bt.h"
+#include "src/shared/util.h"

static char exec_dir[PATH_MAX + 1];

@@ -2219,6 +2220,33 @@ void set_default_ssp_request_handler(void)
schedule_action_verification(step);
}

+bool tester_match_sdp_pdu(const uint8_t *pdu, uint16_t len,
+ const struct pdu *match_pdu)
+{
+ if (match_pdu->size != len)
+ return false;
+
+ /* Verify PDU ID */
+ if (pdu[0] != match_pdu->data[0])
+ return false;
+
+ /* Skip the transaction id and verify data */
+ return !!!memcmp(pdu + 2, match_pdu + 2, match_pdu->size - 2);
+}
+
+void tester_send_sdp_pdu(struct bthost *bthost, uint16_t handle, uint16_t cid,
+ uint16_t trans_id, const struct pdu *pdu)
+{
+ uint8_t *sdp_buf;
+
+ /* overwrite transaction id */
+ sdp_buf = g_memdup(pdu->data, pdu->size);
+ put_be16(trans_id, sdp_buf + 1);
+
+ bthost_send_cid(bthost, handle, cid, sdp_buf, pdu->size);
+ g_free(sdp_buf);
+}
+
static void generic_test_function(const void *test_data)
{
struct test_data *data = tester_get_data();
diff --git a/android/tester-main.h b/android/tester-main.h
index 237242f..e0b1693 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -468,6 +468,11 @@ struct test_case {
const struct step *step;
};

+bool tester_match_sdp_pdu(const uint8_t *pdu, uint16_t len,
+ const struct pdu *match_pdu);
+void tester_send_sdp_pdu(struct bthost *bthost, uint16_t handle, uint16_t cid,
+ uint16_t trans_id, const struct pdu *pdu);
+
/* Get, remove test cases API */
struct queue *get_bluetooth_tests(void);
void remove_bluetooth_tests(void);
--
1.9.3


2014-09-16 08:49:33

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 4/8] android/tester: Make GATT tests use generic pdu struct

---
android/tester-gatt.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index 3b7297c..5defce0 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -120,8 +120,8 @@ static struct gatt_search_service_data search_services_1 = {
.filter_uuid = NULL,
};

-static const uint8_t exchange_mtu_req_pdu[] = { 0x02, 0xa0, 0x02 };
-static const uint8_t exchange_mtu_resp_pdu[] = { 0x03, 0xa0, 0x02 };
+static const struct pdu exchange_mtu_req_pdu = raw_pdu(0x02, 0xa0, 0x02);
+static const struct pdu exchange_mtu_resp_pdu = raw_pdu(0x03, 0xa0, 0x02);

static struct bt_action_data bearer_type = {
.bearer_type = BDADDR_LE_PUBLIC,
@@ -501,10 +501,10 @@ static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)
case L2CAP_ATT_EXCHANGE_MTU_REQ:
tester_print("Exchange MTU request received.");

- if (!memcmp(exchange_mtu_req_pdu, pdu, len))
+ if (!memcmp(exchange_mtu_req_pdu.data, pdu, len))
bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
- exchange_mtu_resp_pdu,
- sizeof(exchange_mtu_resp_pdu));
+ exchange_mtu_resp_pdu.data,
+ exchange_mtu_resp_pdu.size);

break;
case L2CAP_ATT_EXCHANGE_MTU_RSP:
--
1.9.3


2014-09-16 08:49:31

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 2/8] android/tester: Make AVRCP tests use generic pdu struct

---
android/tester-avrcp.c | 74 +++++++++++++++++++++++++-------------------------
1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index b539e0e..46c92e3 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -34,7 +34,8 @@ static struct emu_cid_data sdp_data;
static struct emu_cid_data a2dp_data;
static struct emu_cid_data avrcp_data;

-static const uint8_t sdp_rsp_pdu[] = { 0x07, /* PDU id */
+static struct pdu sdp_rsp_pdu = raw_pdu(
+ 0x07, /* PDU id */
0x00, 0x00, /* Transaction id */
0x00, 0x7f, /* Response length */
0x00, 0x7c, /* Attributes length */
@@ -52,38 +53,37 @@ static const uint8_t sdp_rsp_pdu[] = { 0x07, /* PDU id */
0x19, 0x00, 0x17, 0x09, 0x01, 0x03, 0x09, 0x00, 0x09,
0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x0e, 0x09, 0x01,
0x04, 0x09, 0x03, 0x11, 0x09, 0x00, 0x02,
- 0x00}; /* no continuation */
-static const uint8_t req_dsc[] = { 0x00, 0x01 };
-static const uint8_t rsp_dsc[] = { 0x02, 0x01, 0x04, 0x08 };
-static const uint8_t req_get[] = { 0x10, 0x02, 0x04 };
-static const uint8_t rsp_get[] = { 0x12, 0x02, 0x01, 0x00, 0x07, 0x06, 0x00,
- 0x00, 0xff, 0xff, 0x02, 0x40 };
-static const uint8_t req_cfg[] = { 0x20, 0x03, 0x04, 0x04, 0x01, 0x00, 0x07,
- 0x06, 0x00, 0x00, 0x21, 0x15, 0x02,
- 0x40 };
-static const uint8_t rsp_cfg[] = { 0x22, 0x03 };
-static const uint8_t req_open[] = { 0x30, 0x06, 0x04 };
-static const uint8_t rsp_open[] = { 0x32, 0x06 };
-static const uint8_t req_close[] = { 0x40, 0x08, 0x04 };
-static const uint8_t rsp_close[] = { 0x42, 0x08 };
-static const uint8_t req_start[] = { 0x40, 0x07, 0x04 };
-static const uint8_t rsp_start[] = { 0x42, 0x07 };
-static const uint8_t req_suspend[] = { 0x50, 0x09, 0x04 };
-static const uint8_t rsp_suspend[] = { 0x52, 0x09 };
+ 0x00); /* no continuation */
+
+#define req_dsc 0x00, 0x01
+#define rsp_dsc 0x02, 0x01, 0x04, 0x08
+#define req_get 0x10, 0x02, 0x04
+#define rsp_get 0x12, 0x02, 0x01, 0x00, 0x07, 0x06, 0x00, \
+ 0x00, 0xff, 0xff, 0x02, 0x40
+#define req_cfg 0x20, 0x03, 0x04, 0x04, 0x01, 0x00, 0x07, \
+ 0x06, 0x00, 0x00, 0x21, 0x15, 0x02, \
+ 0x40
+#define rsp_cfg 0x22, 0x03
+#define req_open 0x30, 0x06, 0x04
+#define rsp_open 0x32, 0x06
+#define req_close 0x40, 0x08, 0x04
+#define rsp_close 0x42, 0x08
+#define req_start 0x40, 0x07, 0x04
+#define rsp_start 0x42, 0x07
+#define req_suspend 0x50, 0x09, 0x04
+#define rsp_suspend 0x52, 0x09

static const struct pdu_set {
- const uint8_t *req;
- size_t req_len;
- const uint8_t *rsp;
- size_t rsp_len;
+ const struct pdu req;
+ const struct pdu rsp;
} pdus[] = {
- { req_dsc, sizeof(req_dsc), rsp_dsc, sizeof(rsp_dsc) },
- { req_get, sizeof(req_get), rsp_get, sizeof(rsp_get) },
- { req_cfg, sizeof(req_cfg), rsp_cfg, sizeof(rsp_cfg) },
- { req_open, sizeof(req_open), rsp_open, sizeof(rsp_open) },
- { req_close, sizeof(req_close), rsp_close, sizeof(rsp_close) },
- { req_start, sizeof(req_start), rsp_start, sizeof(rsp_start) },
- { req_suspend, sizeof(req_suspend), rsp_suspend, sizeof(rsp_start) },
+ { raw_pdu(req_dsc), raw_pdu(rsp_dsc)},
+ { raw_pdu(req_get), raw_pdu(rsp_get)},
+ { raw_pdu(req_cfg), raw_pdu(rsp_cfg)},
+ { raw_pdu(req_open), raw_pdu(rsp_open)},
+ { raw_pdu(req_close), raw_pdu(rsp_close)},
+ { raw_pdu(req_start), raw_pdu(rsp_start)},
+ { raw_pdu(req_suspend), raw_pdu(rsp_suspend)},
{ },
};

@@ -130,18 +130,18 @@ static void a2dp_cid_hook_cb(const void *data, uint16_t len, void *user_data)

util_hexdump('>', data, len, print_a2dp, NULL);

- for (i = 0; pdus[i].req; i++) {
- if (pdus[i].req_len != len)
+ for (i = 0; pdus[i].req.data; i++) {
+ if (pdus[i].req.size != len)
continue;

- if (memcmp(pdus[i].req, data, len))
+ if (memcmp(pdus[i].req.data, data, len))
continue;

- util_hexdump('<', pdus[i].rsp, pdus[i].rsp_len, print_a2dp,
- NULL);
+ util_hexdump('<', pdus[i].rsp.data, pdus[i].rsp.size,
+ print_a2dp, NULL);

bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
- pdus[i].rsp, pdus[i].rsp_len);
+ pdus[i].rsp.data, pdus[i].rsp.size);
}
}

@@ -174,7 +174,7 @@ static void sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
struct emu_cid_data *cid_data = user_data;

bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
- sdp_rsp_pdu, sizeof(sdp_rsp_pdu));
+ sdp_rsp_pdu.data, sdp_rsp_pdu.size);
}
static void sdp_connect_request_cb(uint16_t handle, uint16_t cid,
void *user_data)
--
1.9.3


2014-09-16 08:49:30

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 1/8] android/tester: Expose gatt-tester's pdu definition to other testers

This is not to reinvent this mechanism again for every tester that needs
to send raw pdu data.
---
android/tester-a2dp.c | 2 +-
android/tester-avrcp.c | 2 +-
android/tester-gatt.c | 15 ---------------
android/tester-main.h | 15 +++++++++++++++
4 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/android/tester-a2dp.c b/android/tester-a2dp.c
index 1b2a8ce..ab3936e 100644
--- a/android/tester-a2dp.c
+++ b/android/tester-a2dp.c
@@ -50,7 +50,7 @@ static const uint8_t rsp_start[] = { 0x42, 0x07 };
static const uint8_t req_suspend[] = { 0x50, 0x09, 0x04 };
static const uint8_t rsp_suspend[] = { 0x52, 0x09 };

-const struct pdu {
+const struct pdu_set {
const uint8_t *req;
size_t req_len;
const uint8_t *rsp;
diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index 07b95f5..b539e0e 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -71,7 +71,7 @@ static const uint8_t rsp_start[] = { 0x42, 0x07 };
static const uint8_t req_suspend[] = { 0x50, 0x09, 0x04 };
static const uint8_t rsp_suspend[] = { 0x52, 0x09 };

-static const struct pdu {
+static const struct pdu_set {
const uint8_t *req;
size_t req_len;
const uint8_t *rsp;
diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index f22cdae..3b7297c 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -33,23 +33,8 @@
#define CONN1_ID 1
#define CONN2_ID 2

-#define data(args...) ((const unsigned char[]) { args })
-
-#define raw_pdu(args...) \
- { \
- .data = data(args), \
- .size = sizeof(data(args)), \
- }
-
-#define end_pdu { .data = NULL }
-
static struct queue *list; /* List of gatt test cases */

-struct pdu {
- const uint8_t *data;
- uint16_t size;
-};
-
static bt_uuid_t client_app_uuid = {
.uu = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
diff --git a/android/tester-main.h b/android/tester-main.h
index 6f59330..237242f 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -55,6 +55,21 @@
#include <hardware/bt_gatt_client.h>
#include <hardware/bt_gatt_server.h>

+struct pdu {
+ const uint8_t *data;
+ uint16_t size;
+};
+
+#define raw_data(args...) ((const unsigned char[]) { args })
+
+#define raw_pdu(args...) \
+ { \
+ .data = raw_data(args), \
+ .size = sizeof(raw_data(args)), \
+ }
+
+#define end_pdu { .data = NULL }
+
#define TEST_CASE_BREDR(text, ...) { \
HCIEMU_TYPE_BREDR, \
text, \
--
1.9.3