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