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