v1:
This patch set improve handling of ssp requests in few test cases
and adds GATT test cases for searching primary services and
characteristics.
This set contains rebased version of pending commits.
v2:
* rebased
* fixed not comparing status of get_characteristic_cb
Marcin Kraglak (8):
android/tester: Simplify ACTION_FAIL and ACTION_SUCCESS defines
android/tester: Add function to set default ssp handler
android/tester: Add support for search services callbacks
android/tester: Add GATT Client Search Service test case
android/tester: Add GATT Search Service 2 test case
android/tester: Add negative GATT Search Service test
android/tester: Add support for get_characteristic_cb()
android/tester: Add GATT get_characteristic test
android/tester-a2dp.c | 3 +
android/tester-gatt.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++-
android/tester-main.c | 123 ++++++++++++++++++++++-
android/tester-main.h | 44 ++++++---
android/tester-pan.c | 3 +
5 files changed, 426 insertions(+), 16 deletions(-)
--
1.9.0
Add basic test case for get_characteristic() in GATT client
interface.
---
android/tester-gatt.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index ac31d38..e518c13 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -73,6 +73,11 @@ struct gatt_search_service_data {
bt_uuid_t *filter_uuid;
};
+struct get_char_data {
+ const int conn_id;
+ btgatt_srvc_id_t *service;
+};
+
static bt_uuid_t client2_app_uuid = {
.uu = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
@@ -138,6 +143,17 @@ static btgatt_srvc_id_t service_2 = {
0x00, 0x10, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00}
};
+static btgatt_gatt_id_t characteristic_1 = {
+ .inst_id = 0,
+ .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x10, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00}
+};
+
+static struct get_char_data get_char_data_1 = {
+ .conn_id = CONN1_ID,
+ .service = &service_1
+};
+
static struct pdu search_service[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
@@ -162,6 +178,18 @@ static struct pdu search_service_3[] = {
end_pdu
};
+static struct pdu 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),
+ raw_pdu(0x01, 0x11, 0x11, 0x00, 0x0a),
+ raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28),
+ 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
+};
+
static void gatt_client_register_action(void)
{
struct test_data *data = tester_get_data();
@@ -273,6 +301,22 @@ static void gatt_client_stop_listen_action(void)
schedule_action_verification(step);
}
+static void gatt_client_get_characteristic_action(void)
+{
+ struct test_data *data = tester_get_data();
+ struct step *current_data_step = queue_peek_head(data->steps);
+ struct get_char_data *get_char = current_data_step->set_data;
+ const btgatt_client_interface_t *client = data->if_gatt->client;
+ struct step *step = g_new0(struct step, 1);
+ int status;
+
+ status = client->get_characteristic(get_char->conn_id,
+ get_char->service, NULL);
+ step->action_status = status;
+
+ 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();
@@ -641,6 +685,34 @@ 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 - Get Characteristic 1",
+ ACTION_SUCCESS(init_pdus, get_characteristic_1),
+ 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_search_services, &search_services_1),
+ CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID),
+ ACTION_SUCCESS(gatt_client_get_characteristic_action,
+ &get_char_data_1),
+ CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS,
+ CONN1_ID, &service_1, &characteristic_1, 4),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};
struct queue *get_gatt_tests(void)
--
1.9.0
Verify data passed to get_characteristic_cb. It is needed
for tester-gatt.
---
android/tester-main.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-----
android/tester-main.h | 11 +++++++++++
2 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/android/tester-main.c b/android/tester-main.c
index aebc1a1..c0f384c 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -396,17 +396,23 @@ static int verify_property(bt_property_t *exp_props, int exp_num_props,
* data is set and match it with expected result.
*/
-static bool verify_services(btgatt_srvc_id_t *a, btgatt_srvc_id_t *b)
+static bool verify_gatt_ids(btgatt_gatt_id_t *a, btgatt_gatt_id_t *b)
{
- if (a->is_primary != b->is_primary)
- return false;
- if (memcmp(&a->id.uuid, &b->id.uuid, sizeof(bt_uuid_t)))
+ if (memcmp(&a->uuid, &b->uuid, sizeof(bt_uuid_t)))
return false;
return true;
}
+static bool verify_services(btgatt_srvc_id_t *a, btgatt_srvc_id_t *b)
+{
+ if (a->is_primary != b->is_primary)
+ return false;
+
+ return verify_gatt_ids(&a->id, &b->id);
+}
+
static bool match_data(struct step *step)
{
struct test_data *data = tester_get_data();
@@ -548,6 +554,24 @@ static bool match_data(struct step *step)
tester_debug("Gatt service doesn't match");
return false;
}
+
+ if (exp->callback_result.characteristic) {
+ btgatt_gatt_id_t *a;
+ btgatt_gatt_id_t *b;
+ a = step->callback_result.characteristic;
+ b = exp->callback_result.characteristic;
+
+ if (!verify_gatt_ids(a, b)) {
+ tester_debug("Gatt char doesn't match");
+ return false;
+ }
+ }
+
+ if (exp->callback_result.char_prop !=
+ step->callback_result.char_prop) {
+ tester_debug("Gatt char prop doesn't match");
+ return false;
+ }
}
return true;
@@ -635,6 +659,9 @@ static void destroy_callback_step(void *data)
if (step->callback_result.service)
free(step->callback_result.service);
+ if (step->callback_result.characteristic)
+ free(step->callback_result.characteristic);
+
g_free(step);
g_atomic_int_dec_and_test(&scheduled_cbacks_num);
}
@@ -1073,6 +1100,23 @@ static void gattc_search_complete_cb(int conn_id, int status)
schedule_callback_call(step);
}
+static void gattc_get_characteristic_cb(int conn_id, int status,
+ btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
+ int char_prop)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ step->callback = CB_GATTC_GET_CHARACTERISTIC;
+ step->callback_result.status = status;
+ step->callback_result.conn_id = conn_id;
+ step->callback_result.service = g_memdup(srvc_id, sizeof(*srvc_id));
+ step->callback_result.characteristic = g_memdup(char_id,
+ sizeof(*char_id));
+ step->callback_result.char_prop = char_prop;
+
+ schedule_callback_call(step);
+}
+
static void pan_control_state_cb(btpan_control_state_t state,
bt_status_t error, int local_role,
const char *ifname)
@@ -1175,7 +1219,7 @@ static const btgatt_client_callbacks_t btgatt_client_callbacks = {
.close_cb = gattc_disconnect_cb,
.search_complete_cb = gattc_search_complete_cb,
.search_result_cb = gattc_search_result_cb,
- .get_characteristic_cb = NULL,
+ .get_characteristic_cb = gattc_get_characteristic_cb,
.get_descriptor_cb = NULL,
.get_included_service_cb = NULL,
.register_for_notification_cb = NULL,
diff --git a/android/tester-main.h b/android/tester-main.h
index aa7eb2a..46aacce 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -144,6 +144,15 @@
.callback = CB_GATTC_SEARCH_COMPLETE, \
.callback_result.conn_id = cb_conn_id \
}
+#define CALLBACK_GATTC_GET_CHARACTERISTIC_CB(cb_res, cb_conn_id, cb_service, \
+ cb_char, cb_char_prop) { \
+ .callback = CB_GATTC_GET_CHARACTERISTIC, \
+ .callback_result.conn_id = cb_conn_id, \
+ .callback_result.status = cb_res, \
+ .callback_result.service = cb_service, \
+ .callback_result.characteristic = cb_char, \
+ .callback_result.char_prop = cb_char_prop \
+ }
#define CALLBACK_GATTC_DISCONNECT(cb_res, cb_prop, cb_conn_id, cb_client_id) { \
.callback = CB_GATTC_CLOSE, \
@@ -384,6 +393,8 @@ struct bt_callback_data {
int client_id;
int conn_id;
btgatt_srvc_id_t *service;
+ btgatt_gatt_id_t *characteristic;
+ int char_prop;
btpan_control_state_t ctrl_state;
btpan_connection_state_t conn_state;
--
1.9.0
In this test case no Primary Service will be returned.
---
android/tester-gatt.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index 48799e4..ac31d38 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -156,6 +156,12 @@ static struct pdu search_service_2[] = {
end_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
+};
+
static void gatt_client_register_action(void)
{
struct test_data *data = tester_get_data();
@@ -611,6 +617,30 @@ 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 - Search Service 3",
+ ACTION_SUCCESS(init_pdus, search_service_3),
+ 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_search_services, &search_services_1),
+ CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};
struct queue *get_gatt_tests(void)
--
1.9.0
It tests searching for Primary Services. In this scenarion two
services will be returned.
---
android/tester-gatt.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index 1533d1f..48799e4 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -131,6 +131,13 @@ static btgatt_srvc_id_t service_1 = {
0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00}
};
+static btgatt_srvc_id_t service_2 = {
+ .is_primary = true,
+ .id.inst_id = 1,
+ .id.uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x10, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00}
+};
+
static struct pdu search_service[] = {
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18),
@@ -139,6 +146,16 @@ static struct pdu search_service[] = {
end_pdu
};
+static struct pdu 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),
+ 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
+};
+
static void gatt_client_register_action(void)
{
struct test_data *data = tester_get_data();
@@ -568,6 +585,32 @@ 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 - Search Service 2",
+ ACTION_SUCCESS(init_pdus, search_service_2),
+ 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_search_services, &search_services_1),
+ CALLBACK_GATTC_SEARCH_RESULT(CONN1_ID, &service_1),
+ CALLBACK_GATTC_SEARCH_RESULT(CONN1_ID, &service_2),
+ CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};
struct queue *get_gatt_tests(void)
--
1.9.0
It is basic test case for searching primary services.
---
android/tester-gatt.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 123 insertions(+), 1 deletion(-)
diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index b680322..1533d1f 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -33,8 +33,23 @@
#define CONN1_ID 1
#define CONN2_ID 2
+#define data(args...) ((const unsigned char[]) { args })
+
+#define raw_pdu(args...) \
+ { \
+ .data = data(args), \
+ .size = sizeof(data(args)), \
+ }
+
+#define end_pdu { .data = NULL }
+
static struct queue *list; /* List of gatt test cases */
+struct pdu {
+ const uint8_t *data;
+ uint16_t size;
+};
+
static bt_uuid_t client_app_uuid = {
.uu = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
@@ -53,6 +68,11 @@ struct gatt_connect_data {
const int conn_id;
};
+struct gatt_search_service_data {
+ const int conn_id;
+ bt_uuid_t *filter_uuid;
+};
+
static bt_uuid_t client2_app_uuid = {
.uu = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
@@ -92,6 +112,11 @@ static struct gatt_connect_data client2_conn_req = {
.conn_id = CONN2_ID,
};
+static struct gatt_search_service_data search_services_1 = {
+ .conn_id = CONN1_ID,
+ .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 };
@@ -99,6 +124,21 @@ static struct bt_action_data bearer_type = {
.bearer_type = BDADDR_LE_PUBLIC,
};
+static btgatt_srvc_id_t service_1 = {
+ .is_primary = true,
+ .id.inst_id = 0,
+ .id.uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00}
+};
+
+static struct pdu 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),
+ raw_pdu(0x01, 0x10, 0x11, 0x00, 0x0a),
+ end_pdu
+};
+
static void gatt_client_register_action(void)
{
struct test_data *data = tester_get_data();
@@ -216,6 +256,7 @@ 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_cid_data *cid_data = user_data;
const uint8_t *pdu = data;
+ struct pdu *gatt_pdu = queue_peek_head(t_data->pdus);
switch (pdu[0]) {
case L2CAP_ATT_EXCHANGE_MTU_REQ:
@@ -232,7 +273,29 @@ static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data)
break;
default:
- tester_print("Unknown ATT packet.");
+ if (!gatt_pdu || !gatt_pdu->data) {
+ tester_print("Unknown ATT packet.");
+ break;
+ }
+
+ if (gatt_pdu->size != len) {
+ tester_print("Size of incoming frame is not valid");
+ tester_print("Expected size = %d incoming size = %d",
+ gatt_pdu->size, len);
+ break;
+ }
+
+ if (memcmp(gatt_pdu->data, 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->data)
+ break;
+
+ bthost_send_cid(bthost, cid_data->handle, cid_data->cid,
+ gatt_pdu->data, gatt_pdu->size);
break;
}
@@ -257,6 +320,40 @@ static void gatt_conn_cb(uint16_t handle, void *user_data)
&cid_data);
}
+static void gatt_client_search_services(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 gatt_search_service_data *search_data;
+ int status;
+
+ search_data = current_data_step->set_data;
+
+ status = data->if_gatt->client->search_service(search_data->conn_id,
+ search_data->filter_uuid);
+ step->action_status = status;
+
+ schedule_action_verification(step);
+}
+
+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;
+
+ while (pdu->data) {
+ queue_push_tail(data->pdus, pdu);
+ pdu++;
+ }
+
+ 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),
@@ -446,6 +543,31 @@ 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 - Search Service 1",
+ ACTION_SUCCESS(init_pdus, search_service),
+ 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_search_services, &search_services_1),
+ CALLBACK_GATTC_SEARCH_RESULT(CONN1_ID, &service_1),
+ CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};
struct queue *get_gatt_tests(void)
--
1.9.0
Add support for search_result_cb() and search_complete_cb()
in android tester. It is needed for GATT client test cases.
---
android/tester-main.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++--
android/tester-main.h | 14 +++++++++++++
2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/android/tester-main.c b/android/tester-main.c
index 60ccac7..aebc1a1 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -395,6 +395,18 @@ static int verify_property(bt_property_t *exp_props, int exp_num_props,
* Check each test case step if test case expected
* data is set and match it with expected result.
*/
+
+static bool verify_services(btgatt_srvc_id_t *a, btgatt_srvc_id_t *b)
+{
+ if (a->is_primary != b->is_primary)
+ return false;
+
+ if (memcmp(&a->id.uuid, &b->id.uuid, sizeof(bt_uuid_t)))
+ return false;
+
+ return true;
+}
+
static bool match_data(struct step *step)
{
struct test_data *data = tester_get_data();
@@ -529,6 +541,13 @@ static bool match_data(struct step *step)
tester_debug("Gatt properties don't match");
return false;
}
+
+ if (exp->callback_result.service &&
+ !verify_services(step->callback_result.service,
+ exp->callback_result.service)) {
+ tester_debug("Gatt service doesn't match");
+ return false;
+ }
}
return true;
@@ -613,6 +632,9 @@ static void destroy_callback_step(void *data)
if (step->callback_result.properties)
free_properties(step);
+ if (step->callback_result.service)
+ free(step->callback_result.service);
+
g_free(step);
g_atomic_int_dec_and_test(&scheduled_cbacks_num);
}
@@ -1030,6 +1052,27 @@ static void gattc_listen_cb(int status, int server_if)
schedule_callback_call(step);
}
+static void gattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ step->callback = CB_GATTC_SEARCH_RESULT;
+ step->callback_result.conn_id = conn_id;
+ step->callback_result.service = g_memdup(srvc_id, sizeof(*srvc_id));
+
+ schedule_callback_call(step);
+}
+
+static void gattc_search_complete_cb(int conn_id, int status)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ step->callback = CB_GATTC_SEARCH_COMPLETE;
+ step->callback_result.conn_id = conn_id;
+
+ schedule_callback_call(step);
+}
+
static void pan_control_state_cb(btpan_control_state_t state,
bt_status_t error, int local_role,
const char *ifname)
@@ -1130,8 +1173,8 @@ static const btgatt_client_callbacks_t btgatt_client_callbacks = {
.scan_result_cb = gattc_scan_result_cb,
.open_cb = gattc_connect_cb,
.close_cb = gattc_disconnect_cb,
- .search_complete_cb = NULL,
- .search_result_cb = NULL,
+ .search_complete_cb = gattc_search_complete_cb,
+ .search_result_cb = gattc_search_result_cb,
.get_characteristic_cb = NULL,
.get_descriptor_cb = NULL,
.get_included_service_cb = NULL,
@@ -1236,6 +1279,12 @@ static bool setup_base(struct test_data *data)
if (!(data->steps = queue_new()))
return false;
+ data->pdus = queue_new();
+ if (!data->pdus) {
+ queue_destroy(data->steps, NULL);
+ return false;
+ }
+
return true;
}
@@ -1479,6 +1528,9 @@ static void teardown(const void *test_data)
queue_destroy(data->steps, NULL);
data->steps = NULL;
+ queue_destroy(data->pdus, NULL);
+ data->pdus = NULL;
+
if (data->if_gatt) {
data->if_gatt->cleanup();
data->if_gatt = NULL;
diff --git a/android/tester-main.h b/android/tester-main.h
index f7e3c90..aa7eb2a 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -134,6 +134,17 @@
.callback_result.client_id = cb_client_id, \
}
+#define CALLBACK_GATTC_SEARCH_RESULT(cb_conn_id, cb_service) { \
+ .callback = CB_GATTC_SEARCH_RESULT, \
+ .callback_result.conn_id = cb_conn_id, \
+ .callback_result.service = cb_service \
+ }
+
+#define CALLBACK_GATTC_SEARCH_COMPLETE(cb_res, cb_conn_id) { \
+ .callback = CB_GATTC_SEARCH_COMPLETE, \
+ .callback_result.conn_id = cb_conn_id \
+ }
+
#define CALLBACK_GATTC_DISCONNECT(cb_res, cb_prop, cb_conn_id, cb_client_id) { \
.callback = CB_GATTC_CLOSE, \
.callback_result.status = cb_res, \
@@ -309,6 +320,8 @@ struct test_data {
guint signalfd;
uint16_t mgmt_index;
pid_t bluetoothd_pid;
+
+ struct queue *pdus;
};
/*
@@ -370,6 +383,7 @@ struct bt_callback_data {
int client_id;
int conn_id;
+ btgatt_srvc_id_t *service;
btpan_control_state_t ctrl_state;
btpan_connection_state_t conn_state;
--
1.9.0
In most test cases pairing can be performed but is not part of test
case, and shouldn't have impact on test case result. This helper set
defult handler, which will always accept SSP requests.
---
android/tester-a2dp.c | 3 +++
android/tester-main.c | 21 +++++++++++++++++++++
android/tester-main.h | 1 +
android/tester-pan.c | 3 +++
4 files changed, 28 insertions(+)
diff --git a/android/tester-a2dp.c b/android/tester-a2dp.c
index 3d006bc..6d4043b 100644
--- a/android/tester-a2dp.c
+++ b/android/tester-a2dp.c
@@ -186,6 +186,7 @@ static struct test_case test_cases[] = {
ACTION_SUCCESS(dummy_action, NULL),
),
TEST_CASE_BREDRLE("A2DP Connect - Success",
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
ACTION_SUCCESS(bluetooth_enable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
@@ -202,6 +203,7 @@ static struct test_case test_cases[] = {
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
TEST_CASE_BREDRLE("A2DP Disconnect - Success",
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
ACTION_SUCCESS(bluetooth_enable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
@@ -221,6 +223,7 @@ static struct test_case test_cases[] = {
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
TEST_CASE_BREDRLE("A2DP Resume - Success",
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
ACTION_SUCCESS(bluetooth_enable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
diff --git a/android/tester-main.c b/android/tester-main.c
index a001059..60ccac7 100644
--- a/android/tester-main.c
+++ b/android/tester-main.c
@@ -1972,6 +1972,27 @@ void bt_remove_bond_action(void)
schedule_action_verification(step);
}
+static void default_ssp_req_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *name,
+ uint32_t cod, bt_ssp_variant_t pairing_variant,
+ uint32_t pass_key)
+{
+ struct test_data *t_data = tester_get_data();
+
+ t_data->if_bluetooth->ssp_reply(remote_bd_addr, pairing_variant, true,
+ pass_key);
+}
+
+void set_default_ssp_request_handler(void)
+{
+ struct step *step = g_new0(struct step, 1);
+
+ bt_callbacks.ssp_request_cb = default_ssp_req_cb;
+
+ step->action_status = BT_STATUS_SUCCESS;
+
+ schedule_action_verification(step);
+}
+
static void generic_test_function(const void *test_data)
{
struct test_data *data = tester_get_data();
diff --git a/android/tester-main.h b/android/tester-main.h
index 171dbee..f7e3c90 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -451,3 +451,4 @@ void bt_pin_reply_accept_action(void);
void bt_ssp_reply_accept_action(void);
void bt_cancel_bond_action(void);
void bt_remove_bond_action(void);
+void set_default_ssp_request_handler(void);
diff --git a/android/tester-pan.c b/android/tester-pan.c
index c293022..8d41d34 100644
--- a/android/tester-pan.c
+++ b/android/tester-pan.c
@@ -147,6 +147,7 @@ static struct test_case test_cases[] = {
ACTION_SUCCESS(dummy_action, NULL),
),
TEST_CASE_BREDRLE("PAN Connect - Success",
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
ACTION_SUCCESS(bluetooth_enable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
@@ -171,6 +172,7 @@ static struct test_case test_cases[] = {
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
TEST_CASE_BREDRLE("PAN Disconnect - Success",
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
ACTION_SUCCESS(bluetooth_enable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
@@ -196,6 +198,7 @@ static struct test_case test_cases[] = {
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
TEST_CASE_BREDRLE("PAN GetLocalRole - Success",
+ ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
ACTION_SUCCESS(bluetooth_enable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
--
1.9.0
---
android/tester-main.h | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/android/tester-main.h b/android/tester-main.h
index 77f7660..171dbee 100644
--- a/android/tester-main.h
+++ b/android/tester-main.h
@@ -68,24 +68,18 @@
(struct step[]) {__VA_ARGS__}, \
}
-#define ACTION_SUCCESS(act_fun, data_set) { \
- .action_status = BT_STATUS_SUCCESS, \
- .action = act_fun, \
- .set_data = data_set, \
- }
-
-#define ACTION_FAIL(act_fun, data_set) { \
- .action_status = BT_STATUS_FAIL, \
- .action = act_fun, \
- .set_data = data_set, \
- }
-
#define ACTION(status, act_fun, data_set) { \
.action_status = status, \
.action = act_fun, \
.set_data = data_set, \
}
+#define ACTION_FAIL(act_fun, data_set) \
+ ACTION(BT_STATUS_FAIL, act_fun, data_set)
+
+#define ACTION_SUCCESS(act_fun, data_set) \
+ ACTION(BT_STATUS_SUCCESS, act_fun, data_set)
+
#define CALLBACK(cb) { \
.callback = cb, \
}
--
1.9.0