tools/l2cap-tester: Refactor to enable per-test test data

This commit is contained in:
Johan Hedberg 2013-05-29 13:57:45 +03:00
parent 65542c9018
commit 8b112301e5

View File

@ -50,9 +50,22 @@ struct test_data {
struct hciemu *hciemu;
enum hciemu_type hciemu_type;
unsigned int io_id;
};
struct l2cap_client_data {
uint16_t client_psm;
uint16_t server_psm;
int expect_err;
};
struct l2cap_server_data {
uint16_t server_psm;
uint8_t send_req_code;
const void *send_req;
const uint16_t send_req_len;
uint8_t expect_rsp_code;
};
static void mgmt_debug(const char *str, void *user_data)
{
const char *prefix = user_data;
@ -205,13 +218,41 @@ static void test_data_free(void *test_data)
break; \
user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
user->io_id = 0; \
user->expect_err = 0; \
user->test_data = data; \
tester_add_full(name, data, \
test_pre_setup, setup, func, NULL, \
test_post_teardown, 2, user, test_data_free); \
} while (0)
static const struct l2cap_client_data client_connect_success_test = {
.client_psm = 0x0001,
.server_psm = 0x0001,
};
static const struct l2cap_client_data client_connect_nval_psm_test = {
.client_psm = 0x0001,
.expect_err = ECONNREFUSED,
};
static const uint8_t l2cap_connect_req[] = { 0x01, 0x00, 0x41, 0x00 };
static const struct l2cap_server_data l2cap_server_success_test = {
.server_psm = 0x0001,
.send_req_code = BT_L2CAP_PDU_CONN_REQ,
.send_req = l2cap_connect_req,
.send_req_len = sizeof(l2cap_connect_req),
.expect_rsp_code = BT_L2CAP_PDU_CONN_RSP,
};
static const uint8_t l2cap_nval_conn_req[] = { 0x00 };
static const struct l2cap_server_data l2cap_server_nval_pdu_test1 = {
.send_req_code = BT_L2CAP_PDU_CONN_REQ,
.send_req = l2cap_nval_conn_req,
.send_req_len = sizeof(l2cap_nval_conn_req),
.expect_rsp_code = BT_L2CAP_PDU_CMD_REJECT,
};
static void client_connectable_complete(uint16_t opcode, uint8_t status,
const void *param, uint8_t len,
void *user_data)
@ -288,6 +329,7 @@ static gboolean l2cap_connect_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
struct test_data *data = tester_get_data();
const struct l2cap_client_data *l2data = data->test_data;
int err, sk_err, sk;
socklen_t len = sizeof(sk_err);
@ -305,7 +347,7 @@ static gboolean l2cap_connect_cb(GIOChannel *io, GIOCondition cond,
else
tester_print("Successfully connected");
if (-err != data->expect_err)
if (-err != l2data->expect_err)
tester_test_failed();
else
tester_test_passed();
@ -378,55 +420,25 @@ static int connect_l2cap_sock(struct test_data *data, int sk, uint16_t psm)
return 0;
}
static void test_bredr_connect_success(const void *test_data)
static void test_bredr_connect(const void *test_data)
{
struct test_data *data = tester_get_data();
struct bthost *bthost;
uint16_t psm = 0x0001;
const struct l2cap_client_data *l2data = data->test_data;
GIOChannel *io;
int sk;
if (l2data->server_psm) {
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
bthost_set_server_psm(bthost, l2data->server_psm);
}
sk = create_l2cap_sock(data, 0);
if (sk < 0) {
tester_test_failed();
return;
}
bthost = hciemu_client_get_host(data->hciemu);
bthost_set_server_psm(bthost, psm);
if (connect_l2cap_sock(data, sk, psm) < 0) {
close(sk);
tester_test_failed();
return;
}
io = g_io_channel_unix_new(sk);
g_io_channel_set_close_on_unref(io, TRUE);
data->io_id = g_io_add_watch(io, G_IO_OUT, l2cap_connect_cb, NULL);
g_io_channel_unref(io);
tester_print("Connect in progress");
}
static void test_bredr_connect_failure(const void *test_data)
{
struct test_data *data = tester_get_data();
uint16_t psm = 0x0001;
GIOChannel *io;
int sk;
sk = create_l2cap_sock(data, 0);
if (sk < 0) {
tester_test_failed();
return;
}
data->expect_err = ECONNREFUSED;
if (connect_l2cap_sock(data, sk, psm) < 0) {
if (connect_l2cap_sock(data, sk, l2data->client_psm) < 0) {
close(sk);
tester_test_failed();
return;
@ -468,94 +480,77 @@ static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
return FALSE;
}
static void client_new_conn(uint16_t handle, void *user_data)
{
struct test_data *data = user_data;
struct bt_l2cap_pdu_conn_req req;
struct bthost *bthost;
tester_print("Sending L2CAP Connect Request from client");
req.psm = htobs(0x0001);
req.scid = htobs(0x0041);
bthost = hciemu_client_get_host(data->hciemu);
bthost_l2cap_req(bthost, handle, BT_L2CAP_PDU_CONN_REQ,
&req, sizeof(req), NULL, NULL);
}
static void test_bredr_accept_success(const void *test_data)
{
struct test_data *data = tester_get_data();
const uint8_t *master_bdaddr;
struct bthost *bthost;
GIOChannel *io;
int sk;
sk = create_l2cap_sock(data, 0x0001);
if (sk < 0) {
tester_test_failed();
return;
}
if (listen(sk, 5) < 0) {
tester_warn("listening on socket failed: %s (%u)",
strerror(errno), errno);
tester_test_failed();
return;
}
io = g_io_channel_unix_new(sk);
g_io_channel_set_close_on_unref(io, TRUE);
data->io_id = g_io_add_watch(io, G_IO_IN, l2cap_listen_cb, NULL);
g_io_channel_unref(io);
tester_print("Listening for connections");
master_bdaddr = hciemu_get_master_bdaddr(data->hciemu);
if (!master_bdaddr) {
tester_warn("No master bdaddr");
tester_test_failed();
return;
}
bthost = hciemu_client_get_host(data->hciemu);
bthost_set_connect_cb(bthost, client_new_conn, data);
bthost_hci_connect(bthost, master_bdaddr);
}
static void nval_pdu_rsp(uint8_t code, const void *data, uint16_t len,
static void client_l2cap_rsp(uint8_t code, const void *data, uint16_t len,
void *user_data)
{
tester_print("Got response code 0x%02x to invalid PDU", code);
struct test_data *test_data = user_data;
const struct l2cap_server_data *l2data = test_data->test_data;
if (code == BT_L2CAP_PDU_CMD_REJECT)
tester_print("Client received response code 0x%02x", code);
if (code == l2data->expect_rsp_code)
tester_test_passed();
else
tester_test_failed();
}
static void client_new_conn_nval_pdu(uint16_t handle, void *user_data)
static void client_new_conn(uint16_t handle, void *user_data)
{
struct test_data *data = user_data;
const struct l2cap_server_data *l2data = data->test_data;
struct bthost *bthost;
uint8_t req = 0x00;
tester_print("Sending invalid PDU from client");
tester_print("New client connection with handle 0x%04x", handle);
bthost = hciemu_client_get_host(data->hciemu);
bthost_l2cap_req(bthost, handle, BT_L2CAP_PDU_CONN_REQ,
&req, sizeof(req), nval_pdu_rsp, data);
if (l2data->send_req) {
bthost_l2cap_rsp_cb cb;
if (l2data->expect_rsp_code)
cb = client_l2cap_rsp;
else
cb = NULL;
tester_print("Sending L2CAP Request from client");
bthost = hciemu_client_get_host(data->hciemu);
bthost_l2cap_req(bthost, handle, BT_L2CAP_PDU_CONN_REQ,
l2data->send_req, l2data->send_req_len,
cb, data);
}
}
static void test_bredr_invalid_pdu(const void *test_data)
static void test_bredr_server(const void *test_data)
{
struct test_data *data = tester_get_data();
const struct l2cap_server_data *l2data = data->test_data;
const uint8_t *master_bdaddr;
struct bthost *bthost;
GIOChannel *io;
int sk;
if (l2data->server_psm) {
sk = create_l2cap_sock(data, 0x0001);
if (sk < 0) {
tester_test_failed();
return;
}
if (listen(sk, 5) < 0) {
tester_warn("listening on socket failed: %s (%u)",
strerror(errno), errno);
tester_test_failed();
return;
}
io = g_io_channel_unix_new(sk);
g_io_channel_set_close_on_unref(io, TRUE);
data->io_id = g_io_add_watch(io, G_IO_IN, l2cap_listen_cb,
NULL);
g_io_channel_unref(io);
tester_print("Listening for connections");
}
master_bdaddr = hciemu_get_master_bdaddr(data->hciemu);
if (!master_bdaddr) {
@ -565,7 +560,7 @@ static void test_bredr_invalid_pdu(const void *test_data)
}
bthost = hciemu_client_get_host(data->hciemu);
bthost_set_connect_cb(bthost, client_new_conn_nval_pdu, data);
bthost_set_connect_cb(bthost, client_new_conn, data);
bthost_hci_connect(bthost, master_bdaddr);
}
@ -576,16 +571,18 @@ int main(int argc, char *argv[])
test_l2cap("Basic L2CAP Socket - Success", NULL, setup_powered,
test_basic);
test_l2cap("L2CAP BR/EDR Connect - Success", NULL, setup_powered,
test_bredr_connect_success);
test_l2cap("L2CAP BR/EDR Connect - Failure", NULL, setup_powered,
test_bredr_connect_failure);
test_l2cap("L2CAP BR/EDR Client - Success",
&client_connect_success_test,
setup_powered, test_bredr_connect);
test_l2cap("L2CAP BR/EDR Client - Invalid PSM",
&client_connect_nval_psm_test,
setup_powered, test_bredr_connect);
test_l2cap("L2CAP BR/EDR Accept - Success", NULL, setup_powered,
test_bredr_accept_success);
test_l2cap("L2CAP BR/EDR Invalid PDU", NULL, setup_powered,
test_bredr_invalid_pdu);
test_l2cap("L2CAP BR/EDR Server - Success", &l2cap_server_success_test,
setup_powered, test_bredr_server);
test_l2cap("L2CAP BR/EDR Server - Invalid PDU",
&l2cap_server_nval_pdu_test1, setup_powered,
test_bredr_server);
return tester_run();
}