diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2014-01-12 19:46:06 -0800 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-01-12 19:46:06 -0800 |
commit | 138f1386c4d3c9f51342f5a352ee4117561dffe1 (patch) | |
tree | a147295fc5a081455e54ae3f2fcc922d62107519 /tools/hci-tester.c | |
parent | 4e8ff0b5c8b5dbc01027cdf596f59397cfaa122e (diff) | |
download | bluez-138f1386c4d3c9f51342f5a352ee4117561dffe1.tar.gz |
tools: Add test case for creating HCI connections
Diffstat (limited to 'tools/hci-tester.c')
-rw-r--r-- | tools/hci-tester.c | 320 |
1 files changed, 277 insertions, 43 deletions
diff --git a/tools/hci-tester.c b/tools/hci-tester.c index 774642e29..7074e6659 100644 --- a/tools/hci-tester.c +++ b/tools/hci-tester.c @@ -26,45 +26,108 @@ #endif #include <stdlib.h> +#include <string.h> #include "monitor/bt.h" #include "src/shared/hci.h" +#include "src/shared/util.h" #include "src/shared/tester.h" -struct test_data { +struct user_data { const void *test_data; - uint16_t index; - struct bt_hci *hci; + uint16_t index_ut; + uint16_t index_lt; + struct bt_hci *hci_ut; /* Upper Tester / IUT */ + struct bt_hci *hci_lt; /* Lower Tester / Reference */ + + uint8_t bdaddr_lt[6]; + uint16_t handle_ut; }; -static void test_pre_setup_reset_complete(const void *data, uint8_t size, +static void test_pre_setup_lt_address(const void *data, uint8_t size, void *user_data) { + struct user_data *user = tester_get_data(); + const struct bt_hci_rsp_read_bd_addr *rsp = data; + + if (rsp->status) { + tester_warn("Read lower tester address failed (0x%02x)", + rsp->status); + tester_pre_setup_failed(); + return; + } + + memcpy(user->bdaddr_lt, rsp->bdaddr, 6); + + tester_pre_setup_complete(); +} + +static void test_pre_setup_lt_complete(const void *data, uint8_t size, + void *user_data) +{ + struct user_data *user = tester_get_data(); uint8_t status = *((uint8_t *) data); if (status) { - tester_warn("HCI Reset command failed (0x%02x)", status); + tester_warn("Reset lower tester efailed (0x%02x)", status); tester_pre_setup_failed(); return; } - tester_pre_setup_complete(); + if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_READ_BD_ADDR, NULL, 0, + test_pre_setup_lt_address, NULL, NULL)) { + tester_warn("Failed to read lower tester address"); + tester_pre_setup_failed(); + return; + } +} + +static void test_pre_setup_ut_complete(const void *data, uint8_t size, + void *user_data) +{ + struct user_data *user = tester_get_data(); + uint8_t status = *((uint8_t *) data); + + if (status) { + tester_warn("Reset upper tester failed (0x%02x)", status); + tester_pre_setup_failed(); + return; + } + + if (user->index_lt == 0xffff) { + tester_pre_setup_complete(); + return; + } + + user->hci_lt = bt_hci_new_user_channel(user->index_lt); + if (!user->hci_lt) { + tester_warn("Failed to setup lower tester user channel"); + tester_pre_setup_failed(); + return; + } + + if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_RESET, NULL, 0, + test_pre_setup_lt_complete, NULL, NULL)) { + tester_warn("Failed to reset lower tester"); + tester_pre_setup_failed(); + return; + } } static void test_pre_setup(const void *test_data) { - struct test_data *data = tester_get_data(); + struct user_data *user = tester_get_data(); - data->hci = bt_hci_new_user_channel(data->index); - if (!data->hci) { - tester_warn("Failed to setup HCI user channel"); + user->hci_ut = bt_hci_new_user_channel(user->index_ut); + if (!user->hci_ut) { + tester_warn("Failed to setup upper tester user channel"); tester_pre_setup_failed(); return; } - if (!bt_hci_send(data->hci, BT_HCI_CMD_RESET, NULL, 0, - test_pre_setup_reset_complete, NULL, NULL)) { - tester_warn("Failed to send HCI Reset command"); + if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_RESET, NULL, 0, + test_pre_setup_ut_complete, NULL, NULL)) { + tester_warn("Failed to reset upper tester"); tester_pre_setup_failed(); return; } @@ -72,32 +135,50 @@ static void test_pre_setup(const void *test_data) static void test_post_teardown(const void *test_data) { - struct test_data *data = tester_get_data(); + struct user_data *user = tester_get_data(); + + bt_hci_unref(user->hci_lt); + user->hci_lt = NULL; - bt_hci_unref(data->hci); - data->hci = NULL; + bt_hci_unref(user->hci_ut); + user->hci_ut = NULL; tester_post_teardown_complete(); } -static void test_data_free(void *test_data) +static void user_data_free(void *data) { - struct test_data *data = test_data; + struct user_data *user = data; - free(data); + free(user); } -#define test_hci(name, data, setup, func) \ +#define test_hci(name, data, setup, func, teardown) \ do { \ - struct test_data *user; \ - user = calloc(1, sizeof(struct test_data)); \ + struct user_data *user; \ + user = calloc(1, sizeof(struct user_data)); \ if (!user) \ break; \ user->test_data = data; \ - user->index = 0; \ + user->index_ut = 0; \ + user->index_lt = 1; \ + tester_add_full(name, data, \ + test_pre_setup, setup, func, teardown, \ + test_post_teardown, 30, user, user_data_free); \ + } while (0) + +#define test_hci_local(name, data, setup, func) \ + do { \ + struct user_data *user; \ + user = calloc(1, sizeof(struct user_data)); \ + if (!user) \ + break; \ + user->test_data = data; \ + user->index_ut = 0; \ + user->index_lt = 0xffff; \ tester_add_full(name, data, \ test_pre_setup, setup, func, NULL, \ - test_post_teardown, 30, user, test_data_free); \ + test_post_teardown, 30, user, user_data_free); \ } while (0) static void setup_features_complete(const void *data, uint8_t size, @@ -116,9 +197,9 @@ static void setup_features_complete(const void *data, uint8_t size, static void setup_features(const void *test_data) { - struct test_data *data = tester_get_data(); + struct user_data *user = tester_get_data(); - if (!bt_hci_send(data->hci, BT_HCI_CMD_READ_LOCAL_FEATURES, NULL, 0, + if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_READ_LOCAL_FEATURES, NULL, 0, setup_features_complete, NULL, NULL)) { tester_warn("Failed to send HCI features command"); tester_setup_failed(); @@ -147,9 +228,9 @@ static void test_command_complete(const void *data, uint8_t size, static void test_command(uint16_t opcode) { - struct test_data *data = tester_get_data(); + struct user_data *user = tester_get_data(); - if (!bt_hci_send(data->hci, opcode, NULL, 0, + if (!bt_hci_send(user->hci_ut, opcode, NULL, 0, test_command_complete, NULL, NULL)) { tester_warn("Failed to send HCI command 0x%04x", opcode); tester_test_failed(); @@ -189,12 +270,12 @@ static void test_local_extended_features_complete(const void *data, static void test_read_local_extended_features(const void *test_data) { - struct test_data *data = tester_get_data(); + struct user_data *user = tester_get_data(); struct bt_hci_cmd_read_local_ext_features cmd; cmd.page = 0x00; - if (!bt_hci_send(data->hci, BT_HCI_CMD_READ_LOCAL_EXT_FEATURES, + if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_READ_LOCAL_EXT_FEATURES, &cmd, sizeof(cmd), test_local_extended_features_complete, NULL, NULL)) { @@ -253,10 +334,10 @@ static void test_inquiry_status(const void *data, uint8_t size, static void test_inquiry_liac(const void *test_data) { - struct test_data *data = tester_get_data(); + struct user_data *user = tester_get_data(); struct bt_hci_cmd_inquiry cmd; - bt_hci_register(data->hci, BT_HCI_EVT_INQUIRY_COMPLETE, + bt_hci_register(user->hci_ut, BT_HCI_EVT_INQUIRY_COMPLETE, test_inquiry_complete, NULL, NULL); cmd.lap[0] = 0x00; @@ -265,7 +346,7 @@ static void test_inquiry_liac(const void *test_data) cmd.length = 0x08; cmd.num_resp = 0x00; - if (!bt_hci_send(data->hci, BT_HCI_CMD_INQUIRY, &cmd, sizeof(cmd), + if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_INQUIRY, &cmd, sizeof(cmd), test_inquiry_status, NULL, NULL)) { tester_warn("Failed to send HCI inquiry command"); tester_test_failed(); @@ -273,31 +354,184 @@ static void test_inquiry_liac(const void *test_data) } } +static void setup_lt_connectable_complete(const void *data, uint8_t size, + void *user_data) +{ + uint8_t status = *((uint8_t *) data); + + if (status) { + tester_warn("Failed to set HCI scan enable (0x%02x)", status); + tester_setup_failed(); + return; + } + + tester_setup_complete(); +} + +static void setup_lt_connect_request_accept(const void *data, uint8_t size, + void *user_data) +{ + struct user_data *user = tester_get_data(); + const struct bt_hci_evt_conn_request *evt = data; + struct bt_hci_cmd_accept_conn_request cmd; + + memcpy(cmd.bdaddr, evt->bdaddr, 6); + cmd.role = 0x01; + + if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_ACCEPT_CONN_REQUEST, + &cmd, sizeof(cmd), NULL, NULL, NULL)) { + tester_warn("Failed to send HCI accept connection command"); + return; + } +} + +static void setup_lt_connectable(const void *test_data) +{ + struct user_data *user = tester_get_data(); + struct bt_hci_cmd_write_scan_enable cmd; + + bt_hci_register(user->hci_lt, BT_HCI_EVT_CONN_REQUEST, + setup_lt_connect_request_accept, NULL, NULL); + + cmd.enable = 0x02; + + if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_WRITE_SCAN_ENABLE, + &cmd, sizeof(cmd), + setup_lt_connectable_complete, NULL, NULL)) { + tester_warn("Failed to send HCI scan enable command"); + tester_setup_failed(); + return; + } +} + +static void test_create_connection_disconnect(void *user_data) +{ + tester_test_passed(); +} + +static void test_create_connection_complete(const void *data, uint8_t size, + void *user_data) +{ + struct user_data *user = tester_get_data(); + const struct bt_hci_evt_conn_complete *evt = data; + + if (evt->status) { + tester_warn("HCI create connection complete failed (0x%02x)", + evt->status); + tester_test_failed(); + return; + } + + user->handle_ut = le16_to_cpu(evt->handle); + + tester_wait(2, test_create_connection_disconnect, NULL); +} + +static void test_create_connection_status(const void *data, uint8_t size, + void *user_data) +{ + uint8_t status = *((uint8_t *) data); + + if (status) { + tester_warn("HCI create connection command failed (0x%02x)", + status); + tester_test_failed(); + return; + } +} + +static void test_create_connection(const void *test_data) +{ + struct user_data *user = tester_get_data(); + struct bt_hci_cmd_create_conn cmd; + + bt_hci_register(user->hci_ut, BT_HCI_EVT_CONN_COMPLETE, + test_create_connection_complete, NULL, NULL); + + memcpy(cmd.bdaddr, user->bdaddr_lt, 6); + cmd.pkt_type = cpu_to_le16(0x0008); + cmd.pscan_rep_mode = 0x02; + cmd.pscan_mode = 0x00; + cmd.clock_offset = cpu_to_le16(0x0000); + cmd.role_switch = 0x01; + + if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_CREATE_CONN, + &cmd, sizeof(cmd), + test_create_connection_status, + NULL, NULL)) { + tester_warn("Failed to send HCI create connection command"); + tester_test_failed(); + return; + } +} + +static void teardown_timeout(void *user_data) +{ + tester_teardown_complete(); +} + +static void teardown_disconnect_status(const void *data, uint8_t size, + void *user_data) +{ + uint8_t status = *((uint8_t *) data); + + if (status) { + tester_warn("HCI disconnect failed (0x%02x)", status); + tester_teardown_failed(); + return; + } + + tester_wait(1, teardown_timeout, NULL); +} + +static void teardown_connection(const void *test_data) +{ + struct user_data *user = tester_get_data(); + struct bt_hci_cmd_disconnect cmd; + + cmd.handle = cpu_to_le16(user->handle_ut); + cmd.reason = 0x13; + + if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_DISCONNECT, + &cmd, sizeof(cmd), + teardown_disconnect_status, + NULL, NULL)) { + tester_warn("Failed to send HCI disconnect command"); + tester_test_failed(); + return; + } +} + int main(int argc, char *argv[]) { tester_init(&argc, &argv); - test_hci("Reset", NULL, NULL, test_reset); + test_hci_local("Reset", NULL, NULL, test_reset); - test_hci("Read Local Version Information", NULL, NULL, + test_hci_local("Read Local Version Information", NULL, NULL, test_read_local_version_information); - test_hci("Read Local Supported Commands", NULL, NULL, + test_hci_local("Read Local Supported Commands", NULL, NULL, test_read_local_supported_commands); - test_hci("Read Local Supported Features", NULL, NULL, + test_hci_local("Read Local Supported Features", NULL, NULL, test_read_local_supported_features); - test_hci("Read Local Extended Features", NULL, + test_hci_local("Read Local Extended Features", NULL, setup_features, test_read_local_extended_features); - test_hci("Read Buffer Size", NULL, NULL, + test_hci_local("Read Buffer Size", NULL, NULL, test_read_buffer_size); - test_hci("Read Country Code", NULL, NULL, + test_hci_local("Read Country Code", NULL, NULL, test_read_country_code); - test_hci("Read BD_ADDR", NULL, NULL, + test_hci_local("Read BD_ADDR", NULL, NULL, test_read_bd_addr); - test_hci("Read Local Supported Codecs", NULL, NULL, + test_hci_local("Read Local Supported Codecs", NULL, NULL, test_read_local_supported_codecs); - test_hci("Inquiry (LIAC)", NULL, NULL, test_inquiry_liac); + test_hci_local("Inquiry (LIAC)", NULL, NULL, test_inquiry_liac); + + test_hci("Create Connection", NULL, + setup_lt_connectable, + test_create_connection, + teardown_connection); return tester_run(); } |