tools/ioctl-tester - Add ioctl-tester
[platform/upstream/bluez.git] / tools / ioctl-tester.c
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3  *
4  *  BlueZ - Bluetooth protocol stack for Linux
5  *
6  *  Copyright (C) 2022  Intel Corporation.
7  *
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <errno.h>
17 #include <poll.h>
18 #include <stdbool.h>
19
20 #include <sys/ioctl.h>
21 #include <sys/socket.h>
22
23 #include <glib.h>
24
25 #include "lib/bluetooth.h"
26 #include "lib/mgmt.h"
27 #include "lib/hci.h"
28 #include "lib/hci_lib.h"
29
30 #include "monitor/bt.h"
31 #include "emulator/bthost.h"
32 #include "emulator/hciemu.h"
33
34 #include "src/shared/tester.h"
35 #include "src/shared/mgmt.h"
36 #include "src/shared/util.h"
37
38 struct test_data {
39         const void *test_data;
40         int sock_fd;
41         struct hciemu *hciemu;
42         enum hciemu_type hciemu_type;
43         uint8_t client_num;
44         uint16_t hci_dev_id;
45
46         struct mgmt *mgmt;
47         uint16_t mgmt_index;
48         struct mgmt *mgmt_alt;
49         unsigned int mgmt_alt_ev_id;
50
51         uint16_t handle;
52         uint16_t acl_handle;
53         GIOChannel *io;
54         unsigned int io_id[2];
55         int step;
56         bool reconnect;
57
58         int unmet_conditions;
59 };
60
61 struct ioctl_data {
62         uint32_t cmd;
63         const uint32_t opt;
64         const void *param;
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);
70 };
71
72 static void print_debug(const char *str, void *user_data)
73 {
74         const char *prefix = user_data;
75
76         tester_print("%s%s", prefix, str);
77 }
78
79 static void test_add_condition(struct test_data *data)
80 {
81         data->unmet_conditions++;
82
83         tester_print("Test condition added, total %d", data->unmet_conditions);
84 }
85
86 static void test_condition_complete(struct test_data *data)
87 {
88         data->unmet_conditions--;
89
90         tester_print("Test condition complete, %d left",
91                                                 data->unmet_conditions);
92
93         if (data->unmet_conditions > 0)
94                 return;
95
96         tester_test_passed();
97 }
98
99 static int update_hci_dev_id(struct test_data *data)
100 {
101         struct hci_dev_list_req *dl;
102         struct hci_dev_req *dr;
103         int ret = 0;
104
105         dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(uint16_t));
106         if (!dl)
107                 return -ENOMEM;
108
109         dl->dev_num = HCI_MAX_DEV;
110         dr = dl->dev_req;
111
112         if (ioctl(data->sock_fd, HCIGETDEVLIST, (void *) dl) < 0) {
113                 ret = -EIO;
114                 goto exit;
115         }
116
117         if (dl->dev_num != 1) {
118                 tester_warn("dev num mismatch returned %d:expected 1",
119                                                                 dl->dev_num);
120                 ret = -ENODEV;
121                 goto exit;
122         }
123
124         data->hci_dev_id = dr->dev_id;
125         tester_print("HCI device id: %d", data->hci_dev_id);
126
127 exit:
128         free(dl);
129         return ret;
130 }
131
132 static void read_info_callback(uint8_t status, uint16_t length,
133                                         const void *param, void *user_data)
134 {
135         struct test_data *data = tester_get_data();
136         const struct mgmt_rp_read_info *rp = param;
137         char addr[18];
138         uint16_t manufacturer;
139         uint32_t supported_settings, current_settings;
140
141         tester_print("Read Info callback");
142         tester_print("  Status: 0x%02x", status);
143
144         if (status || !param) {
145                 tester_pre_setup_failed();
146                 return;
147         }
148
149         ba2str(&rp->bdaddr, addr);
150         manufacturer = btohs(rp->manufacturer);
151         supported_settings = btohl(rp->supported_settings);
152         current_settings = btohl(rp->current_settings);
153
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);
163
164         if (strcmp(hciemu_get_address(data->hciemu), addr)) {
165                 tester_pre_setup_failed();
166                 return;
167         }
168
169         tester_pre_setup_complete();
170 }
171
172 static void index_added_callback(uint16_t index, uint16_t length,
173                                         const void *param, void *user_data)
174 {
175         struct test_data *data = tester_get_data();
176
177         tester_print("Index Added callback");
178         tester_print("  Index: 0x%04x", index);
179
180         data->mgmt_index = index;
181
182         mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
183                                         read_info_callback, NULL, NULL);
184 }
185
186 static void index_removed_callback(uint16_t index, uint16_t length,
187                                         const void *param, void *user_data)
188 {
189         struct test_data *data = tester_get_data();
190
191         tester_print("Index Removed callback");
192         tester_print("  Index: 0x%04x", index);
193
194         if (index != data->mgmt_index)
195                 return;
196
197         mgmt_unregister_index(data->mgmt, data->mgmt_index);
198         mgmt_unregister_index(data->mgmt_alt, data->mgmt_index);
199
200         mgmt_unref(data->mgmt);
201         data->mgmt = NULL;
202
203         mgmt_unref(data->mgmt_alt);
204         data->mgmt_alt = NULL;
205
206         tester_post_teardown_complete();
207 }
208
209 static void read_index_list_callback(uint8_t status, uint16_t length,
210                                         const void *param, void *user_data)
211 {
212         struct test_data *data = tester_get_data();
213
214         tester_print("Read Index List callback");
215         tester_print("  Status: 0x%02x", status);
216
217         if (status || !param) {
218                 tester_pre_setup_failed();
219                 return;
220         }
221
222         mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
223                                         index_added_callback, NULL, NULL);
224
225         mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
226                                         index_removed_callback, NULL, NULL);
227
228         data->hciemu = hciemu_new(data->hciemu_type);
229         if (!data->hciemu) {
230                 tester_warn("Failed to setup HCI emulation");
231                 tester_pre_setup_failed();
232         }
233
234         if (tester_use_debug())
235                 hciemu_set_debug(data->hciemu, print_debug, "hciemu: ", NULL);
236
237         tester_print("New hciemu instance created");
238
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();
243                 return;
244         }
245
246         update_hci_dev_id(data);
247 }
248
249 static void test_pre_setup(const void *test_data)
250 {
251         struct test_data *data = tester_get_data();
252
253         data->mgmt = mgmt_new_default();
254         if (!data->mgmt) {
255                 tester_warn("Failed to setup mgmt interface");
256                 tester_pre_setup_failed();
257                 return;
258         }
259
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();
264
265                 mgmt_unref(data->mgmt);
266                 data->mgmt = NULL;
267                 return;
268         }
269
270
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);
274         }
275
276         mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
277                                         read_index_list_callback, NULL, NULL);
278 }
279
280 static void test_post_teardown(const void *test_data)
281 {
282         struct test_data *data = tester_get_data();
283
284         if (data->sock_fd >= 0) {
285                 tester_print("Socket closed");
286                 hci_close_dev(data->sock_fd);
287         }
288
289         hciemu_unref(data->hciemu);
290         data->hciemu = NULL;
291 }
292
293 static void test_data_free(void *test_data)
294 {
295         struct test_data *data = test_data;
296
297         // TODO: free any data allocated during pre-setup
298
299         free(data);
300 }
301
302 #define test_ioctl_full(name, data, setup, func, num) \
303         do { \
304                 struct test_data *user; \
305                 user = new0(struct test_data, 1); \
306                 if (!user) \
307                         break; \
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); \
314         } while (0)
315
316 #define test_ioctl(name, data, setup, func) \
317         test_ioctl_full(name, data, setup, func, 1)
318
319 static void setup_powered_callback(uint8_t status, uint16_t length,
320                                         const void *param, void *user_data)
321 {
322         if (status != MGMT_STATUS_SUCCESS) {
323                 tester_setup_failed();
324                 return;
325         }
326
327         tester_print("Controller powered on");
328
329         tester_setup_complete();
330 }
331
332 static void setup_powered(const void *test_data)
333 {
334         struct test_data *data = tester_get_data();
335         unsigned char param[] = { 0x01 };
336
337         mgmt_send(data->mgmt, MGMT_OP_SET_BONDABLE, data->mgmt_index,
338                                 sizeof(param), param, NULL, NULL, NULL);
339
340         mgmt_send(data->mgmt, MGMT_OP_SET_CONNECTABLE, data->mgmt_index,
341                                 sizeof(param), param, NULL, NULL, NULL);
342
343         mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
344                                 sizeof(param), param, NULL, NULL, NULL);
345
346         mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
347                                         sizeof(param), param,
348                                         setup_powered_callback, NULL, NULL);
349 }
350
351 static void setup_add_block_bdaddr(const void *test_data)
352 {
353         struct test_data *data = tester_get_data();
354         const struct ioctl_data *ioctl_data = data->test_data;
355
356         if (!ioctl_data->block_bdaddr) {
357                 tester_warn("Invalid test data: block bdaddr");
358                 tester_setup_failed();
359                 return;
360         }
361
362         if (ioctl(data->sock_fd, HCIBLOCKADDR, ioctl_data->block_bdaddr) < 0) {
363                 tester_warn("Failed to add block bdaddr");
364                 tester_setup_failed();
365                 return;
366         }
367
368         tester_print("Added block BDADDR");
369
370         tester_setup_complete();
371 }
372
373 static int conn_list_empty_check_func(const void *param, uint32_t length)
374 {
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;
379
380         if (cl->conn_num != cl_input->conn_num)
381                 return -1;
382
383         return 0;
384 }
385
386 static int conn_info_cmd_param_func(void *param, uint32_t *length)
387 {
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;
392
393         memcpy(&cr->bdaddr, &cr_input->bdaddr, sizeof(bdaddr_t));
394         cr->type = cr_input->type;
395
396         return 0;
397 }
398
399 static int auth_info_cmd_param_func(void *param, uint32_t *length)
400 {
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;
405
406         memcpy(&ar->bdaddr, &ar_input->bdaddr, sizeof(bdaddr_t));
407         if (ar_input->type)
408                 ar->type = ar_input->type;
409
410         return 0;
411 }
412
413 static const struct ioctl_data dev_down = {
414         .cmd = HCIDEVDOWN,
415 };
416
417 static const struct hci_dev_list_req dev_list_1 = {
418         .dev_num = 0x01,
419         .dev_req = {{
420                 .dev_id = 0x00,
421                 .dev_opt = 0x04,
422         }},
423 };
424
425 static const struct ioctl_data dev_list = {
426         .cmd = HCIGETDEVLIST,
427         .expected_data = (void *)&dev_list_1,
428 };
429
430 static const struct hci_dev_list_req dev_list_invalid_1_param = {
431         .dev_num = 0x00,
432 };
433
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,
438 };
439
440 static const struct ioctl_data dev_info = {
441         .cmd = HCIGETDEVINFO,
442 };
443
444 static const struct ioctl_data reset_stat = {
445         .cmd = HCIDEVRESTAT,
446 };
447
448 static const struct ioctl_data set_link_mode_master = {
449         .cmd = HCISETLINKMODE,
450         .opt = HCI_LM_MASTER,
451 };
452
453 static const struct ioctl_data set_link_mode_accept = {
454         .cmd = HCISETLINKMODE,
455         .opt = HCI_LM_ACCEPT,
456 };
457
458 static const struct ioctl_data set_pkt_type_dm = {
459         .cmd = HCISETPTYPE,
460         .opt = HCI_DM1 | HCI_DM3 | HCI_DM5,
461 };
462
463 static const struct ioctl_data set_pkt_type_dh = {
464         .cmd = HCISETPTYPE,
465         .opt = HCI_DH1 | HCI_DH3 | HCI_DH5,
466 };
467
468 static const struct ioctl_data set_pkt_type_hv = {
469         .cmd = HCISETPTYPE,
470         .opt = HCI_HV1 | HCI_HV2 | HCI_HV3,
471 };
472
473 static const struct ioctl_data set_pkt_type_2dh = {
474         .cmd = HCISETPTYPE,
475         .opt = HCI_2DH1 | HCI_2DH3 | HCI_2DH5,
476 };
477
478 static const struct ioctl_data set_pkt_type_3dh = {
479         .cmd = HCISETPTYPE,
480         .opt = HCI_3DH1 | HCI_3DH3 | HCI_3DH5,
481 };
482
483 static const struct ioctl_data set_pkt_type_all = {
484         .cmd = HCISETPTYPE,
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,
488 };
489
490 static const struct ioctl_data set_acl_mtu_1 = {
491         .cmd = HCISETACLMTU,
492         .opt = 0x1 | (0x3FE << 16),
493 };
494
495 static const struct ioctl_data set_acl_mtu_2 = {
496         .cmd = HCISETACLMTU,
497         .opt = 0x4 | (0x63 << 16),
498 };
499
500 static const struct ioctl_data set_sco_mtu_1 = {
501         .cmd = HCISETSCOMTU,
502         .opt = 0x1 | (0x3FE << 16),
503 };
504
505 static const struct ioctl_data set_sco_mtu_2 = {
506         .cmd = HCISETSCOMTU,
507         .opt = 0x4 | (0x63 << 16),
508 };
509
510 static const uint8_t bdaddr1[] = {
511         0x11, 0x22, 0x33, 0x44, 0x55, 0x66
512 };
513
514 static const struct ioctl_data block_bdaddr_success = {
515         .cmd = HCIBLOCKADDR,
516         .param = bdaddr1,
517 };
518
519 static const struct ioctl_data block_bdaddr_fail = {
520         .cmd = HCIBLOCKADDR,
521         .param = bdaddr1,
522         .expected_ioctl_err = EEXIST,
523         .block_bdaddr = bdaddr1,
524 };
525
526 static const struct ioctl_data unblock_bdaddr_success = {
527         .cmd = HCIUNBLOCKADDR,
528         .param = bdaddr1,
529         .block_bdaddr = bdaddr1,
530 };
531
532 static const struct ioctl_data unblock_bdaddr_fail = {
533         .cmd = HCIUNBLOCKADDR,
534         .param = bdaddr1,
535         .expected_ioctl_err = ENOENT,
536 };
537
538 static const struct hci_conn_list_req conn_list_empty = {
539         .dev_id = 0x00,
540         .conn_num = 0x00,
541 };
542
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,
547 };
548
549 static const struct hci_conn_list_req conn_list_req_1 = {
550         .dev_id = 0x00,
551         .conn_num = 0x01,
552         .conn_info = {{
553                 .handle = 0x002a,
554                 .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
555                 .type = 0x01,
556                 .out = 0x00,
557                 .state = 0x0001,
558                 .link_mode = 0x00000000,
559         }},
560 };
561
562 static const struct ioctl_data conn_list = {
563         .cmd = HCIGETCONNLIST,
564         .expected_data = (void *)&conn_list_req_1,
565 };
566
567 static const struct hci_conn_info_req conn_info_req = {
568         .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
569         .type = ACL_LINK,
570         .conn_info = {{
571                 .handle = 0x002a,
572                 .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
573                 .type = 0x01,
574                 .out = 0x00,
575                 .state = 0x0001,
576                 .link_mode = 0x00000000,
577         }},
578 };
579
580 static const struct hci_conn_info_req conn_info_req_acl = {
581         .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
582         .type = ACL_LINK,
583 };
584
585 static const struct hci_conn_info_req conn_info_req_sco = {
586         .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
587         .type = SCO_LINK,
588 };
589
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,
595 };
596
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,
602 };
603
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,
609 };
610
611 static const struct hci_auth_info_req auth_info_req = {
612         .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
613 };
614
615 static const struct hci_auth_info_req auth_info_connected = {
616         .bdaddr = {{ 0x00, 0x00, 0x01, 0x01, 0xaa, 0x00 }},
617         .type = 0x04,
618 };
619
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,
625 };
626
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,
632 };
633
634 /* Allocate the command request parameters based on the command.
635  * returns the allocated request buffer and its length
636  */
637 static int test_alloc_cmd_param(void **req, uint32_t *req_len)
638 {
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;
649         uint32_t len;
650
651         switch (ioctl_data->cmd) {
652         case HCISETAUTH:
653         case HCISETENCRYPT:
654         case HCISETLINKMODE:
655         case HCISETPTYPE:
656         case HCISETACLMTU:
657         case HCISETSCOMTU:
658                 len = sizeof(*dr);
659                 dr = malloc(len);
660                 if (!dr)
661                         return -ENOMEM;
662                 memset(dr, 0, len);
663                 dr->dev_id = data->hci_dev_id;
664                 dr->dev_opt = ioctl_data->opt;
665                 *req = dr;
666                 *req_len = len;
667                 break;
668         case HCIGETDEVINFO:
669                 len = sizeof(*di);
670                 di = malloc(len);
671                 if (!di)
672                         return -ENOMEM;
673                 memset(di, 0, len);
674                 di->dev_id = data->hci_dev_id;
675                 *req = di;
676                 *req_len = len;
677                 break;
678         case HCIGETDEVLIST:
679                 len = sizeof(*dr) + sizeof(uint16_t);
680                 dl = malloc(len);
681                 if (!dl)
682                         return -ENOMEM;
683                 memset(dl, 0, len);
684                 dl->dev_num = 1;
685                 *req = dl;
686                 *req_len = len;
687                 break;
688         case HCIGETCONNLIST:
689                 len = sizeof(*cl) + sizeof(*ci);
690                 cl = malloc(len);
691                 if (!cl)
692                         return -ENOMEM;
693                 memset(cl, 0, len);
694                 cl->dev_id = data->hci_dev_id;
695                 cl->conn_num = 1;
696                 *req = cl;
697                 *req_len = len;
698                 break;
699         case HCIGETCONNINFO:
700                 len = sizeof(*cr) + sizeof(*ci);
701                 cr = malloc(len);
702                 if (!cr)
703                         return -ENOMEM;
704                 memset(cr, 0, len);
705                 *req = cr;
706                 *req_len = len;
707                 break;
708         case HCIGETAUTHINFO:
709                 len = sizeof(*ar);
710                 ar = malloc(len);
711                 if (!ar)
712                         return -ENOMEM;
713                 memset(ar, 0, len);
714                 *req = ar;
715                 *req_len = len;
716                 break;
717         case HCIBLOCKADDR:
718         case HCIUNBLOCKADDR:
719                 len = sizeof(bdaddr_t);
720                 bdaddr = malloc(len);
721                 if (!bdaddr)
722                         return -ENOMEM;
723                 memset(bdaddr, 0, len);
724                 *req = bdaddr;
725                 *req_len = len;
726                 break;
727         case HCIDEVUP:
728         case HCIDEVDOWN:
729         case HCIDEVRESET:
730         case HCIDEVRESTAT:
731                 /* These command uses the HCI dev id for param */
732                 return -ENODATA;
733         default:
734                 return -EINVAL;
735         }
736
737         return 0;
738 }
739
740 static void test_ioctl_common(const void *test_data)
741 {
742         struct test_data *data = tester_get_data();
743         const struct ioctl_data *ioctl_data = data->test_data;
744         bool use_dev_id = false;
745         void *req = NULL;
746         uint32_t req_len = 0;
747         int ret;
748
749         ret = test_alloc_cmd_param(&req, &req_len);
750         if (ret < 0) {
751                 if (ret == -ENODATA)
752                         use_dev_id = true;
753                 else {
754                         tester_warn("Failed to allocate CMD parameter");
755                         tester_test_failed();
756                         return;
757                 }
758         }
759
760         if (ioctl_data->expected_ioctl_err)
761                 test_add_condition(data);
762
763         if (ioctl_data->expected_data)
764                 test_add_condition(data);
765
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);
770                         if (ret) {
771                                 tester_warn("Failed to update cmd param");
772                                 tester_test_failed();
773                                 goto exit_free;
774                         }
775                 } else
776                         memcpy(req, ioctl_data->param, req_len);
777
778                 tester_print("Command Parameter is updated");
779                 test_condition_complete(data);
780         }
781
782         if (use_dev_id)
783                 ret = ioctl(data->sock_fd, ioctl_data->cmd, data->hci_dev_id);
784         else
785                 ret = ioctl(data->sock_fd, ioctl_data->cmd, req);
786
787         if (ret < 0) {
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();
793                                 goto exit_free;
794                         }
795
796                         test_condition_complete(data);
797                         tester_print("Received expected error: %d", errno);
798                         goto exit_pass;
799                 }
800
801                 tester_warn("IOCTL failed with error: %d", errno);
802                 tester_test_failed();
803                 goto exit_free;
804         }
805
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);
809                 else
810                         ret = memcmp(req, ioctl_data->expected_data, req_len);
811
812                 if (ret != 0) {
813                         tester_warn("Mismatch expected data");
814                         util_hexdump('>', req, req_len, print_debug, "");
815                         util_hexdump('!', ioctl_data->expected_data, req_len,
816                                                         print_debug, "");
817                         tester_test_failed();
818                         goto exit_free;
819                 }
820
821                 test_condition_complete(data);
822         }
823
824 exit_pass:
825         tester_test_passed();
826 exit_free:
827         if (req)
828                 free(req);
829
830 }
831
832 static void test_ioctl_connected_event(uint16_t index, uint16_t length,
833                                         const void *param, void *user_data)
834 {
835         struct test_data *data = tester_get_data();
836
837         tester_print("Device Connected");
838
839         test_ioctl_common(data);
840 }
841
842 static void test_ioctl_connection(const void *test_data)
843 {
844         struct test_data *data = tester_get_data();
845         unsigned int id;
846         const uint8_t *central_bdaddr;
847         struct bthost *bthost;
848         uint8_t addr_type;
849
850         tester_print("Registering %s notification",
851                                         mgmt_evstr(MGMT_EV_DEVICE_CONNECTED));
852         id = mgmt_register(data->mgmt_alt, MGMT_EV_DEVICE_CONNECTED,
853                                 data->mgmt_index,
854                                 test_ioctl_connected_event,
855                                 NULL, NULL);
856         data->mgmt_alt_ev_id = id;
857
858         central_bdaddr = hciemu_get_central_bdaddr(data->hciemu);
859         if (!central_bdaddr) {
860                 tester_warn("No central bdaddr");
861                 tester_setup_failed();
862                 return;
863         }
864
865         addr_type = data->hciemu_type == HCIEMU_TYPE_BREDRLE ? BDADDR_BREDR :
866                                                         BDADDR_LE_PUBLIC;
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);
870 }
871
872 int main(int argc, char *argv[])
873 {
874         tester_init(&argc, &argv);
875
876         test_ioctl("HCI Down", &dev_down, NULL, test_ioctl_common);
877
878         test_ioctl("Device List", &dev_list,
879                                 NULL, test_ioctl_common);
880
881         test_ioctl("Device List - Invalid Param 1", &dev_list_invalid_1,
882                                 NULL, test_ioctl_common);
883
884         test_ioctl("Device Info", &dev_info,
885                                 NULL, test_ioctl_common);
886
887         test_ioctl("Reset Stat", &reset_stat,
888                                 setup_powered, test_ioctl_common);
889
890         test_ioctl("Set Link Mode - ACCEPT", &set_link_mode_accept,
891                                 NULL, test_ioctl_common);
892
893         test_ioctl("Set Link Mode - MASTER", &set_link_mode_master,
894                                 NULL, test_ioctl_common);
895
896         test_ioctl("Set Pkt Type - DM", &set_pkt_type_dm,
897                                 NULL, test_ioctl_common);
898
899         test_ioctl("Set Pkt Type - DH", &set_pkt_type_dh,
900                                 NULL, test_ioctl_common);
901
902         test_ioctl("Set Pkt Type - HV", &set_pkt_type_hv,
903                                 NULL, test_ioctl_common);
904
905         test_ioctl("Set Pkt Type - 2-DH", &set_pkt_type_2dh,
906                                 NULL, test_ioctl_common);
907
908         test_ioctl("Set Pkt Type - 2-DH", &set_pkt_type_3dh,
909                                 NULL, test_ioctl_common);
910
911         test_ioctl("Set Pkt Type - ALL", &set_pkt_type_all,
912                                 NULL, test_ioctl_common);
913
914         test_ioctl("Set ACL MTU - 1", &set_acl_mtu_1,
915                                 NULL, test_ioctl_common);
916
917         test_ioctl("Set ACL MTU - 2", &set_acl_mtu_2,
918                                 NULL, test_ioctl_common);
919
920         test_ioctl("Set SCO MTU - 1", &set_sco_mtu_1,
921                                 NULL, test_ioctl_common);
922
923         test_ioctl("Set SCO MTU - 2", &set_sco_mtu_2,
924                                 NULL, test_ioctl_common);
925
926         test_ioctl("Block BDADDR - Success", &block_bdaddr_success,
927                                 NULL, test_ioctl_common);
928
929         test_ioctl("Block BDADDR - Fail", &block_bdaddr_fail,
930                                 setup_add_block_bdaddr, test_ioctl_common);
931
932         test_ioctl("Unblock BDADDR - Success", &unblock_bdaddr_success,
933                                 setup_add_block_bdaddr, test_ioctl_common);
934
935         test_ioctl("Unblock BDADDR - Fail", &unblock_bdaddr_fail,
936                                 NULL, test_ioctl_common);
937
938         test_ioctl("Connection List - No Conn", &conn_list_no_conn,
939                                 NULL, test_ioctl_common);
940
941         test_ioctl("Connection List", &conn_list,
942                                 setup_powered, test_ioctl_connection);
943
944         test_ioctl("Connection Info", &conn_info,
945                                 setup_powered, test_ioctl_connection);
946
947         test_ioctl("Connection Info - No Connection", &conn_info_no_conn,
948                                 setup_powered, test_ioctl_common);
949
950         test_ioctl("Connection Info - Wrong Type", &conn_info_wrong_type,
951                                 setup_powered, test_ioctl_common);
952
953         test_ioctl("Authentication Info - No Connection", &auth_info_no_conn,
954                                 setup_powered, test_ioctl_common);
955
956         test_ioctl("Authentication Info", &auth_info,
957                                 setup_powered, test_ioctl_connection);
958
959         return tester_run();
960 }