tizen 2.3.1 release
[framework/connectivity/bluez.git] / tools / hci-tester.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2013  Intel Corporation. All rights reserved.
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "monitor/bt.h"
32 #include "src/shared/hci.h"
33 #include "src/shared/util.h"
34 #include "src/shared/tester.h"
35
36 struct user_data {
37         const void *test_data;
38         uint16_t index_ut;
39         uint16_t index_lt;
40         struct bt_hci *hci_ut;          /* Upper Tester / IUT */
41         struct bt_hci *hci_lt;          /* Lower Tester / Reference */
42
43         uint8_t bdaddr_ut[6];
44         uint8_t bdaddr_lt[6];
45         uint16_t handle_ut;
46 };
47
48 static void test_pre_setup_lt_address(const void *data, uint8_t size,
49                                                         void *user_data)
50 {
51         struct user_data *user = tester_get_data();
52         const struct bt_hci_rsp_read_bd_addr *rsp = data;
53
54         if (rsp->status) {
55                 tester_warn("Read lower tester address failed (0x%02x)",
56                                                                 rsp->status);
57                 tester_pre_setup_failed();
58                 return;
59         }
60
61         memcpy(user->bdaddr_lt, rsp->bdaddr, 6);
62
63         tester_pre_setup_complete();
64 }
65
66 static void test_pre_setup_lt_complete(const void *data, uint8_t size,
67                                                         void *user_data)
68 {
69         struct user_data *user = tester_get_data();
70         uint8_t status = *((uint8_t *) data);
71
72         if (status) {
73                 tester_warn("Reset lower tester failed (0x%02x)", status);
74                 tester_pre_setup_failed();
75                 return;
76         }
77
78         if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_READ_BD_ADDR, NULL, 0,
79                                 test_pre_setup_lt_address, NULL, NULL)) {
80                 tester_warn("Failed to read lower tester address");
81                 tester_pre_setup_failed();
82                 return;
83         }
84 }
85
86 static void test_pre_setup_ut_address(const void *data, uint8_t size,
87                                                         void *user_data)
88 {
89         struct user_data *user = tester_get_data();
90         const struct bt_hci_rsp_read_bd_addr *rsp = data;
91
92         if (rsp->status) {
93                 tester_warn("Read upper tester address failed (0x%02x)",
94                                                                 rsp->status);
95                 tester_pre_setup_failed();
96                 return;
97         }
98
99         memcpy(user->bdaddr_ut, rsp->bdaddr, 6);
100
101         user->hci_lt = bt_hci_new_user_channel(user->index_lt);
102         if (!user->hci_lt) {
103                 tester_warn("Failed to setup lower tester user channel");
104                 tester_pre_setup_failed();
105                 return;
106         }
107
108         if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_RESET, NULL, 0,
109                                 test_pre_setup_lt_complete, NULL, NULL)) {
110                 tester_warn("Failed to reset lower tester");
111                 tester_pre_setup_failed();
112                 return;
113         }
114 }
115
116 static void test_pre_setup_ut_complete(const void *data, uint8_t size,
117                                                         void *user_data)
118 {
119         struct user_data *user = tester_get_data();
120         uint8_t status = *((uint8_t *) data);
121
122         if (status) {
123                 tester_warn("Reset upper tester failed (0x%02x)", status);
124                 tester_pre_setup_failed();
125                 return;
126         }
127
128         if (user->index_lt == 0xffff) {
129                 tester_pre_setup_complete();
130                 return;
131         }
132
133         if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_READ_BD_ADDR, NULL, 0,
134                                 test_pre_setup_ut_address, NULL, NULL)) {
135                 tester_warn("Failed to read upper tester address");
136                 tester_pre_setup_failed();
137                 return;
138         }
139 }
140
141 static void test_pre_setup(const void *test_data)
142 {
143         struct user_data *user = tester_get_data();
144
145         user->hci_ut = bt_hci_new_user_channel(user->index_ut);
146         if (!user->hci_ut) {
147                 tester_warn("Failed to setup upper tester user channel");
148                 tester_pre_setup_failed();
149                 return;
150         }
151
152         if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_RESET, NULL, 0,
153                                 test_pre_setup_ut_complete, NULL, NULL)) {
154                 tester_warn("Failed to reset upper tester");
155                 tester_pre_setup_failed();
156                 return;
157         }
158 }
159
160 static void test_post_teardown(const void *test_data)
161 {
162         struct user_data *user = tester_get_data();
163
164         bt_hci_unref(user->hci_lt);
165         user->hci_lt = NULL;
166
167         bt_hci_unref(user->hci_ut);
168         user->hci_ut = NULL;
169
170         tester_post_teardown_complete();
171 }
172
173 static void user_data_free(void *data)
174 {
175         struct user_data *user = data;
176
177         free(user);
178 }
179
180 #define test_hci(name, data, setup, func, teardown) \
181         do { \
182                 struct user_data *user; \
183                 user = calloc(1, sizeof(struct user_data)); \
184                 if (!user) \
185                         break; \
186                 user->test_data = data; \
187                 user->index_ut = 0; \
188                 user->index_lt = 1; \
189                 tester_add_full(name, data, \
190                                 test_pre_setup, setup, func, teardown, \
191                                 test_post_teardown, 30, user, user_data_free); \
192         } while (0)
193
194 #define test_hci_local(name, data, setup, func) \
195         do { \
196                 struct user_data *user; \
197                 user = calloc(1, sizeof(struct user_data)); \
198                 if (!user) \
199                         break; \
200                 user->test_data = data; \
201                 user->index_ut = 0; \
202                 user->index_lt = 0xffff; \
203                 tester_add_full(name, data, \
204                                 test_pre_setup, setup, func, NULL, \
205                                 test_post_teardown, 30, user, user_data_free); \
206         } while (0)
207
208 static void setup_features_complete(const void *data, uint8_t size,
209                                                         void *user_data)
210 {
211         const struct bt_hci_rsp_read_local_features *rsp = data;
212
213         if (rsp->status) {
214                 tester_warn("Failed to get HCI features (0x%02x)", rsp->status);
215                 tester_setup_failed();
216                 return;
217         }
218
219         tester_setup_complete();
220 }
221
222 static void setup_features(const void *test_data)
223 {
224         struct user_data *user = tester_get_data();
225
226         if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_READ_LOCAL_FEATURES, NULL, 0,
227                                         setup_features_complete, NULL, NULL)) {
228                 tester_warn("Failed to send HCI features command");
229                 tester_setup_failed();
230                 return;
231         }
232 }
233
234 static void test_reset(const void *test_data)
235 {
236         tester_test_passed();
237 }
238
239 static void test_command_complete(const void *data, uint8_t size,
240                                                         void *user_data)
241 {
242         uint8_t status = *((uint8_t *) data);
243
244         if (status) {
245                 tester_warn("HCI command failed (0x%02x)", status);
246                 tester_test_failed();
247                 return;
248         }
249
250         tester_test_passed();
251 }
252
253 static void test_command(uint16_t opcode)
254 {
255         struct user_data *user = tester_get_data();
256
257         if (!bt_hci_send(user->hci_ut, opcode, NULL, 0,
258                                         test_command_complete, NULL, NULL)) {
259                 tester_warn("Failed to send HCI command 0x%04x", opcode);
260                 tester_test_failed();
261                 return;
262         }
263 }
264
265 static void test_read_local_version_information(const void *test_data)
266 {
267         test_command(BT_HCI_CMD_READ_LOCAL_VERSION);
268 }
269
270 static void test_read_local_supported_commands(const void *test_data)
271 {
272         test_command(BT_HCI_CMD_READ_LOCAL_COMMANDS);
273 }
274
275 static void test_read_local_supported_features(const void *test_data)
276 {
277         test_command(BT_HCI_CMD_READ_LOCAL_FEATURES);
278 }
279
280 static void test_local_extended_features_complete(const void *data,
281                                                 uint8_t size, void *user_data)
282 {
283         const struct bt_hci_rsp_read_local_ext_features *rsp = data;
284
285         if (rsp->status) {
286                 tester_warn("Failed to get HCI extended features (0x%02x)",
287                                                                 rsp->status);
288                 tester_test_failed();
289                 return;
290         }
291
292         tester_test_passed();
293 }
294
295 static void test_read_local_extended_features(const void *test_data)
296 {
297         struct user_data *user = tester_get_data();
298         struct bt_hci_cmd_read_local_ext_features cmd;
299
300         cmd.page = 0x00;
301
302         if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_READ_LOCAL_EXT_FEATURES,
303                                         &cmd, sizeof(cmd),
304                                         test_local_extended_features_complete,
305                                                                 NULL, NULL)) {
306                 tester_warn("Failed to send HCI extended features command");
307                 tester_test_failed();
308                 return;
309         }
310 }
311
312 static void test_read_buffer_size(const void *test_data)
313 {
314         test_command(BT_HCI_CMD_READ_BUFFER_SIZE);
315 }
316
317 static void test_read_country_code(const void *test_data)
318 {
319         test_command(BT_HCI_CMD_READ_COUNTRY_CODE);
320 }
321
322 static void test_read_bd_addr(const void *test_data)
323 {
324         test_command(BT_HCI_CMD_READ_BD_ADDR);
325 }
326
327 static void test_read_local_supported_codecs(const void *test_data)
328 {
329         test_command(BT_HCI_CMD_READ_LOCAL_CODECS);
330 }
331
332 static void test_le_read_white_list_size(const void *test_data)
333 {
334         test_command(BT_HCI_CMD_LE_READ_WHITE_LIST_SIZE);
335 }
336
337 static void test_le_clear_white_list(const void *test_data)
338 {
339         test_command(BT_HCI_CMD_LE_CLEAR_WHITE_LIST);
340 }
341
342 static void test_inquiry_complete(const void *data, uint8_t size,
343                                                         void *user_data)
344 {
345         const struct bt_hci_evt_inquiry_complete *evt = data;
346
347         if (evt->status) {
348                 tester_warn("HCI inquiry complete failed (0x%02x)",
349                                                         evt->status);
350                 tester_test_failed();
351                 return;
352         }
353
354         tester_test_passed();
355 }
356
357 static void test_inquiry_status(const void *data, uint8_t size,
358                                                         void *user_data)
359 {
360         uint8_t status = *((uint8_t *) data);
361
362         if (status) {
363                 tester_warn("HCI inquiry command failed (0x%02x)", status);
364                 tester_test_failed();
365                 return;
366         }
367 }
368
369 static void test_inquiry_liac(const void *test_data)
370 {
371         struct user_data *user = tester_get_data();
372         struct bt_hci_cmd_inquiry cmd;
373
374         bt_hci_register(user->hci_ut, BT_HCI_EVT_INQUIRY_COMPLETE,
375                                         test_inquiry_complete, NULL, NULL);
376
377         cmd.lap[0] = 0x00;
378         cmd.lap[1] = 0x8b;
379         cmd.lap[2] = 0x9e;
380         cmd.length = 0x08;
381         cmd.num_resp = 0x00;
382
383         if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_INQUIRY, &cmd, sizeof(cmd),
384                                         test_inquiry_status, NULL, NULL)) {
385                 tester_warn("Failed to send HCI inquiry command");
386                 tester_test_failed();
387                 return;
388         }
389 }
390
391 static void setup_lt_connectable_complete(const void *data, uint8_t size,
392                                                         void *user_data)
393 {
394         uint8_t status = *((uint8_t *) data);
395
396         if (status) {
397                 tester_warn("Failed to set HCI scan enable (0x%02x)", status);
398                 tester_setup_failed();
399                 return;
400         }
401
402         tester_setup_complete();
403 }
404
405 static void setup_lt_connect_request_accept(const void *data, uint8_t size,
406                                                         void *user_data)
407 {
408         struct user_data *user = tester_get_data();
409         const struct bt_hci_evt_conn_request *evt = data;
410         struct bt_hci_cmd_accept_conn_request cmd;
411
412         memcpy(cmd.bdaddr, evt->bdaddr, 6);
413         cmd.role = 0x01;
414
415         if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_ACCEPT_CONN_REQUEST,
416                                         &cmd, sizeof(cmd), NULL, NULL, NULL)) {
417                 tester_warn("Failed to send HCI accept connection command");
418                 return;
419         }
420 }
421
422 static void setup_lt_connectable(const void *test_data)
423 {
424         struct user_data *user = tester_get_data();
425         struct bt_hci_cmd_write_scan_enable cmd;
426
427         bt_hci_register(user->hci_lt, BT_HCI_EVT_CONN_REQUEST,
428                                 setup_lt_connect_request_accept, NULL, NULL);
429
430         cmd.enable = 0x02;
431
432         if (!bt_hci_send(user->hci_lt, BT_HCI_CMD_WRITE_SCAN_ENABLE,
433                                 &cmd, sizeof(cmd),
434                                 setup_lt_connectable_complete, NULL, NULL)) {
435                 tester_warn("Failed to send HCI scan enable command");
436                 tester_setup_failed();
437                 return;
438         }
439 }
440
441 static void test_create_connection_disconnect(void *user_data)
442 {
443         tester_test_passed();
444 }
445
446 static void test_create_connection_complete(const void *data, uint8_t size,
447                                                         void *user_data)
448 {
449         struct user_data *user = tester_get_data();
450         const struct bt_hci_evt_conn_complete *evt = data;
451
452         if (evt->status) {
453                 tester_warn("HCI create connection complete failed (0x%02x)",
454                                                                 evt->status);
455                 tester_test_failed();
456                 return;
457         }
458
459         user->handle_ut = le16_to_cpu(evt->handle);
460
461         tester_wait(2, test_create_connection_disconnect, NULL);
462 }
463
464 static void test_create_connection_status(const void *data, uint8_t size,
465                                                         void *user_data)
466 {
467         uint8_t status = *((uint8_t *) data);
468
469         if (status) {
470                 tester_warn("HCI create connection command failed (0x%02x)",
471                                                                 status);
472                 tester_test_failed();
473                 return;
474         }
475 }
476
477 static void test_create_connection(const void *test_data)
478 {
479         struct user_data *user = tester_get_data();
480         struct bt_hci_cmd_create_conn cmd;
481
482         bt_hci_register(user->hci_ut, BT_HCI_EVT_CONN_COMPLETE,
483                                 test_create_connection_complete, NULL, NULL);
484
485         memcpy(cmd.bdaddr, user->bdaddr_lt, 6);
486         cmd.pkt_type = cpu_to_le16(0x0008);
487         cmd.pscan_rep_mode = 0x02;
488         cmd.pscan_mode = 0x00;
489         cmd.clock_offset = cpu_to_le16(0x0000);
490         cmd.role_switch = 0x01;
491
492         if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_CREATE_CONN,
493                                                 &cmd, sizeof(cmd),
494                                                 test_create_connection_status,
495                                                                 NULL, NULL)) {
496                 tester_warn("Failed to send HCI create connection command");
497                 tester_test_failed();
498                 return;
499         }
500 }
501
502 static void teardown_timeout(void *user_data)
503 {
504         tester_teardown_complete();
505 }
506
507 static void teardown_disconnect_status(const void *data, uint8_t size,
508                                                         void *user_data)
509 {
510         uint8_t status = *((uint8_t *) data);
511
512         if (status) {
513                 tester_warn("HCI disconnect failed (0x%02x)", status);
514                 tester_teardown_failed();
515                 return;
516         }
517
518         tester_wait(1, teardown_timeout, NULL);
519 }
520
521 static void teardown_connection(const void *test_data)
522 {
523         struct user_data *user = tester_get_data();
524         struct bt_hci_cmd_disconnect cmd;
525
526         cmd.handle = cpu_to_le16(user->handle_ut);
527         cmd.reason = 0x13;
528
529         if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_DISCONNECT,
530                                                 &cmd, sizeof(cmd),
531                                                 teardown_disconnect_status,
532                                                                 NULL, NULL)) {
533                 tester_warn("Failed to send HCI disconnect command");
534                 tester_test_failed();
535                 return;
536         }
537 }
538
539 static void test_adv_report(const void *data, uint8_t size, void *user_data)
540 {
541         struct user_data *user = tester_get_data();
542         uint8_t subevent = *((uint8_t *) data);
543         const struct bt_hci_evt_le_adv_report *lar = data + 1;
544
545         switch (subevent) {
546         case BT_HCI_EVT_LE_ADV_REPORT:
547                 if (!memcmp(lar->addr, user->bdaddr_ut, 6))
548                         tester_setup_complete();
549                 break;
550         }
551 }
552
553 static void setup_advertising_initiated(const void *test_data)
554 {
555         struct user_data *user = tester_get_data();
556         struct bt_hci_cmd_set_event_mask sem;
557         struct bt_hci_cmd_le_set_event_mask lsem;
558         struct bt_hci_cmd_le_set_scan_enable lsse;
559         struct bt_hci_cmd_le_set_adv_parameters lsap;
560         struct bt_hci_cmd_le_set_adv_enable lsae;
561
562         bt_hci_register(user->hci_lt, BT_HCI_EVT_LE_META_EVENT,
563                                         test_adv_report, NULL, NULL);
564
565         memset(sem.mask, 0, 8);
566         sem.mask[1] |= 0x20;    /* Command Complete */
567         sem.mask[1] |= 0x40;    /* Command Status */
568         sem.mask[7] |= 0x20;    /* LE Meta */
569
570         bt_hci_send(user->hci_lt, BT_HCI_CMD_SET_EVENT_MASK,
571                                         &sem, sizeof(sem), NULL, NULL, NULL);
572
573         memset(lsem.mask, 0, 8);
574         lsem.mask[0] |= 0x02;   /* LE Advertising Report */
575
576         bt_hci_send(user->hci_lt, BT_HCI_CMD_LE_SET_EVENT_MASK,
577                                         &lsem, sizeof(lsem), NULL, NULL, NULL);
578
579         lsse.enable = 0x01;
580         lsse.filter_dup = 0x00;
581
582         bt_hci_send(user->hci_lt, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
583                                         &lsse, sizeof(lsse), NULL, NULL, NULL);
584
585         lsap.min_interval = cpu_to_le16(0x0800);
586         lsap.max_interval = cpu_to_le16(0x0800);
587         lsap.type = 0x03;
588         lsap.own_addr_type = 0x00;
589         lsap.direct_addr_type = 0x00;
590         memset(lsap.direct_addr, 0, 6);
591         lsap.channel_map = 0x07;
592         lsap.filter_policy = 0x00;
593
594         bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_SET_ADV_PARAMETERS,
595                                         &lsap, sizeof(lsap), NULL, NULL, NULL);
596
597         lsae.enable = 0x01;
598
599         bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_SET_ADV_ENABLE,
600                                         &lsae, sizeof(lsae), NULL, NULL, NULL);
601 }
602
603 static void test_reset_in_advertising_state_timeout(void *user_data)
604 {
605         struct user_data *user = tester_get_data();
606         struct bt_hci_cmd_le_set_adv_enable lsae;
607         struct bt_hci_cmd_le_set_scan_enable lsse;
608
609         lsae.enable = 0x00;
610
611         bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_SET_ADV_ENABLE,
612                                         &lsae, sizeof(lsae), NULL, NULL, NULL);
613
614         lsse.enable = 0x00;
615         lsse.filter_dup = 0x00;
616
617         bt_hci_send(user->hci_lt, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
618                                         &lsse, sizeof(lsse), NULL, NULL, NULL);
619
620         tester_test_passed();
621 }
622
623 static void test_reset_in_advertising_state(const void *test_data)
624 {
625         struct user_data *user = tester_get_data();
626
627         bt_hci_send(user->hci_ut, BT_HCI_CMD_RESET, NULL, 0, NULL, NULL, NULL);
628
629         tester_wait(5, test_reset_in_advertising_state_timeout, NULL);
630 }
631
632 int main(int argc, char *argv[])
633 {
634         tester_init(&argc, &argv);
635
636         test_hci_local("Reset", NULL, NULL, test_reset);
637
638         test_hci_local("Read Local Version Information", NULL, NULL,
639                                 test_read_local_version_information);
640         test_hci_local("Read Local Supported Commands", NULL, NULL,
641                                 test_read_local_supported_commands);
642         test_hci_local("Read Local Supported Features", NULL, NULL,
643                                 test_read_local_supported_features);
644         test_hci_local("Read Local Extended Features", NULL,
645                                 setup_features,
646                                 test_read_local_extended_features);
647         test_hci_local("Read Buffer Size", NULL, NULL,
648                                 test_read_buffer_size);
649         test_hci_local("Read Country Code", NULL, NULL,
650                                 test_read_country_code);
651         test_hci_local("Read BD_ADDR", NULL, NULL,
652                                 test_read_bd_addr);
653         test_hci_local("Read Local Supported Codecs", NULL, NULL,
654                                 test_read_local_supported_codecs);
655
656         test_hci_local("LE Read White List Size", NULL, NULL,
657                                 test_le_read_white_list_size);
658         test_hci_local("LE Clear White List", NULL, NULL,
659                                 test_le_clear_white_list);
660
661         test_hci_local("Inquiry (LIAC)", NULL, NULL, test_inquiry_liac);
662
663         test_hci("Create Connection", NULL,
664                                 setup_lt_connectable,
665                                 test_create_connection,
666                                 teardown_connection);
667
668         test_hci("TP/DSU/BV-02-C Reset in Advertising State", NULL,
669                                 setup_advertising_initiated,
670                                 test_reset_in_advertising_state, NULL);
671
672         return tester_run();
673 }