xref: /freebsd/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c (revision 7aa383846770374466b1dcb2cefd71bde9acf463)
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 
1878