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