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