2014-08-04 10:53:32

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 0/4] Initial set of GATT test cases

This adds some basic test cases for the GATT profile.

There is an issue with the latest bluetooth-next that is triggered by the
"Gatt Client - Double Listen" case. With the Ubuntu's vanila 3.14 kernel it is
not triggered, so I assumed it is not tester's fault. This needs to be
investigated. I'll fill an issue in Girra for that.

Regards,
Jakub Tyszkowski (4):
android/bluetooth: Fix retriggering the discovery
android/tester: Add Gatt Client basic test cases
android/tester: Add Gatt Client connect cases
android/tester: Add Gatt Client Listen cases

android/bluetooth.c | 18 +-
android/tester-gatt.c | 444 ++++++++++++++++++++++++++++++++++++++++++++++++++
android/tester-main.c | 120 +++++++++++++-
android/tester-main.h | 30 ++++
4 files changed, 602 insertions(+), 10 deletions(-)

--
1.9.1



2014-08-04 11:36:26

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH 0/4] Initial set of GATT test cases

Hi Jakub,

On Mon, Aug 04, 2014, Jakub Tyszkowski wrote:
> This adds some basic test cases for the GATT profile.
>
> There is an issue with the latest bluetooth-next that is triggered by the
> "Gatt Client - Double Listen" case. With the Ubuntu's vanila 3.14 kernel it is
> not triggered, so I assumed it is not tester's fault. This needs to be
> investigated. I'll fill an issue in Girra for that.
>
> Regards,
> Jakub Tyszkowski (4):
> android/bluetooth: Fix retriggering the discovery
> android/tester: Add Gatt Client basic test cases
> android/tester: Add Gatt Client connect cases
> android/tester: Add Gatt Client Listen cases
>
> android/bluetooth.c | 18 +-
> android/tester-gatt.c | 444 ++++++++++++++++++++++++++++++++++++++++++++++++++
> android/tester-main.c | 120 +++++++++++++-
> android/tester-main.h | 30 ++++
> 4 files changed, 602 insertions(+), 10 deletions(-)

All patches in this set have been applied. Thanks.

Johan

2014-08-04 10:53:33

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 1/4] android/bluetooth: Fix retriggering the discovery

Previously le device found callback was set every time we triggered the scan
from gatt. But it does no longer work like that. This callback is now set
when gatt profile is registered and should not be used for checking if we
should be retriggering the scan. Expected discovery flag should be
used directly instead.
---
android/bluetooth.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index cd1772a..48866b3 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -3714,9 +3714,16 @@ bool bt_le_discovery_start(void)

adapter.le_scanning = true;

- /* If core is discovering, don't bother */
- if (adapter.cur_discovery_type != SCAN_TYPE_NONE)
+ /*
+ * If core is discovering - just set expected next scan type.
+ * It will be triggered in case current scan session is almost done
+ * i.e. we missed LE phase in interleaved scan, or we're trying to
+ * connect to device that was already discovered.
+ */
+ if (adapter.cur_discovery_type != SCAN_TYPE_NONE) {
+ adapter.exp_discovery_type = SCAN_TYPE_LE;
return true;
+ }

if (start_discovery(SCAN_TYPE_LE))
return true;
@@ -4703,7 +4710,7 @@ static void handle_cancel_discovery_cmd(const void *buf, uint16_t len)
if (get_supported_discovery_type() != SCAN_TYPE_LE)
break;

- if (gatt_device_found_cb) {
+ if (adapter.exp_discovery_type == SCAN_TYPE_LE) {
status = HAL_STATUS_BUSY;
goto failed;
}
@@ -4721,8 +4728,9 @@ static void handle_cancel_discovery_cmd(const void *buf, uint16_t len)
goto failed;
}

- adapter.exp_discovery_type = gatt_device_found_cb ?
- SCAN_TYPE_LE : SCAN_TYPE_NONE;
+ if (adapter.exp_discovery_type != SCAN_TYPE_LE)
+ adapter.exp_discovery_type = SCAN_TYPE_NONE;
+
break;
}

--
1.9.1


2014-08-04 10:53:36

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 4/4] android/tester: Add Gatt Client Listen cases

---
android/tester-gatt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++
android/tester-main.c | 12 ++++-
2 files changed, 141 insertions(+), 1 deletion(-)

diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index c81b8da..d69b027 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -66,6 +66,15 @@ static bt_property_t prop_emu_remotes_default_set[] = {
&emu_remote_bdaddr_val },
};

+static bt_scan_mode_t setprop_scan_mode_conn_val =
+ BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
+
+static bt_property_t prop_test_scan_mode_conn = {
+ .type = BT_PROPERTY_ADAPTER_SCAN_MODE,
+ .val = &setprop_scan_mode_conn_val,
+ .len = sizeof(setprop_scan_mode_conn_val),
+};
+
static struct emu_cid_data cid_data;

static struct gatt_connect_data client1_conn_req = {
@@ -73,6 +82,11 @@ static struct gatt_connect_data client1_conn_req = {
.conn_id = CONN1_ID,
};

+static struct gatt_connect_data client1_conn2_req = {
+ .client_id = CLIENT1_ID,
+ .conn_id = CONN2_ID,
+};
+
static struct gatt_connect_data client2_conn_req = {
.client_id = CLIENT2_ID,
.conn_id = CONN2_ID,
@@ -164,6 +178,34 @@ static void gatt_client_disconnect_action(void)
schedule_action_verification(step);
}

+static void gatt_client_do_listen_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *current_data_step = queue_peek_head(data->steps);
+ struct gatt_connect_data *conn_data = current_data_step->set_data;
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->if_gatt->client->listen(
+ conn_data->client_id,
+ 1);
+
+ schedule_action_verification(step);
+}
+
+static void gatt_client_stop_listen_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *current_data_step = queue_peek_head(data->steps);
+ struct gatt_connect_data *conn_data = current_data_step->set_data;
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->if_gatt->client->listen(
+ conn_data->client_id,
+ 0);
+
+ schedule_action_verification(step);
+}
+
static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
struct test_data *t_data = tester_get_data();
@@ -226,6 +268,24 @@ static void emu_set_connect_cb_action(void)
schedule_action_verification(step);
}

+static void emu_remote_connect_hci_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct step *step = g_new0(struct step, 1);
+ const uint8_t *master_addr;
+
+ master_addr = hciemu_get_master_bdaddr(data->hciemu);
+
+ tester_print("Trying to connect hci");
+
+ bthost_hci_connect(bthost, master_addr, BDADDR_LE_PUBLIC);
+
+ step->action_status = BT_STATUS_SUCCESS;
+
+ schedule_action_verification(step);
+}
+
static struct test_case test_cases[] = {
TEST_CASE_BREDRLE("Gatt Init",
ACTION_SUCCESS(dummy_action, NULL),
@@ -340,6 +400,76 @@ static struct test_case test_cases[] = {
ACTION_SUCCESS(bluetooth_disable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
+ TEST_CASE_BREDRLE("Gatt Client - Listen and Disconnect",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb),
+ ACTION_SUCCESS(bt_set_property_action,
+ &prop_test_scan_mode_conn),
+ CALLBACK_ADAPTER_PROPS(&prop_test_scan_mode_conn, 1),
+ ACTION_SUCCESS(gatt_client_register_action, &client_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_do_listen_action, &client1_conn_req),
+ CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS),
+ ACTION_SUCCESS(emu_remote_connect_hci_action, NULL),
+ CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN1_ID, CLIENT1_ID),
+ ACTION_SUCCESS(gatt_client_stop_listen_action,
+ &client1_conn_req),
+ CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_disconnect_action,
+ &client1_conn_req),
+ CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN1_ID, CLIENT1_ID),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
+ TEST_CASE_BREDRLE("Gatt Client - Double Listen",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb),
+ ACTION_SUCCESS(bt_set_property_action,
+ &prop_test_scan_mode_conn),
+ CALLBACK_ADAPTER_PROPS(&prop_test_scan_mode_conn, 1),
+ ACTION_SUCCESS(gatt_client_register_action, &client_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_do_listen_action, &client1_conn_req),
+ CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS),
+ ACTION_SUCCESS(emu_remote_connect_hci_action, NULL),
+ CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN1_ID, CLIENT1_ID),
+ ACTION_SUCCESS(gatt_client_stop_listen_action,
+ &client1_conn_req),
+ CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_disconnect_action,
+ &client1_conn_req),
+ CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN1_ID, CLIENT1_ID),
+ ACTION_SUCCESS(gatt_client_do_listen_action, &client1_conn_req),
+ CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS),
+ ACTION_SUCCESS(emu_remote_connect_hci_action, NULL),
+ CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN2_ID, CLIENT1_ID),
+ ACTION_SUCCESS(gatt_client_disconnect_action,
+ &client1_conn2_req),
+ CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN2_ID, CLIENT1_ID),
+ ACTION_SUCCESS(gatt_client_stop_listen_action,
+ &client1_conn_req),
+ CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};

struct queue *get_gatt_tests(void)
diff --git a/android/tester-main.c b/android/tester-main.c
index e683150..ba1ae9f 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -953,6 +953,16 @@ static void gattc_disconnect_cb(int conn_id, int status, int client_if,
schedule_callback_call(step);
}

+static void gattc_listen_cb(int status, int server_if)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ step->callback = CB_GATTC_LISTEN;
+ step->callback_result.status = status;
+
+ schedule_callback_call(step);
+}
+
static const btgatt_client_callbacks_t btgatt_client_callbacks = {
.register_client_cb = gattc_register_client_cb,
.scan_result_cb = gattc_scan_result_cb,
@@ -971,7 +981,7 @@ static const btgatt_client_callbacks_t btgatt_client_callbacks = {
.write_descriptor_cb = NULL,
.execute_write_cb = NULL,
.read_remote_rssi_cb = NULL,
- .listen_cb = NULL
+ .listen_cb = gattc_listen_cb
};

static const btgatt_server_callbacks_t btgatt_server_callbacks = {
--
1.9.1


2014-08-04 10:53:35

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 3/4] android/tester: Add Gatt Client connect cases

This adds gatt connect cases.
---
android/tester-gatt.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++
android/tester-main.c | 62 +++++++++++++-
android/tester-main.h | 21 +++++
3 files changed, 299 insertions(+), 2 deletions(-)

diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index 2ee999c..c81b8da 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -21,7 +21,17 @@
#include "tester-main.h"
#include "src/shared/util.h"

+#define L2CAP_ATT_EXCHANGE_MTU_REQ 0x02
+#define L2CAP_ATT_EXCHANGE_MTU_RSP 0x03
+
+#define GATT_STATUS_SUCCESS 0x00000000
+#define GATT_STATUS_FAILURE 0x00000101
+
#define CLIENT1_ID 1
+#define CLIENT2_ID 2
+
+#define CONN1_ID 1
+#define CONN2_ID 2

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

@@ -30,6 +40,24 @@ static bt_uuid_t client_app_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 client_id;
+ const int conn_id;
+};
+
+static bt_uuid_t client2_app_uuid = {
+ .uu = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
+};
+
static bt_bdaddr_t emu_remote_bdaddr_val = {
.address = { 0x00, 0xaa, 0x01, 0x01, 0x00, 0x00 },
};
@@ -38,6 +66,21 @@ static bt_property_t prop_emu_remotes_default_set[] = {
&emu_remote_bdaddr_val },
};

+static struct emu_cid_data cid_data;
+
+static struct gatt_connect_data client1_conn_req = {
+ .client_id = CLIENT1_ID,
+ .conn_id = CONN1_ID,
+};
+
+static struct gatt_connect_data client2_conn_req = {
+ .client_id = CLIENT2_ID,
+ .conn_id = CONN2_ID,
+};
+
+static const uint8_t exchange_mtu_req_pdu[] = { 0x02, 0xa0, 0x02 };
+static const uint8_t exchange_mtu_resp_pdu[] = { 0x03, 0xa0, 0x02 };
+
static void gatt_client_register_action(void)
{
struct test_data *data = tester_get_data();
@@ -91,6 +134,98 @@ static void gatt_client_stop_scan_action(void)
schedule_action_verification(step);
}

+static void gatt_client_connect_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *current_data_step = queue_peek_head(data->steps);
+ struct gatt_connect_data *conn_data = current_data_step->set_data;
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->if_gatt->client->connect(
+ conn_data->client_id,
+ &emu_remote_bdaddr_val,
+ 0);
+
+ schedule_action_verification(step);
+}
+
+static void gatt_client_disconnect_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *current_data_step = queue_peek_head(data->steps);
+ struct gatt_connect_data *conn_data = current_data_step->set_data;
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->if_gatt->client->disconnect(
+ conn_data->client_id,
+ &emu_remote_bdaddr_val,
+ conn_data->conn_id);
+
+ schedule_action_verification(step);
+}
+
+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;
+ const uint8_t *pdu = data;
+
+ switch (pdu[0]) {
+ case L2CAP_ATT_EXCHANGE_MTU_REQ:
+ tester_print("Exchange MTU request received.");
+
+ if (!memcmp(exchange_mtu_req_pdu, pdu, len))
+ bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
+ exchange_mtu_resp_pdu,
+ sizeof(exchange_mtu_resp_pdu));
+
+ break;
+ case L2CAP_ATT_EXCHANGE_MTU_RSP:
+ tester_print("Exchange MTU response received.");
+
+ break;
+ default:
+ tester_print("Unknown ATT packet.");
+
+ break;
+ }
+}
+
+static void gatt_conn_cb(uint16_t handle, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+ tester_print("New connection with handle 0x%04x", handle);
+
+ if (data->hciemu_type == HCIEMU_TYPE_BREDR) {
+ tester_warn("Not handled device type.");
+ return;
+ }
+
+ cid_data.cid = 0x0004;
+ cid_data.handle = handle;
+
+ bthost_add_cid_hook(bthost, handle, cid_data.cid, gatt_cid_hook_cb,
+ &cid_data);
+}
+
+static void emu_set_connect_cb_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ struct step *current_data_step = queue_peek_head(data->steps);
+ void *cb = current_data_step->set_data;
+ struct step *step = g_new0(struct step, 1);
+
+ bthost_set_connect_cb(bthost, cb, data);
+
+ step->action_status = BT_STATUS_SUCCESS;
+
+ schedule_action_verification(step);
+}
+
static struct test_case test_cases[] = {
TEST_CASE_BREDRLE("Gatt Init",
ACTION_SUCCESS(dummy_action, NULL),
@@ -122,6 +257,89 @@ static struct test_case test_cases[] = {
ACTION_SUCCESS(bluetooth_disable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
+ TEST_CASE_BREDRLE("Gatt Client - Connect",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb),
+ ACTION_SUCCESS(gatt_client_register_action, &client_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_start_scan_action,
+ INT_TO_PTR(CLIENT1_ID)),
+ CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE),
+ ACTION_SUCCESS(gatt_client_stop_scan_action,
+ INT_TO_PTR(CLIENT1_ID)),
+ ACTION_SUCCESS(gatt_client_connect_action,
+ &client1_conn_req),
+ CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN1_ID, CLIENT1_ID),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
+ TEST_CASE_BREDRLE("Gatt Client - Disconnect",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb),
+ ACTION_SUCCESS(gatt_client_register_action, &client_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_start_scan_action,
+ INT_TO_PTR(CLIENT1_ID)),
+ CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE),
+ ACTION_SUCCESS(gatt_client_stop_scan_action,
+ INT_TO_PTR(CLIENT1_ID)),
+ ACTION_SUCCESS(gatt_client_connect_action,
+ &client1_conn_req),
+ CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN1_ID, CLIENT1_ID),
+ ACTION_SUCCESS(gatt_client_disconnect_action,
+ &client1_conn_req),
+ CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN1_ID, CLIENT1_ID),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
+ TEST_CASE_BREDRLE("Gatt Client - Multiple Client Conn./Disc.",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb),
+ ACTION_SUCCESS(gatt_client_register_action, &client_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_register_action, &client2_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_start_scan_action,
+ INT_TO_PTR(CLIENT1_ID)),
+ CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE),
+ ACTION_SUCCESS(gatt_client_stop_scan_action,
+ INT_TO_PTR(CLIENT1_ID)),
+ ACTION_SUCCESS(gatt_client_connect_action, &client1_conn_req),
+ CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN1_ID, CLIENT1_ID),
+ ACTION_SUCCESS(gatt_client_connect_action, &client2_conn_req),
+ CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN2_ID, CLIENT2_ID),
+ ACTION_SUCCESS(gatt_client_disconnect_action,
+ &client2_conn_req),
+ CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN2_ID, CLIENT2_ID),
+ ACTION_SUCCESS(gatt_client_disconnect_action,
+ &client1_conn_req),
+ CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS,
+ prop_emu_remotes_default_set,
+ CONN1_ID, CLIENT1_ID),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};

struct queue *get_gatt_tests(void)
diff --git a/android/tester-main.c b/android/tester-main.c
index df608fc..e683150 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -455,6 +455,18 @@ static bool match_data(struct step *step)
return false;
}

+ if (exp->callback_result.conn_id !=
+ step->callback_result.conn_id) {
+ tester_debug("Callback conn_id don't match");
+ return false;
+ }
+
+ if (exp->callback_result.client_id !=
+ step->callback_result.client_id) {
+ tester_debug("Callback client_id don't match");
+ return false;
+ }
+
if (exp->callback_result.properties &&
verify_property(exp->callback_result.properties,
exp->callback_result.num_properties,
@@ -895,11 +907,57 @@ static void gattc_scan_result_cb(bt_bdaddr_t *bda, int rssi, uint8_t *adv_data)
schedule_callback_call(step);
}

+static void gattc_connect_cb(int conn_id, int status, int client_if,
+ bt_bdaddr_t *bda)
+{
+ struct step *step = g_new0(struct step, 1);
+ bt_property_t *props[1];
+
+ step->callback = CB_GATTC_OPEN;
+ step->callback_result.status = status;
+ step->callback_result.conn_id = conn_id;
+ step->callback_result.client_id = client_if;
+
+ /* Utilize property verification mechanism for bdaddr */
+ props[0] = create_property(BT_PROPERTY_BDADDR, bda, sizeof(*bda));
+
+ step->callback_result.num_properties = 1;
+ step->callback_result.properties = repack_properties(1, props);
+
+ g_free(props[0]->val);
+ g_free(props[0]);
+
+ schedule_callback_call(step);
+}
+
+static void gattc_disconnect_cb(int conn_id, int status, int client_if,
+ bt_bdaddr_t *bda)
+{
+ struct step *step = g_new0(struct step, 1);
+ bt_property_t *props[1];
+
+ step->callback = CB_GATTC_CLOSE;
+ step->callback_result.status = status;
+ step->callback_result.conn_id = conn_id;
+ step->callback_result.client_id = client_if;
+
+ /* Utilize property verification mechanism for bdaddr */
+ props[0] = create_property(BT_PROPERTY_BDADDR, bda, sizeof(*bda));
+
+ step->callback_result.num_properties = 1;
+ step->callback_result.properties = repack_properties(1, props);
+
+ g_free(props[0]->val);
+ g_free(props[0]);
+
+ schedule_callback_call(step);
+}
+
static const btgatt_client_callbacks_t btgatt_client_callbacks = {
.register_client_cb = gattc_register_client_cb,
.scan_result_cb = gattc_scan_result_cb,
- .open_cb = NULL,
- .close_cb = NULL,
+ .open_cb = gattc_connect_cb,
+ .close_cb = gattc_disconnect_cb,
.search_complete_cb = NULL,
.search_result_cb = NULL,
.get_characteristic_cb = NULL,
diff --git a/android/tester-main.h b/android/tester-main.h
index 9fb3034..778bdc4 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -127,6 +127,24 @@
.callback_result.adv_data = cb_adv_data, \
}

+#define CALLBACK_GATTC_CONNECT(cb_res, cb_prop, cb_conn_id, cb_client_id) { \
+ .callback = CB_GATTC_OPEN, \
+ .callback_result.status = cb_res, \
+ .callback_result.properties = cb_prop, \
+ .callback_result.num_properties = 1, \
+ .callback_result.conn_id = cb_conn_id, \
+ .callback_result.client_id = cb_client_id, \
+ }
+
+#define CALLBACK_GATTC_DISCONNECT(cb_res, cb_prop, cb_conn_id, cb_client_id) { \
+ .callback = CB_GATTC_CLOSE, \
+ .callback_result.status = cb_res, \
+ .callback_result.properties = cb_prop, \
+ .callback_result.num_properties = 1, \
+ .callback_result.conn_id = cb_conn_id, \
+ .callback_result.client_id = cb_client_id, \
+ }
+
#define CALLBACK_DEVICE_PROPS(props, prop_cnt) \
CALLBACK_PROPS(CB_BT_REMOTE_DEVICE_PROPERTIES, props, prop_cnt)

@@ -289,6 +307,9 @@ struct bt_callback_data {
int report_size;

bool adv_data;
+
+ int client_id;
+ int conn_id;
};

/*
--
1.9.1


2014-08-04 10:53:34

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCH 2/4] android/tester: Add Gatt Client basic test cases

This adds basic tests for client register, unregister and scan.
---
android/tester-gatt.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
android/tester-main.c | 46 ++++++++++++++++++++++--
android/tester-main.h | 9 +++++
3 files changed, 149 insertions(+), 2 deletions(-)

diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index bdfbd8b..2ee999c 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -19,13 +19,109 @@

#include "emulator/bthost.h"
#include "tester-main.h"
+#include "src/shared/util.h"
+
+#define CLIENT1_ID 1

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

+static bt_uuid_t client_app_uuid = {
+ .uu = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
+};
+
+static bt_bdaddr_t emu_remote_bdaddr_val = {
+ .address = { 0x00, 0xaa, 0x01, 0x01, 0x00, 0x00 },
+};
+static bt_property_t prop_emu_remotes_default_set[] = {
+ { BT_PROPERTY_BDADDR, sizeof(emu_remote_bdaddr_val),
+ &emu_remote_bdaddr_val },
+};
+
+static void gatt_client_register_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *current_data_step = queue_peek_head(data->steps);
+ bt_uuid_t *app_uuid = current_data_step->set_data;
+ struct step *step = g_new0(struct step, 1);
+
+ if (!app_uuid) {
+ tester_warn("No app uuid provided for register action.");
+ return;
+ }
+
+ step->action_status = data->if_gatt->client->register_client(app_uuid);
+
+ schedule_action_verification(step);
+}
+
+static void gatt_client_unregister_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *current_data_step = queue_peek_head(data->steps);
+ int32_t cl_id = PTR_TO_INT(current_data_step->set_data);
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->if_gatt->client->unregister_client(cl_id);
+
+ schedule_action_verification(step);
+}
+
+static void gatt_client_start_scan_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *current_data_step = queue_peek_head(data->steps);
+ int32_t cl_id = PTR_TO_INT(current_data_step->set_data);
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->if_gatt->client->scan(cl_id, TRUE);
+
+ schedule_action_verification(step);
+}
+
+static void gatt_client_stop_scan_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *current_data_step = queue_peek_head(data->steps);
+ int32_t cl_id = PTR_TO_INT(current_data_step->set_data);
+ struct step *step = g_new0(struct step, 1);
+
+ step->action_status = data->if_gatt->client->scan(cl_id, FALSE);
+
+ schedule_action_verification(step);
+}
+
static struct test_case test_cases[] = {
TEST_CASE_BREDRLE("Gatt Init",
ACTION_SUCCESS(dummy_action, NULL),
),
+ TEST_CASE_BREDRLE("Gatt Client - Register",
+ ACTION_SUCCESS(gatt_client_register_action, &client_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ),
+ TEST_CASE_BREDRLE("Gatt Client - Unregister",
+ ACTION_SUCCESS(gatt_client_register_action, &client_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_unregister_action,
+ INT_TO_PTR(CLIENT1_ID)),
+ ACTION_SUCCESS(gatt_client_register_action, &client_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ),
+ TEST_CASE_BREDRLE("Gatt Client - Scan",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(gatt_client_register_action, &client_app_uuid),
+ CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS),
+ ACTION_SUCCESS(gatt_client_start_scan_action,
+ INT_TO_PTR(CLIENT1_ID)),
+ CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE),
+ ACTION_SUCCESS(gatt_client_stop_scan_action,
+ INT_TO_PTR(CLIENT1_ID)),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};

struct queue *get_gatt_tests(void)
diff --git a/android/tester-main.c b/android/tester-main.c
index 8800ad3..df608fc 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -449,6 +449,12 @@ static bool match_data(struct step *step)
return false;
}

+ if (exp->callback_result.adv_data !=
+ step->callback_result.adv_data) {
+ tester_debug("Callback adv. data status don't match");
+ return false;
+ }
+
if (exp->callback_result.properties &&
verify_property(exp->callback_result.properties,
exp->callback_result.num_properties,
@@ -853,9 +859,45 @@ static bthh_callbacks_t bthh_callbacks = {
.virtual_unplug_cb = hidhost_virual_unplug_cb
};

+static void gattc_register_client_cb(int status, int client_if,
+ bt_uuid_t *app_uuid)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ step->callback = CB_GATTC_REGISTER_CLIENT;
+
+ step->callback_result.status = status;
+
+ schedule_callback_call(step);
+}
+
+static void gattc_scan_result_cb(bt_bdaddr_t *bda, int rssi, uint8_t *adv_data)
+{
+ struct step *step = g_new0(struct step, 1);
+ bt_property_t *props[2];
+
+ step->callback = CB_GATTC_SCAN_RESULT;
+ step->callback_result.adv_data = adv_data ? TRUE : FALSE;
+
+ /* Utilize property verification mechanism for those */
+ props[0] = create_property(BT_PROPERTY_BDADDR, bda, sizeof(*bda));
+ props[1] = create_property(BT_PROPERTY_REMOTE_RSSI, &rssi,
+ sizeof(rssi));
+
+ step->callback_result.num_properties = 2;
+ step->callback_result.properties = repack_properties(2, props);
+
+ g_free(props[0]->val);
+ g_free(props[0]);
+ g_free(props[1]->val);
+ g_free(props[1]);
+
+ schedule_callback_call(step);
+}
+
static const btgatt_client_callbacks_t btgatt_client_callbacks = {
- .register_client_cb = NULL,
- .scan_result_cb = NULL,
+ .register_client_cb = gattc_register_client_cb,
+ .scan_result_cb = gattc_scan_result_cb,
.open_cb = NULL,
.close_cb = NULL,
.search_complete_cb = NULL,
diff --git a/android/tester-main.h b/android/tester-main.h
index de9061a..9fb3034 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -120,6 +120,13 @@
.callback_result.report_size = cb_rep_size, \
}

+#define CLLBACK_GATTC_SCAN_RES(props, prop_cnt, cb_adv_data) {\
+ .callback = CB_GATTC_SCAN_RESULT, \
+ .callback_result.properties = props, \
+ .callback_result.num_properties = prop_cnt, \
+ .callback_result.adv_data = cb_adv_data, \
+ }
+
#define CALLBACK_DEVICE_PROPS(props, prop_cnt) \
CALLBACK_PROPS(CB_BT_REMOTE_DEVICE_PROPERTIES, props, prop_cnt)

@@ -280,6 +287,8 @@ struct bt_callback_data {

bthh_protocol_mode_t mode;
int report_size;
+
+ bool adv_data;
};

/*
--
1.9.1