1 // SPDX-License-Identifier: LGPL-2.1-or-later
4 * BlueZ - Bluetooth protocol stack for Linux
6 * Copyright (C) 2022 Intel Corporation.
20 #include <sys/ioctl.h>
21 #include <sys/socket.h>
25 #include "lib/bluetooth.h"
28 #include "lib/hci_lib.h"
30 #include "monitor/bt.h"
31 #include "emulator/bthost.h"
32 #include "emulator/hciemu.h"
34 #include "src/shared/tester.h"
35 #include "src/shared/mgmt.h"
36 #include "src/shared/util.h"
39 const void *test_data;
41 struct hciemu *hciemu;
42 enum hciemu_type hciemu_type;
48 struct mgmt *mgmt_alt;
49 unsigned int mgmt_alt_ev_id;
54 unsigned int io_id[2];
65 int (*cmd_param_func)(void *param, uint32_t *length);
66 int expected_ioctl_err;
67 const void *block_bdaddr;
68 const void *expected_data;
69 int (*expect_data_check_func)(const void *param, uint32_t length);
72 static void print_debug(const char *str, void *user_data)
74 const char *prefix = user_data;
76 tester_print("%s%s", prefix, str);
79 static void test_add_condition(struct test_data *data)
81 data->unmet_conditions++;
83 tester_print("Test condition added, total %d", data->unmet_conditions);
86 static void test_condition_complete(struct test_data *data)
88 data->unmet_conditions--;
90 tester_print("Test condition complete, %d left",
91 data->unmet_conditions);
93 if (data->unmet_conditions > 0)
99 static int update_hci_dev_id(struct test_data *data)
101 struct hci_dev_list_req *dl;
102 struct hci_dev_req *dr;
105 dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(uint16_t));
109 dl->dev_num = HCI_MAX_DEV;
112 if (ioctl(data->sock_fd, HCIGETDEVLIST, (void *) dl) < 0) {
117 if (dl->dev_num != 1) {
118 tester_warn("dev num mismatch returned %d:expected 1",
124 data->hci_dev_id = dr->dev_id;
125 tester_print("HCI device id: %d", data->hci_dev_id);
132 static void read_info_callback(uint8_t status, uint16_t length,
133 const void *param, void *user_data)
135 struct test_data *data = tester_get_data();
136 const struct mgmt_rp_read_info *rp = param;
138 uint16_t manufacturer;
139 uint32_t supported_settings, current_settings;
141 tester_print("Read Info callback");
142 tester_print(" Status: 0x%02x", status);
144 if (status || !param) {
145 tester_pre_setup_failed();
149 ba2str(&rp->bdaddr, addr);
150 manufacturer = btohs(rp->manufacturer);
151 supported_settings = btohl(rp->supported_settings);
152 current_settings = btohl(rp->current_settings);
154 tester_print(" Address: %s", addr);
155 tester_print(" Version: 0x%02x", rp->version);
156 tester_print(" Manufacturer: 0x%04x", manufacturer);
157 tester_print(" Supported settings: 0x%08x", supported_settings);
158 tester_print(" Current settings: 0x%08x", current_settings);
159 tester_print(" Class: 0x%02x%02x%02x",
160 rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
161 tester_print(" Name: %s", rp->name);
162 tester_print(" Short name: %s", rp->short_name);
164 if (strcmp(hciemu_get_address(data->hciemu), addr)) {
165 tester_pre_setup_failed();
169 tester_pre_setup_complete();
172 static void index_added_callback(uint16_t index, uint16_t length,
173 const void *param, void *user_data)
175 struct test_data *data = tester_get_data();
177 tester_print("Index Added callback");
178 tester_print(" Index: 0x%04x", index);
180 data->mgmt_index = index;
182 mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
183 read_info_callback, NULL, NULL);
186 static void index_removed_callback(uint16_t index, uint16_t length,
187 const void *param, void *user_data)
189 struct test_data *data = tester_get_data();
191 tester_print("Index Removed callback");
192 tester_print(" Index: 0x%04x", index);
194 if (index != data->mgmt_index)
197 mgmt_unregister_index(data->mgmt, data->mgmt_index);
198 mgmt_unregister_index(data->mgmt_alt, data->mgmt_index);
200 mgmt_unref(data->mgmt);
203 mgmt_unref(data->mgmt_alt);
204 data->mgmt_alt = NULL;
206 tester_post_teardown_complete();
209 static void read_index_list_callback(uint8_t status, uint16_t length,
210 const void *param, void *user_data)
212 struct test_data *data = tester_get_data();
214 tester_print("Read Index List callback");
215 tester_print(" Status: 0x%02x", status);
217 if (status || !param) {
218 tester_pre_setup_failed();
222 mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
223 index_added_callback, NULL, NULL);
225 mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
226 index_removed_callback, NULL, NULL);
228 data->hciemu = hciemu_new(data->hciemu_type);
230 tester_warn("Failed to setup HCI emulation");
231 tester_pre_setup_failed();
234 if (tester_use_debug())
235 hciemu_set_debug(data->hciemu, print_debug, "hciemu: ", NULL);
237 tester_print("New hciemu instance created");
239 data->sock_fd = hci_open_dev(0);
240 if (data->sock_fd < 0) {
241 tester_warn("Failed to open socket for ioctl");
242 tester_pre_setup_failed();
246 update_hci_dev_id(data);
249 static void test_pre_setup(const void *test_data)
251 struct test_data *data = tester_get_data();
253 data->mgmt = mgmt_new_default();
255 tester_warn("Failed to setup mgmt interface");
256 tester_pre_setup_failed();
260 data->mgmt_alt = mgmt_new_default();
261 if (!data->mgmt_alt) {
262 tester_warn("Failed to setup alternate management interface");
263 tester_pre_setup_failed();
265 mgmt_unref(data->mgmt);
271 if (tester_use_debug()) {
272 mgmt_set_debug(data->mgmt, print_debug, "mgmt: ", NULL);
273 mgmt_set_debug(data->mgmt_alt, print_debug, "mgmt-alt: ", NULL);
276 mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
277 read_index_list_callback, NULL, NULL);
280 static void test_post_teardown(const void *test_data)
282 struct test_data *data = tester_get_data();
284 if (data->sock_fd >= 0) {
285 tester_print("Socket closed");
286 hci_close_dev(data->sock_fd);
289 hciemu_unref(data->hciemu);
293 static void test_data_free(void *test_data)
295 struct test_data *data = test_data;
297 // TODO: free any data allocated during pre-setup
302 #define test_ioctl_full(name, data, setup, func, num) \
304 struct test_data *user; \
305 user = new0(struct test_data, 1); \
308 user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
309 user->test_data = data; \
310 user->client_num = num; \
311 tester_add_full(name, data, \
312 test_pre_setup, setup, func, NULL, \
313 test_post_teardown, 2, user, test_data_free); \
316 #define test_ioctl(name, data, setup, func) \
317 test_ioctl_full(name, data, setup, func, 1)
319 static void setup_powered_callback(uint8_t status, uint16_t length,
320 const void *param, void *user_data)
322 if (status != MGMT_STATUS_SUCCESS) {
323 tester_setup_failed();
327 tester_print("Controller powered on");
329 tester_setup_complete();
332 static void setup_powered(const void *test_data)
334 struct test_data *data = tester_get_data();
335 unsigned char param[] = { 0x01 };
337 mgmt_send(data->mgmt, MGMT_OP_SET_BONDABLE, data->mgmt_index,
338 sizeof(param), param, NULL, NULL, NULL);
340 mgmt_send(data->mgmt, MGMT_OP_SET_CONNECTABLE, data->mgmt_index,
341 sizeof(param), param, NULL, NULL, NULL);
343 mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
344 sizeof(param), param, NULL, NULL, NULL);
346 mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
347 sizeof(param), param,
348 setup_powered_callback, NULL, NULL);
351 static void setup_add_block_bdaddr(const void *test_data)
353 struct test_data *data = tester_get_data();
354 const struct ioctl_data *ioctl_data = data->test_data;
356 if (!ioctl_data->block_bdaddr) {
357 tester_warn("Invalid test data: block bdaddr");
358 tester_setup_failed();
362 if (ioctl(data->sock_fd, HCIBLOCKADDR, ioctl_data->block_bdaddr) < 0) {
363 tester_warn("Failed to add block bdaddr");
364 tester_setup_failed();
368 tester_print("Added block BDADDR");
370 tester_setup_complete();
373 static int conn_list_empty_check_func(const void *param, uint32_t length)
375 struct test_data *data = tester_get_data();
376 const struct ioctl_data *ioctl_data = data->test_data;
377 const struct hci_conn_list_req *cl_input = ioctl_data->expected_data;
378 const struct hci_conn_list_req *cl = param;
380 if (cl->conn_num != cl_input->conn_num)
386 static int conn_info_cmd_param_func(void *param, uint32_t *length)
388 struct test_data *data = tester_get_data();
389 const struct ioctl_data *ioctl_data = data->test_data;
390 const struct hci_conn_info_req *cr_input = ioctl_data->param;
391 struct hci_conn_info_req *cr = param;
393 memcpy(&cr->bdaddr, &cr_input->bdaddr, sizeof(bdaddr_t));
394 cr->type = cr_input->type;
399 static int auth_info_cmd_param_func(void *param, uint32_t *length)
401 struct test_data *data = tester_get_data();
402 const struct ioctl_data *ioctl_data = data->test_data;
403 const struct hci_auth_info_req *ar_input = ioctl_data->param;
404 struct hci_auth_info_req *ar = param;
406 memcpy(&ar->bdaddr, &ar_input->bdaddr, sizeof(bdaddr_t));
408 ar->type = ar_input->type;
413 static const struct ioctl_data dev_down = {
417 static const struct hci_dev_list_req dev_list_1 = {
425 static const struct ioctl_data dev_list = {
426 .cmd = HCIGETDEVLIST,
427 .expected_data = (void *)&dev_list_1,
430 static const struct hci_dev_list_req dev_list_invalid_1_param = {
434 static const struct ioctl_data dev_list_invalid_1 = {
435 .cmd = HCIGETDEVLIST,
436 .param = (void *)&dev_list_invalid_1_param,
437 .expected_ioctl_err = EINVAL,
440 static const struct ioctl_data dev_info = {
441 .cmd = HCIGETDEVINFO,
444 static const struct ioctl_data reset_stat = {
448 static const struct ioctl_data set_link_mode_master = {
449 .cmd = HCISETLINKMODE,
450 .opt = HCI_LM_MASTER,
453 static const struct ioctl_data set_link_mode_accept = {
454 .cmd = HCISETLINKMODE,
455 .opt = HCI_LM_ACCEPT,
458 static const struct ioctl_data set_pkt_type_dm = {
460 .opt = HCI_DM1 | HCI_DM3 | HCI_DM5,
463 static const struct ioctl_data set_pkt_type_dh = {
465 .opt = HCI_DH1 | HCI_DH3 | HCI_DH5,
468 static const struct ioctl_data set_pkt_type_hv = {
470 .opt = HCI_HV1 | HCI_HV2 | HCI_HV3,
473 static const struct ioctl_data set_pkt_type_2dh = {
475 .opt = HCI_2DH1 | HCI_2DH3 | HCI_2DH5,
478 static const struct ioctl_data set_pkt_type_3dh = {
480 .opt = HCI_3DH1 | HCI_3DH3 | HCI_3DH5,
483 static const struct ioctl_data set_pkt_type_all = {
485 .opt = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5 |
486 HCI_HV1 | HCI_HV2 | HCI_HV3 | HCI_2DH1 | HCI_2DH3 | HCI_2DH5 |
487 HCI_3DH1 | HCI_3DH3 | HCI_3DH5,
490 static const struct ioctl_data set_acl_mtu_1 = {
492 .opt = 0x1 | (0x3FE << 16),
495 static const struct ioctl_data set_acl_mtu_2 = {
497 .opt = 0x4 | (0x63 << 16),
500 static const struct ioctl_data set_sco_mtu_1 = {
502 .opt = 0x1 | (0x3FE << 16),
505 static const struct ioctl_data set_sco_mtu_2 = {
507 .opt = 0x4 | (0x63 << 16),
510 static const uint8_t bdaddr1[] = {
511 0x11, 0x22, 0x33, 0x44, 0x55, 0x66
514 static const struct ioctl_data block_bdaddr_success = {
519 static const struct ioctl_data block_bdaddr_fail = {
522 .expected_ioctl_err = EEXIST,
523 .block_bdaddr = bdaddr1,
526 static const struct ioctl_data unblock_bdaddr_success = {
527 .cmd = HCIUNBLOCKADDR,
529 .block_bdaddr = bdaddr1,
532 static const struct ioctl_data unblock_bdaddr_fail = {
533 .cmd = HCIUNBLOCKADDR,
535 .expected_ioctl_err = ENOENT,
538 static const struct hci_conn_list_req conn_list_empty = {
543 static const struct ioctl_data conn_list_no_conn = {
544 .cmd = HCIGETCONNLIST,
545 .expected_data = (void *)&conn_list_empty,
546 .expect_data_check_func = conn_list_empty_check_func,
549 static const struct hci_conn_list_req conn_list_req_1 = {
554 .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
558 .link_mode = 0x00000000,
562 static const struct ioctl_data conn_list = {
563 .cmd = HCIGETCONNLIST,
564 .expected_data = (void *)&conn_list_req_1,
567 static const struct hci_conn_info_req conn_info_req = {
568 .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
572 .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
576 .link_mode = 0x00000000,
580 static const struct hci_conn_info_req conn_info_req_acl = {
581 .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
585 static const struct hci_conn_info_req conn_info_req_sco = {
586 .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
590 static const struct ioctl_data conn_info = {
591 .cmd = HCIGETCONNINFO,
592 .param = (void *)&conn_info_req_acl,
593 .cmd_param_func = conn_info_cmd_param_func,
594 .expected_data = (void *)&conn_info_req,
597 static const struct ioctl_data conn_info_no_conn = {
598 .cmd = HCIGETCONNINFO,
599 .param = (void *)&conn_info_req_acl,
600 .expected_ioctl_err = ENOENT,
601 .cmd_param_func = conn_info_cmd_param_func,
604 static const struct ioctl_data conn_info_wrong_type = {
605 .cmd = HCIGETCONNINFO,
606 .param = (void *)&conn_info_req_sco,
607 .expected_ioctl_err = ENOENT,
608 .cmd_param_func = conn_info_cmd_param_func,
611 static const struct hci_auth_info_req auth_info_req = {
612 .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
615 static const struct hci_auth_info_req auth_info_connected = {
616 .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
620 static const struct ioctl_data auth_info_no_conn = {
621 .cmd = HCIGETAUTHINFO,
622 .param = (void *)&auth_info_req,
623 .expected_ioctl_err = ENOENT,
624 .cmd_param_func = auth_info_cmd_param_func,
627 static const struct ioctl_data auth_info = {
628 .cmd = HCIGETAUTHINFO,
629 .param = (void *)&auth_info_req,
630 .cmd_param_func = auth_info_cmd_param_func,
631 .expected_data = (void *)&auth_info_connected,
634 /* Allocate the command request parameters based on the command.
635 * returns the allocated request buffer and its length
637 static int test_alloc_cmd_param(void **req, uint32_t *req_len)
639 struct test_data *data = tester_get_data();
640 const struct ioctl_data *ioctl_data = data->test_data;
641 struct hci_dev_req *dr = NULL;
642 struct hci_dev_info *di = NULL;
643 struct hci_dev_list_req *dl = NULL;
644 struct hci_conn_list_req *cl = NULL;
645 struct hci_conn_info *ci = NULL;
646 struct hci_conn_info_req *cr = NULL;
647 struct hci_auth_info_req *ar = NULL;
648 bdaddr_t *bdaddr = NULL;
651 switch (ioctl_data->cmd) {
663 dr->dev_id = data->hci_dev_id;
664 dr->dev_opt = ioctl_data->opt;
674 di->dev_id = data->hci_dev_id;
679 len = sizeof(*dr) + sizeof(uint16_t);
689 len = sizeof(*cl) + sizeof(*ci);
694 cl->dev_id = data->hci_dev_id;
700 len = sizeof(*cr) + sizeof(*ci);
719 len = sizeof(bdaddr_t);
720 bdaddr = malloc(len);
723 memset(bdaddr, 0, len);
731 /* These command uses the HCI dev id for param */
740 static void test_ioctl_common(const void *test_data)
742 struct test_data *data = tester_get_data();
743 const struct ioctl_data *ioctl_data = data->test_data;
744 bool use_dev_id = false;
746 uint32_t req_len = 0;
749 ret = test_alloc_cmd_param(&req, &req_len);
754 tester_warn("Failed to allocate CMD parameter");
755 tester_test_failed();
760 if (ioctl_data->expected_ioctl_err)
761 test_add_condition(data);
763 if (ioctl_data->expected_data)
764 test_add_condition(data);
766 if (!use_dev_id && ioctl_data->param) {
767 test_add_condition(data);
768 if (ioctl_data->cmd_param_func) {
769 ret = ioctl_data->cmd_param_func(req, &req_len);
771 tester_warn("Failed to update cmd param");
772 tester_test_failed();
776 memcpy(req, ioctl_data->param, req_len);
778 tester_print("Command Parameter is updated");
779 test_condition_complete(data);
783 ret = ioctl(data->sock_fd, ioctl_data->cmd, data->hci_dev_id);
785 ret = ioctl(data->sock_fd, ioctl_data->cmd, req);
788 if (ioctl_data->expected_ioctl_err) {
789 if (errno != ioctl_data->expected_ioctl_err) {
790 tester_warn("Unexpected error: %d expected: %d",
791 errno, ioctl_data->expected_ioctl_err);
792 tester_test_failed();
796 test_condition_complete(data);
797 tester_print("Received expected error: %d", errno);
801 tester_warn("IOCTL failed with error: %d", errno);
802 tester_test_failed();
806 if (ioctl_data->expected_data && req) {
807 if (ioctl_data->expect_data_check_func)
808 ret = ioctl_data->expect_data_check_func(req, req_len);
810 ret = memcmp(req, ioctl_data->expected_data, req_len);
813 tester_warn("Mismatch expected data");
814 util_hexdump('>', req, req_len, print_debug, "");
815 util_hexdump('!', ioctl_data->expected_data, req_len,
817 tester_test_failed();
821 test_condition_complete(data);
825 tester_test_passed();
832 static void test_ioctl_connected_event(uint16_t index, uint16_t length,
833 const void *param, void *user_data)
835 struct test_data *data = tester_get_data();
837 tester_print("Device Connected");
839 test_ioctl_common(data);
842 static void test_ioctl_connection(const void *test_data)
844 struct test_data *data = tester_get_data();
846 const uint8_t *central_bdaddr;
847 struct bthost *bthost;
850 tester_print("Registering %s notification",
851 mgmt_evstr(MGMT_EV_DEVICE_CONNECTED));
852 id = mgmt_register(data->mgmt_alt, MGMT_EV_DEVICE_CONNECTED,
854 test_ioctl_connected_event,
856 data->mgmt_alt_ev_id = id;
858 central_bdaddr = hciemu_get_central_bdaddr(data->hciemu);
859 if (!central_bdaddr) {
860 tester_warn("No central bdaddr");
861 tester_setup_failed();
865 addr_type = data->hciemu_type == HCIEMU_TYPE_BREDRLE ? BDADDR_BREDR :
867 tester_print("ADDR TYPE: %d", addr_type);
868 bthost = hciemu_client_get_host(data->hciemu);
869 bthost_hci_connect(bthost, central_bdaddr, addr_type);
872 int main(int argc, char *argv[])
874 tester_init(&argc, &argv);
876 test_ioctl("HCI Down", &dev_down, NULL, test_ioctl_common);
878 test_ioctl("Device List", &dev_list,
879 NULL, test_ioctl_common);
881 test_ioctl("Device List - Invalid Param 1", &dev_list_invalid_1,
882 NULL, test_ioctl_common);
884 test_ioctl("Device Info", &dev_info,
885 NULL, test_ioctl_common);
887 test_ioctl("Reset Stat", &reset_stat,
888 setup_powered, test_ioctl_common);
890 test_ioctl("Set Link Mode - ACCEPT", &set_link_mode_accept,
891 NULL, test_ioctl_common);
893 test_ioctl("Set Link Mode - MASTER", &set_link_mode_master,
894 NULL, test_ioctl_common);
896 test_ioctl("Set Pkt Type - DM", &set_pkt_type_dm,
897 NULL, test_ioctl_common);
899 test_ioctl("Set Pkt Type - DH", &set_pkt_type_dh,
900 NULL, test_ioctl_common);
902 test_ioctl("Set Pkt Type - HV", &set_pkt_type_hv,
903 NULL, test_ioctl_common);
905 test_ioctl("Set Pkt Type - 2-DH", &set_pkt_type_2dh,
906 NULL, test_ioctl_common);
908 test_ioctl("Set Pkt Type - 2-DH", &set_pkt_type_3dh,
909 NULL, test_ioctl_common);
911 test_ioctl("Set Pkt Type - ALL", &set_pkt_type_all,
912 NULL, test_ioctl_common);
914 test_ioctl("Set ACL MTU - 1", &set_acl_mtu_1,
915 NULL, test_ioctl_common);
917 test_ioctl("Set ACL MTU - 2", &set_acl_mtu_2,
918 NULL, test_ioctl_common);
920 test_ioctl("Set SCO MTU - 1", &set_sco_mtu_1,
921 NULL, test_ioctl_common);
923 test_ioctl("Set SCO MTU - 2", &set_sco_mtu_2,
924 NULL, test_ioctl_common);
926 test_ioctl("Block BDADDR - Success", &block_bdaddr_success,
927 NULL, test_ioctl_common);
929 test_ioctl("Block BDADDR - Fail", &block_bdaddr_fail,
930 setup_add_block_bdaddr, test_ioctl_common);
932 test_ioctl("Unblock BDADDR - Success", &unblock_bdaddr_success,
933 setup_add_block_bdaddr, test_ioctl_common);
935 test_ioctl("Unblock BDADDR - Fail", &unblock_bdaddr_fail,
936 NULL, test_ioctl_common);
938 test_ioctl("Connection List - No Conn", &conn_list_no_conn,
939 NULL, test_ioctl_common);
941 test_ioctl("Connection List", &conn_list,
942 setup_powered, test_ioctl_connection);
944 test_ioctl("Connection Info", &conn_info,
945 setup_powered, test_ioctl_connection);
947 test_ioctl("Connection Info - No Connection", &conn_info_no_conn,
948 setup_powered, test_ioctl_common);
950 test_ioctl("Connection Info - Wrong Type", &conn_info_wrong_type,
951 setup_powered, test_ioctl_common);
953 test_ioctl("Authentication Info - No Connection", &auth_info_no_conn,
954 setup_powered, test_ioctl_common);
956 test_ioctl("Authentication Info", &auth_info,
957 setup_powered, test_ioctl_connection);