From 8b112301e5f2eab2325c754ff1e498da41211e23 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 29 May 2013 13:57:45 +0300 Subject: [PATCH] tools/l2cap-tester: Refactor to enable per-test test data --- tools/l2cap-tester.c | 235 +++++++++++++++++++++---------------------- 1 file changed, 116 insertions(+), 119 deletions(-) diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c index 3d1185f34..61e141049 100644 --- a/tools/l2cap-tester.c +++ b/tools/l2cap-tester.c @@ -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(); }