From 7b48adc08a457a198a163976189a349bc2368a50 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Jan 2013 12:28:42 -0800 Subject: [PATCH] tools: Add initial set of basic management interface tests --- Makefile.tools | 2 +- tools/mgmt-tester.c | 364 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 365 insertions(+), 1 deletion(-) diff --git a/Makefile.tools b/Makefile.tools index 1375b9595..7a1284622 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -46,7 +46,7 @@ tools_mgmt_tester_SOURCES = tools/mgmt-tester.c \ src/shared/util.h src/shared/util.c \ src/shared/mgmt.h src/shared/mgmt.c \ src/shared/tester.h src/shared/tester.c -tools_mgmt_tester_LDADD = @GLIB_LIBS@ +tools_mgmt_tester_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@ tools_gap_tester_SOURCES = $(gdbus_sources) \ tools/gap-tester.c \ diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c index b792f29d5..a99402adf 100644 --- a/tools/mgmt-tester.c +++ b/tools/mgmt-tester.c @@ -25,13 +25,377 @@ #include #endif +#include + +#include "lib/bluetooth.h" +#include "lib/mgmt.h" + #include "src/shared/tester.h" #include "src/shared/mgmt.h" #include "tools/hciemu.h" +struct test_data { + const void *test_data; + uint8_t expected_version; + uint16_t expected_manufacturer; + uint32_t expected_supported_settings; + uint32_t initial_settings; + struct mgmt *mgmt; + uint8_t mgmt_version; + uint16_t mgmt_revision; + uint16_t mgmt_index; + struct hciemu *hciemu; +}; + +static void mgmt_debug(const char *str, void *user_data) +{ + const char *prefix = user_data; + + tester_print("%s%s", prefix, str); +} + +static void read_version_callback(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + struct test_data *data = tester_get_data(); + const struct mgmt_rp_read_version *rp = param; + + tester_print("Read Version callback"); + tester_print(" Status: 0x%02x", status); + + if (status || !param) { + tester_pre_setup_failed(); + return; + } + + data->mgmt_version = rp->version; + data->mgmt_revision = btohs(rp->revision); + + tester_print(" Version %u.%u", + data->mgmt_version, data->mgmt_revision); +} + +static void read_commands_callback(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + tester_print("Read Commands callback"); + tester_print(" Status: 0x%02x", status); + + if (status || !param) { + tester_pre_setup_failed(); + return; + } +} + +static void read_info_callback(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + struct test_data *data = tester_get_data(); + const struct mgmt_rp_read_info *rp = param; + char addr[18]; + uint16_t manufacturer; + uint32_t supported_settings, current_settings; + + tester_print("Read Info callback"); + tester_print(" Status: 0x%02x", status); + + if (status || !param) { + tester_pre_setup_failed(); + return; + } + + ba2str(&rp->bdaddr, addr); + manufacturer = btohs(rp->manufacturer); + supported_settings = btohl(rp->supported_settings); + current_settings = btohl(rp->current_settings); + + tester_print(" Address: %s", addr); + tester_print(" Version: 0x%02x", rp->version); + tester_print(" Manufacturer: 0x%04x", manufacturer); + tester_print(" Supported settings: 0x%08x", supported_settings); + tester_print(" Current settings: 0x%08x", current_settings); + tester_print(" Class: 0x%02x%02x%02x", + rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]); + tester_print(" Name: %s", rp->name); + tester_print(" Short name: %s", rp->short_name); + + if (strcmp(hciemu_get_address(data->hciemu), addr)) { + tester_pre_setup_failed(); + return; + } + + if (rp->version != data->expected_version) { + tester_pre_setup_failed(); + return; + } + + if (manufacturer != data->expected_manufacturer) { + tester_pre_setup_failed(); + return; + } + + if (supported_settings != data->expected_supported_settings) { + tester_pre_setup_failed(); + return; + } + + if (current_settings != data->initial_settings) { + tester_pre_setup_failed(); + return; + } + + if (rp->dev_class[0] != 0x00 || rp->dev_class[1] != 0x00 || + rp->dev_class[2] != 0x00) { + tester_pre_setup_failed(); + return; + } + + tester_pre_setup_complete(); +} + +static void new_settings_callback(uint16_t index, uint16_t length, + const void *param, void *user_data) +{ + tester_print("New Settings callback"); +} + +static void index_added_callback(uint16_t index, uint16_t length, + const void *param, void *user_data) +{ + struct test_data *data = tester_get_data(); + + tester_print("Index Added callback"); + tester_print(" Index: 0x%04x", index); + + data->mgmt_index = index; + + mgmt_register(data->mgmt, MGMT_EV_NEW_SETTINGS, data->mgmt_index, + new_settings_callback, NULL, NULL); + + mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL, + read_info_callback, NULL, NULL); +} + +static void index_removed_callback(uint16_t index, uint16_t length, + const void *param, void *user_data) +{ + struct test_data *data = tester_get_data(); + + tester_print("Index Removed callback"); + tester_print(" Index: 0x%04x", index); + + if (index != data->mgmt_index) + return; + + mgmt_unregister_index(data->mgmt, data->mgmt_index); + + mgmt_unref(data->mgmt); + data->mgmt = NULL; + + tester_post_teardown_complete(); +} + +static void read_index_list_callback(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + struct test_data *data = tester_get_data(); + + tester_print("Read Index List callback"); + tester_print(" Status: 0x%02x", status); + + if (status || !param) { + tester_pre_setup_failed(); + return; + } + + mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE, + index_added_callback, NULL, NULL); + + mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE, + index_removed_callback, NULL, NULL); + + data->hciemu = hciemu_new(); +} + +static void test_pre_setup(const void *test_data) +{ + struct test_data *data = tester_get_data(); + + data->mgmt = mgmt_new_default(); + if (!data->mgmt) { + tester_warn("Failed to setup management interface"); + tester_pre_setup_failed(); + return; + } + + if (tester_use_debug()) + mgmt_set_debug(data->mgmt, mgmt_debug, "mgmt: ", NULL); + + mgmt_send(data->mgmt, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL, + read_version_callback, NULL, NULL); + + mgmt_send(data->mgmt, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL, + read_commands_callback, NULL, NULL); + + mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL, + read_index_list_callback, NULL, NULL); +} + +static void test_post_teardown(const void *test_data) +{ + struct test_data *data = tester_get_data(); + + hciemu_unref(data->hciemu); + data->hciemu = NULL; +} + +#define test_bredr(name, data, setup, func) \ + do { \ + struct test_data *user; \ + user = malloc(sizeof(struct test_data)); \ + if (!user) \ + break; \ + user->test_data = data; \ + user->expected_version = 0x06; \ + user->expected_manufacturer = 0x003f; \ + user->expected_supported_settings = 0x000002ff; \ + user->initial_settings = 0x00000080; \ + tester_add_full(name, data, \ + test_pre_setup, setup, func, NULL, \ + test_post_teardown, user, free); \ + } while (0) + +static void controller_setup(const void *test_data) +{ + tester_test_passed(); +} + +struct generic_data { + bool send_index_none; + uint16_t send_opcode; + const void *send_param; + uint16_t send_len; + uint8_t expect_status; +}; + +static const char dummy_data[] = { 0x00 }; + +static const struct generic_data invalid_command_test = { + .send_opcode = 0xffff, + .expect_status = MGMT_STATUS_UNKNOWN_COMMAND, +}; + +static const struct generic_data read_version_invalid_param_test = { + .send_index_none = true, + .send_opcode = MGMT_OP_READ_VERSION, + .send_param = dummy_data, + .send_len = sizeof(dummy_data), + .expect_status = MGMT_STATUS_INVALID_PARAMS, +}; + +static const struct generic_data read_version_invalid_index_test = { + .send_opcode = MGMT_OP_READ_VERSION, + .expect_status = MGMT_STATUS_INVALID_INDEX, +}; + +static const struct generic_data read_commands_invalid_param_test = { + .send_index_none = true, + .send_opcode = MGMT_OP_READ_COMMANDS, + .send_param = dummy_data, + .send_len = sizeof(dummy_data), + .expect_status = MGMT_STATUS_INVALID_PARAMS, +}; + +static const struct generic_data read_commands_invalid_index_test = { + .send_opcode = MGMT_OP_READ_COMMANDS, + .expect_status = MGMT_STATUS_INVALID_INDEX, +}; + +static const struct generic_data read_index_list_invalid_param_test = { + .send_index_none = true, + .send_opcode = MGMT_OP_READ_INDEX_LIST, + .send_param = dummy_data, + .send_len = sizeof(dummy_data), + .expect_status = MGMT_STATUS_INVALID_PARAMS, +}; + +static const struct generic_data read_index_list_invalid_index_test = { + .send_opcode = MGMT_OP_READ_INDEX_LIST, + .expect_status = MGMT_STATUS_INVALID_INDEX, +}; + +static const struct generic_data read_info_invalid_param_test = { + .send_opcode = MGMT_OP_READ_INFO, + .send_param = dummy_data, + .send_len = sizeof(dummy_data), + .expect_status = MGMT_STATUS_INVALID_PARAMS, +}; + +static const struct generic_data read_info_invalid_index_test = { + .send_index_none = true, + .send_opcode = MGMT_OP_READ_INFO, + .expect_status = MGMT_STATUS_INVALID_INDEX, +}; + +static void command_generic_callback(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + struct test_data *data = tester_get_data(); + const struct generic_data *test = data->test_data; + + if (status != test->expect_status) { + tester_test_failed(); + return; + } + + tester_test_passed(); +} + +static void test_command_generic(const void *test_data) +{ + struct test_data *data = tester_get_data(); + const struct generic_data *test = data->test_data; + uint16_t index; + + index = test->send_index_none ? MGMT_INDEX_NONE : data->mgmt_index; + + mgmt_send(data->mgmt, test->send_opcode, index, + test->send_len, test->send_param, + command_generic_callback, NULL, NULL); +} + int main(int argc, char *argv[]) { tester_init(&argc, &argv); + test_bredr("Controller setup", NULL, NULL, controller_setup); + test_bredr("Invalid command", &invalid_command_test, + NULL, test_command_generic); + + test_bredr("Read version - Invalid parameters", + &read_version_invalid_param_test, + NULL, test_command_generic); + test_bredr("Read version - Invalid index", + &read_version_invalid_index_test, + NULL, test_command_generic); + test_bredr("Read commands - Invalid parameters", + &read_commands_invalid_param_test, + NULL, test_command_generic); + test_bredr("Read commands - Invalid index", + &read_commands_invalid_index_test, + NULL, test_command_generic); + test_bredr("Read index list - Invalid parameters", + &read_index_list_invalid_param_test, + NULL, test_command_generic); + test_bredr("Read index list - Invalid index", + &read_index_list_invalid_index_test, + NULL, test_command_generic); + test_bredr("Read info - Invalid parameters", + &read_info_invalid_param_test, + NULL, test_command_generic); + test_bredr("Read info - Invalid index", + &read_info_invalid_index_test, + NULL, test_command_generic); + return tester_run(); } -- 2.47.3