2014-10-01 09:01:22

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 00/17] 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 and sending.

v3 changes:
* added one more patch replacing the pdu struct with iovec and making testers
use bthost's iovec specific API.
* minor include fix
* minor commit message correction

v2 changes:
* added generic hook and connect callback in tester-main for handling simple
cases when only pdu exchange is needed on given channel

Jakub Tyszkowski (17):
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: Make PAN tests use generic pdu struct
android/tester: Make HDP tests use generic pdu struct
android/tester: Expose pdu_set structure so it can be reused
android/tester: Add generic hook to handle pdu exchange
android/tester: Make A2DP use pdu exchange mechanism
android/tester: Make AVRCP tests use generic pdu exchange mechanism
android/tester: Make GATT use generic cid_data
android/tester: Make HDP tests use generic PDU exchange mechanism
android/tester: Make HIDHost tests use generic PDU exchange mechanism
android/tester: Make PAN use generic PDU exchange mechanism
android/tester: Use generic connect callback for simple cases
android/tester: Replace pdu struct with iovec

android/tester-a2dp.c | 109 +++++++--------------
android/tester-avrcp.c | 181 +++++++++++++----------------------
android/tester-gatt.c | 130 +++++++++++--------------
android/tester-hdp.c | 200 ++++++++++++++++-----------------------
android/tester-hidhost.c | 241 +++++++++++++++++++++--------------------------
android/tester-main.c | 61 ++++++++++++
android/tester-main.h | 28 ++++++
android/tester-pan.c | 45 +++------
8 files changed, 439 insertions(+), 556 deletions(-)

--
1.9.1



2014-10-02 07:18:07

by Jakub Tyszkowski

[permalink] [raw]
Subject: Re: [PATCHv3 17/17] android/tester: Replace pdu struct with iovec

Hi Luiz,

On 10/01/2014 02:37 PM, Luiz Augusto von Dentz wrote:
> Hi Jakub,
>
> On Wed, Oct 1, 2014 at 12:01 PM, Jakub Tyszkowski
> <[email protected]> wrote:
>> I/O vectors are now supported on bthost API.
>> ---
>> android/tester-gatt.c | 68 ++++++++++++++++++++++++------------------------
>> android/tester-hidhost.c | 10 +++----
>> android/tester-main.c | 25 ++++++++++--------
>> android/tester-main.h | 16 +++++-------
>> 4 files changed, 58 insertions(+), 61 deletions(-)
>>
>> diff --git a/android/tester-gatt.c b/android/tester-gatt.c
>> index 1460329..81ae257 100644
>> --- a/android/tester-gatt.c
>> +++ b/android/tester-gatt.c
>> @@ -137,8 +137,8 @@ static struct gatt_search_service_data search_services_1 = {
>> .filter_uuid = NULL,
>> };
>>
>> -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 const struct iovec exchange_mtu_req_pdu = raw_pdu(0x02, 0xa0, 0x02);
>> +static const struct iovec exchange_mtu_resp_pdu = raw_pdu(0x03, 0xa0, 0x02);
>>
>> static struct bt_action_data bearer_type = {
>> .bearer_type = BDADDR_LE_PUBLIC,
>> @@ -368,7 +368,7 @@ static struct set_write_params set_write_param_3 = {
>> .status = 0x01
>> };
>>
>> -static struct pdu search_service[] = {
>> +static struct iovec search_service[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -376,7 +376,7 @@ static struct pdu search_service[] = {
>> null_pdu
>> };
>>
>> -static struct pdu search_service_2[] = {
>> +static struct iovec search_service_2[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -386,13 +386,13 @@ static struct pdu search_service_2[] = {
>> null_pdu
>> };
>>
>> -static struct pdu search_service_3[] = {
>> +static struct iovec search_service_3[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
>> null_pdu
>> };
>>
>> -static struct pdu get_characteristic_1[] = {
>> +static struct iovec get_characteristic_1[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -404,7 +404,7 @@ static struct pdu get_characteristic_1[] = {
>> null_pdu
>> };
>>
>> -static struct pdu get_descriptor_1[] = {
>> +static struct iovec get_descriptor_1[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -420,7 +420,7 @@ static struct pdu get_descriptor_1[] = {
>> null_pdu
>> };
>>
>> -static struct pdu get_descriptor_2[] = {
>> +static struct iovec get_descriptor_2[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -436,7 +436,7 @@ static struct pdu get_descriptor_2[] = {
>> null_pdu
>> };
>>
>> -static struct pdu get_descriptor_3[] = {
>> +static struct iovec get_descriptor_3[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -450,7 +450,7 @@ static struct pdu get_descriptor_3[] = {
>> null_pdu
>> };
>>
>> -static struct pdu get_included_1[] = {
>> +static struct iovec get_included_1[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -462,7 +462,7 @@ static struct pdu get_included_1[] = {
>> null_pdu
>> };
>>
>> -static struct pdu get_included_2[] = {
>> +static struct iovec get_included_2[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -477,7 +477,7 @@ static struct pdu get_included_2[] = {
>> null_pdu
>> };
>>
>> -static struct pdu get_included_3[] = {
>> +static struct iovec get_included_3[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -487,7 +487,7 @@ static struct pdu get_included_3[] = {
>> null_pdu
>> };
>>
>> -static struct pdu read_characteristic_1[] = {
>> +static struct iovec read_characteristic_1[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -501,7 +501,7 @@ static struct pdu read_characteristic_1[] = {
>> null_pdu
>> };
>>
>> -static struct pdu read_characteristic_2[] = {
>> +static struct iovec read_characteristic_2[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -515,7 +515,7 @@ static struct pdu read_characteristic_2[] = {
>> null_pdu
>> };
>>
>> -static struct pdu read_descriptor_1[] = {
>> +static struct iovec read_descriptor_1[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -533,7 +533,7 @@ static struct pdu read_descriptor_1[] = {
>> null_pdu
>> };
>>
>> -static struct pdu read_descriptor_2[] = {
>> +static struct iovec read_descriptor_2[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -551,7 +551,7 @@ static struct pdu read_descriptor_2[] = {
>> null_pdu
>> };
>>
>> -static struct pdu write_characteristic_1[] = {
>> +static struct iovec write_characteristic_1[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -564,7 +564,7 @@ static struct pdu write_characteristic_1[] = {
>> null_pdu
>> };
>>
>> -static struct pdu write_characteristic_2[] = {
>> +static struct iovec write_characteristic_2[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -578,7 +578,7 @@ static struct pdu write_characteristic_2[] = {
>> null_pdu
>> };
>>
>> -static struct pdu write_characteristic_3[] = {
>> +static struct iovec write_characteristic_3[] = {
>> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
>> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
>> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
>> @@ -847,16 +847,16 @@ static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)
>> struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
>> struct emu_l2cap_cid_data *cid_data = user_data;
>> const uint8_t *pdu = data;
>> - struct pdu *gatt_pdu = queue_peek_head(t_data->pdus);
>> + struct iovec *gatt_pdu = queue_peek_head(t_data->pdus);
>>
>> switch (pdu[0]) {
>> case L2CAP_ATT_EXCHANGE_MTU_REQ:
>> tester_print("Exchange MTU request received.");
>>
>> - if (!memcmp(exchange_mtu_req_pdu.data, pdu, len))
>> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
>> - exchange_mtu_resp_pdu.data,
>> - exchange_mtu_resp_pdu.size);
>> + if (!memcmp(exchange_mtu_req_pdu.iov_base, pdu, len))
>> + bthost_send_cid_v(bthost, cid_data->handle,
>> + cid_data->cid,
>> + &exchange_mtu_resp_pdu, 1);
>>
>> break;
>> case L2CAP_ATT_EXCHANGE_MTU_RSP:
>> @@ -864,29 +864,29 @@ static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)
>>
>> break;
>> default:
>> - if (!gatt_pdu || !gatt_pdu->data) {
>> + if (!gatt_pdu || !gatt_pdu->iov_base) {
>> tester_print("Unknown ATT packet.");
>> break;
>> }
>>
>> - if (gatt_pdu->size != len) {
>> + if (gatt_pdu->iov_len != len) {
>> tester_print("Size of incoming frame is not valid");
>> - tester_print("Expected size = %d incoming size = %d",
>> - gatt_pdu->size, len);
>> + tester_print("Expected size = %zd incoming size = %d",
>> + gatt_pdu->iov_len, len);
>> break;
>> }
>>
>> - if (memcmp(gatt_pdu->data, data, len)) {
>> + if (memcmp(gatt_pdu->iov_base, data, len)) {
>> tester_print("Incoming data mismatch");
>> break;
>> }
>> queue_pop_head(t_data->pdus);
>> gatt_pdu = queue_pop_head(t_data->pdus);
>> - if (!gatt_pdu || !gatt_pdu->data)
>> + if (!gatt_pdu || !gatt_pdu->iov_base)
>> break;
>>
>> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
>> - gatt_pdu->data, gatt_pdu->size);
>> + bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid,
>> + gatt_pdu, 1);
>>
>> break;
>> }
>> @@ -933,9 +933,9 @@ static void init_pdus(void)
>> struct test_data *data = tester_get_data();
>> struct step *current_data_step = queue_peek_head(data->steps);
>> struct step *step = g_new0(struct step, 1);
>> - struct pdu *pdu = current_data_step->set_data;
>> + struct iovec *pdu = current_data_step->set_data;
>>
>> - while (pdu->data) {
>> + while (pdu->iov_base) {
>> queue_push_tail(data->pdus, pdu);
>> pdu++;
>> }
>> diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
>> index 4c8b4c6..a9d7bd9 100644
>> --- a/android/tester-hidhost.c
>> +++ b/android/tester-hidhost.c
>> @@ -139,20 +139,18 @@ static void hid_prepare_reply_protocol_mode(struct emu_l2cap_cid_data *cid_data)
>> {
>> struct test_data *t_data = tester_get_data();
>> struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
>> - const struct pdu pdu = raw_pdu(0xa0, 0x00);
>> + const struct iovec pdu = raw_pdu(0xa0, 0x00);
>>
>> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid, pdu.data,
>> - pdu.size);
>> + bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1);
>> }
>>
>> static void hid_prepare_reply_report(struct emu_l2cap_cid_data *cid_data)
>> {
>> struct test_data *t_data = tester_get_data();
>> struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
>> - const struct pdu pdu = raw_pdu(0xa2, 0x01, 0x00);
>> + const struct iovec pdu = raw_pdu(0xa2, 0x01, 0x00);
>>
>> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid, pdu.data,
>> - pdu.size);
>> + bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1);
>> }
>>
>> static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
>> diff --git a/android/tester-main.c b/android/tester-main.c
>> index c728f05..41abf6d 100644
>> --- a/android/tester-main.c
>> +++ b/android/tester-main.c
>> @@ -2141,27 +2141,30 @@ static void emu_generic_cid_hook_cb(const void *data, uint16_t len,
>> struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
>> int i;
>>
>> - for (i = 0; pdus[i].rsp.data; i++) {
>> - if (pdus[i].req.data) {
>> - if (pdus[i].req.size != len)
>> + for (i = 0; pdus[i].rsp.iov_base; i++) {
>> + if (pdus[i].req.iov_base) {
>> + if (pdus[i].req.iov_len != len)
>> continue;
>>
>> - if (memcmp(pdus[i].req.data, data, len))
>> + if (memcmp(pdus[i].req.iov_base, data, len))
>> continue;
>> }
>>
>> - if (pdus[i].rsp.data) {
>> + if (pdus[i].rsp.iov_base) {
>> /* overwrite transaction id if its sdp pdu */
>> if (cid_data->is_sdp) {
>> - pdus[i].rsp.data[1] = ((uint8_t *) data)[1];
>> - pdus[i].rsp.data[2] = ((uint8_t *) data)[2];
>> + ((uint8_t *) pdus[i].rsp.iov_base)[1] =
>> + ((uint8_t *) data)[1];
>> + ((uint8_t *) pdus[i].rsp.iov_base)[2] =
>> + ((uint8_t *) data)[2];
>> }
>>
>> - util_hexdump('>', pdus[i].rsp.data, pdus[i].rsp.size,
>> - print_data, NULL);
>> + util_hexdump('>', pdus[i].rsp.iov_base,
>> + pdus[i].rsp.iov_len, print_data, NULL);
>> +
>> + bthost_send_cid_v(bthost, cid_data->handle,
>> + cid_data->cid, &pdus[i].rsp, 1);
>>
>> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
>> - pdus[i].rsp.data, pdus[i].rsp.size);
>> }
>> }
>> }
>> diff --git a/android/tester-main.h b/android/tester-main.h
>> index 560277a..1b679d6 100644
>> --- a/android/tester-main.h
>> +++ b/android/tester-main.h
>> @@ -33,6 +33,7 @@
>> #include <sys/wait.h>
>> #include <libgen.h>
>> #include <sys/signalfd.h>
>> +#include <sys/uio.h>
>>
>> #include "lib/bluetooth.h"
>> #include "lib/mgmt.h"
>> @@ -56,25 +57,20 @@
>> #include <hardware/bt_gatt_client.h>
>> #include <hardware/bt_gatt_server.h>
>>
>> -struct pdu {
>> - uint8_t *data;
>> - uint16_t size;
>> -};
>> -
>> struct pdu_set {
>> - struct pdu req;
>> - struct pdu rsp;
>> + struct iovec req;
>> + struct iovec rsp;
>> };
>>
>> #define raw_data(args...) ((unsigned char[]) { args })
>>
>> #define raw_pdu(args...) \
>> { \
>> - .data = raw_data(args), \
>> - .size = sizeof(raw_data(args)), \
>> + .iov_base = raw_data(args), \
>> + .iov_len = sizeof(raw_data(args)), \
>> }
>>
>> -#define null_pdu { .data = NULL }
>> +#define null_pdu { .iov_base = NULL }
>>
>> #define TEST_CASE_BREDR(text, ...) { \
>> HCIEMU_TYPE_BREDR, \
>> --
>> 1.9.1
>
> I guess it would be beneficial to use bthost_send_cid_v since the
> beginning here, perhaps you didn't want to rebase the changes or found
> some problem while doing it. Normally what I would do is to rebase -i
> --exec make, then mark the patch to edit and let make catch the
> errors, it should really not take more than 30 min to rebase these.

I thought about it more like the one last step of simplification. And
yes, it was also a simpler way to achieve the same result.

I'll send V4 redone with iovecs from the start (and with const pdus).
And btw it took a bit more than 30 min. :)

>
>

Regards


2014-10-02 07:10:10

by Jakub Tyszkowski

[permalink] [raw]
Subject: Re: [PATCHv3 07/17] android/tester: Make HDP tests use generic pdu struct

Hi Luiz,

On 10/01/2014 02:21 PM, Luiz Augusto von Dentz wrote:
> Hi Jakub,
>
> On Wed, Oct 1, 2014 at 12:01 PM, Jakub Tyszkowski
> <[email protected]> wrote:
>> ---
>> android/tester-hdp.c | 11 ++++++-----
>> 1 file changed, 6 insertions(+), 5 deletions(-)
>>
>> diff --git a/android/tester-hdp.c b/android/tester-hdp.c
>> index 9ecef21..e81df71 100644
>> --- a/android/tester-hdp.c
>> +++ b/android/tester-hdp.c
>> @@ -184,7 +184,8 @@ static void hdp_unregister_app_action(void)
>> schedule_action_verification(step);
>> }
>>
>> -static uint8_t hdp_rsp_pdu[] = { 0x07, /* PDU id */
>> +static const struct pdu hdp_rsp_pdu = raw_pdu(
>> + 0x07, /* PDU id */
>> 0x00, 0x00, /* Transaction id */
>> 0x01, 0xc8, /* Response length */
>> 0x01, 0xc5, /* Attributes length */
>> @@ -239,7 +240,7 @@ static uint8_t hdp_rsp_pdu[] = { 0x07, /* PDU id */
>> 0x63, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x65,
>> 0x72, 0x0d, 0x09, 0x03, 0x01, 0x08, 0x01, 0x09, 0x03,
>> 0x02, 0x08, 0x00,
>> - 0x00 };
>> + 0x00);
>>
>> static void hdp_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
>> {
>> @@ -247,11 +248,11 @@ static void hdp_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;
>>
>> - hdp_rsp_pdu[1] = ((uint8_t *) data)[1];
>> - hdp_rsp_pdu[2] = ((uint8_t *) data)[2];
>> + hdp_rsp_pdu.data[1] = ((uint8_t *) data)[1];
>> + hdp_rsp_pdu.data[2] = ((uint8_t *) data)[2];
>
> I suppose we could use memcpy here, or in case of iovec you can
> actually send them separably them like this:
>
> struct iovec iov[2]
>
> iov[0].iov_base = data;
> iov[0].iov_len = 2;
>
> iov[1].iov_base = hdp_rsp_pdu.data + 2;
> iov[1].iov_len = hdp_rsp_pdu.size - 2;
>
> This way the variables can be const.

memcpy was the first solution I proposed when this pdu refactor was part
of some other patch set. At that time You suggested to make pdus non
const and overwrite transaction ID to avoid copying. :)
But I agree that with iovecs it will work with const pdus and without
copying. I'll fix that.

>
>> bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
>> - hdp_rsp_pdu, sizeof(hdp_rsp_pdu));
>> + hdp_rsp_pdu.data, hdp_rsp_pdu.size);
>> }
>>
>> static void hdp_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
>

Regards

2014-10-01 12:37:09

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCHv3 17/17] android/tester: Replace pdu struct with iovec

Hi Jakub,

On Wed, Oct 1, 2014 at 12:01 PM, Jakub Tyszkowski
<[email protected]> wrote:
> I/O vectors are now supported on bthost API.
> ---
> android/tester-gatt.c | 68 ++++++++++++++++++++++++------------------------
> android/tester-hidhost.c | 10 +++----
> android/tester-main.c | 25 ++++++++++--------
> android/tester-main.h | 16 +++++-------
> 4 files changed, 58 insertions(+), 61 deletions(-)
>
> diff --git a/android/tester-gatt.c b/android/tester-gatt.c
> index 1460329..81ae257 100644
> --- a/android/tester-gatt.c
> +++ b/android/tester-gatt.c
> @@ -137,8 +137,8 @@ static struct gatt_search_service_data search_services_1 = {
> .filter_uuid = NULL,
> };
>
> -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 const struct iovec exchange_mtu_req_pdu = raw_pdu(0x02, 0xa0, 0x02);
> +static const struct iovec exchange_mtu_resp_pdu = raw_pdu(0x03, 0xa0, 0x02);
>
> static struct bt_action_data bearer_type = {
> .bearer_type = BDADDR_LE_PUBLIC,
> @@ -368,7 +368,7 @@ static struct set_write_params set_write_param_3 = {
> .status = 0x01
> };
>
> -static struct pdu search_service[] = {
> +static struct iovec search_service[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -376,7 +376,7 @@ static struct pdu search_service[] = {
> null_pdu
> };
>
> -static struct pdu search_service_2[] = {
> +static struct iovec search_service_2[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -386,13 +386,13 @@ static struct pdu search_service_2[] = {
> null_pdu
> };
>
> -static struct pdu search_service_3[] = {
> +static struct iovec search_service_3[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
> null_pdu
> };
>
> -static struct pdu get_characteristic_1[] = {
> +static struct iovec get_characteristic_1[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -404,7 +404,7 @@ static struct pdu get_characteristic_1[] = {
> null_pdu
> };
>
> -static struct pdu get_descriptor_1[] = {
> +static struct iovec get_descriptor_1[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -420,7 +420,7 @@ static struct pdu get_descriptor_1[] = {
> null_pdu
> };
>
> -static struct pdu get_descriptor_2[] = {
> +static struct iovec get_descriptor_2[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -436,7 +436,7 @@ static struct pdu get_descriptor_2[] = {
> null_pdu
> };
>
> -static struct pdu get_descriptor_3[] = {
> +static struct iovec get_descriptor_3[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -450,7 +450,7 @@ static struct pdu get_descriptor_3[] = {
> null_pdu
> };
>
> -static struct pdu get_included_1[] = {
> +static struct iovec get_included_1[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -462,7 +462,7 @@ static struct pdu get_included_1[] = {
> null_pdu
> };
>
> -static struct pdu get_included_2[] = {
> +static struct iovec get_included_2[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -477,7 +477,7 @@ static struct pdu get_included_2[] = {
> null_pdu
> };
>
> -static struct pdu get_included_3[] = {
> +static struct iovec get_included_3[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -487,7 +487,7 @@ static struct pdu get_included_3[] = {
> null_pdu
> };
>
> -static struct pdu read_characteristic_1[] = {
> +static struct iovec read_characteristic_1[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -501,7 +501,7 @@ static struct pdu read_characteristic_1[] = {
> null_pdu
> };
>
> -static struct pdu read_characteristic_2[] = {
> +static struct iovec read_characteristic_2[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -515,7 +515,7 @@ static struct pdu read_characteristic_2[] = {
> null_pdu
> };
>
> -static struct pdu read_descriptor_1[] = {
> +static struct iovec read_descriptor_1[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -533,7 +533,7 @@ static struct pdu read_descriptor_1[] = {
> null_pdu
> };
>
> -static struct pdu read_descriptor_2[] = {
> +static struct iovec read_descriptor_2[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -551,7 +551,7 @@ static struct pdu read_descriptor_2[] = {
> null_pdu
> };
>
> -static struct pdu write_characteristic_1[] = {
> +static struct iovec write_characteristic_1[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -564,7 +564,7 @@ static struct pdu write_characteristic_1[] = {
> null_pdu
> };
>
> -static struct pdu write_characteristic_2[] = {
> +static struct iovec write_characteristic_2[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -578,7 +578,7 @@ static struct pdu write_characteristic_2[] = {
> null_pdu
> };
>
> -static struct pdu write_characteristic_3[] = {
> +static struct iovec write_characteristic_3[] = {
> raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
> raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
> raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
> @@ -847,16 +847,16 @@ static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)
> struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
> struct emu_l2cap_cid_data *cid_data = user_data;
> const uint8_t *pdu = data;
> - struct pdu *gatt_pdu = queue_peek_head(t_data->pdus);
> + struct iovec *gatt_pdu = queue_peek_head(t_data->pdus);
>
> switch (pdu[0]) {
> case L2CAP_ATT_EXCHANGE_MTU_REQ:
> tester_print("Exchange MTU request received.");
>
> - if (!memcmp(exchange_mtu_req_pdu.data, pdu, len))
> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
> - exchange_mtu_resp_pdu.data,
> - exchange_mtu_resp_pdu.size);
> + if (!memcmp(exchange_mtu_req_pdu.iov_base, pdu, len))
> + bthost_send_cid_v(bthost, cid_data->handle,
> + cid_data->cid,
> + &exchange_mtu_resp_pdu, 1);
>
> break;
> case L2CAP_ATT_EXCHANGE_MTU_RSP:
> @@ -864,29 +864,29 @@ static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)
>
> break;
> default:
> - if (!gatt_pdu || !gatt_pdu->data) {
> + if (!gatt_pdu || !gatt_pdu->iov_base) {
> tester_print("Unknown ATT packet.");
> break;
> }
>
> - if (gatt_pdu->size != len) {
> + if (gatt_pdu->iov_len != len) {
> tester_print("Size of incoming frame is not valid");
> - tester_print("Expected size = %d incoming size = %d",
> - gatt_pdu->size, len);
> + tester_print("Expected size = %zd incoming size = %d",
> + gatt_pdu->iov_len, len);
> break;
> }
>
> - if (memcmp(gatt_pdu->data, data, len)) {
> + if (memcmp(gatt_pdu->iov_base, data, len)) {
> tester_print("Incoming data mismatch");
> break;
> }
> queue_pop_head(t_data->pdus);
> gatt_pdu = queue_pop_head(t_data->pdus);
> - if (!gatt_pdu || !gatt_pdu->data)
> + if (!gatt_pdu || !gatt_pdu->iov_base)
> break;
>
> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
> - gatt_pdu->data, gatt_pdu->size);
> + bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid,
> + gatt_pdu, 1);
>
> break;
> }
> @@ -933,9 +933,9 @@ static void init_pdus(void)
> struct test_data *data = tester_get_data();
> struct step *current_data_step = queue_peek_head(data->steps);
> struct step *step = g_new0(struct step, 1);
> - struct pdu *pdu = current_data_step->set_data;
> + struct iovec *pdu = current_data_step->set_data;
>
> - while (pdu->data) {
> + while (pdu->iov_base) {
> queue_push_tail(data->pdus, pdu);
> pdu++;
> }
> diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
> index 4c8b4c6..a9d7bd9 100644
> --- a/android/tester-hidhost.c
> +++ b/android/tester-hidhost.c
> @@ -139,20 +139,18 @@ static void hid_prepare_reply_protocol_mode(struct emu_l2cap_cid_data *cid_data)
> {
> struct test_data *t_data = tester_get_data();
> struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
> - const struct pdu pdu = raw_pdu(0xa0, 0x00);
> + const struct iovec pdu = raw_pdu(0xa0, 0x00);
>
> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid, pdu.data,
> - pdu.size);
> + bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1);
> }
>
> static void hid_prepare_reply_report(struct emu_l2cap_cid_data *cid_data)
> {
> struct test_data *t_data = tester_get_data();
> struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
> - const struct pdu pdu = raw_pdu(0xa2, 0x01, 0x00);
> + const struct iovec pdu = raw_pdu(0xa2, 0x01, 0x00);
>
> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid, pdu.data,
> - pdu.size);
> + bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1);
> }
>
> static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
> diff --git a/android/tester-main.c b/android/tester-main.c
> index c728f05..41abf6d 100644
> --- a/android/tester-main.c
> +++ b/android/tester-main.c
> @@ -2141,27 +2141,30 @@ static void emu_generic_cid_hook_cb(const void *data, uint16_t len,
> struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
> int i;
>
> - for (i = 0; pdus[i].rsp.data; i++) {
> - if (pdus[i].req.data) {
> - if (pdus[i].req.size != len)
> + for (i = 0; pdus[i].rsp.iov_base; i++) {
> + if (pdus[i].req.iov_base) {
> + if (pdus[i].req.iov_len != len)
> continue;
>
> - if (memcmp(pdus[i].req.data, data, len))
> + if (memcmp(pdus[i].req.iov_base, data, len))
> continue;
> }
>
> - if (pdus[i].rsp.data) {
> + if (pdus[i].rsp.iov_base) {
> /* overwrite transaction id if its sdp pdu */
> if (cid_data->is_sdp) {
> - pdus[i].rsp.data[1] = ((uint8_t *) data)[1];
> - pdus[i].rsp.data[2] = ((uint8_t *) data)[2];
> + ((uint8_t *) pdus[i].rsp.iov_base)[1] =
> + ((uint8_t *) data)[1];
> + ((uint8_t *) pdus[i].rsp.iov_base)[2] =
> + ((uint8_t *) data)[2];
> }
>
> - util_hexdump('>', pdus[i].rsp.data, pdus[i].rsp.size,
> - print_data, NULL);
> + util_hexdump('>', pdus[i].rsp.iov_base,
> + pdus[i].rsp.iov_len, print_data, NULL);
> +
> + bthost_send_cid_v(bthost, cid_data->handle,
> + cid_data->cid, &pdus[i].rsp, 1);
>
> - bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
> - pdus[i].rsp.data, pdus[i].rsp.size);
> }
> }
> }
> diff --git a/android/tester-main.h b/android/tester-main.h
> index 560277a..1b679d6 100644
> --- a/android/tester-main.h
> +++ b/android/tester-main.h
> @@ -33,6 +33,7 @@
> #include <sys/wait.h>
> #include <libgen.h>
> #include <sys/signalfd.h>
> +#include <sys/uio.h>
>
> #include "lib/bluetooth.h"
> #include "lib/mgmt.h"
> @@ -56,25 +57,20 @@
> #include <hardware/bt_gatt_client.h>
> #include <hardware/bt_gatt_server.h>
>
> -struct pdu {
> - uint8_t *data;
> - uint16_t size;
> -};
> -
> struct pdu_set {
> - struct pdu req;
> - struct pdu rsp;
> + struct iovec req;
> + struct iovec rsp;
> };
>
> #define raw_data(args...) ((unsigned char[]) { args })
>
> #define raw_pdu(args...) \
> { \
> - .data = raw_data(args), \
> - .size = sizeof(raw_data(args)), \
> + .iov_base = raw_data(args), \
> + .iov_len = sizeof(raw_data(args)), \
> }
>
> -#define null_pdu { .data = NULL }
> +#define null_pdu { .iov_base = NULL }
>
> #define TEST_CASE_BREDR(text, ...) { \
> HCIEMU_TYPE_BREDR, \
> --
> 1.9.1

I guess it would be beneficial to use bthost_send_cid_v since the
beginning here, perhaps you didn't want to rebase the changes or found
some problem while doing it. Normally what I would do is to rebase -i
--exec make, then mark the patch to edit and let make catch the
errors, it should really not take more than 30 min to rebase these.


--
Luiz Augusto von Dentz

2014-10-01 12:21:53

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCHv3 07/17] android/tester: Make HDP tests use generic pdu struct

Hi Jakub,

On Wed, Oct 1, 2014 at 12:01 PM, Jakub Tyszkowski
<[email protected]> wrote:
> ---
> android/tester-hdp.c | 11 ++++++-----
> 1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/android/tester-hdp.c b/android/tester-hdp.c
> index 9ecef21..e81df71 100644
> --- a/android/tester-hdp.c
> +++ b/android/tester-hdp.c
> @@ -184,7 +184,8 @@ static void hdp_unregister_app_action(void)
> schedule_action_verification(step);
> }
>
> -static uint8_t hdp_rsp_pdu[] = { 0x07, /* PDU id */
> +static const struct pdu hdp_rsp_pdu = raw_pdu(
> + 0x07, /* PDU id */
> 0x00, 0x00, /* Transaction id */
> 0x01, 0xc8, /* Response length */
> 0x01, 0xc5, /* Attributes length */
> @@ -239,7 +240,7 @@ static uint8_t hdp_rsp_pdu[] = { 0x07, /* PDU id */
> 0x63, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x65,
> 0x72, 0x0d, 0x09, 0x03, 0x01, 0x08, 0x01, 0x09, 0x03,
> 0x02, 0x08, 0x00,
> - 0x00 };
> + 0x00);
>
> static void hdp_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
> {
> @@ -247,11 +248,11 @@ static void hdp_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;
>
> - hdp_rsp_pdu[1] = ((uint8_t *) data)[1];
> - hdp_rsp_pdu[2] = ((uint8_t *) data)[2];
> + hdp_rsp_pdu.data[1] = ((uint8_t *) data)[1];
> + hdp_rsp_pdu.data[2] = ((uint8_t *) data)[2];

I suppose we could use memcpy here, or in case of iovec you can
actually send them separably them like this:

struct iovec iov[2]

iov[0].iov_base = data;
iov[0].iov_len = 2;

iov[1].iov_base = hdp_rsp_pdu.data + 2;
iov[1].iov_len = hdp_rsp_pdu.size - 2;

This way the variables can be const.

> bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
> - hdp_rsp_pdu, sizeof(hdp_rsp_pdu));
> + hdp_rsp_pdu.data, hdp_rsp_pdu.size);
> }
>
> static void hdp_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html



--
Luiz Augusto von Dentz

2014-10-01 09:01:25

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 03/17] android/tester: Make A2DP tests use generic pdu struct

---
android/tester-a2dp.c | 68 +++++++++++++++++++++++++--------------------------
1 file changed, 33 insertions(+), 35 deletions(-)

diff --git a/android/tester-a2dp.c b/android/tester-a2dp.c
index ab3936e..047822e 100644
--- a/android/tester-a2dp.c
+++ b/android/tester-a2dp.c
@@ -32,38 +32,36 @@ 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) },
+ { null_pdu, null_pdu },
};

static void print_data(const char *str, void *user_data)
@@ -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.1


2014-10-01 09:01:35

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 13/17] android/tester: Make HDP tests use generic PDU exchange mechanism

sdp_pdus in not constant so that transaction ID can be overwritten
in-place every time SDP response is sent.
---
android/tester-hdp.c | 185 ++++++++++++++++++++++++---------------------------
1 file changed, 87 insertions(+), 98 deletions(-)

diff --git a/android/tester-hdp.c b/android/tester-hdp.c
index e81df71..f021943 100644
--- a/android/tester-hdp.c
+++ b/android/tester-hdp.c
@@ -28,16 +28,75 @@ typedef enum {
HDP_APP_SOURCE_STREAM,
} hdp_app_reg_type;

-struct emu_cid_data {
- uint16_t sdp_handle;
- uint16_t sdp_cid;
- uint16_t ctrl_handle;
- uint16_t ctrl_cid;
- uint16_t data_handle;
- uint16_t data_cid;
+#define hdp_rsp_pdu 0x07, \
+ 0x00, 0x00, \
+ 0x01, 0xc8, \
+ 0x01, 0xc5, \
+ 0x36, 0x01, 0xc2, 0x36, 0x01, 0xbf, 0x09, 0x00, 0x00, \
+ 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, \
+ 0x03, 0x19, 0x14, 0x01, 0x09, 0x00, 0x04, 0x35, 0x10, \
+ 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x10, 0x01, 0x35, \
+ 0x06, 0x19, 0x00, 0x1e, 0x09, 0x01, 0x00, 0x09, 0x00, \
+ 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x14, 0x00, 0x09, \
+ 0x01, 0x01, 0x09, 0x00, 0x0d, 0x35, 0x0f, 0x35, 0x0d, \
+ 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x10, 0x03, 0x35, \
+ 0x03, 0x19, 0x00, 0x1f, 0x09, 0x01, 0x00, 0x25, 0x03, \
+ 0x48, 0x44, 0x50, 0x09, 0x01, 0x01, 0x25, 0x28, 0x43, \
+ 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x64, \
+ 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x20, 0x61, \
+ 0x6e, 0x64, 0x20, 0x72, 0x65, 0x8b, 0x6c, 0x61, 0x79, \
+ 0x20, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x20, 0x64, \
+ 0x61, 0x74, 0x61, 0x09, 0x01, 0x02, 0x25, 0x0d, 0x42, \
+ 0x4c, 0x55, 0x45, 0x54, 0x4f, 0x4f, 0x54, 0x48, 0x20, \
+ 0x53, 0x49, 0x47, 0x09, 0x02, 0x00, 0x36, 0x01, 0x22, \
+ 0x35, 0x18, 0x08, 0x01, 0x09, 0x10, 0x04, 0x08, 0x00, \
+ 0x25, 0x0f, 0x50, 0x75, 0x6c, 0x73, 0x65, 0x20, 0x4f, \
+ 0x78, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, 0x35, \
+ 0x20, 0x08, 0x02, 0x09, 0x10, 0x07, 0x08, 0x00, 0x25, \
+ 0x17, 0x42, 0x6c, 0x6f, 0x6f, 0x64, 0x20, 0x50, 0x72, \
+ 0x65, 0x73, 0x73, 0x75, 0x72, 0x65, 0x20, 0x4d, 0x6f, \
+ 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x0d, 0x35, 0x1a, 0x08, \
+ 0x03, 0x09, 0x10, 0x08, 0x08, 0x00, 0x25, 0x11, 0x42, \
+ 0x6f, 0x64, 0x79, 0x20, 0x54, 0x68, 0x65, 0x72, 0x6d, \
+ 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, 0x35, 0x1e, \
+ 0x08, 0x04, 0x09, 0x10, 0x0f, 0x08, 0x00, 0x25, 0x15, \
+ 0x42, 0x6f, 0x64, 0x79, 0x20, 0x57, 0x65, 0x69, 0x67, \
+ 0x68, 0x74, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x09, \
+ 0x09, 0x09, 0x0d, 0x35, 0x17, 0x08, 0x05, 0x09, 0x10, \
+ 0x11, 0x08, 0x00, 0x25, 0x0e, 0x47, 0x6c, 0x75, 0x63, \
+ 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x65, 0x72, \
+ 0x0d, 0x35, 0x18, 0x08, 0x06, 0x09, 0x10, 0x04, 0x08, \
+ 0x01, 0x25, 0x0f, 0x50, 0x75, 0x6c, 0x73, 0x65, 0x20, \
+ 0x4f, 0x78, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, \
+ 0x35, 0x20, 0x08, 0x07, 0x09, 0x10, 0x07, 0x08, 0x01, \
+ 0x25, 0x17, 0x42, 0x6c, 0x6f, 0x6f, 0x64, 0x20, 0x50, \
+ 0x72, 0x65, 0x73, 0x73, 0x75, 0x72, 0x65, 0x20, 0x4d, \
+ 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x0d, 0x35, 0x1a, \
+ 0x08, 0x08, 0x09, 0x10, 0x08, 0x08, 0x01, 0x25, 0x11, \
+ 0x42, 0x6f, 0x64, 0x79, 0x20, 0x54, 0x68, 0x65, 0x72, \
+ 0x6d, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, 0x35, \
+ 0x1e, 0x08, 0x09, 0x09, 0x10, 0x0f, 0x08, 0x01, 0x25, \
+ 0x15, 0x42, 0x6f, 0x64, 0x79, 0x20, 0x57, 0x65, 0x69, \
+ 0x67, 0x68, 0x74, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65, \
+ 0x09, 0x09, 0x09, 0x0d, 0x35, 0x17, 0x08, 0x0a, 0x09, \
+ 0x10, 0x11, 0x08, 0x01, 0x25, 0x0e, 0x47, 0x6c, 0x75, \
+ 0x63, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x65, \
+ 0x72, 0x0d, 0x09, 0x03, 0x01, 0x08, 0x01, 0x09, 0x03, \
+ 0x02, 0x08, 0x00, \
+ 0x00
+
+static struct pdu_set sdp_pdus[] = {
+ { null_pdu, raw_pdu(hdp_rsp_pdu) },
+ { null_pdu, null_pdu },
};

-struct emu_cid_data cid_data;
+static struct emu_l2cap_cid_data sdp_cid_data = {
+ .pdu = sdp_pdus,
+ .is_sdp = TRUE,
+};
+
+static struct emu_l2cap_cid_data ctrl_cid_data;
+static struct emu_l2cap_cid_data data_cid_data;

static struct queue *list; /* List of hdp test cases */

@@ -184,87 +243,14 @@ static void hdp_unregister_app_action(void)
schedule_action_verification(step);
}

-static const struct pdu hdp_rsp_pdu = raw_pdu(
- 0x07, /* PDU id */
- 0x00, 0x00, /* Transaction id */
- 0x01, 0xc8, /* Response length */
- 0x01, 0xc5, /* Attributes length */
- 0x36, 0x01, 0xc2, 0x36, 0x01, 0xbf, 0x09, 0x00, 0x00,
- 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35,
- 0x03, 0x19, 0x14, 0x01, 0x09, 0x00, 0x04, 0x35, 0x10,
- 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x10, 0x01, 0x35,
- 0x06, 0x19, 0x00, 0x1e, 0x09, 0x01, 0x00, 0x09, 0x00,
- 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x14, 0x00, 0x09,
- 0x01, 0x01, 0x09, 0x00, 0x0d, 0x35, 0x0f, 0x35, 0x0d,
- 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x10, 0x03, 0x35,
- 0x03, 0x19, 0x00, 0x1f, 0x09, 0x01, 0x00, 0x25, 0x03,
- 0x48, 0x44, 0x50, 0x09, 0x01, 0x01, 0x25, 0x28, 0x43,
- 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x64,
- 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x20, 0x61,
- 0x6e, 0x64, 0x20, 0x72, 0x65, 0x8b, 0x6c, 0x61, 0x79,
- 0x20, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x20, 0x64,
- 0x61, 0x74, 0x61, 0x09, 0x01, 0x02, 0x25, 0x0d, 0x42,
- 0x4c, 0x55, 0x45, 0x54, 0x4f, 0x4f, 0x54, 0x48, 0x20,
- 0x53, 0x49, 0x47, 0x09, 0x02, 0x00, 0x36, 0x01, 0x22,
- 0x35, 0x18, 0x08, 0x01, 0x09, 0x10, 0x04, 0x08, 0x00,
- 0x25, 0x0f, 0x50, 0x75, 0x6c, 0x73, 0x65, 0x20, 0x4f,
- 0x78, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, 0x35,
- 0x20, 0x08, 0x02, 0x09, 0x10, 0x07, 0x08, 0x00, 0x25,
- 0x17, 0x42, 0x6c, 0x6f, 0x6f, 0x64, 0x20, 0x50, 0x72,
- 0x65, 0x73, 0x73, 0x75, 0x72, 0x65, 0x20, 0x4d, 0x6f,
- 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x0d, 0x35, 0x1a, 0x08,
- 0x03, 0x09, 0x10, 0x08, 0x08, 0x00, 0x25, 0x11, 0x42,
- 0x6f, 0x64, 0x79, 0x20, 0x54, 0x68, 0x65, 0x72, 0x6d,
- 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, 0x35, 0x1e,
- 0x08, 0x04, 0x09, 0x10, 0x0f, 0x08, 0x00, 0x25, 0x15,
- 0x42, 0x6f, 0x64, 0x79, 0x20, 0x57, 0x65, 0x69, 0x67,
- 0x68, 0x74, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x09,
- 0x09, 0x09, 0x0d, 0x35, 0x17, 0x08, 0x05, 0x09, 0x10,
- 0x11, 0x08, 0x00, 0x25, 0x0e, 0x47, 0x6c, 0x75, 0x63,
- 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x65, 0x72,
- 0x0d, 0x35, 0x18, 0x08, 0x06, 0x09, 0x10, 0x04, 0x08,
- 0x01, 0x25, 0x0f, 0x50, 0x75, 0x6c, 0x73, 0x65, 0x20,
- 0x4f, 0x78, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d,
- 0x35, 0x20, 0x08, 0x07, 0x09, 0x10, 0x07, 0x08, 0x01,
- 0x25, 0x17, 0x42, 0x6c, 0x6f, 0x6f, 0x64, 0x20, 0x50,
- 0x72, 0x65, 0x73, 0x73, 0x75, 0x72, 0x65, 0x20, 0x4d,
- 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x0d, 0x35, 0x1a,
- 0x08, 0x08, 0x09, 0x10, 0x08, 0x08, 0x01, 0x25, 0x11,
- 0x42, 0x6f, 0x64, 0x79, 0x20, 0x54, 0x68, 0x65, 0x72,
- 0x6d, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, 0x35,
- 0x1e, 0x08, 0x09, 0x09, 0x10, 0x0f, 0x08, 0x01, 0x25,
- 0x15, 0x42, 0x6f, 0x64, 0x79, 0x20, 0x57, 0x65, 0x69,
- 0x67, 0x68, 0x74, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65,
- 0x09, 0x09, 0x09, 0x0d, 0x35, 0x17, 0x08, 0x0a, 0x09,
- 0x10, 0x11, 0x08, 0x01, 0x25, 0x0e, 0x47, 0x6c, 0x75,
- 0x63, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x65,
- 0x72, 0x0d, 0x09, 0x03, 0x01, 0x08, 0x01, 0x09, 0x03,
- 0x02, 0x08, 0x00,
- 0x00);
-
-static void hdp_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
-{
- struct test_data *t_data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- struct emu_cid_data *cid_data = user_data;
-
- hdp_rsp_pdu.data[1] = ((uint8_t *) data)[1];
- hdp_rsp_pdu.data[2] = ((uint8_t *) data)[2];
-
- bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
- hdp_rsp_pdu.data, hdp_rsp_pdu.size);
-}
-
static void hdp_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct emu_l2cap_cid_data *cid_data = user_data;

- cid_data.sdp_handle = handle;
- cid_data.sdp_cid = cid;
+ cid_data->handle = handle;
+ cid_data->cid = cid;

- bthost_add_cid_hook(bthost, handle, cid, hdp_sdp_cid_hook_cb,
- &cid_data);
+ tester_handle_l2cap_data_exchange(cid_data);
}

static void mcap_ctrl_cid_hook_cb(const void *data, uint16_t len,
@@ -272,6 +258,7 @@ static void mcap_ctrl_cid_hook_cb(const void *data, uint16_t len,
{
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
+ struct emu_l2cap_cid_data *cid_data = user_data;
uint8_t crt_rsp[5], del_rsp[4], config;
uint8_t opcode = ((uint8_t *) data)[0];
static bool reliable = false;
@@ -296,8 +283,8 @@ static void mcap_ctrl_cid_hook_cb(const void *data, uint16_t len,
crt_rsp[4] = config;
}

- bthost_send_cid(bthost, cid_data.ctrl_handle,
- cid_data.ctrl_cid,
+ bthost_send_cid(bthost, cid_data->handle,
+ cid_data->cid,
crt_rsp, sizeof(crt_rsp));
break;
case 0x03: /* MD_RECONNECT_MDL_REQ */
@@ -308,8 +295,8 @@ static void mcap_ctrl_cid_hook_cb(const void *data, uint16_t len,
del_rsp[1] = 0x00; /* Response code - Success */
del_rsp[2] = ((uint8_t *) data)[1]; /* mdlid */
del_rsp[3] = ((uint8_t *) data)[2];
- bthost_send_cid(bthost, cid_data.ctrl_handle,
- cid_data.ctrl_cid,
+ bthost_send_cid(bthost, cid_data->handle,
+ cid_data->cid,
del_rsp, sizeof(del_rsp));
break;
}
@@ -319,12 +306,13 @@ static void mcap_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
{
struct test_data *data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct emu_l2cap_cid_data *cid_data = user_data;

- cid_data.ctrl_handle = handle;
- cid_data.ctrl_cid = cid;
+ cid_data->handle = handle;
+ cid_data->cid = cid;

bthost_add_cid_hook(bthost, handle, cid, mcap_ctrl_cid_hook_cb,
- &cid_data);
+ cid_data);
}

static void mcap_data_cid_hook_cb(const void *data, uint16_t len,
@@ -336,33 +324,34 @@ static void mcap_data_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
{
struct test_data *data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct emu_l2cap_cid_data *cid_data = user_data;

- cid_data.data_handle = handle;
- cid_data.data_cid = cid;
+ cid_data->handle = handle;
+ cid_data->cid = cid;

bthost_add_cid_hook(bthost, handle, cid, mcap_data_cid_hook_cb,
- &cid_data);
+ cid_data);
}

/* Emulate SDP (PSM = 1) */
static struct emu_set_l2cap_data l2cap_setup_sdp_data = {
.psm = 1,
.func = hdp_sdp_search_cb,
- .user_data = NULL,
+ .user_data = &sdp_cid_data,
};

/* Emulate Control Channel (PSM = 0x1001) */
static struct emu_set_l2cap_data l2cap_setup_cc_data = {
.psm = 0x1001,
.func = mcap_ctrl_connect_cb,
- .user_data = NULL,
+ .user_data = &ctrl_cid_data,
};

/* Emulate Data Channel (PSM = 0x1003) */
static struct emu_set_l2cap_data l2cap_setup_dc_data = {
.psm = 0x1003,
.func = mcap_data_connect_cb,
- .user_data = NULL,
+ .user_data = &data_cid_data,
};

static void hdp_connect_source_reliable_action(void)
--
1.9.1


2014-10-01 09:01:38

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 16/17] android/tester: Use generic connect callback for simple cases

This is usefull when no custom behavior and just simple pdu exchange
is needed.
---
android/tester-avrcp.c | 13 +------------
android/tester-hdp.c | 32 ++------------------------------
android/tester-hidhost.c | 12 +-----------
android/tester-main.c | 10 ++++++++++
android/tester-main.h | 1 +
android/tester-pan.c | 13 +------------
6 files changed, 16 insertions(+), 65 deletions(-)

diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index 4a49bb0..a2ceff6 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -138,20 +138,9 @@ static struct emu_set_l2cap_data a2dp_setup_data = {
.user_data = &a2dp_data,
};

-static void sdp_connect_request_cb(uint16_t handle, uint16_t cid,
- void *user_data)
-{
- struct emu_l2cap_cid_data *cid_data = user_data;
-
- cid_data->handle = handle;
- cid_data->cid = cid;
-
- tester_handle_l2cap_data_exchange(cid_data);
-}
-
static struct emu_set_l2cap_data sdp_setup_data = {
.psm = 1,
- .func = sdp_connect_request_cb,
+ .func = tester_generic_connect_cb,
.user_data = &sdp_data,
};

diff --git a/android/tester-hdp.c b/android/tester-hdp.c
index f021943..c9c5a78 100644
--- a/android/tester-hdp.c
+++ b/android/tester-hdp.c
@@ -243,16 +243,6 @@ static void hdp_unregister_app_action(void)
schedule_action_verification(step);
}

-static void hdp_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
-{
- struct emu_l2cap_cid_data *cid_data = user_data;
-
- cid_data->handle = handle;
- cid_data->cid = cid;
-
- tester_handle_l2cap_data_exchange(cid_data);
-}
-
static void mcap_ctrl_cid_hook_cb(const void *data, uint16_t len,
void *user_data)
{
@@ -315,28 +305,10 @@ static void mcap_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
cid_data);
}

-static void mcap_data_cid_hook_cb(const void *data, uint16_t len,
- void *user_data)
-{
-}
-
-static void mcap_data_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
-{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
- struct emu_l2cap_cid_data *cid_data = user_data;
-
- cid_data->handle = handle;
- cid_data->cid = cid;
-
- bthost_add_cid_hook(bthost, handle, cid, mcap_data_cid_hook_cb,
- cid_data);
-}
-
/* Emulate SDP (PSM = 1) */
static struct emu_set_l2cap_data l2cap_setup_sdp_data = {
.psm = 1,
- .func = hdp_sdp_search_cb,
+ .func = tester_generic_connect_cb,
.user_data = &sdp_cid_data,
};

@@ -350,7 +322,7 @@ static struct emu_set_l2cap_data l2cap_setup_cc_data = {
/* Emulate Data Channel (PSM = 0x1003) */
static struct emu_set_l2cap_data l2cap_setup_dc_data = {
.psm = 0x1003,
- .func = mcap_data_connect_cb,
+ .func = tester_generic_connect_cb,
.user_data = &data_cid_data,
};

diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index 9ee026a..4c8b4c6 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -135,16 +135,6 @@ static struct emu_l2cap_cid_data sdp_cid_data = {
static struct emu_l2cap_cid_data ctrl_cid_data;
static struct emu_l2cap_cid_data intr_cid_data;

-static void hid_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
-{
- struct emu_l2cap_cid_data *cid_data = user_data;
-
- cid_data->handle = handle;
- cid_data->cid = cid;
-
- tester_handle_l2cap_data_exchange(cid_data);
-}
-
static void hid_prepare_reply_protocol_mode(struct emu_l2cap_cid_data *cid_data)
{
struct test_data *t_data = tester_get_data();
@@ -247,7 +237,7 @@ static void hid_intr_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
/* Emulate SDP (PSM = 1) */
static struct emu_set_l2cap_data l2cap_setup_sdp_data = {
.psm = 1,
- .func = hid_sdp_search_cb,
+ .func = tester_generic_connect_cb,
.user_data = &sdp_cid_data,
};

diff --git a/android/tester-main.c b/android/tester-main.c
index 0152374..c728f05 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -2175,6 +2175,16 @@ void tester_handle_l2cap_data_exchange(struct emu_l2cap_cid_data *cid_data)
emu_generic_cid_hook_cb, cid_data);
}

+void tester_generic_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
+{
+ struct emu_l2cap_cid_data *cid_data = user_data;
+
+ cid_data->handle = handle;
+ cid_data->cid = cid;
+
+ tester_handle_l2cap_data_exchange(cid_data);
+}
+
static void rfcomm_connect_cb(uint16_t handle, uint16_t cid, void *user_data,
bool status)
{
diff --git a/android/tester-main.h b/android/tester-main.h
index 8c619da..560277a 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -516,6 +516,7 @@ struct test_case {
};

void tester_handle_l2cap_data_exchange(struct emu_l2cap_cid_data *cid_data);
+void tester_generic_connect_cb(uint16_t handle, uint16_t cid, void *user_data);

/* Get, remove test cases API */
struct queue *get_bluetooth_tests(void);
diff --git a/android/tester-pan.c b/android/tester-pan.c
index 503b9ed..4c9354a 100644
--- a/android/tester-pan.c
+++ b/android/tester-pan.c
@@ -35,20 +35,9 @@ static struct emu_l2cap_cid_data cid_data = {
.pdu = pdus,
};

-static void pan_connect_request_cb(uint16_t handle, uint16_t cid,
- void *user_data)
-{
- struct emu_l2cap_cid_data *cid_data = user_data;
-
- cid_data->handle = handle;
- cid_data->cid = cid;
-
- tester_handle_l2cap_data_exchange(cid_data);
-}
-
static struct emu_set_l2cap_data l2cap_setup_data = {
.psm = 15,
- .func = pan_connect_request_cb,
+ .func = tester_generic_connect_cb,
.user_data = &cid_data,
};

--
1.9.1


2014-10-01 09:01:39

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 17/17] android/tester: Replace pdu struct with iovec

I/O vectors are now supported on bthost API.
---
android/tester-gatt.c | 68 ++++++++++++++++++++++++------------------------
android/tester-hidhost.c | 10 +++----
android/tester-main.c | 25 ++++++++++--------
android/tester-main.h | 16 +++++-------
4 files changed, 58 insertions(+), 61 deletions(-)

diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index 1460329..81ae257 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -137,8 +137,8 @@ static struct gatt_search_service_data search_services_1 = {
.filter_uuid = NULL,
};

-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 const struct iovec exchange_mtu_req_pdu = raw_pdu(0x02, 0xa0, 0x02);
+static const struct iovec exchange_mtu_resp_pdu = raw_pdu(0x03, 0xa0, 0x02);

static struct bt_action_data bearer_type = {
.bearer_type = BDADDR_LE_PUBLIC,
@@ -368,7 +368,7 @@ static struct set_write_params set_write_param_3 = {
.status = 0x01
};

-static struct pdu search_service[] = {
+static struct iovec search_service[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -376,7 +376,7 @@ static struct pdu search_service[] = {
null_pdu
};

-static struct pdu search_service_2[] = {
+static struct iovec search_service_2[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -386,13 +386,13 @@ static struct pdu search_service_2[] = {
null_pdu
};

-static struct pdu search_service_3[] = {
+static struct iovec search_service_3[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
null_pdu
};

-static struct pdu get_characteristic_1[] = {
+static struct iovec get_characteristic_1[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -404,7 +404,7 @@ static struct pdu get_characteristic_1[] = {
null_pdu
};

-static struct pdu get_descriptor_1[] = {
+static struct iovec get_descriptor_1[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -420,7 +420,7 @@ static struct pdu get_descriptor_1[] = {
null_pdu
};

-static struct pdu get_descriptor_2[] = {
+static struct iovec get_descriptor_2[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -436,7 +436,7 @@ static struct pdu get_descriptor_2[] = {
null_pdu
};

-static struct pdu get_descriptor_3[] = {
+static struct iovec get_descriptor_3[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -450,7 +450,7 @@ static struct pdu get_descriptor_3[] = {
null_pdu
};

-static struct pdu get_included_1[] = {
+static struct iovec get_included_1[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -462,7 +462,7 @@ static struct pdu get_included_1[] = {
null_pdu
};

-static struct pdu get_included_2[] = {
+static struct iovec get_included_2[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -477,7 +477,7 @@ static struct pdu get_included_2[] = {
null_pdu
};

-static struct pdu get_included_3[] = {
+static struct iovec get_included_3[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -487,7 +487,7 @@ static struct pdu get_included_3[] = {
null_pdu
};

-static struct pdu read_characteristic_1[] = {
+static struct iovec read_characteristic_1[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -501,7 +501,7 @@ static struct pdu read_characteristic_1[] = {
null_pdu
};

-static struct pdu read_characteristic_2[] = {
+static struct iovec read_characteristic_2[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -515,7 +515,7 @@ static struct pdu read_characteristic_2[] = {
null_pdu
};

-static struct pdu read_descriptor_1[] = {
+static struct iovec read_descriptor_1[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -533,7 +533,7 @@ static struct pdu read_descriptor_1[] = {
null_pdu
};

-static struct pdu read_descriptor_2[] = {
+static struct iovec read_descriptor_2[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -551,7 +551,7 @@ static struct pdu read_descriptor_2[] = {
null_pdu
};

-static struct pdu write_characteristic_1[] = {
+static struct iovec write_characteristic_1[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -564,7 +564,7 @@ static struct pdu write_characteristic_1[] = {
null_pdu
};

-static struct pdu write_characteristic_2[] = {
+static struct iovec write_characteristic_2[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -578,7 +578,7 @@ static struct pdu write_characteristic_2[] = {
null_pdu
};

-static struct pdu write_characteristic_3[] = {
+static struct iovec write_characteristic_3[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
@@ -847,16 +847,16 @@ static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
struct emu_l2cap_cid_data *cid_data = user_data;
const uint8_t *pdu = data;
- struct pdu *gatt_pdu = queue_peek_head(t_data->pdus);
+ struct iovec *gatt_pdu = queue_peek_head(t_data->pdus);

switch (pdu[0]) {
case L2CAP_ATT_EXCHANGE_MTU_REQ:
tester_print("Exchange MTU request received.");

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

break;
case L2CAP_ATT_EXCHANGE_MTU_RSP:
@@ -864,29 +864,29 @@ static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)

break;
default:
- if (!gatt_pdu || !gatt_pdu->data) {
+ if (!gatt_pdu || !gatt_pdu->iov_base) {
tester_print("Unknown ATT packet.");
break;
}

- if (gatt_pdu->size != len) {
+ if (gatt_pdu->iov_len != len) {
tester_print("Size of incoming frame is not valid");
- tester_print("Expected size = %d incoming size = %d",
- gatt_pdu->size, len);
+ tester_print("Expected size = %zd incoming size = %d",
+ gatt_pdu->iov_len, len);
break;
}

- if (memcmp(gatt_pdu->data, data, len)) {
+ if (memcmp(gatt_pdu->iov_base, data, len)) {
tester_print("Incoming data mismatch");
break;
}
queue_pop_head(t_data->pdus);
gatt_pdu = queue_pop_head(t_data->pdus);
- if (!gatt_pdu || !gatt_pdu->data)
+ if (!gatt_pdu || !gatt_pdu->iov_base)
break;

- bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
- gatt_pdu->data, gatt_pdu->size);
+ bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid,
+ gatt_pdu, 1);

break;
}
@@ -933,9 +933,9 @@ static void init_pdus(void)
struct test_data *data = tester_get_data();
struct step *current_data_step = queue_peek_head(data->steps);
struct step *step = g_new0(struct step, 1);
- struct pdu *pdu = current_data_step->set_data;
+ struct iovec *pdu = current_data_step->set_data;

- while (pdu->data) {
+ while (pdu->iov_base) {
queue_push_tail(data->pdus, pdu);
pdu++;
}
diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index 4c8b4c6..a9d7bd9 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -139,20 +139,18 @@ static void hid_prepare_reply_protocol_mode(struct emu_l2cap_cid_data *cid_data)
{
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- const struct pdu pdu = raw_pdu(0xa0, 0x00);
+ const struct iovec pdu = raw_pdu(0xa0, 0x00);

- bthost_send_cid(bthost, cid_data->handle, cid_data->cid, pdu.data,
- pdu.size);
+ bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1);
}

static void hid_prepare_reply_report(struct emu_l2cap_cid_data *cid_data)
{
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- const struct pdu pdu = raw_pdu(0xa2, 0x01, 0x00);
+ const struct iovec pdu = raw_pdu(0xa2, 0x01, 0x00);

- bthost_send_cid(bthost, cid_data->handle, cid_data->cid, pdu.data,
- pdu.size);
+ bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1);
}

static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
diff --git a/android/tester-main.c b/android/tester-main.c
index c728f05..41abf6d 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -2141,27 +2141,30 @@ static void emu_generic_cid_hook_cb(const void *data, uint16_t len,
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
int i;

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

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

- if (pdus[i].rsp.data) {
+ if (pdus[i].rsp.iov_base) {
/* overwrite transaction id if its sdp pdu */
if (cid_data->is_sdp) {
- pdus[i].rsp.data[1] = ((uint8_t *) data)[1];
- pdus[i].rsp.data[2] = ((uint8_t *) data)[2];
+ ((uint8_t *) pdus[i].rsp.iov_base)[1] =
+ ((uint8_t *) data)[1];
+ ((uint8_t *) pdus[i].rsp.iov_base)[2] =
+ ((uint8_t *) data)[2];
}

- util_hexdump('>', pdus[i].rsp.data, pdus[i].rsp.size,
- print_data, NULL);
+ util_hexdump('>', pdus[i].rsp.iov_base,
+ pdus[i].rsp.iov_len, print_data, NULL);
+
+ bthost_send_cid_v(bthost, cid_data->handle,
+ cid_data->cid, &pdus[i].rsp, 1);

- bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
- pdus[i].rsp.data, pdus[i].rsp.size);
}
}
}
diff --git a/android/tester-main.h b/android/tester-main.h
index 560277a..1b679d6 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -33,6 +33,7 @@
#include <sys/wait.h>
#include <libgen.h>
#include <sys/signalfd.h>
+#include <sys/uio.h>

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -56,25 +57,20 @@
#include <hardware/bt_gatt_client.h>
#include <hardware/bt_gatt_server.h>

-struct pdu {
- uint8_t *data;
- uint16_t size;
-};
-
struct pdu_set {
- struct pdu req;
- struct pdu rsp;
+ struct iovec req;
+ struct iovec rsp;
};

#define raw_data(args...) ((unsigned char[]) { args })

#define raw_pdu(args...) \
{ \
- .data = raw_data(args), \
- .size = sizeof(raw_data(args)), \
+ .iov_base = raw_data(args), \
+ .iov_len = sizeof(raw_data(args)), \
}

-#define null_pdu { .data = NULL }
+#define null_pdu { .iov_base = NULL }

#define TEST_CASE_BREDR(text, ...) { \
HCIEMU_TYPE_BREDR, \
--
1.9.1


2014-10-01 09:01:31

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 09/17] android/tester: Add generic hook to handle pdu exchange

This allows tester-main to register hooks for certain CID to
automatically perform pdu exchange by registering array of pdu pairs
(request_pdu, response_pdu). When null_pdu is used instead of
request_pdu, response is sent immediately without incoming pdu
verification.

This callback can also handle sdp request<->response with automaticaly
overwriting the transaction ID inside the response pdu to match the one
from request.

'emu_l2cap_cid_data' is used to pass tha appropriate data to the hook
mechanism. It is similar to 'emu_cid_data" used in other testers and
eventually will replace those.
---
android/tester-a2dp.c | 1 -
android/tester-avrcp.c | 1 -
android/tester-gatt.c | 1 -
android/tester-main.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
android/tester-main.h | 11 +++++++++++
5 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/android/tester-a2dp.c b/android/tester-a2dp.c
index e12844e..59384f9 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"
diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index 13ffd74..647c0fd 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"
diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index f182c56..6898935 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-main.c b/android/tester-main.c
index 5bf9096..0152374 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -2127,6 +2127,54 @@ void emu_add_l2cap_server_action(void)
schedule_action_verification(step);
}

+static void print_data(const char *str, void *user_data)
+{
+ tester_debug("tester: %s", str);
+}
+
+static void emu_generic_cid_hook_cb(const void *data, uint16_t len,
+ void *user_data)
+{
+ struct test_data *t_data = tester_get_data();
+ struct emu_l2cap_cid_data *cid_data = user_data;
+ struct pdu_set *pdus = cid_data->pdu;
+ struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
+ int i;
+
+ for (i = 0; pdus[i].rsp.data; i++) {
+ if (pdus[i].req.data) {
+ if (pdus[i].req.size != len)
+ continue;
+
+ if (memcmp(pdus[i].req.data, data, len))
+ continue;
+ }
+
+ if (pdus[i].rsp.data) {
+ /* overwrite transaction id if its sdp pdu */
+ if (cid_data->is_sdp) {
+ pdus[i].rsp.data[1] = ((uint8_t *) data)[1];
+ pdus[i].rsp.data[2] = ((uint8_t *) data)[2];
+ }
+
+ 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);
+ }
+ }
+}
+
+void tester_handle_l2cap_data_exchange(struct emu_l2cap_cid_data *cid_data)
+{
+ struct test_data *t_data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
+
+ bthost_add_cid_hook(bthost, cid_data->handle, cid_data->cid,
+ emu_generic_cid_hook_cb, cid_data);
+}
+
static void rfcomm_connect_cb(uint16_t handle, uint16_t cid, void *user_data,
bool status)
{
diff --git a/android/tester-main.h b/android/tester-main.h
index 3484c3e..8c619da 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -40,6 +40,7 @@
#include "src/shared/tester.h"
#include "src/shared/mgmt.h"
#include "src/shared/queue.h"
+#include "src/shared/util.h"
#include "emulator/hciemu.h"

#include <hardware/hardware.h>
@@ -444,6 +445,14 @@ struct emu_set_l2cap_data {
void *user_data;
};

+struct emu_l2cap_cid_data {
+ struct pdu_set *pdu;
+
+ uint16_t handle;
+ uint16_t cid;
+ bool is_sdp;
+};
+
/*
* Callback data structure should be enhanced with data
* returned by callbacks. It's used for test case step
@@ -506,6 +515,8 @@ struct test_case {
const struct step *step;
};

+void tester_handle_l2cap_data_exchange(struct emu_l2cap_cid_data *cid_data);
+
/* Get, remove test cases API */
struct queue *get_bluetooth_tests(void);
void remove_bluetooth_tests(void);
--
1.9.1


2014-10-01 09:01:37

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 15/17] android/tester: Make PAN use generic PDU exchange mechanism

sdp_pdus is not constatnt as transaction ID is overwritten every time
SDP response is sent.
---
android/tester-pan.c | 40 ++++++++++++++--------------------------
1 file changed, 14 insertions(+), 26 deletions(-)

diff --git a/android/tester-pan.c b/android/tester-pan.c
index dfc8c04..503b9ed 100644
--- a/android/tester-pan.c
+++ b/android/tester-pan.c
@@ -23,45 +23,33 @@

static struct queue *list; /* List of pan test cases */

-struct emu_cid_data {
- uint16_t nap_handle;
- uint16_t nap_cid;
-};
+#define pan_conn_req_pdu 0x01, 0x01, 0x02, 0x11, 0x16, 0x11, 0x15
+#define pan_conn_rsp_pdu 0x01, 0x02, 0x00, 0x00

-static struct emu_cid_data cid_data;
-static const struct pdu pan_conn_req_pdu = raw_pdu(0x01, 0x01, 0x02, 0x11, 0x16,
- 0x11, 0x15);
-static const struct pdu pan_conn_rsp_pdu = raw_pdu(0x01, 0x02, 0x00, 0x00);
+static struct pdu_set pdus[] = {
+ { raw_pdu(pan_conn_req_pdu), raw_pdu(pan_conn_rsp_pdu) },
+ { null_pdu, null_pdu },
+};

-static void pan_nap_cid_hook_cb(const void *data, uint16_t len, void *user_data)
-{
- struct test_data *t_data = tester_get_data();
- struct emu_cid_data *cid_data = user_data;
- struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
-
- if (!memcmp((uint8_t *) data, pan_conn_req_pdu.data,
- pan_conn_req_pdu.size))
- bthost_send_cid(bthost, cid_data->nap_handle, cid_data->nap_cid,
- pan_conn_rsp_pdu.data, pan_conn_rsp_pdu.size);
-}
+static struct emu_l2cap_cid_data cid_data = {
+ .pdu = pdus,
+};

static void pan_connect_request_cb(uint16_t handle, uint16_t cid,
void *user_data)
{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct emu_l2cap_cid_data *cid_data = user_data;

- cid_data.nap_handle = handle;
- cid_data.nap_cid = cid;
+ cid_data->handle = handle;
+ cid_data->cid = cid;

- bthost_add_cid_hook(bthost, handle, cid, pan_nap_cid_hook_cb,
- &cid_data);
+ tester_handle_l2cap_data_exchange(cid_data);
}

static struct emu_set_l2cap_data l2cap_setup_data = {
.psm = 15,
.func = pan_connect_request_cb,
- .user_data = NULL,
+ .user_data = &cid_data,
};

static void pan_connect_action(void)
--
1.9.1


2014-10-01 09:01:36

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 14/17] android/tester: Make HIDHost tests use generic PDU exchange mechanism

sdp_pdus is not constant as transaction ID os overwritten every time SDP
response is sent.
---
android/tester-hidhost.c | 227 ++++++++++++++++++++++-------------------------
1 file changed, 108 insertions(+), 119 deletions(-)

diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index 6f524f2..9ee026a 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -45,143 +45,130 @@

static struct queue *list; /* List of hidhost test cases */

-struct emu_cid_data {
- const int pdu_len;
- const void *pdu;
-
- uint16_t sdp_handle;
- uint16_t sdp_cid;
- uint16_t ctrl_handle;
- uint16_t ctrl_cid;
- uint16_t intr_handle;
- uint16_t intr_cid;
+#define did_req_pdu 0x06, \
+ 0x00, 0x00, \
+ 0x00, 0x0f, \
+ 0x35, 0x03, \
+ 0x19, 0x12, 0x00, 0xff, 0xff, 0x35, 0x05, 0x0a, 0x00, \
+ 0x00, 0xff, 0xff, 0x00
+
+#define did_rsp_pdu 0x07, \
+ 0x00, 0x00, \
+ 0x00, 0x4f, \
+ 0x00, 0x4c, \
+ 0x35, 0x4a, 0x35, 0x48, 0x09, 0x00, 0x00, 0x0a, 0x00, \
+ 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, \
+ 0x12, 0x00, 0x09, 0x00, 0x05, 0x35, 0x03, 0x19, 0x10, \
+ 0x02, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, \
+ 0x12, 0x00, 0x09, 0x01, 0x03, 0x09, 0x02, 0x00, 0x09, \
+ 0x01, 0x03, 0x09, 0x02, 0x01, 0x09, 0x1d, 0x6b, 0x09, \
+ 0x02, 0x02, 0x09, 0x02, 0x46, 0x09, 0x02, 0x03, 0x09, \
+ 0x05, 0x0e, 0x09, 0x02, 0x04, 0x28, 0x01, 0x09, 0x02, \
+ 0x05, 0x09, 0x00, 0x02, \
+ 0x00
+
+#define hid_req_pdu 0x06, \
+ 0x00, 0x01, \
+ 0x00, 0x0f, \
+ 0x35, 0x03, \
+ 0x19, 0x11, 0x24, 0xff, 0xff, 0x35, 0x05, 0x0a, 0x00, \
+ 0x00, 0xff, 0xff, 0x00
+
+#define hid_rsp_pdu 0x07, \
+ 0x00, 0x01, \
+ 0x01, 0x71, \
+ 0x01, 0x6E, \
+ 0x36, 0x01, 0x6b, 0x36, 0x01, 0x68, 0x09, 0x00, 0x00, \
+ 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, \
+ 0x03, 0x19, 0x11, 0x24, 0x09, 0x00, 0x04, 0x35, 0x0d, \
+ 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x11, 0x35, \
+ 0x03, 0x19, 0x00, 0x11, 0x09, 0x00, 0x05, 0x35, 0x03, \
+ 0x19, 0x10, 0x02, 0x09, 0x00, 0x06, 0x35, 0x09, 0x09, \
+ 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, 0x00, 0x09, \
+ 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x24, \
+ 0x09, 0x01, 0x00, 0x09, 0x00, 0x0d, 0x35, 0x0f, 0x35, \
+ 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x13, \
+ 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x01, 0x00, 0x25, \
+ 0x1e, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63, 0x68, \
+ 0x20, 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, \
+ 0x68, 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x20, 0x4d, \
+ 0x35, 0x35, 0x35, 0x62, 0x09, 0x01, 0x01, 0x25, 0x0f, \
+ 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68, \
+ 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x09, 0x01, 0x02, \
+ 0x25, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63, \
+ 0x68, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02, \
+ 0x01, 0x09, 0x01, 0x11, 0x09, 0x02, 0x02, 0x08, 0x80, \
+ 0x09, 0x02, 0x03, 0x08, 0x21, 0x09, 0x02, 0x04, 0x28, \
+ 0x01, 0x09, 0x02, 0x05, 0x28, 0x01, 0x09, 0x02, 0x06, \
+ 0x35, 0x74, 0x35, 0x72, 0x08, 0x22, 0x25, 0x6e, 0x05, \
+ 0x01, 0x09, 0x02, 0xa1, 0x01, 0x85, 0x02, 0x09, 0x01, \
+ 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15, \
+ 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, \
+ 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x16, 0x01, 0xf8, \
+ 0x26, 0xff, 0x07, 0x75, 0x0c, 0x95, 0x02, 0x81, 0x06, \
+ 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, \
+ 0x01, 0x81, 0x06, 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x81, \
+ 0x06, 0x05, 0x09, 0x19, 0x09, 0x29, 0x10, 0x15, 0x00, \
+ 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0xc0, \
+ 0xc0, 0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x85, \
+ 0x10, 0x75, 0x08, 0x95, 0x06, 0x15, 0x00, 0x26, 0xff, \
+ 0x00, 0x09, 0x01, 0x81, 0x00, 0x09, 0x01, 0x91, 0x00, \
+ 0xc0, 0x09, 0x02, 0x07, 0x35, 0x08, 0x35, 0x06, 0x09, \
+ 0x04, 0x09, 0x09, 0x01, 0x00, 0x09, 0x02, 0x08, 0x28, \
+ 0x00, 0x09, 0x02, 0x09, 0x28, 0x01, 0x09, 0x02, 0x0a, \
+ 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
+
+static struct pdu_set sdp_pdus[] = {
+ { raw_pdu(did_req_pdu), raw_pdu(did_rsp_pdu) },
+ { raw_pdu(hid_req_pdu), raw_pdu(hid_rsp_pdu) },
+ { null_pdu, null_pdu },
};

-static struct emu_cid_data cid_data;
-
-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 */
-
-static struct pdu did_rsp_pdu = raw_pdu(
- 0x07, /* PDU id */
- 0x00, 0x00, /* Transaction id */
- 0x00, 0x4f, /* Response length */
- 0x00, 0x4c, /* Attributes length */
- 0x35, 0x4a, 0x35, 0x48, 0x09, 0x00, 0x00, 0x0a, 0x00,
- 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19,
- 0x12, 0x00, 0x09, 0x00, 0x05, 0x35, 0x03, 0x19, 0x10,
- 0x02, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19,
- 0x12, 0x00, 0x09, 0x01, 0x03, 0x09, 0x02, 0x00, 0x09,
- 0x01, 0x03, 0x09, 0x02, 0x01, 0x09, 0x1d, 0x6b, 0x09,
- 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 */
-
-static struct pdu hid_rsp_pdu = raw_pdu(
- 0x07, /* PDU id */
- 0x00, 0x01, /* Transaction id */
- 0x01, 0x71, /* Response length */
- 0x01, 0x6E, /* Attributes length */
- 0x36, 0x01, 0x6b, 0x36, 0x01, 0x68, 0x09, 0x00, 0x00,
- 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35,
- 0x03, 0x19, 0x11, 0x24, 0x09, 0x00, 0x04, 0x35, 0x0d,
- 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x11, 0x35,
- 0x03, 0x19, 0x00, 0x11, 0x09, 0x00, 0x05, 0x35, 0x03,
- 0x19, 0x10, 0x02, 0x09, 0x00, 0x06, 0x35, 0x09, 0x09,
- 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, 0x00, 0x09,
- 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x24,
- 0x09, 0x01, 0x00, 0x09, 0x00, 0x0d, 0x35, 0x0f, 0x35,
- 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x13,
- 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x01, 0x00, 0x25,
- 0x1e, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63, 0x68,
- 0x20, 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74,
- 0x68, 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x20, 0x4d,
- 0x35, 0x35, 0x35, 0x62, 0x09, 0x01, 0x01, 0x25, 0x0f,
- 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68,
- 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x09, 0x01, 0x02,
- 0x25, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63,
- 0x68, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02,
- 0x01, 0x09, 0x01, 0x11, 0x09, 0x02, 0x02, 0x08, 0x80,
- 0x09, 0x02, 0x03, 0x08, 0x21, 0x09, 0x02, 0x04, 0x28,
- 0x01, 0x09, 0x02, 0x05, 0x28, 0x01, 0x09, 0x02, 0x06,
- 0x35, 0x74, 0x35, 0x72, 0x08, 0x22, 0x25, 0x6e, 0x05,
- 0x01, 0x09, 0x02, 0xa1, 0x01, 0x85, 0x02, 0x09, 0x01,
- 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15,
- 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02,
- 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x16, 0x01, 0xf8,
- 0x26, 0xff, 0x07, 0x75, 0x0c, 0x95, 0x02, 0x81, 0x06,
- 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95,
- 0x01, 0x81, 0x06, 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x81,
- 0x06, 0x05, 0x09, 0x19, 0x09, 0x29, 0x10, 0x15, 0x00,
- 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0xc0,
- 0xc0, 0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x85,
- 0x10, 0x75, 0x08, 0x95, 0x06, 0x15, 0x00, 0x26, 0xff,
- 0x00, 0x09, 0x01, 0x81, 0x00, 0x09, 0x01, 0x91, 0x00,
- 0xc0, 0x09, 0x02, 0x07, 0x35, 0x08, 0x35, 0x06, 0x09,
- 0x04, 0x09, 0x09, 0x01, 0x00, 0x09, 0x02, 0x08, 0x28,
- 0x00, 0x09, 0x02, 0x09, 0x28, 0x01, 0x09, 0x02, 0x0a,
- 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 */
-
-static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
-{
- struct test_data *t_data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- struct emu_cid_data *cid_data = user_data;
+static struct emu_l2cap_cid_data sdp_cid_data = {
+ .pdu = sdp_pdus,
+ .is_sdp = TRUE,
+};

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

- bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
- hid_rsp_pdu.data, hid_rsp_pdu.size);
-}
static void hid_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct emu_l2cap_cid_data *cid_data = user_data;

- cid_data.sdp_handle = handle;
- cid_data.sdp_cid = cid;
+ cid_data->handle = handle;
+ cid_data->cid = cid;

- bthost_add_cid_hook(bthost, handle, cid, hid_sdp_cid_hook_cb,
- &cid_data);
+ tester_handle_l2cap_data_exchange(cid_data);
}

-static void hid_prepare_reply_protocol_mode(struct emu_cid_data *cid_data)
+static void hid_prepare_reply_protocol_mode(struct emu_l2cap_cid_data *cid_data)
{
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
const struct pdu pdu = raw_pdu(0xa0, 0x00);

- bthost_send_cid(bthost, cid_data->ctrl_handle, cid_data->ctrl_cid,
- pdu.data, pdu.size);
+ bthost_send_cid(bthost, cid_data->handle, cid_data->cid, pdu.data,
+ pdu.size);
}

-static void hid_prepare_reply_report(struct emu_cid_data *cid_data)
+static void hid_prepare_reply_report(struct emu_l2cap_cid_data *cid_data)
{
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
const struct pdu pdu = raw_pdu(0xa2, 0x01, 0x00);

- bthost_send_cid(bthost, cid_data->ctrl_handle, cid_data->ctrl_cid,
- pdu.data, pdu.size);
+ bthost_send_cid(bthost, cid_data->handle, cid_data->cid, pdu.data,
+ pdu.size);
}

static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
void *user_data)
{
- struct emu_cid_data *cid_data = user_data;
+ struct emu_l2cap_cid_data *cid_data = user_data;
uint8_t header = ((uint8_t *) data)[0];
struct step *step;

@@ -218,12 +205,13 @@ static void hid_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
{
struct test_data *data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct emu_l2cap_cid_data *cid_data = user_data;

- cid_data.ctrl_handle = handle;
- cid_data.ctrl_cid = cid;
+ cid_data->handle = handle;
+ cid_data->cid = cid;

bthost_add_cid_hook(bthost, handle, cid, hid_ctrl_cid_hook_cb,
- &cid_data);
+ cid_data);
}

static void hid_intr_cid_hook_cb(const void *data, uint16_t len,
@@ -247,33 +235,34 @@ static void hid_intr_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
{
struct test_data *data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct emu_l2cap_cid_data *cid_data = user_data;

- cid_data.intr_handle = handle;
- cid_data.intr_cid = cid;
+ cid_data->handle = handle;
+ cid_data->cid = cid;

bthost_add_cid_hook(bthost, handle, cid, hid_intr_cid_hook_cb,
- &cid_data);
+ cid_data);
}

/* Emulate SDP (PSM = 1) */
static struct emu_set_l2cap_data l2cap_setup_sdp_data = {
.psm = 1,
.func = hid_sdp_search_cb,
- .user_data = NULL,
+ .user_data = &sdp_cid_data,
};

/* Emulate Control Channel (PSM = 17) */
static struct emu_set_l2cap_data l2cap_setup_cc_data = {
.psm = 17,
.func = hid_ctrl_connect_cb,
- .user_data = NULL,
+ .user_data = &ctrl_cid_data,
};

/* Emulate Interrupt Channel (PSM = 19) */
static struct emu_set_l2cap_data l2cap_setup_ic_data = {
.psm = 19,
.func = hid_intr_connect_cb,
- .user_data = NULL,
+ .user_data = &intr_cid_data,
};

static void hidhost_connect_action(void)
--
1.9.1


2014-10-01 09:01:32

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 10/17] android/tester: Make A2DP use pdu exchange mechanism

---
android/tester-a2dp.c | 51 +++++++++------------------------------------------
1 file changed, 9 insertions(+), 42 deletions(-)

diff --git a/android/tester-a2dp.c b/android/tester-a2dp.c
index 59384f9..a82aa71 100644
--- a/android/tester-a2dp.c
+++ b/android/tester-a2dp.c
@@ -24,13 +24,6 @@

static struct queue *list;

-struct emu_cid_data {
- uint16_t handle;
- uint16_t cid;
-};
-
-static struct emu_cid_data cid_data;
-
#define req_dsc 0x00, 0x01
#define rsp_dsc 0x02, 0x01, 0x04, 0x08
#define req_get 0x10, 0x02, 0x04
@@ -60,54 +53,28 @@ static struct pdu_set pdus[] = {
{ null_pdu, null_pdu },
};

-static void print_data(const char *str, void *user_data)
-{
- tester_debug("a2dp: %s", str);
-}
-
-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);
- }
-}
+static struct emu_l2cap_cid_data cid_data = {
+ .pdu = pdus,
+};

static void a2dp_connect_request_cb(uint16_t handle, uint16_t cid,
void *user_data)
{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct emu_l2cap_cid_data *cid_data = user_data;

- if (cid_data.handle)
+ if (cid_data->handle)
return;

- cid_data.handle = handle;
- cid_data.cid = cid;
+ cid_data->handle = handle;
+ cid_data->cid = cid;

- bthost_add_cid_hook(bthost, handle, cid, a2dp_cid_hook_cb, &cid_data);
+ tester_handle_l2cap_data_exchange(cid_data);
}

static struct emu_set_l2cap_data l2cap_setup_data = {
.psm = 25,
.func = a2dp_connect_request_cb,
- .user_data = NULL,
+ .user_data = &cid_data,
};

static void a2dp_connect_action(void)
--
1.9.1


2014-10-01 09:01:34

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 12/17] android/tester: Make GATT use generic cid_data

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

diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index 6898935..1460329 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -40,14 +40,6 @@ static bt_uuid_t app1_uuid = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
};

-struct emu_cid_data {
- const int pdu_len;
- const void *pdu;
-
- uint16_t handle;
- uint16_t cid;
-};
-
struct gatt_connect_data {
const int app_id;
const int conn_id;
@@ -123,7 +115,7 @@ static bt_property_t prop_test_scan_mode_conn = {
.len = sizeof(setprop_scan_mode_conn_val),
};

-static struct emu_cid_data cid_data;
+static struct emu_l2cap_cid_data cid_data;

static struct gatt_connect_data app1_conn_req = {
.app_id = APP1_ID,
@@ -853,7 +845,7 @@ static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
struct test_data *t_data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
- struct emu_cid_data *cid_data = user_data;
+ struct emu_l2cap_cid_data *cid_data = user_data;
const uint8_t *pdu = data;
struct pdu *gatt_pdu = queue_peek_head(t_data->pdus);

--
1.9.1


2014-10-01 09:01:30

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 08/17] android/tester: Expose pdu_set structure so it can be reused

More tester will reuse this structure when we move to generic pdu
exchange mechanism.
---
android/tester-a2dp.c | 5 +----
android/tester-avrcp.c | 5 +----
android/tester-main.h | 5 +++++
3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/android/tester-a2dp.c b/android/tester-a2dp.c
index 047822e..e12844e 100644
--- a/android/tester-a2dp.c
+++ b/android/tester-a2dp.c
@@ -50,10 +50,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[] = {
+static 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) },
diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index fab6dfc..13ffd74 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -73,10 +73,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 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) },
diff --git a/android/tester-main.h b/android/tester-main.h
index 0b3b9ff..3484c3e 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -60,6 +60,11 @@ struct pdu {
uint16_t size;
};

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

#define raw_pdu(args...) \
--
1.9.1


2014-10-01 09:01:33

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 11/17] android/tester: Make AVRCP tests use generic pdu exchange mechanism

sdp_pdus is not constant as transaction ID is always overwritten before
SDP response is sent. This is to avoid using intermediate buffers.
---
android/tester-avrcp.c | 112 +++++++++++++++++--------------------------------
1 file changed, 38 insertions(+), 74 deletions(-)

diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index 647c0fd..4a49bb0 100644
--- a/android/tester-avrcp.c
+++ b/android/tester-avrcp.c
@@ -24,35 +24,35 @@

static struct queue *list;

-struct emu_cid_data {
- uint16_t handle;
- uint16_t cid;
+#define sdp_rsp_pdu 0x07, \
+ 0x00, 0x00, \
+ 0x00, 0x7f, \
+ 0x00, 0x7c, \
+ 0x36, 0x00, 0x79, 0x36, 0x00, 0x3b, 0x09, 0x00, 0x00, \
+ 0x0a, 0x00, 0x01, 0x00, 0x04, 0x09, 0x00, 0x01, 0x35, \
+ 0x06, 0x19, 0x11, 0x0e, 0x19, 0x11, 0x0f, 0x09, 0x00, \
+ 0x04, 0x35, 0x10, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, \
+ 0x00, 0x17, 0x35, 0x06, 0x19, 0x00, 0x17, 0x09, 0x01, \
+ 0x03, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, \
+ 0x11, 0x0e, 0x09, 0x01, 0x00, 0x09, 0x03, 0x11, 0x09, \
+ 0x00, 0x01, 0x36, 0x00, 0x38, 0x09, 0x00, 0x00, 0x0a, \
+ 0x00, 0x01, 0x00, 0x05, 0x09, 0x00, 0x01, 0x35, 0x03, \
+ 0x19, 0x11, 0x0c, 0x09, 0x00, 0x04, 0x35, 0x10, 0x35, \
+ 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x17, 0x35, 0x06, \
+ 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
+
+static struct pdu_set sdp_pdus[] = {
+ { null_pdu, raw_pdu(sdp_rsp_pdu) },
+ { null_pdu, null_pdu },
};

-static struct emu_cid_data sdp_data;
-static struct emu_cid_data a2dp_data;
-static struct emu_cid_data avrcp_data;
-
-static struct pdu sdp_rsp_pdu = raw_pdu(
- 0x07, /* PDU id */
- 0x00, 0x00, /* Transaction id */
- 0x00, 0x7f, /* Response length */
- 0x00, 0x7c, /* Attributes length */
- 0x36, 0x00, 0x79, 0x36, 0x00, 0x3b, 0x09, 0x00, 0x00,
- 0x0a, 0x00, 0x01, 0x00, 0x04, 0x09, 0x00, 0x01, 0x35,
- 0x06, 0x19, 0x11, 0x0e, 0x19, 0x11, 0x0f, 0x09, 0x00,
- 0x04, 0x35, 0x10, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09,
- 0x00, 0x17, 0x35, 0x06, 0x19, 0x00, 0x17, 0x09, 0x01,
- 0x03, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19,
- 0x11, 0x0e, 0x09, 0x01, 0x00, 0x09, 0x03, 0x11, 0x09,
- 0x00, 0x01, 0x36, 0x00, 0x38, 0x09, 0x00, 0x00, 0x0a,
- 0x00, 0x01, 0x00, 0x05, 0x09, 0x00, 0x01, 0x35, 0x03,
- 0x19, 0x11, 0x0c, 0x09, 0x00, 0x04, 0x35, 0x10, 0x35,
- 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x17, 0x35, 0x06,
- 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 struct emu_l2cap_cid_data sdp_data = {
+ .pdu = sdp_pdus,
+ .is_sdp = TRUE,
+};

#define req_dsc 0x00, 0x01
#define rsp_dsc 0x02, 0x01, 0x04, 0x08
@@ -83,6 +83,12 @@ static struct pdu_set pdus[] = {
{ null_pdu, null_pdu },
};

+static struct emu_l2cap_cid_data a2dp_data = {
+ .pdu = pdus,
+};
+
+static struct emu_l2cap_cid_data avrcp_data;
+
static void print_avrcp(const char *str, void *user_data)
{
tester_debug("avrcp: %s", str);
@@ -98,7 +104,7 @@ static void avrcp_connect_request_cb(uint16_t handle, uint16_t cid,
{
struct test_data *data = tester_get_data();
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
- struct emu_cid_data *cid_data = user_data;
+ struct emu_l2cap_cid_data *cid_data = user_data;

cid_data->handle = handle;
cid_data->cid = cid;
@@ -112,41 +118,10 @@ static struct emu_set_l2cap_data avrcp_setup_data = {
.user_data = &avrcp_data,
};

-static void print_a2dp(const char *str, void *user_data)
-{
- tester_debug("a2dp: %s", str);
-}
-
-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);
- }
-}
-
static void a2dp_connect_request_cb(uint16_t handle, uint16_t cid,
void *user_data)
{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
- struct emu_cid_data *cid_data = user_data;
+ struct emu_l2cap_cid_data *cid_data = user_data;

if (cid_data->handle)
return;
@@ -154,7 +129,7 @@ static void a2dp_connect_request_cb(uint16_t handle, uint16_t cid,
cid_data->handle = handle;
cid_data->cid = cid;

- bthost_add_cid_hook(bthost, handle, cid, a2dp_cid_hook_cb, cid_data);
+ tester_handle_l2cap_data_exchange(cid_data);
}

static struct emu_set_l2cap_data a2dp_setup_data = {
@@ -163,26 +138,15 @@ static struct emu_set_l2cap_data a2dp_setup_data = {
.user_data = &a2dp_data,
};

-static void sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
-{
- struct test_data *t_data = tester_get_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);
-}
static void sdp_connect_request_cb(uint16_t handle, uint16_t cid,
void *user_data)
{
- struct test_data *data = tester_get_data();
- struct bthost *bthost = hciemu_client_get_host(data->hciemu);
- struct emu_cid_data *cid_data = user_data;
+ struct emu_l2cap_cid_data *cid_data = user_data;

cid_data->handle = handle;
cid_data->cid = cid;

- bthost_add_cid_hook(bthost, handle, cid, sdp_cid_hook_cb, cid_data);
+ tester_handle_l2cap_data_exchange(cid_data);
}

static struct emu_set_l2cap_data sdp_setup_data = {
--
1.9.1


2014-10-01 09:01:29

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 07/17] android/tester: Make HDP tests use generic pdu struct

---
android/tester-hdp.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/android/tester-hdp.c b/android/tester-hdp.c
index 9ecef21..e81df71 100644
--- a/android/tester-hdp.c
+++ b/android/tester-hdp.c
@@ -184,7 +184,8 @@ static void hdp_unregister_app_action(void)
schedule_action_verification(step);
}

-static uint8_t hdp_rsp_pdu[] = { 0x07, /* PDU id */
+static const struct pdu hdp_rsp_pdu = raw_pdu(
+ 0x07, /* PDU id */
0x00, 0x00, /* Transaction id */
0x01, 0xc8, /* Response length */
0x01, 0xc5, /* Attributes length */
@@ -239,7 +240,7 @@ static uint8_t hdp_rsp_pdu[] = { 0x07, /* PDU id */
0x63, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x65,
0x72, 0x0d, 0x09, 0x03, 0x01, 0x08, 0x01, 0x09, 0x03,
0x02, 0x08, 0x00,
- 0x00 };
+ 0x00);

static void hdp_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
@@ -247,11 +248,11 @@ static void hdp_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;

- hdp_rsp_pdu[1] = ((uint8_t *) data)[1];
- hdp_rsp_pdu[2] = ((uint8_t *) data)[2];
+ hdp_rsp_pdu.data[1] = ((uint8_t *) data)[1];
+ hdp_rsp_pdu.data[2] = ((uint8_t *) data)[2];

bthost_send_cid(bthost, cid_data->sdp_handle, cid_data->sdp_cid,
- hdp_rsp_pdu, sizeof(hdp_rsp_pdu));
+ hdp_rsp_pdu.data, hdp_rsp_pdu.size);
}

static void hdp_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
--
1.9.1


2014-10-01 09:01:24

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 02/17] android/tester: Make AVRCP tests use generic pdu struct

SDP pdus are made not const, so that transaction ID can be replaced
in-place just before response to SDP request is send.
---
android/tester-avrcp.c | 76 +++++++++++++++++++++++++-------------------------
1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c
index b539e0e..fab6dfc 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,39 +53,38 @@ 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) },
+ { null_pdu, null_pdu },
};

static void print_avrcp(const char *str, void *user_data)
@@ -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.1


2014-10-01 09:01:26

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 04/17] 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 654ccd7..f182c56 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -146,8 +146,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,
@@ -862,10 +862,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.1


2014-10-01 09:01:27

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 05/17] android/tester: Make HidHost tests use generic pdu struct

SDP pdus are made non const so that transaction ID can be replaced
in-place just before response to SDP request is sent.
---
android/tester-hidhost.c | 40 ++++++++++++++++------------------------
1 file changed, 16 insertions(+), 24 deletions(-)

diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c
index c7e3a67..6f524f2 100644
--- a/android/tester-hidhost.c
+++ b/android/tester-hidhost.c
@@ -59,14 +59,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 +81,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 +129,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 +137,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 +162,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.1


2014-10-01 09:01:28

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 06/17] android/tester: Make PAN tests use generic pdu struct

---
android/tester-pan.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/android/tester-pan.c b/android/tester-pan.c
index 8d41d34..dfc8c04 100644
--- a/android/tester-pan.c
+++ b/android/tester-pan.c
@@ -29,9 +29,9 @@ struct emu_cid_data {
};

static struct emu_cid_data cid_data;
-static uint8_t pan_conn_req_pdu[] = { 0x01, 0x01, 0x02, 0x11, 0x16,
- 0x11, 0x15 };
-static uint8_t pan_conn_rsp_pdu[] = { 0x01, 0x02, 0x00, 0x00 };
+static const struct pdu pan_conn_req_pdu = raw_pdu(0x01, 0x01, 0x02, 0x11, 0x16,
+ 0x11, 0x15);
+static const struct pdu pan_conn_rsp_pdu = raw_pdu(0x01, 0x02, 0x00, 0x00);

static void pan_nap_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
@@ -39,10 +39,10 @@ static void pan_nap_cid_hook_cb(const void *data, uint16_t len, void *user_data)
struct emu_cid_data *cid_data = user_data;
struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);

- if (!memcmp((uint8_t *) data, pan_conn_req_pdu,
- sizeof(pan_conn_req_pdu)))
+ if (!memcmp((uint8_t *) data, pan_conn_req_pdu.data,
+ pan_conn_req_pdu.size))
bthost_send_cid(bthost, cid_data->nap_handle, cid_data->nap_cid,
- pan_conn_rsp_pdu, sizeof(pan_conn_rsp_pdu));
+ pan_conn_rsp_pdu.data, pan_conn_rsp_pdu.size);
}

static void pan_connect_request_cb(uint16_t handle, uint16_t cid,
--
1.9.1


2014-10-01 09:01:23

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv3 01/17] 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.

'end_pdu' was renamed to 'null_pdu' to better fit also as request pdu in
'pdu_set' structure while setting the response not null.

This mechanism can be used later to send response regardles of data that
came with request on this specific CID. This will siplify responding to
sdp request without defining request pdus.
---
android/tester-a2dp.c | 2 +-
android/tester-avrcp.c | 2 +-
android/tester-gatt.c | 49 +++++++++++++++++--------------------------------
android/tester-main.h | 15 +++++++++++++++
4 files changed, 34 insertions(+), 34 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 693a8a3..654ccd7 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -34,23 +34,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 app1_uuid = {
.uu = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
@@ -397,7 +382,7 @@ static struct pdu search_service[] = {
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x01, 0x10, 0x11, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu search_service_2[] = {
@@ -407,13 +392,13 @@ static struct pdu search_service_2[] = {
raw_pdu(0x11, 0x06, 0x11, 0x00, 0x20, 0x00, 0x01, 0x18),
raw_pdu(0x10, 0x21, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x01, 0x10, 0x21, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu search_service_3[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu get_characteristic_1[] = {
@@ -425,7 +410,7 @@ static struct pdu get_characteristic_1[] = {
raw_pdu(0x09, 0x07, 0x02, 0x00, 0x04, 0x00, 0x00, 0x19, 0x00),
raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28),
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu get_descriptor_1[] = {
@@ -441,7 +426,7 @@ static struct pdu get_descriptor_1[] = {
raw_pdu(0x05, 0x01, 0x04, 0x00, 0x00, 0x29),
raw_pdu(0x04, 0x05, 0x00, 0x10, 0x00),
raw_pdu(0x01, 0x04, 0x05, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu get_descriptor_2[] = {
@@ -457,7 +442,7 @@ static struct pdu get_descriptor_2[] = {
raw_pdu(0x05, 0x01, 0x04, 0x00, 0x00, 0x29, 0x05, 0x00, 0x01, 0x29),
raw_pdu(0x04, 0x06, 0x00, 0x10, 0x00),
raw_pdu(0x01, 0x04, 0x06, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu get_descriptor_3[] = {
@@ -471,7 +456,7 @@ static struct pdu get_descriptor_3[] = {
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),
raw_pdu(0x04, 0x01, 0x00, 0x10, 0x00),
raw_pdu(0x01, 0x04, 0x01, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu get_included_1[] = {
@@ -483,7 +468,7 @@ static struct pdu get_included_1[] = {
raw_pdu(0x09, 0x08, 0x02, 0x00, 0x15, 0x00, 0x19, 0x00, 0xff, 0xfe),
raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x02, 0x28),
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu get_included_2[] = {
@@ -498,7 +483,7 @@ static struct pdu get_included_2[] = {
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10),
raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x02, 0x28),
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu get_included_3[] = {
@@ -508,7 +493,7 @@ static struct pdu get_included_3[] = {
raw_pdu(0x01, 0x11, 0x11, 0x00, 0x0a),
raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x02, 0x28),
raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
- end_pdu
+ null_pdu
};

static struct pdu read_characteristic_1[] = {
@@ -522,7 +507,7 @@ static struct pdu read_characteristic_1[] = {
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),
raw_pdu(0x0a, 0x03, 0x00),
raw_pdu(0x0b, 0x01),
- end_pdu
+ null_pdu
};

static struct pdu read_characteristic_2[] = {
@@ -536,7 +521,7 @@ static struct pdu read_characteristic_2[] = {
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),
raw_pdu(0x0a, 0x03, 0x00),
raw_pdu(0x01, 0x0a, 0x03, 0x00, 0x08),
- end_pdu
+ null_pdu
};

static struct pdu read_descriptor_1[] = {
@@ -554,7 +539,7 @@ static struct pdu read_descriptor_1[] = {
raw_pdu(0x01, 0x04, 0x05, 0x00, 0x0a),
raw_pdu(0x0a, 0x04, 0x00),
raw_pdu(0x0b, 0x01),
- end_pdu
+ null_pdu
};

static struct pdu read_descriptor_2[] = {
@@ -572,7 +557,7 @@ static struct pdu read_descriptor_2[] = {
raw_pdu(0x01, 0x04, 0x05, 0x00, 0x0a),
raw_pdu(0x0a, 0x04, 0x00),
raw_pdu(0x01, 0x0a, 0x04, 0x00, 0x08),
- end_pdu
+ null_pdu
};

static struct pdu write_characteristic_1[] = {
@@ -585,7 +570,7 @@ static struct pdu write_characteristic_1[] = {
raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28),
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),
raw_pdu(0x52, 0x03, 0x00, 0x00, 0x01, 0x02, 0x03),
- end_pdu
+ null_pdu
};

static struct pdu write_characteristic_2[] = {
@@ -599,7 +584,7 @@ static struct pdu write_characteristic_2[] = {
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),
raw_pdu(0x12, 0x03, 0x00, 0x00, 0x01, 0x02, 0x03),
raw_pdu(0x13),
- end_pdu
+ null_pdu
};

static struct pdu write_characteristic_3[] = {
@@ -613,7 +598,7 @@ static struct pdu write_characteristic_3[] = {
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),
raw_pdu(0x12, 0x03, 0x00, 0x00, 0x01, 0x02, 0x03),
raw_pdu(0x01, 0x12, 0x03, 0x00, 0x08),
- end_pdu
+ null_pdu
};

static void gatt_client_register_action(void)
diff --git a/android/tester-main.h b/android/tester-main.h
index e152ff3..0b3b9ff 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 {
+ uint8_t *data;
+ uint16_t size;
+};
+
+#define raw_data(args...) ((unsigned char[]) { args })
+
+#define raw_pdu(args...) \
+ { \
+ .data = raw_data(args), \
+ .size = sizeof(raw_data(args)), \
+ }
+
+#define null_pdu { .data = NULL }
+
#define TEST_CASE_BREDR(text, ...) { \
HCIEMU_TYPE_BREDR, \
text, \
--
1.9.1