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