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