1 /*-
2 * host_controller_baseband.c
3 *
4 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5 *
6 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $Id: host_controller_baseband.c,v 1.4 2003/08/18 19:19:53 max Exp $
31 * $FreeBSD$
32 */
33
34 #define L2CAP_SOCKET_CHECKED
35 #include <bluetooth.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include "hccontrol.h"
40
41 /* Convert hex ASCII to int4 */
42 static int
hci_hexa2int4(const char * a)43 hci_hexa2int4(const char *a)
44 {
45 if ('0' <= *a && *a <= '9')
46 return (*a - '0');
47
48 if ('A' <= *a && *a <= 'F')
49 return (*a - 'A' + 0xa);
50
51 if ('a' <= *a && *a <= 'f')
52 return (*a - 'a' + 0xa);
53
54 return (-1);
55 }
56
57 /* Convert hex ASCII to int8 */
58 static int
hci_hexa2int8(const char * a)59 hci_hexa2int8(const char *a)
60 {
61 int hi = hci_hexa2int4(a);
62 int lo = hci_hexa2int4(a + 1);
63
64 if (hi < 0 || lo < 0)
65 return (-1);
66
67 return ((hi << 4) | lo);
68 }
69
70 /* Convert ascii hex string to the uint8_t[] */
71 static int
hci_hexstring2array(char const * s,uint8_t * a,int asize)72 hci_hexstring2array(char const *s, uint8_t *a, int asize)
73 {
74 int i, l, b;
75
76 l = strlen(s) / 2;
77 if (l > asize)
78 l = asize;
79
80 for (i = 0; i < l; i++) {
81 b = hci_hexa2int8(s + i * 2);
82 if (b < 0)
83 return (-1);
84
85 a[i] = (b & 0xff);
86 }
87
88 return (0);
89 }
90
91 /* Send RESET to the unit */
92 static int
hci_reset(int s,int argc,char ** argv)93 hci_reset(int s, int argc, char **argv)
94 {
95 ng_hci_status_rp rp;
96 int n;
97
98 n = sizeof(rp);
99 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
100 NG_HCI_OCF_RESET), (char *) &rp, &n) == ERROR)
101 return (ERROR);
102
103 if (rp.status != 0x00) {
104 fprintf(stdout, "Status: %s [%#02x]\n",
105 hci_status2str(rp.status), rp.status);
106 return (FAILED);
107 }
108
109 return (OK);
110 } /* hci_reset */
111
112 /* Send Read_PIN_Type command to the unit */
113 static int
hci_read_pin_type(int s,int argc,char ** argv)114 hci_read_pin_type(int s, int argc, char **argv)
115 {
116 ng_hci_read_pin_type_rp rp;
117 int n;
118
119 n = sizeof(rp);
120 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
121 NG_HCI_OCF_READ_PIN_TYPE),
122 (char *) &rp, &n) == ERROR)
123 return (ERROR);
124
125 if (rp.status != 0x00) {
126 fprintf(stdout, "Status: %s [%#02x]\n",
127 hci_status2str(rp.status), rp.status);
128 return (FAILED);
129 }
130
131 fprintf(stdout, "PIN type: %s [%#02x]\n",
132 hci_pin2str(rp.pin_type), rp.pin_type);
133
134 return (OK);
135 } /* hci_read_pin_type */
136
137 /* Send Write_PIN_Type command to the unit */
138 static int
hci_write_pin_type(int s,int argc,char ** argv)139 hci_write_pin_type(int s, int argc, char **argv)
140 {
141 ng_hci_write_pin_type_cp cp;
142 ng_hci_write_pin_type_rp rp;
143 int n;
144
145 /* parse command parameters */
146 switch (argc) {
147 case 1:
148 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)
149 return (USAGE);
150
151 cp.pin_type = (uint8_t) n;
152 break;
153
154 default:
155 return (USAGE);
156 }
157
158 /* send command */
159 n = sizeof(rp);
160 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
161 NG_HCI_OCF_WRITE_PIN_TYPE),
162 (char const *) &cp, sizeof(cp),
163 (char *) &rp , &n) == ERROR)
164 return (ERROR);
165
166 if (rp.status != 0x00) {
167 fprintf(stdout, "Status: %s [%#02x]\n",
168 hci_status2str(rp.status), rp.status);
169 return (FAILED);
170 }
171
172 return (OK);
173 } /* hci_write_pin_type */
174
175 /* Send Read_Stored_Link_Key command to the unit */
176 static int
hci_read_stored_link_key(int s,int argc,char ** argv)177 hci_read_stored_link_key(int s, int argc, char **argv)
178 {
179 struct {
180 ng_hci_cmd_pkt_t hdr;
181 ng_hci_read_stored_link_key_cp cp;
182 } __attribute__ ((packed)) cmd;
183
184 struct {
185 ng_hci_event_pkt_t hdr;
186 union {
187 ng_hci_command_compl_ep cc;
188 ng_hci_return_link_keys_ep key;
189 uint8_t b[NG_HCI_EVENT_PKT_SIZE];
190 } ep;
191 } __attribute__ ((packed)) event;
192
193 int n, n1;
194
195 /* Send command */
196 memset(&cmd, 0, sizeof(cmd));
197 cmd.hdr.type = NG_HCI_CMD_PKT;
198 cmd.hdr.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
199 NG_HCI_OCF_READ_STORED_LINK_KEY));
200 cmd.hdr.length = sizeof(cmd.cp);
201
202 switch (argc) {
203 case 1:
204 /* parse BD_ADDR */
205 if (!bt_aton(argv[0], &cmd.cp.bdaddr)) {
206 struct hostent *he = NULL;
207
208 if ((he = bt_gethostbyname(argv[0])) == NULL)
209 return (USAGE);
210
211 memcpy(&cmd.cp.bdaddr, he->h_addr, sizeof(cmd.cp.bdaddr));
212 }
213 break;
214
215 default:
216 cmd.cp.read_all = 1;
217 break;
218 }
219
220 if (hci_send(s, (char const *) &cmd, sizeof(cmd)) != OK)
221 return (ERROR);
222
223 /* Receive events */
224 again:
225 memset(&event, 0, sizeof(event));
226 n = sizeof(event);
227 if (hci_recv(s, (char *) &event, &n) != OK)
228 return (ERROR);
229
230 if (n <= sizeof(event.hdr)) {
231 errno = EMSGSIZE;
232 return (ERROR);
233 }
234
235 if (event.hdr.type != NG_HCI_EVENT_PKT) {
236 errno = EIO;
237 return (ERROR);
238 }
239
240 /* Parse event */
241 switch (event.hdr.event) {
242 case NG_HCI_EVENT_COMMAND_COMPL: {
243 ng_hci_read_stored_link_key_rp *rp = NULL;
244
245 if (event.ep.cc.opcode == 0x0000 ||
246 event.ep.cc.opcode != cmd.hdr.opcode)
247 goto again;
248
249 rp = (ng_hci_read_stored_link_key_rp *)(event.ep.b +
250 sizeof(event.ep.cc));
251
252 fprintf(stdout, "Complete: Status: %s [%#x]\n",
253 hci_status2str(rp->status), rp->status);
254 fprintf(stdout, "Maximum Number of keys: %d\n",
255 le16toh(rp->max_num_keys));
256 fprintf(stdout, "Number of keys read: %d\n",
257 le16toh(rp->num_keys_read));
258 } break;
259
260 case NG_HCI_EVENT_RETURN_LINK_KEYS: {
261 struct _key {
262 bdaddr_t bdaddr;
263 uint8_t key[NG_HCI_KEY_SIZE];
264 } __attribute__ ((packed)) *k = NULL;
265
266 fprintf(stdout, "Event: Number of keys: %d\n",
267 event.ep.key.num_keys);
268
269 k = (struct _key *)(event.ep.b + sizeof(event.ep.key));
270 for (n = 0; n < event.ep.key.num_keys; n++) {
271 fprintf(stdout, "\t%d: %s ",
272 n + 1, hci_bdaddr2str(&k->bdaddr));
273
274 for (n1 = 0; n1 < sizeof(k->key); n1++)
275 fprintf(stdout, "%02x", k->key[n1]);
276 fprintf(stdout, "\n");
277
278 k ++;
279 }
280
281 goto again;
282
283 } break;
284
285 default:
286 goto again;
287 }
288
289 return (OK);
290 } /* hci_read_store_link_key */
291
292 /* Send Write_Stored_Link_Key command to the unit */
293 static int
hci_write_stored_link_key(int s,int argc,char ** argv)294 hci_write_stored_link_key(int s, int argc, char **argv)
295 {
296 struct {
297 ng_hci_write_stored_link_key_cp p;
298 bdaddr_t bdaddr;
299 uint8_t key[NG_HCI_KEY_SIZE];
300 } cp;
301 ng_hci_write_stored_link_key_rp rp;
302 int32_t n;
303
304 memset(&cp, 0, sizeof(cp));
305
306 switch (argc) {
307 case 2:
308 cp.p.num_keys_write = 1;
309
310 /* parse BD_ADDR */
311 if (!bt_aton(argv[0], &cp.bdaddr)) {
312 struct hostent *he = NULL;
313
314 if ((he = bt_gethostbyname(argv[0])) == NULL)
315 return (USAGE);
316
317 memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
318 }
319
320 /* parse key */
321 if (hci_hexstring2array(argv[1], cp.key, sizeof(cp.key)) < 0)
322 return (USAGE);
323 break;
324
325 default:
326 return (USAGE);
327 }
328
329 /* send command */
330 n = sizeof(rp);
331 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
332 NG_HCI_OCF_WRITE_STORED_LINK_KEY),
333 (char const *) &cp, sizeof(cp),
334 (char *) &rp, &n) == ERROR)
335 return (ERROR);
336
337 if (rp.status != 0x00) {
338 fprintf(stdout, "Status: %s [%#02x]\n",
339 hci_status2str(rp.status), rp.status);
340 return (FAILED);
341 }
342
343 fprintf(stdout, "Number of keys written: %d\n", rp.num_keys_written);
344
345 return (OK);
346 } /* hci_write_stored_link_key */
347
348
349 /* Send Delete_Stored_Link_Key command to the unit */
350 static int
hci_delete_stored_link_key(int s,int argc,char ** argv)351 hci_delete_stored_link_key(int s, int argc, char **argv)
352 {
353 ng_hci_delete_stored_link_key_cp cp;
354 ng_hci_delete_stored_link_key_rp rp;
355 int32_t n;
356
357 memset(&cp, 0, sizeof(cp));
358
359 switch (argc) {
360 case 1:
361 /* parse BD_ADDR */
362 if (!bt_aton(argv[0], &cp.bdaddr)) {
363 struct hostent *he = NULL;
364
365 if ((he = bt_gethostbyname(argv[0])) == NULL)
366 return (USAGE);
367
368 memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
369 }
370 break;
371
372 default:
373 cp.delete_all = 1;
374 break;
375 }
376
377 /* send command */
378 n = sizeof(cp);
379 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
380 NG_HCI_OCF_DELETE_STORED_LINK_KEY),
381 (char const *) &cp, sizeof(cp),
382 (char *) &rp, &n) == ERROR)
383 return (ERROR);
384
385 if (rp.status != 0x00) {
386 fprintf(stdout, "Status: %s [%#02x]\n",
387 hci_status2str(rp.status), rp.status);
388 return (FAILED);
389 }
390
391 fprintf(stdout, "Number of keys deleted: %d\n", rp.num_keys_deleted);
392
393 return (OK);
394 } /* hci_delete_stored_link_key */
395
396 /* Send Change_Local_Name command to the unit */
397 static int
hci_change_local_name(int s,int argc,char ** argv)398 hci_change_local_name(int s, int argc, char **argv)
399 {
400 ng_hci_change_local_name_cp cp;
401 ng_hci_change_local_name_rp rp;
402 int n;
403
404 /* parse command parameters */
405 switch (argc) {
406 case 1:
407 snprintf(cp.name, sizeof(cp.name), "%s", argv[0]);
408 break;
409
410 default:
411 return (USAGE);
412 }
413
414 /* send command */
415 n = sizeof(rp);
416 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
417 NG_HCI_OCF_CHANGE_LOCAL_NAME),
418 (char const *) &cp, sizeof(cp),
419 (char *) &rp, &n) == ERROR)
420 return (ERROR);
421
422 if (rp.status != 0x00) {
423 fprintf(stdout, "Status: %s [%#02x]\n",
424 hci_status2str(rp.status), rp.status);
425 return (FAILED);
426 }
427
428 return (OK);
429 } /* hci_change_local_name */
430
431 /* Send Read_Local_Name command to the unit */
432 static int
hci_read_local_name(int s,int argc,char ** argv)433 hci_read_local_name(int s, int argc, char **argv)
434 {
435 ng_hci_read_local_name_rp rp;
436 int n;
437
438 n = sizeof(rp);
439 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
440 NG_HCI_OCF_READ_LOCAL_NAME),
441 (char *) &rp, &n) == ERROR)
442 return (ERROR);
443
444 if (rp.status != 0x00) {
445 fprintf(stdout, "Status: %s [%#02x]\n",
446 hci_status2str(rp.status), rp.status);
447 return (FAILED);
448 }
449
450 fprintf(stdout, "Local name: %s\n", rp.name);
451
452 return (OK);
453 } /* hci_read_local_name */
454
455 /* Send Read_Connection_Accept_Timeout to the unit */
456 static int
hci_read_connection_accept_timeout(int s,int argc,char ** argv)457 hci_read_connection_accept_timeout(int s, int argc, char **argv)
458 {
459 ng_hci_read_con_accept_timo_rp rp;
460 int n;
461
462 n = sizeof(rp);
463 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
464 NG_HCI_OCF_READ_CON_ACCEPT_TIMO),
465 (char *) &rp, &n) == ERROR)
466 return (ERROR);
467
468 if (rp.status != 0x00) {
469 fprintf(stdout, "Status: %s [%#02x]\n",
470 hci_status2str(rp.status), rp.status);
471 return (FAILED);
472 }
473
474 rp.timeout = le16toh(rp.timeout);
475 fprintf(stdout, "Connection accept timeout: %.2f msec [%d slots]\n",
476 rp.timeout * 0.625, rp.timeout);
477
478 return (OK);
479 } /* hci_read_connection_accept_timeout */
480
481 /* Send Write_Connection_Accept_Timeout to the unit */
482 static int
hci_write_connection_accept_timeout(int s,int argc,char ** argv)483 hci_write_connection_accept_timeout(int s, int argc, char **argv)
484 {
485 ng_hci_write_con_accept_timo_cp cp;
486 ng_hci_write_con_accept_timo_rp rp;
487 int n;
488
489 /* parse command parameters */
490 switch (argc) {
491 case 1:
492 if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xb540)
493 return (USAGE);
494
495 cp.timeout = (uint16_t) n;
496 cp.timeout = htole16(cp.timeout);
497 break;
498
499 default:
500 return (USAGE);
501 }
502
503 /* send command */
504 n = sizeof(rp);
505 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
506 NG_HCI_OCF_WRITE_CON_ACCEPT_TIMO),
507 (char const *) &cp, sizeof(cp),
508 (char *) &rp, &n) == ERROR)
509 return (ERROR);
510
511 if (rp.status != 0x00) {
512 fprintf(stdout, "Status: %s [%#02x]\n",
513 hci_status2str(rp.status), rp.status);
514 return (FAILED);
515 }
516
517 return (OK);
518 } /* hci_write_connection_accept_timeout */
519
520 /* Send Read_Page_Timeout command to the unit */
521 static int
hci_read_page_timeout(int s,int argc,char ** argv)522 hci_read_page_timeout(int s, int argc, char **argv)
523 {
524 ng_hci_read_page_timo_rp rp;
525 int n;
526
527 n = sizeof(rp);
528 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
529 NG_HCI_OCF_READ_PAGE_TIMO),
530 (char *) &rp, &n) == ERROR)
531 return (ERROR);
532
533 if (rp.status != 0x00) {
534 fprintf(stdout, "Status: %s [%#02x]\n",
535 hci_status2str(rp.status), rp.status);
536 return (FAILED);
537 }
538
539 rp.timeout = le16toh(rp.timeout);
540 fprintf(stdout, "Page timeout: %.2f msec [%d slots]\n",
541 rp.timeout * 0.625, rp.timeout);
542
543 return (OK);
544 } /* hci_read_page_timeoout */
545
546 /* Send Write_Page_Timeout command to the unit */
547 static int
hci_write_page_timeout(int s,int argc,char ** argv)548 hci_write_page_timeout(int s, int argc, char **argv)
549 {
550 ng_hci_write_page_timo_cp cp;
551 ng_hci_write_page_timo_rp rp;
552 int n;
553
554 /* parse command parameters */
555 switch (argc) {
556 case 1:
557 if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xffff)
558 return (USAGE);
559
560 cp.timeout = (uint16_t) n;
561 cp.timeout = htole16(cp.timeout);
562 break;
563
564 default:
565 return (USAGE);
566 }
567
568 /* send command */
569 n = sizeof(rp);
570 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
571 NG_HCI_OCF_WRITE_PAGE_TIMO),
572 (char const *) &cp, sizeof(cp),
573 (char *) &rp, &n) == ERROR)
574 return (ERROR);
575
576 if (rp.status != 0x00) {
577 fprintf(stdout, "Status: %s [%#02x]\n",
578 hci_status2str(rp.status), rp.status);
579 return (FAILED);
580 }
581
582 return (OK);
583 } /* hci_write_page_timeout */
584
585 /* Send Read_Scan_Enable command to the unit */
586 static int
hci_read_scan_enable(int s,int argc,char ** argv)587 hci_read_scan_enable(int s, int argc, char **argv)
588 {
589 ng_hci_read_scan_enable_rp rp;
590 int n;
591
592 n = sizeof(rp);
593 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
594 NG_HCI_OCF_READ_SCAN_ENABLE),
595 (char *) &rp, &n) == ERROR)
596 return (ERROR);
597
598 if (rp.status != 0x00) {
599 fprintf(stdout, "Status: %s [%#02x]\n",
600 hci_status2str(rp.status), rp.status);
601 return (FAILED);
602 }
603
604 fprintf(stdout, "Scan enable: %s [%#02x]\n",
605 hci_scan2str(rp.scan_enable), rp.scan_enable);
606
607 return (OK);
608 } /* hci_read_scan_enable */
609
610 /* Send Write_Scan_Enable command to the unit */
611 static int
hci_write_scan_enable(int s,int argc,char ** argv)612 hci_write_scan_enable(int s, int argc, char **argv)
613 {
614 ng_hci_write_scan_enable_cp cp;
615 ng_hci_write_scan_enable_rp rp;
616 int n;
617
618 /* parse command parameters */
619 switch (argc) {
620 case 1:
621 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3)
622 return (USAGE);
623
624 cp.scan_enable = (uint8_t) n;
625 break;
626
627 default:
628 return (USAGE);
629 }
630
631 n = sizeof(rp);
632 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
633 NG_HCI_OCF_WRITE_SCAN_ENABLE),
634 (char const *) &cp, sizeof(cp),
635 (char *) &rp, &n) == ERROR)
636 return (ERROR);
637
638 if (rp.status != 0x00) {
639 fprintf(stdout, "Status: %s [%#02x]\n",
640 hci_status2str(rp.status), rp.status);
641 return (FAILED);
642 }
643
644 return (OK);
645 } /* hci_write_scan_enable */
646
647 /* Send Read_Page_Scan_Activity command to the unit */
648 static int
hci_read_page_scan_activity(int s,int argc,char ** argv)649 hci_read_page_scan_activity(int s, int argc, char **argv)
650 {
651 ng_hci_read_page_scan_activity_rp rp;
652 int n;
653
654 n = sizeof(rp);
655 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
656 NG_HCI_OCF_READ_PAGE_SCAN_ACTIVITY),
657 (char *) &rp, &n) == ERROR)
658 return (ERROR);
659
660 if (rp.status != 0x00) {
661 fprintf(stdout, "Status: %s [%#02x]\n",
662 hci_status2str(rp.status), rp.status);
663 return (FAILED);
664 }
665
666 rp.page_scan_interval = le16toh(rp.page_scan_interval);
667 rp.page_scan_window = le16toh(rp.page_scan_window);
668
669 fprintf(stdout, "Page Scan Interval: %.2f msec [%d slots]\n",
670 rp.page_scan_interval * 0.625, rp.page_scan_interval);
671 fprintf(stdout, "Page Scan Window: %.2f msec [%d slots]\n",
672 rp.page_scan_window * 0.625, rp.page_scan_window);
673
674 return (OK);
675 } /* hci_read_page_scan_activity */
676
677 /* Send Write_Page_Scan_Activity command to the unit */
678 static int
hci_write_page_scan_activity(int s,int argc,char ** argv)679 hci_write_page_scan_activity(int s, int argc, char **argv)
680 {
681 ng_hci_write_page_scan_activity_cp cp;
682 ng_hci_write_page_scan_activity_rp rp;
683 int n;
684
685 /* parse command parameters */
686 switch (argc) {
687 case 2:
688 /* page scan interval */
689 if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
690 return (USAGE);
691
692 cp.page_scan_interval = (uint16_t) n;
693
694 /* page scan window */
695 if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
696 return (USAGE);
697
698 cp.page_scan_window = (uint16_t) n;
699
700 if (cp.page_scan_window > cp.page_scan_interval)
701 return (USAGE);
702
703 cp.page_scan_interval = htole16(cp.page_scan_interval);
704 cp.page_scan_window = htole16(cp.page_scan_window);
705 break;
706
707 default:
708 return (USAGE);
709 }
710
711 /* send command */
712 n = sizeof(rp);
713 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
714 NG_HCI_OCF_WRITE_PAGE_SCAN_ACTIVITY),
715 (char const *) &cp, sizeof(cp),
716 (char *) &rp, &n) == ERROR)
717 return (ERROR);
718
719 if (rp.status != 0x00) {
720 fprintf(stdout, "Status: %s [%#02x]\n",
721 hci_status2str(rp.status), rp.status);
722 return (FAILED);
723 }
724
725 return (OK);
726 } /* hci_write_page_scan_activity */
727
728 /* Send Read_Inquiry_Scan_Activity command to the unit */
729 static int
hci_read_inquiry_scan_activity(int s,int argc,char ** argv)730 hci_read_inquiry_scan_activity(int s, int argc, char **argv)
731 {
732 ng_hci_read_inquiry_scan_activity_rp rp;
733 int n;
734
735 n = sizeof(rp);
736 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
737 NG_HCI_OCF_READ_INQUIRY_SCAN_ACTIVITY),
738 (char *) &rp, &n) == ERROR)
739 return (ERROR);
740
741 if (rp.status != 0x00) {
742 fprintf(stdout, "Status: %s [%#02x]\n",
743 hci_status2str(rp.status), rp.status);
744 return (FAILED);
745 }
746
747 rp.inquiry_scan_interval = le16toh(rp.inquiry_scan_interval);
748 rp.inquiry_scan_window = le16toh(rp.inquiry_scan_window);
749
750 fprintf(stdout, "Inquiry Scan Interval: %.2f msec [%d slots]\n",
751 rp.inquiry_scan_interval * 0.625, rp.inquiry_scan_interval);
752 fprintf(stdout, "Inquiry Scan Window: %.2f msec [%d slots]\n",
753 rp.inquiry_scan_window * 0.625, rp.inquiry_scan_interval);
754
755 return (OK);
756 } /* hci_read_inquiry_scan_activity */
757
758 /* Send Write_Inquiry_Scan_Activity command to the unit */
759 static int
hci_write_inquiry_scan_activity(int s,int argc,char ** argv)760 hci_write_inquiry_scan_activity(int s, int argc, char **argv)
761 {
762 ng_hci_write_inquiry_scan_activity_cp cp;
763 ng_hci_write_inquiry_scan_activity_rp rp;
764 int n;
765
766 /* parse command parameters */
767 switch (argc) {
768 case 2:
769 /* inquiry scan interval */
770 if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
771 return (USAGE);
772
773 cp.inquiry_scan_interval = (uint16_t) n;
774
775 /* inquiry scan window */
776 if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
777 return (USAGE);
778
779 cp.inquiry_scan_window = (uint16_t) n;
780
781 if (cp.inquiry_scan_window > cp.inquiry_scan_interval)
782 return (USAGE);
783
784 cp.inquiry_scan_interval =
785 htole16(cp.inquiry_scan_interval);
786 cp.inquiry_scan_window = htole16(cp.inquiry_scan_window);
787 break;
788
789 default:
790 return (USAGE);
791 }
792
793 /* send command */
794 n = sizeof(rp);
795 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
796 NG_HCI_OCF_WRITE_INQUIRY_SCAN_ACTIVITY),
797 (char const *) &cp, sizeof(cp),
798 (char *) &rp, &n) == ERROR)
799 return (ERROR);
800
801 if (rp.status != 0x00) {
802 fprintf(stdout, "Status: %s [%#02x]\n",
803 hci_status2str(rp.status), rp.status);
804 return (FAILED);
805 }
806
807 return (OK);
808 } /* hci_write_inquiry_scan_activity */
809
810 /* Send Read_Authentication_Enable command to the unit */
811 static int
hci_read_authentication_enable(int s,int argc,char ** argv)812 hci_read_authentication_enable(int s, int argc, char **argv)
813 {
814 ng_hci_read_auth_enable_rp rp;
815 int n;
816
817 n = sizeof(rp);
818 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
819 NG_HCI_OCF_READ_AUTH_ENABLE),
820 (char *) &rp, &n) == ERROR)
821 return (ERROR);
822
823 if (rp.status != 0x00) {
824 fprintf(stdout, "Status: %s [%#02x]\n",
825 hci_status2str(rp.status), rp.status);
826 return (FAILED);
827 }
828
829 fprintf(stdout, "Authentication Enable: %s [%d]\n",
830 rp.auth_enable? "Enabled" : "Disabled", rp.auth_enable);
831
832 return (OK);
833 } /* hci_read_authentication_enable */
834
835 /* Send Write_Authentication_Enable command to the unit */
836 static int
hci_write_authentication_enable(int s,int argc,char ** argv)837 hci_write_authentication_enable(int s, int argc, char **argv)
838 {
839 ng_hci_write_auth_enable_cp cp;
840 ng_hci_write_auth_enable_rp rp;
841 int n;
842
843 /* parse command parameters */
844 switch (argc) {
845 case 1:
846 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)
847 return (USAGE);
848
849 cp.auth_enable = (uint8_t) n;
850 break;
851
852 default:
853 return (USAGE);
854 }
855
856 /* send command */
857 n = sizeof(rp);
858 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
859 NG_HCI_OCF_WRITE_AUTH_ENABLE),
860 (char const *) &cp, sizeof(cp),
861 (char *) &rp, &n) == ERROR)
862 return (ERROR);
863
864 if (rp.status != 0x00) {
865 fprintf(stdout, "Status: %s [%#02x]\n",
866 hci_status2str(rp.status), rp.status);
867 return (FAILED);
868 }
869
870 return (OK);
871 } /* hci_write_authentication_enable */
872
873 /* Send Read_Encryption_Mode command to the unit */
874 static int
hci_read_encryption_mode(int s,int argc,char ** argv)875 hci_read_encryption_mode(int s, int argc, char **argv)
876 {
877 ng_hci_read_encryption_mode_rp rp;
878 int n;
879
880 n = sizeof(rp);
881 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
882 NG_HCI_OCF_READ_ENCRYPTION_MODE),
883 (char *) &rp, &n) == ERROR)
884 return (ERROR);
885
886 if (rp.status != 0x00) {
887 fprintf(stdout, "Status: %s [%#02x]\n",
888 hci_status2str(rp.status), rp.status);
889 return (FAILED);
890 }
891
892 fprintf(stdout, "Encryption mode: %s [%#02x]\n",
893 hci_encrypt2str(rp.encryption_mode, 0), rp.encryption_mode);
894
895 return (OK);
896 } /* hci_read_encryption_mode */
897
898 /* Send Write_Encryption_Mode command to the unit */
899 static int
hci_write_encryption_mode(int s,int argc,char ** argv)900 hci_write_encryption_mode(int s, int argc, char **argv)
901 {
902 ng_hci_write_encryption_mode_cp cp;
903 ng_hci_write_encryption_mode_rp rp;
904 int n;
905
906 /* parse command parameters */
907 switch (argc) {
908 case 1:
909 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2)
910 return (USAGE);
911
912 cp.encryption_mode = (uint8_t) n;
913 break;
914
915 default:
916 return (USAGE);
917 }
918
919 /* send command */
920 n = sizeof(rp);
921 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
922 NG_HCI_OCF_WRITE_ENCRYPTION_MODE),
923 (char const *) &cp, sizeof(cp),
924 (char *) &rp, &n) == ERROR)
925 return (ERROR);
926
927 if (rp.status != 0x00) {
928 fprintf(stdout, "Status: %s [%#02x]\n",
929 hci_status2str(rp.status), rp.status);
930 return (FAILED);
931 }
932
933 return (OK);
934 } /* hci_write_encryption_mode */
935
936 /* Send Read_Class_Of_Device command to the unit */
937 static int
hci_read_class_of_device(int s,int argc,char ** argv)938 hci_read_class_of_device(int s, int argc, char **argv)
939 {
940 ng_hci_read_unit_class_rp rp;
941 int n;
942
943 n = sizeof(rp);
944 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
945 NG_HCI_OCF_READ_UNIT_CLASS),
946 (char *) &rp, &n) == ERROR)
947 return (ERROR);
948
949 if (rp.status != 0x00) {
950 fprintf(stdout, "Status: %s [%#02x]\n",
951 hci_status2str(rp.status), rp.status);
952 return (FAILED);
953 }
954
955 fprintf(stdout, "Class: %02x:%02x:%02x\n",
956 rp.uclass[2], rp.uclass[1], rp.uclass[0]);
957
958 return (0);
959 } /* hci_read_class_of_device */
960
961 /* Send Write_Class_Of_Device command to the unit */
962 static int
hci_write_class_of_device(int s,int argc,char ** argv)963 hci_write_class_of_device(int s, int argc, char **argv)
964 {
965 ng_hci_write_unit_class_cp cp;
966 ng_hci_write_unit_class_rp rp;
967 int n0, n1, n2;
968
969 /* parse command parameters */
970 switch (argc) {
971 case 1:
972 if (sscanf(argv[0], "%x:%x:%x", &n2, &n1, &n0) != 3)
973 return (USAGE);
974
975 cp.uclass[0] = (n0 & 0xff);
976 cp.uclass[1] = (n1 & 0xff);
977 cp.uclass[2] = (n2 & 0xff);
978 break;
979
980 default:
981 return (USAGE);
982 }
983
984 /* send command */
985 n0 = sizeof(rp);
986 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
987 NG_HCI_OCF_WRITE_UNIT_CLASS),
988 (char const *) &cp, sizeof(cp),
989 (char *) &rp, &n0) == ERROR)
990 return (ERROR);
991
992 if (rp.status != 0x00) {
993 fprintf(stdout, "Status: %s [%#02x]\n",
994 hci_status2str(rp.status), rp.status);
995 return (FAILED);
996 }
997
998 return (OK);
999 } /* hci_write_class_of_device */
1000
1001 /* Send Read_Voice_Settings command to the unit */
1002 static int
hci_read_voice_settings(int s,int argc,char ** argv)1003 hci_read_voice_settings(int s, int argc, char **argv)
1004 {
1005 ng_hci_read_voice_settings_rp rp;
1006 int n,
1007 input_coding,
1008 input_data_format,
1009 input_sample_size;
1010
1011 n = sizeof(rp);
1012 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1013 NG_HCI_OCF_READ_VOICE_SETTINGS),
1014 (char *) &rp, &n) == ERROR)
1015 return (ERROR);
1016
1017 if (rp.status != 0x00) {
1018 fprintf(stdout, "Status: %s [%#02x]\n",
1019 hci_status2str(rp.status), rp.status);
1020 return (FAILED);
1021 }
1022
1023 rp.settings = le16toh(rp.settings);
1024
1025 input_coding = (rp.settings & 0x0300) >> 8;
1026 input_data_format = (rp.settings & 0x00c0) >> 6;
1027 input_sample_size = (rp.settings & 0x0020) >> 5;
1028
1029 fprintf(stdout, "Voice settings: %#04x\n", rp.settings);
1030 fprintf(stdout, "Input coding: %s [%d]\n",
1031 hci_coding2str(input_coding), input_coding);
1032 fprintf(stdout, "Input data format: %s [%d]\n",
1033 hci_vdata2str(input_data_format), input_data_format);
1034
1035 if (input_coding == 0x00) /* Only for Linear PCM */
1036 fprintf(stdout, "Input sample size: %d bit [%d]\n",
1037 input_sample_size? 16 : 8, input_sample_size);
1038
1039 return (OK);
1040 } /* hci_read_voice_settings */
1041
1042 /* Send Write_Voice_Settings command to the unit */
1043 static int
hci_write_voice_settings(int s,int argc,char ** argv)1044 hci_write_voice_settings(int s, int argc, char **argv)
1045 {
1046 ng_hci_write_voice_settings_cp cp;
1047 ng_hci_write_voice_settings_rp rp;
1048 int n;
1049
1050 /* parse command parameters */
1051 switch (argc) {
1052 case 1:
1053 if (sscanf(argv[0], "%x", &n) != 1)
1054 return (USAGE);
1055
1056 cp.settings = (uint16_t) n;
1057 cp.settings = htole16(cp.settings);
1058 break;
1059
1060 default:
1061 return (USAGE);
1062 }
1063
1064 /* send command */
1065 n = sizeof(rp);
1066 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1067 NG_HCI_OCF_WRITE_VOICE_SETTINGS),
1068 (char const *) &cp, sizeof(cp),
1069 (char *) &rp, &n) == ERROR)
1070 return (ERROR);
1071
1072 if (rp.status != 0x00) {
1073 fprintf(stdout, "Status: %s [%#02x]\n",
1074 hci_status2str(rp.status), rp.status);
1075 return (FAILED);
1076 }
1077
1078 return (OK);
1079 } /* hci_write_voice_settings */
1080
1081 /* Send Read_Number_Broadcast_Restransmissions */
1082 static int
hci_read_number_broadcast_retransmissions(int s,int argc,char ** argv)1083 hci_read_number_broadcast_retransmissions(int s, int argc, char **argv)
1084 {
1085 ng_hci_read_num_broadcast_retrans_rp rp;
1086 int n;
1087
1088 n = sizeof(rp);
1089 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1090 NG_HCI_OCF_READ_NUM_BROADCAST_RETRANS),
1091 (char *) &rp, &n) == ERROR)
1092 return (ERROR);
1093
1094 if (rp.status != 0x00) {
1095 fprintf(stdout, "Status: %s [%#02x]\n",
1096 hci_status2str(rp.status), rp.status);
1097 return (FAILED);
1098 }
1099
1100 fprintf(stdout, "Number of broadcast retransmissions: %d\n",
1101 rp.counter);
1102
1103 return (OK);
1104 } /* hci_read_number_broadcast_retransmissions */
1105
1106 /* Send Write_Number_Broadcast_Restransmissions */
1107 static int
hci_write_number_broadcast_retransmissions(int s,int argc,char ** argv)1108 hci_write_number_broadcast_retransmissions(int s, int argc, char **argv)
1109 {
1110 ng_hci_write_num_broadcast_retrans_cp cp;
1111 ng_hci_write_num_broadcast_retrans_rp rp;
1112 int n;
1113
1114 /* parse command parameters */
1115 switch (argc) {
1116 case 1:
1117 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0xff)
1118 return (USAGE);
1119
1120 cp.counter = (uint8_t) n;
1121 break;
1122
1123 default:
1124 return (USAGE);
1125 }
1126
1127 /* send command */
1128 n = sizeof(rp);
1129 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1130 NG_HCI_OCF_WRITE_NUM_BROADCAST_RETRANS),
1131 (char const *) &cp, sizeof(cp),
1132 (char *) &rp, &n) == ERROR)
1133 return (ERROR);
1134
1135 if (rp.status != 0x00) {
1136 fprintf(stdout, "Status: %s [%#02x]\n",
1137 hci_status2str(rp.status), rp.status);
1138 return (FAILED);
1139 }
1140
1141 return (OK);
1142 } /* hci_write_number_broadcast_retransmissions */
1143
1144 /* Send Read_Hold_Mode_Activity command to the unit */
1145 static int
hci_read_hold_mode_activity(int s,int argc,char ** argv)1146 hci_read_hold_mode_activity(int s, int argc, char **argv)
1147 {
1148 ng_hci_read_hold_mode_activity_rp rp;
1149 int n;
1150 char buffer[1024];
1151
1152 n = sizeof(rp);
1153 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1154 NG_HCI_OCF_READ_HOLD_MODE_ACTIVITY),
1155 (char *) &rp, &n) == ERROR)
1156 return (ERROR);
1157
1158 if (rp.status != 0x00) {
1159 fprintf(stdout, "Status: %s [%#02x]\n",
1160 hci_status2str(rp.status), rp.status);
1161 return (FAILED);
1162 }
1163
1164 fprintf(stdout, "Hold Mode Activities: %#02x\n", rp.hold_mode_activity);
1165 if (rp.hold_mode_activity == 0)
1166 fprintf(stdout, "Maintain current Power State");
1167 else
1168 fprintf(stdout, "%s", hci_hmode2str(rp.hold_mode_activity,
1169 buffer, sizeof(buffer)));
1170
1171 fprintf(stdout, "\n");
1172
1173 return (OK);
1174 } /* hci_read_hold_mode_activity */
1175
1176 /* Send Write_Hold_Mode_Activity command to the unit */
1177 static int
hci_write_hold_mode_activity(int s,int argc,char ** argv)1178 hci_write_hold_mode_activity(int s, int argc, char **argv)
1179 {
1180 ng_hci_write_hold_mode_activity_cp cp;
1181 ng_hci_write_hold_mode_activity_rp rp;
1182 int n;
1183
1184 /* parse command parameters */
1185 switch (argc) {
1186 case 1:
1187 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 4)
1188 return (USAGE);
1189
1190 cp.hold_mode_activity = (uint8_t) n;
1191 break;
1192
1193 default:
1194 return (USAGE);
1195 }
1196
1197 /* send command */
1198 n = sizeof(rp);
1199 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1200 NG_HCI_OCF_WRITE_HOLD_MODE_ACTIVITY),
1201 (char const *) &cp, sizeof(cp),
1202 (char *) &rp, &n) == ERROR)
1203 return (ERROR);
1204
1205 if (rp.status != 0x00) {
1206 fprintf(stdout, "Status: %s [%#02x]\n",
1207 hci_status2str(rp.status), rp.status);
1208 return (FAILED);
1209 }
1210
1211 return (OK);
1212 } /* hci_write_hold_mode_activity */
1213
1214 /* Send Read_SCO_Flow_Control_Enable command to the unit */
1215 static int
hci_read_sco_flow_control_enable(int s,int argc,char ** argv)1216 hci_read_sco_flow_control_enable(int s, int argc, char **argv)
1217 {
1218 ng_hci_read_sco_flow_control_rp rp;
1219 int n;
1220
1221 n = sizeof(rp);
1222 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1223 NG_HCI_OCF_READ_SCO_FLOW_CONTROL),
1224 (char *) &rp, &n) == ERROR)
1225 return (ERROR);
1226
1227 if (rp.status != 0x00) {
1228 fprintf(stdout, "Status: %s [%#02x]\n",
1229 hci_status2str(rp.status), rp.status);
1230 return (FAILED);
1231 }
1232
1233 fprintf(stdout, "SCO flow control %s [%d]\n",
1234 rp.flow_control? "enabled" : "disabled", rp.flow_control);
1235
1236 return (OK);
1237 } /* hci_read_sco_flow_control_enable */
1238
1239 /* Send Write_SCO_Flow_Control_Enable command to the unit */
1240 static int
hci_write_sco_flow_control_enable(int s,int argc,char ** argv)1241 hci_write_sco_flow_control_enable(int s, int argc, char **argv)
1242 {
1243 ng_hci_write_sco_flow_control_cp cp;
1244 ng_hci_write_sco_flow_control_rp rp;
1245 int n;
1246
1247 /* parse command parameters */
1248 switch (argc) {
1249 case 1:
1250 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)
1251 return (USAGE);
1252
1253 cp.flow_control = (uint8_t) n;
1254 break;
1255
1256 default:
1257 return (USAGE);
1258 }
1259
1260 /* send command */
1261 n = sizeof(rp);
1262 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1263 NG_HCI_OCF_WRITE_SCO_FLOW_CONTROL),
1264 (char const *) &cp, sizeof(cp),
1265 (char *) &rp, &n) == ERROR)
1266 return (ERROR);
1267
1268 if (rp.status != 0x00) {
1269 fprintf(stdout, "Status: %s [%#02x]\n",
1270 hci_status2str(rp.status), rp.status);
1271 return (FAILED);
1272 }
1273
1274 return (OK);
1275 } /* hci_write_sco_flow_control_enable */
1276
1277 /* Send Read_Link_Supervision_Timeout command to the unit */
1278 static int
hci_read_link_supervision_timeout(int s,int argc,char ** argv)1279 hci_read_link_supervision_timeout(int s, int argc, char **argv)
1280 {
1281 ng_hci_read_link_supervision_timo_cp cp;
1282 ng_hci_read_link_supervision_timo_rp rp;
1283 int n;
1284
1285 switch (argc) {
1286 case 1:
1287 /* connection handle */
1288 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
1289 return (USAGE);
1290
1291 cp.con_handle = (uint16_t) (n & 0x0fff);
1292 cp.con_handle = htole16(cp.con_handle);
1293 break;
1294
1295 default:
1296 return (USAGE);
1297 }
1298
1299 /* send command */
1300 n = sizeof(rp);
1301 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1302 NG_HCI_OCF_READ_LINK_SUPERVISION_TIMO),
1303 (char const *) &cp, sizeof(cp),
1304 (char *) &rp, &n) == ERROR)
1305 return (ERROR);
1306
1307 if (rp.status != 0x00) {
1308 fprintf(stdout, "Status: %s [%#02x]\n",
1309 hci_status2str(rp.status), rp.status);
1310 return (FAILED);
1311 }
1312
1313 rp.timeout = le16toh(rp.timeout);
1314
1315 fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
1316 fprintf(stdout, "Link supervision timeout: %.2f msec [%d slots]\n",
1317 rp.timeout * 0.625, rp.timeout);
1318
1319 return (OK);
1320 } /* hci_read_link_supervision_timeout */
1321
1322 /* Send Write_Link_Supervision_Timeout command to the unit */
1323 static int
hci_write_link_supervision_timeout(int s,int argc,char ** argv)1324 hci_write_link_supervision_timeout(int s, int argc, char **argv)
1325 {
1326 ng_hci_write_link_supervision_timo_cp cp;
1327 ng_hci_write_link_supervision_timo_rp rp;
1328 int n;
1329
1330 switch (argc) {
1331 case 2:
1332 /* connection handle */
1333 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
1334 return (USAGE);
1335
1336 cp.con_handle = (uint16_t) (n & 0x0fff);
1337 cp.con_handle = htole16(cp.con_handle);
1338
1339 /* link supervision timeout */
1340 if (sscanf(argv[1], "%d", &n) != 1 || n < 0 || n > 0xffff)
1341 return (USAGE);
1342
1343 cp.timeout = (uint16_t) (n & 0x0fff);
1344 cp.timeout = htole16(cp.timeout);
1345 break;
1346
1347 default:
1348 return (USAGE);
1349 }
1350
1351 /* send command */
1352 n = sizeof(rp);
1353 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1354 NG_HCI_OCF_WRITE_LINK_SUPERVISION_TIMO),
1355 (char const *) &cp, sizeof(cp),
1356 (char *) &rp, &n) == ERROR)
1357 return (ERROR);
1358
1359 if (rp.status != 0x00) {
1360 fprintf(stdout, "Status: %s [%#02x]\n",
1361 hci_status2str(rp.status), rp.status);
1362 return (FAILED);
1363 }
1364
1365 return (OK);
1366 } /* hci_write_link_supervision_timeout */
1367
1368 /* Send Read_Page_Scan_Period_Mode command to the unit */
1369 static int
hci_read_page_scan_period_mode(int s,int argc,char ** argv)1370 hci_read_page_scan_period_mode(int s, int argc, char **argv)
1371 {
1372 ng_hci_read_page_scan_period_rp rp;
1373 int n;
1374
1375 n = sizeof(rp);
1376 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1377 NG_HCI_OCF_READ_PAGE_SCAN_PERIOD),
1378 (char *) &rp, &n) == ERROR)
1379 return (ERROR);
1380
1381 if (rp.status != 0x00) {
1382 fprintf(stdout, "Status: %s [%#02x]\n",
1383 hci_status2str(rp.status), rp.status);
1384 return (FAILED);
1385 }
1386
1387 fprintf(stdout, "Page scan period mode: %#02x\n",
1388 rp.page_scan_period_mode);
1389
1390 return (OK);
1391 } /* hci_read_page_scan_period_mode */
1392
1393 /* Send Write_Page_Scan_Period_Mode command to the unit */
1394 static int
hci_write_page_scan_period_mode(int s,int argc,char ** argv)1395 hci_write_page_scan_period_mode(int s, int argc, char **argv)
1396 {
1397 ng_hci_write_page_scan_period_cp cp;
1398 ng_hci_write_page_scan_period_rp rp;
1399 int n;
1400
1401 /* parse command arguments */
1402 switch (argc) {
1403 case 1:
1404 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2)
1405 return (USAGE);
1406
1407 cp.page_scan_period_mode = (n & 0xff);
1408 break;
1409
1410 default:
1411 return (USAGE);
1412 }
1413
1414 /* send command */
1415 n = sizeof(rp);
1416 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1417 NG_HCI_OCF_WRITE_PAGE_SCAN_PERIOD),
1418 (char const *) &cp, sizeof(cp),
1419 (char *) &rp, &n) == ERROR)
1420 return (ERROR);
1421
1422 if (rp.status != 0x00) {
1423 fprintf(stdout, "Status: %s [%#02x]\n",
1424 hci_status2str(rp.status), rp.status);
1425 return (FAILED);
1426 }
1427
1428 return (OK);
1429 } /* hci_write_page_scan_period_mode */
1430
1431 /* Send Read_Page_Scan_Mode command to the unit */
1432 static int
hci_read_page_scan_mode(int s,int argc,char ** argv)1433 hci_read_page_scan_mode(int s, int argc, char **argv)
1434 {
1435 ng_hci_read_page_scan_rp rp;
1436 int n;
1437
1438 n = sizeof(rp);
1439 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1440 NG_HCI_OCF_READ_PAGE_SCAN),
1441 (char *) &rp, &n) == ERROR)
1442 return (ERROR);
1443
1444 if (rp.status != 0x00) {
1445 fprintf(stdout, "Status: %s [%#02x]\n",
1446 hci_status2str(rp.status), rp.status);
1447 return (FAILED);
1448 }
1449
1450 fprintf(stdout, "Page scan mode: %#02x\n", rp.page_scan_mode);
1451
1452 return (OK);
1453 } /* hci_read_page_scan_mode */
1454
1455 /* Send Write_Page_Scan_Mode command to the unit */
1456 static int
hci_write_page_scan_mode(int s,int argc,char ** argv)1457 hci_write_page_scan_mode(int s, int argc, char **argv)
1458 {
1459 ng_hci_write_page_scan_cp cp;
1460 ng_hci_write_page_scan_rp rp;
1461 int n;
1462
1463 /* parse command arguments */
1464 switch (argc) {
1465 case 1:
1466 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3)
1467 return (USAGE);
1468
1469 cp.page_scan_mode = (n & 0xff);
1470 break;
1471
1472 default:
1473 return (USAGE);
1474 }
1475
1476 /* send command */
1477 n = sizeof(rp);
1478 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1479 NG_HCI_OCF_WRITE_PAGE_SCAN),
1480 (char const *) &cp, sizeof(cp),
1481 (char *) &rp, &n) == ERROR)
1482 return (ERROR);
1483
1484 if (rp.status != 0x00) {
1485 fprintf(stdout, "Status: %s [%#02x]\n",
1486 hci_status2str(rp.status), rp.status);
1487 return (FAILED);
1488 }
1489
1490 return (OK);
1491 } /* hci_write_page_scan_mode */
1492
1493 static int
hci_read_le_host_support(int s,int argc,char ** argv)1494 hci_read_le_host_support(int s, int argc, char **argv)
1495 {
1496 ng_hci_read_le_host_supported_rp rp;
1497 int n;
1498 n = sizeof(rp);
1499 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1500 NG_HCI_OCF_READ_LE_HOST_SUPPORTED),
1501 (char *) &rp, &n) == ERROR)
1502 return (ERROR);
1503
1504 if (rp.status != 0x00) {
1505 fprintf(stdout, "Status: %s [%#02x]\n",
1506 hci_status2str(rp.status), rp.status);
1507 return (FAILED);
1508 }
1509
1510 fprintf(stdout, "LE Host support: %#02x\n", rp.le_supported_host);
1511 fprintf(stdout, "Simultaneous LE Host : %#02x\n", rp.simultaneous_le_host);
1512
1513 return (OK);
1514
1515 }
1516 static int
hci_write_le_host_support(int s,int argc,char ** argv)1517 hci_write_le_host_support(int s, int argc, char **argv)
1518 {
1519 ng_hci_write_le_host_supported_cp cp;
1520 ng_hci_write_le_host_supported_rp rp;
1521
1522 int n;
1523
1524 cp.le_supported_host = 0;
1525 cp.simultaneous_le_host = 0;
1526 switch (argc) {
1527 case 2:
1528 if (sscanf(argv[1], "%d", &n) != 1 || (n != 0 && n != 1)){
1529 printf("ARGC2: %d\n", n);
1530 return (USAGE);
1531 }
1532 cp.simultaneous_le_host = (n &1);
1533
1534 case 1:
1535 if (sscanf(argv[0], "%d", &n) != 1 || (n != 0 && n != 1)){
1536 printf("ARGC1: %d\n", n);
1537 return (USAGE);
1538 }
1539
1540 cp.le_supported_host = (n &1);
1541 break;
1542
1543 default:
1544 return (USAGE);
1545 }
1546
1547
1548 /* send command */
1549 n = sizeof(rp);
1550 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1551 NG_HCI_OCF_WRITE_LE_HOST_SUPPORTED),
1552 (char const *) &cp, sizeof(cp),
1553 (char *) &rp, &n) == ERROR)
1554 return (ERROR);
1555
1556 if (rp.status != 0x00) {
1557 fprintf(stdout, "Status: %s [%#02x]\n",
1558 hci_status2str(rp.status), rp.status);
1559 return (FAILED);
1560 }
1561
1562 return (OK);
1563 }
1564
1565 struct hci_command host_controller_baseband_commands[] = {
1566 {
1567 "reset",
1568 "\nThe Reset command will reset the Host Controller and the Link Manager.\n" \
1569 "After the reset is completed, the current operational state will be lost,\n" \
1570 "the Bluetooth unit will enter standby mode and the Host Controller will\n" \
1571 "automatically revert to the default values for the parameters for which\n" \
1572 "default values are defined in the specification.",
1573 &hci_reset
1574 },
1575 {
1576 "read_pin_type",
1577 "\nThe Read_PIN_Type command is used for the Host to read whether the Link\n" \
1578 "Manager assumes that the Host supports variable PIN codes only a fixed PIN\n" \
1579 "code.",
1580 &hci_read_pin_type
1581 },
1582 {
1583 "write_pin_type <pin_type>",
1584 "\nThe Write_PIN_Type command is used for the Host to write to the Host\n" \
1585 "Controller whether the Host supports variable PIN codes or only a fixed PIN\n"\
1586 "code.\n\n" \
1587 "\t<pin_type> - dd; 0 - Variable; 1 - Fixed",
1588 &hci_write_pin_type
1589 },
1590 {
1591 "read_stored_link_key [<BD_ADDR>]",
1592 "\nThe Read_Stored_Link_Key command provides the ability to read one or\n" \
1593 "more link keys stored in the Bluetooth Host Controller. The Bluetooth Host\n" \
1594 "Controller can store a limited number of link keys for other Bluetooth\n" \
1595 "devices.\n\n" \
1596 "\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name",
1597 &hci_read_stored_link_key
1598 },
1599 {
1600 "write_stored_link_key <BD_ADDR> <key>",
1601 "\nThe Write_Stored_Link_Key command provides the ability to write one\n" \
1602 "or more link keys to be stored in the Bluetooth Host Controller. The\n" \
1603 "Bluetooth Host Controller can store a limited number of link keys for other\n"\
1604 "Bluetooth devices. If no additional space is available in the Bluetooth\n"\
1605 "Host Controller then no additional link keys will be stored.\n\n" \
1606 "\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name\n" \
1607 "\t<key> - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx up to 16 bytes link key",
1608 &hci_write_stored_link_key
1609 },
1610 {
1611 "delete_stored_link_key [<BD_ADDR>]",
1612 "\nThe Delete_Stored_Link_Key command provides the ability to remove one\n" \
1613 "or more of the link keys stored in the Bluetooth Host Controller. The\n" \
1614 "Bluetooth Host Controller can store a limited number of link keys for other\n"\
1615 "Bluetooth devices.\n\n" \
1616 "\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name",
1617 &hci_delete_stored_link_key
1618 },
1619 {
1620 "change_local_name <name>",
1621 "\nThe Change_Local_Name command provides the ability to modify the user\n" \
1622 "friendly name for the Bluetooth unit.\n\n" \
1623 "\t<name> - string",
1624 &hci_change_local_name
1625 },
1626 {
1627 "read_local_name",
1628 "\nThe Read_Local_Name command provides the ability to read the\n" \
1629 "stored user-friendly name for the Bluetooth unit.",
1630 &hci_read_local_name
1631 },
1632 {
1633 "read_connection_accept_timeout",
1634 "\nThis command will read the value for the Connection_Accept_Timeout\n" \
1635 "configuration parameter. The Connection_Accept_Timeout configuration\n" \
1636 "parameter allows the Bluetooth hardware to automatically deny a\n" \
1637 "connection request after a specified time period has occurred and\n" \
1638 "the new connection is not accepted. Connection Accept Timeout\n" \
1639 "measured in Number of Baseband slots.",
1640 &hci_read_connection_accept_timeout
1641 },
1642 {
1643 "write_connection_accept_timeout <timeout>",
1644 "\nThis command will write the value for the Connection_Accept_Timeout\n" \
1645 "configuration parameter.\n\n" \
1646 "\t<timeout> - dddd; measured in number of baseband slots.",
1647 &hci_write_connection_accept_timeout
1648 },
1649 {
1650 "read_page_timeout",
1651 "\nThis command will read the value for the Page_Timeout configuration\n" \
1652 "parameter. The Page_Timeout configuration parameter defines the\n" \
1653 "maximum time the local Link Manager will wait for a baseband page\n" \
1654 "response from the remote unit at a locally initiated connection\n" \
1655 "attempt. Page Timeout measured in Number of Baseband slots.",
1656 &hci_read_page_timeout
1657 },
1658 {
1659 "write_page_timeout <timeout>",
1660 "\nThis command will write the value for the Page_Timeout configuration\n" \
1661 "parameter.\n\n" \
1662 "\t<timeout> - dddd; measured in number of baseband slots.",
1663 &hci_write_page_timeout
1664 },
1665 {
1666 "read_scan_enable",
1667 "\nThis command will read the value for the Scan_Enable parameter. The\n" \
1668 "Scan_Enable parameter controls whether or not the Bluetooth uint\n" \
1669 "will periodically scan for page attempts and/or inquiry requests\n" \
1670 "from other Bluetooth unit.\n\n" \
1671 "\t0x00 - No Scans enabled.\n" \
1672 "\t0x01 - Inquiry Scan enabled. Page Scan disabled.\n" \
1673 "\t0x02 - Inquiry Scan disabled. Page Scan enabled.\n" \
1674 "\t0x03 - Inquiry Scan enabled. Page Scan enabled.",
1675 &hci_read_scan_enable
1676 },
1677 {
1678 "write_scan_enable <scan_enable>",
1679 "\nThis command will write the value for the Scan_Enable parameter.\n" \
1680 "The Scan_Enable parameter controls whether or not the Bluetooth\n" \
1681 "unit will periodically scan for page attempts and/or inquiry\n" \
1682 "requests from other Bluetooth unit.\n\n" \
1683 "\t<scan_enable> - dd;\n" \
1684 "\t0 - No Scans enabled.\n" \
1685 "\t1 - Inquiry Scan enabled. Page Scan disabled.\n" \
1686 "\t2 - Inquiry Scan disabled. Page Scan enabled.\n" \
1687 "\t3 - Inquiry Scan enabled. Page Scan enabled.",
1688 &hci_write_scan_enable
1689 },
1690 {
1691 "read_page_scan_activity",
1692 "\nThis command will read the value for Page_Scan_Activity configuration\n" \
1693 "parameters. The Page_Scan_Interval configuration parameter defines the\n" \
1694 "amount of time between consecutive page scans. This time interval is \n" \
1695 "defined from when the Host Controller started its last page scan until\n" \
1696 "it begins the next page scan. The Page_Scan_Window configuration parameter\n" \
1697 "defines the amount of time for the duration of the page scan. The\n" \
1698 "Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.",
1699 &hci_read_page_scan_activity
1700 },
1701 {
1702 "write_page_scan_activity interval(dddd) window(dddd)",
1703 "\nThis command will write the value for Page_Scan_Activity configuration\n" \
1704 "parameter. The Page_Scan_Interval configuration parameter defines the\n" \
1705 "amount of time between consecutive page scans. This is defined as the time\n" \
1706 "interval from when the Host Controller started its last page scan until it\n" \
1707 "begins the next page scan. The Page_Scan_Window configuration parameter\n" \
1708 "defines the amount of time for the duration of the page scan. \n" \
1709 "The Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.\n\n" \
1710 "\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \
1711 "\t<window> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec",
1712 &hci_write_page_scan_activity
1713 },
1714 {
1715 "read_inquiry_scan_activity",
1716 "\nThis command will read the value for Inquiry_Scan_Activity configuration\n" \
1717 "parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \
1718 "amount of time between consecutive inquiry scans. This is defined as the\n" \
1719 "time interval from when the Host Controller started its last inquiry scan\n" \
1720 "until it begins the next inquiry scan.",
1721 &hci_read_inquiry_scan_activity
1722 },
1723 {
1724 "write_inquiry_scan_activity interval(dddd) window(dddd)",
1725 "\nThis command will write the value for Inquiry_Scan_Activity configuration\n"\
1726 "parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \
1727 "amount of time between consecutive inquiry scans. This is defined as the\n" \
1728 "time interval from when the Host Controller started its last inquiry scan\n" \
1729 "until it begins the next inquiry scan. The Inquiry_Scan_Window configuration\n" \
1730 "parameter defines the amount of time for the duration of the inquiry scan.\n" \
1731 "The Inquiry_Scan_Window can only be less than or equal to the Inquiry_Scan_Interval.\n\n" \
1732 "\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \
1733 "\t<window> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec",
1734 &hci_write_inquiry_scan_activity
1735 },
1736 {
1737 "read_authentication_enable",
1738 "\nThis command will read the value for the Authentication_Enable parameter.\n"\
1739 "The Authentication_Enable parameter controls if the local unit requires\n"\
1740 "to authenticate the remote unit at connection setup (between the\n" \
1741 "Create_Connection command or acceptance of an incoming ACL connection\n"\
1742 "and the corresponding Connection Complete event). At connection setup, only\n"\
1743 "the unit(s) with the Authentication_Enable parameter enabled will try to\n"\
1744 "authenticate the other unit.",
1745 &hci_read_authentication_enable
1746 },
1747 {
1748 "write_authentication_enable enable(0|1)",
1749 "\nThis command will write the value for the Authentication_Enable parameter.\n"\
1750 "The Authentication_Enable parameter controls if the local unit requires to\n"\
1751 "authenticate the remote unit at connection setup (between the\n" \
1752 "Create_Connection command or acceptance of an incoming ACL connection\n" \
1753 "and the corresponding Connection Complete event). At connection setup, only\n"\
1754 "the unit(s) with the Authentication_Enable parameter enabled will try to\n"\
1755 "authenticate the other unit.",
1756 &hci_write_authentication_enable
1757 },
1758 {
1759 "read_encryption_mode",
1760 "\nThis command will read the value for the Encryption_Mode parameter. The\n" \
1761 "Encryption_Mode parameter controls if the local unit requires encryption\n" \
1762 "to the remote unit at connection setup (between the Create_Connection\n" \
1763 "command or acceptance of an incoming ACL connection and the corresponding\n" \
1764 "Connection Complete event). At connection setup, only the unit(s) with\n" \
1765 "the Authentication_Enable parameter enabled and Encryption_Mode parameter\n" \
1766 "enabled will try to encrypt the connection to the other unit.\n\n" \
1767 "\t<encryption_mode>:\n" \
1768 "\t0x00 - Encryption disabled.\n" \
1769 "\t0x01 - Encryption only for point-to-point packets.\n" \
1770 "\t0x02 - Encryption for both point-to-point and broadcast packets.",
1771 &hci_read_encryption_mode
1772 },
1773 {
1774 "write_encryption_mode mode(0|1|2)",
1775 "\tThis command will write the value for the Encryption_Mode parameter.\n" \
1776 "The Encryption_Mode parameter controls if the local unit requires\n" \
1777 "encryption to the remote unit at connection setup (between the\n" \
1778 "Create_Connection command or acceptance of an incoming ACL connection\n" \
1779 "and the corresponding Connection Complete event). At connection setup,\n" \
1780 "only the unit(s) with the Authentication_Enable parameter enabled and\n" \
1781 "Encryption_Mode parameter enabled will try to encrypt the connection to\n" \
1782 "the other unit.\n\n" \
1783 "\t<encryption_mode> (dd)\n" \
1784 "\t0 - Encryption disabled.\n" \
1785 "\t1 - Encryption only for point-to-point packets.\n" \
1786 "\t2 - Encryption for both point-to-point and broadcast packets.",
1787 &hci_write_encryption_mode
1788 },
1789 {
1790 "read_class_of_device",
1791 "\nThis command will read the value for the Class_of_Device parameter.\n" \
1792 "The Class_of_Device parameter is used to indicate the capabilities of\n" \
1793 "the local unit to other units.",
1794 &hci_read_class_of_device
1795 },
1796 {
1797 "write_class_of_device class(xx:xx:xx)",
1798 "\nThis command will write the value for the Class_of_Device parameter.\n" \
1799 "The Class_of_Device parameter is used to indicate the capabilities of \n" \
1800 "the local unit to other units.\n\n" \
1801 "\t<class> (xx:xx:xx) - class of device",
1802 &hci_write_class_of_device
1803 },
1804 {
1805 "read_voice_settings",
1806 "\nThis command will read the values for the Voice_Setting parameter.\n" \
1807 "The Voice_Setting parameter controls all the various settings for voice\n" \
1808 "connections. These settings apply to all voice connections, and cannot be\n" \
1809 "set for individual voice connections. The Voice_Setting parameter controls\n" \
1810 "the configuration for voice connections: Input Coding, Air coding format,\n" \
1811 "input data format, Input sample size, and linear PCM parameter.",
1812 &hci_read_voice_settings
1813 },
1814 {
1815 "write_voice_settings settings(xxxx)",
1816 "\nThis command will write the values for the Voice_Setting parameter.\n" \
1817 "The Voice_Setting parameter controls all the various settings for voice\n" \
1818 "connections. These settings apply to all voice connections, and cannot be\n" \
1819 "set for individual voice connections. The Voice_Setting parameter controls\n" \
1820 "the configuration for voice connections: Input Coding, Air coding format,\n" \
1821 "input data format, Input sample size, and linear PCM parameter.\n\n" \
1822 "\t<voice_settings> (xxxx) - voice settings",
1823 &hci_write_voice_settings
1824 },
1825 {
1826 "read_number_broadcast_retransmissions",
1827 "\nThis command will read the unit's parameter value for the Number of\n" \
1828 "Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \
1829 "unreliable.",
1830 &hci_read_number_broadcast_retransmissions
1831 },
1832 {
1833 "write_number_broadcast_retransmissions count(dd)",
1834 "\nThis command will write the unit's parameter value for the Number of\n" \
1835 "Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \
1836 "unreliable.\n\n" \
1837 "\t<count> (dd) - number of broadcast retransimissions",
1838 &hci_write_number_broadcast_retransmissions
1839 },
1840 {
1841 "read_hold_mode_activity",
1842 "\nThis command will read the value for the Hold_Mode_Activity parameter.\n" \
1843 "The Hold_Mode_Activity value is used to determine what activities should\n" \
1844 "be suspended when the unit is in hold mode.",
1845 &hci_read_hold_mode_activity
1846 },
1847 {
1848 "write_hold_mode_activity settings(0|1|2|4)",
1849 "\nThis command will write the value for the Hold_Mode_Activity parameter.\n" \
1850 "The Hold_Mode_Activity value is used to determine what activities should\n" \
1851 "be suspended when the unit is in hold mode.\n\n" \
1852 "\t<settings> (dd) - bit mask:\n" \
1853 "\t0 - Maintain current Power State. Default\n" \
1854 "\t1 - Suspend Page Scan.\n" \
1855 "\t2 - Suspend Inquiry Scan.\n" \
1856 "\t4 - Suspend Periodic Inquiries.",
1857 &hci_write_hold_mode_activity
1858 },
1859 {
1860 "read_sco_flow_control_enable",
1861 "\nThe Read_SCO_Flow_Control_Enable command provides the ability to read\n" \
1862 "the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \
1863 "decide if the Host Controller will send Number Of Completed Packets events\n" \
1864 "for SCO Connection Handles. This setting allows the Host to enable and\n" \
1865 "disable SCO flow control.",
1866 &hci_read_sco_flow_control_enable
1867 },
1868 {
1869 "write_sco_flow_control_enable enable(0|1)",
1870 "\nThe Write_SCO_Flow_Control_Enable command provides the ability to write\n" \
1871 "the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \
1872 "decide if the Host Controller will send Number Of Completed Packets events\n" \
1873 "for SCO Connection Handles. This setting allows the Host to enable and\n" \
1874 "disable SCO flow control. The SCO_Flow_Control_Enable setting can only be\n" \
1875 "changed if no connections exist.",
1876 &hci_write_sco_flow_control_enable
1877 },
1878 {
1879 "read_link_supervision_timeout <connection_handle>",
1880 "\nThis command will read the value for the Link_Supervision_Timeout\n" \
1881 "parameter for the device. The Link_Supervision_Timeout parameter is used\n" \
1882 "by the master or slave Bluetooth device to monitor link loss. If, for any\n" \
1883 "reason, no Baseband packets are received from that Connection Handle for a\n" \
1884 "duration longer than the Link_Supervision_Timeout, the connection is\n"
1885 "disconnected.\n\n" \
1886 "\t<connection_handle> - dddd; connection handle\n",
1887 &hci_read_link_supervision_timeout
1888 },
1889 {
1890 "write_link_supervision_timeout <connection_handle> <timeout>",
1891 "\nThis command will write the value for the Link_Supervision_Timeout\n" \
1892 "parameter for the device. The Link_Supervision_Timeout parameter is used\n" \
1893 "by the master or slave Bluetooth device to monitor link loss. If, for any\n" \
1894 "reason, no Baseband packets are received from that connection handle for a\n" \
1895 "duration longer than the Link_Supervision_Timeout, the connection is\n" \
1896 "disconnected.\n\n" \
1897 "\t<connection_handle> - dddd; connection handle\n" \
1898 "\t<timeout> - dddd; timeout measured in number of baseband slots\n",
1899 &hci_write_link_supervision_timeout
1900 },
1901 {
1902 "read_page_scan_period_mode",
1903 "\nThis command is used to read the mandatory Page_Scan_Period_Mode of the\n" \
1904 "local Bluetooth device. Every time an inquiry response message is sent, the\n"\
1905 "Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\
1906 "is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \
1907 "expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \
1908 "following page scans.",
1909 &hci_read_page_scan_period_mode
1910 },
1911 {
1912 "write_page_scan_period_mode <page_scan_period_mode>",
1913 "\nThis command is used to write the mandatory Page_Scan_Period_Mode of the\n" \
1914 "local Bluetooth device. Every time an inquiry response message is sent, the\n"\
1915 "Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\
1916 "is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \
1917 "expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \
1918 "following page scans.\n\n" \
1919 "\t<page_scan_period_mode> - dd; page scan period mode:\n" \
1920 "\t0x00 - P0 (Default)\n" \
1921 "\t0x01 - P1\n" \
1922 "\t0x02 - P2",
1923 &hci_write_page_scan_period_mode
1924 },
1925 {
1926 "read_page_scan_mode",
1927 "\nThis command is used to read the default page scan mode of the local\n" \
1928 "Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\
1929 "that is used for the default page scan. Currently one mandatory page scan\n"\
1930 "mode and three optional page scan modes are defined. Following an inquiry\n" \
1931 "response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \
1932 "mandatory page scan mode must be applied.",
1933 &hci_read_page_scan_mode
1934 },
1935 {
1936 "write_page_scan_mode <page_scan_mode>",
1937 "\nThis command is used to write the default page scan mode of the local\n" \
1938 "Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\
1939 "that is used for the default page scan. Currently, one mandatory page scan\n"\
1940 "mode and three optional page scan modes are defined. Following an inquiry\n"\
1941 "response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \
1942 "mandatory page scan mode must be applied.\n\n" \
1943 "\t<page_scan_mode> - dd; page scan mode:\n" \
1944 "\t0x00 - Mandatory Page Scan Mode (Default)\n" \
1945 "\t0x01 - Optional Page Scan Mode I\n" \
1946 "\t0x02 - Optional Page Scan Mode II\n" \
1947 "\t0x03 - Optional Page Scan Mode III",
1948 &hci_write_page_scan_mode
1949 },
1950 {
1951 "read_le_host_support", \
1952 "Read if this host is in LE supported mode and simultaneous LE supported mode",
1953 &hci_read_le_host_support,
1954 },
1955 {
1956 "write_le_host_support", \
1957 "write_le_host_support le_host[0|1] simultaneous_le[0|1]",
1958 &hci_write_le_host_support,
1959 },
1960
1961 { NULL, }
1962 };
1963
1964