1330449Seadler/*-
2107120Sjulian * host_controller_baseband.c
3107120Sjulian *
4330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5330449Seadler *
6107120Sjulian * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7107120Sjulian * All rights reserved.
8107120Sjulian *
9107120Sjulian * Redistribution and use in source and binary forms, with or without
10107120Sjulian * modification, are permitted provided that the following conditions
11107120Sjulian * are met:
12107120Sjulian * 1. Redistributions of source code must retain the above copyright
13107120Sjulian *    notice, this list of conditions and the following disclaimer.
14107120Sjulian * 2. Redistributions in binary form must reproduce the above copyright
15107120Sjulian *    notice, this list of conditions and the following disclaimer in the
16107120Sjulian *    documentation and/or other materials provided with the distribution.
17107120Sjulian *
18107120Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19107120Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20107120Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21107120Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22107120Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23107120Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24107120Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25107120Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26107120Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27107120Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28107120Sjulian * SUCH DAMAGE.
29107120Sjulian *
30121054Semax * $Id: host_controller_baseband.c,v 1.4 2003/08/18 19:19:53 max Exp $
31107120Sjulian * $FreeBSD: stable/11/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c 361185 2020-05-18 09:14:58Z hselasky $
32107120Sjulian */
33107120Sjulian
34281210Stakawata#define L2CAP_SOCKET_CHECKED
35121054Semax#include <bluetooth.h>
36107120Sjulian#include <errno.h>
37107120Sjulian#include <stdio.h>
38107120Sjulian#include <string.h>
39107120Sjulian#include "hccontrol.h"
40107120Sjulian
41107120Sjulian/* Convert hex ASCII to int4 */
42107120Sjulianstatic int
43107120Sjulianhci_hexa2int4(const char *a)
44107120Sjulian{
45107120Sjulian	if ('0' <= *a && *a <= '9')
46107120Sjulian		return (*a - '0');
47107120Sjulian
48107120Sjulian	if ('A' <= *a && *a <= 'F')
49107120Sjulian		return (*a - 'A' + 0xa);
50107120Sjulian
51107120Sjulian	if ('a' <= *a && *a <= 'f')
52107120Sjulian		return (*a - 'a' + 0xa);
53107120Sjulian
54107120Sjulian	return (-1);
55107120Sjulian}
56107120Sjulian
57107120Sjulian/* Convert hex ASCII to int8 */
58107120Sjulianstatic int
59107120Sjulianhci_hexa2int8(const char *a)
60107120Sjulian{
61107120Sjulian	int	hi = hci_hexa2int4(a);
62107120Sjulian	int	lo = hci_hexa2int4(a + 1);
63107120Sjulian
64107120Sjulian	if (hi < 0 || lo < 0)
65107120Sjulian		return (-1);
66107120Sjulian
67107120Sjulian	return ((hi << 4) | lo);
68107120Sjulian}
69107120Sjulian
70128079Semax/* Convert ascii hex string to the uint8_t[] */
71107120Sjulianstatic int
72128079Semaxhci_hexstring2array(char const *s, uint8_t *a, int asize)
73107120Sjulian{
74107120Sjulian	int	i, l, b;
75107120Sjulian
76107120Sjulian	l = strlen(s) / 2;
77107120Sjulian	if (l > asize)
78107120Sjulian		l = asize;
79107120Sjulian
80107120Sjulian	for (i = 0; i < l; i++) {
81107120Sjulian		b = hci_hexa2int8(s + i * 2);
82107120Sjulian		if (b < 0)
83107120Sjulian			return (-1);
84107120Sjulian
85107120Sjulian		a[i] = (b & 0xff);
86107120Sjulian	}
87107120Sjulian
88107120Sjulian	return (0);
89107120Sjulian}
90107120Sjulian
91107120Sjulian/* Send RESET to the unit */
92107120Sjulianstatic int
93107120Sjulianhci_reset(int s, int argc, char **argv)
94107120Sjulian{
95107120Sjulian	ng_hci_status_rp	rp;
96107120Sjulian	int			n;
97107120Sjulian
98107120Sjulian	n = sizeof(rp);
99107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
100107120Sjulian			NG_HCI_OCF_RESET), (char *) &rp, &n) == ERROR)
101107120Sjulian		return (ERROR);
102107120Sjulian
103107120Sjulian	if (rp.status != 0x00) {
104107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
105107120Sjulian			hci_status2str(rp.status), rp.status);
106107120Sjulian		return (FAILED);
107107120Sjulian	}
108107120Sjulian
109107120Sjulian	return (OK);
110107120Sjulian} /* hci_reset */
111107120Sjulian
112107120Sjulian/* Send Read_PIN_Type command to the unit */
113107120Sjulianstatic int
114107120Sjulianhci_read_pin_type(int s, int argc, char **argv)
115107120Sjulian{
116107120Sjulian	ng_hci_read_pin_type_rp	rp;
117107120Sjulian	int			n;
118107120Sjulian
119107120Sjulian	n = sizeof(rp);
120107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
121107120Sjulian			NG_HCI_OCF_READ_PIN_TYPE),
122107120Sjulian			(char *) &rp, &n) == ERROR)
123107120Sjulian		return (ERROR);
124107120Sjulian
125107120Sjulian	if (rp.status != 0x00) {
126107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
127107120Sjulian			hci_status2str(rp.status), rp.status);
128107120Sjulian		return (FAILED);
129107120Sjulian	}
130107120Sjulian
131107120Sjulian	fprintf(stdout, "PIN type: %s [%#02x]\n",
132107120Sjulian			hci_pin2str(rp.pin_type), rp.pin_type);
133107120Sjulian
134107120Sjulian	return (OK);
135107120Sjulian} /* hci_read_pin_type */
136107120Sjulian
137107120Sjulian/* Send Write_PIN_Type command to the unit */
138107120Sjulianstatic int
139107120Sjulianhci_write_pin_type(int s, int argc, char **argv)
140107120Sjulian{
141107120Sjulian	ng_hci_write_pin_type_cp	cp;
142107120Sjulian	ng_hci_write_pin_type_rp	rp;
143107120Sjulian	int				n;
144107120Sjulian
145107120Sjulian	/* parse command parameters */
146107120Sjulian	switch (argc) {
147107120Sjulian	case 1:
148107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)
149107120Sjulian			return (USAGE);
150107120Sjulian
151128079Semax		cp.pin_type = (uint8_t) n;
152107120Sjulian		break;
153107120Sjulian
154107120Sjulian	default:
155107120Sjulian		return (USAGE);
156107120Sjulian	}
157107120Sjulian
158107120Sjulian	/* send command */
159107120Sjulian	n = sizeof(rp);
160107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
161107120Sjulian			NG_HCI_OCF_WRITE_PIN_TYPE),
162107120Sjulian			(char const *) &cp, sizeof(cp),
163107120Sjulian			(char *) &rp , &n) ==  ERROR)
164107120Sjulian		return (ERROR);
165107120Sjulian
166107120Sjulian	if (rp.status != 0x00) {
167107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
168107120Sjulian			hci_status2str(rp.status), rp.status);
169107120Sjulian		return (FAILED);
170107120Sjulian	}
171107120Sjulian
172107120Sjulian	return (OK);
173107120Sjulian} /* hci_write_pin_type */
174107120Sjulian
175107120Sjulian/* Send Read_Stored_Link_Key command to the unit */
176107120Sjulianstatic int
177107120Sjulianhci_read_stored_link_key(int s, int argc, char **argv)
178107120Sjulian{
179107120Sjulian	struct {
180107120Sjulian		ng_hci_cmd_pkt_t			hdr;
181107120Sjulian		ng_hci_read_stored_link_key_cp		cp;
182107120Sjulian	} __attribute__ ((packed))			cmd;
183107120Sjulian
184107120Sjulian	struct {
185107120Sjulian		ng_hci_event_pkt_t			hdr;
186107120Sjulian		union {
187107120Sjulian			ng_hci_command_compl_ep		cc;
188107120Sjulian			ng_hci_return_link_keys_ep	key;
189128079Semax			uint8_t				b[NG_HCI_EVENT_PKT_SIZE];
190107120Sjulian		}					ep;
191107120Sjulian	} __attribute__ ((packed))			event;
192107120Sjulian
193121054Semax	int						n, n1;
194107120Sjulian
195107120Sjulian	/* Send command */
196107120Sjulian	memset(&cmd, 0, sizeof(cmd));
197107120Sjulian	cmd.hdr.type = NG_HCI_CMD_PKT;
198107120Sjulian	cmd.hdr.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
199107120Sjulian				NG_HCI_OCF_READ_STORED_LINK_KEY));
200107120Sjulian	cmd.hdr.length = sizeof(cmd.cp);
201107120Sjulian
202107120Sjulian	switch (argc) {
203107120Sjulian	case 1:
204107120Sjulian		/* parse BD_ADDR */
205121054Semax		if (!bt_aton(argv[0], &cmd.cp.bdaddr)) {
206121054Semax			struct hostent	*he = NULL;
207107120Sjulian
208121054Semax			if ((he = bt_gethostbyname(argv[0])) == NULL)
209121054Semax				return (USAGE);
210121054Semax
211121054Semax			memcpy(&cmd.cp.bdaddr, he->h_addr, sizeof(cmd.cp.bdaddr));
212121054Semax		}
213107120Sjulian		break;
214107120Sjulian
215107120Sjulian	default:
216107120Sjulian		cmd.cp.read_all = 1;
217107120Sjulian		break;
218107120Sjulian	}
219107120Sjulian
220107120Sjulian	if (hci_send(s, (char const *) &cmd, sizeof(cmd)) != OK)
221107120Sjulian		return (ERROR);
222107120Sjulian
223107120Sjulian	/* Receive events */
224107120Sjulianagain:
225107120Sjulian	memset(&event, 0, sizeof(event));
226107120Sjulian	n = sizeof(event);
227107120Sjulian	if (hci_recv(s, (char *) &event, &n) != OK)
228107120Sjulian		return (ERROR);
229107120Sjulian
230107120Sjulian	if (n <= sizeof(event.hdr)) {
231107120Sjulian		errno = EMSGSIZE;
232107120Sjulian		return (ERROR);
233107120Sjulian	}
234107120Sjulian
235107120Sjulian	if (event.hdr.type != NG_HCI_EVENT_PKT) {
236107120Sjulian		errno = EIO;
237107120Sjulian		return (ERROR);
238107120Sjulian	}
239107120Sjulian
240107120Sjulian	/* Parse event */
241107120Sjulian	switch (event.hdr.event) {
242107120Sjulian	case NG_HCI_EVENT_COMMAND_COMPL: {
243107120Sjulian		ng_hci_read_stored_link_key_rp	*rp = NULL;
244107120Sjulian
245107120Sjulian		if (event.ep.cc.opcode == 0x0000 ||
246107120Sjulian		    event.ep.cc.opcode != cmd.hdr.opcode)
247107120Sjulian			goto again;
248107120Sjulian
249107120Sjulian		rp = (ng_hci_read_stored_link_key_rp *)(event.ep.b +
250107120Sjulian				sizeof(event.ep.cc));
251107120Sjulian
252107120Sjulian		fprintf(stdout, "Complete: Status: %s [%#x]\n",
253107120Sjulian				hci_status2str(rp->status), rp->status);
254107120Sjulian		fprintf(stdout, "Maximum Number of keys: %d\n",
255107120Sjulian				le16toh(rp->max_num_keys));
256107120Sjulian		fprintf(stdout, "Number of keys read: %d\n",
257107120Sjulian				le16toh(rp->num_keys_read));
258107120Sjulian		} break;
259107120Sjulian
260107120Sjulian	case NG_HCI_EVENT_RETURN_LINK_KEYS: {
261107120Sjulian		struct _key {
262107120Sjulian			bdaddr_t	bdaddr;
263128079Semax			uint8_t		key[NG_HCI_KEY_SIZE];
264107120Sjulian		} __attribute__ ((packed))	*k = NULL;
265107120Sjulian
266107120Sjulian		fprintf(stdout, "Event: Number of keys: %d\n",
267107120Sjulian			event.ep.key.num_keys);
268107120Sjulian
269107120Sjulian		k = (struct _key *)(event.ep.b + sizeof(event.ep.key));
270107120Sjulian		for (n = 0; n < event.ep.key.num_keys; n++) {
271121054Semax			fprintf(stdout, "\t%d: %s ",
272121054Semax				n + 1, hci_bdaddr2str(&k->bdaddr));
273107120Sjulian
274121054Semax			for (n1 = 0; n1 < sizeof(k->key); n1++)
275121054Semax				fprintf(stdout, "%02x", k->key[n1]);
276107120Sjulian			fprintf(stdout, "\n");
277107120Sjulian
278107120Sjulian			k ++;
279107120Sjulian		}
280107120Sjulian
281107120Sjulian		goto again;
282107120Sjulian
283107120Sjulian		} break;
284107120Sjulian
285107120Sjulian	default:
286107120Sjulian		goto again;
287107120Sjulian	}
288107120Sjulian
289107120Sjulian	return (OK);
290107120Sjulian} /* hci_read_store_link_key */
291107120Sjulian
292107120Sjulian/* Send Write_Stored_Link_Key command to the unit */
293107120Sjulianstatic int
294107120Sjulianhci_write_stored_link_key(int s, int argc, char **argv)
295107120Sjulian{
296107120Sjulian	struct {
297107120Sjulian		ng_hci_write_stored_link_key_cp	p;
298107120Sjulian		bdaddr_t			bdaddr;
299128079Semax		uint8_t				key[NG_HCI_KEY_SIZE];
300107120Sjulian	}					cp;
301107120Sjulian	ng_hci_write_stored_link_key_rp		rp;
302121054Semax	int32_t					n;
303107120Sjulian
304107120Sjulian	memset(&cp, 0, sizeof(cp));
305107120Sjulian
306107120Sjulian	switch (argc) {
307107120Sjulian	case 2:
308107120Sjulian		cp.p.num_keys_write = 1;
309107120Sjulian
310107120Sjulian		/* parse BD_ADDR */
311121054Semax		if (!bt_aton(argv[0], &cp.bdaddr)) {
312121054Semax			struct hostent	*he = NULL;
313107120Sjulian
314121054Semax			if ((he = bt_gethostbyname(argv[0])) == NULL)
315121054Semax				return (USAGE);
316107120Sjulian
317121054Semax			memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
318121054Semax		}
319121054Semax
320107120Sjulian		/* parse key */
321107120Sjulian		if (hci_hexstring2array(argv[1], cp.key, sizeof(cp.key)) < 0)
322107120Sjulian			return (USAGE);
323107120Sjulian		break;
324107120Sjulian
325107120Sjulian	default:
326107120Sjulian		return (USAGE);
327107120Sjulian	}
328107120Sjulian
329107120Sjulian	/* send command */
330107120Sjulian	n = sizeof(rp);
331107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
332107120Sjulian			NG_HCI_OCF_WRITE_STORED_LINK_KEY),
333107120Sjulian			(char const *) &cp, sizeof(cp),
334107120Sjulian			(char *) &rp, &n) == ERROR)
335107120Sjulian		return (ERROR);
336107120Sjulian
337107120Sjulian	if (rp.status != 0x00) {
338107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
339107120Sjulian			hci_status2str(rp.status), rp.status);
340107120Sjulian		return (FAILED);
341107120Sjulian	}
342107120Sjulian
343107120Sjulian	fprintf(stdout, "Number of keys written: %d\n", rp.num_keys_written);
344107120Sjulian
345107120Sjulian	return (OK);
346107120Sjulian} /* hci_write_stored_link_key */
347107120Sjulian
348107120Sjulian
349107120Sjulian/* Send Delete_Stored_Link_Key command to the unit */
350107120Sjulianstatic int
351107120Sjulianhci_delete_stored_link_key(int s, int argc, char **argv)
352107120Sjulian{
353107120Sjulian	ng_hci_delete_stored_link_key_cp	cp;
354107120Sjulian	ng_hci_delete_stored_link_key_rp	rp;
355121054Semax	int32_t					n;
356107120Sjulian
357107120Sjulian	memset(&cp, 0, sizeof(cp));
358107120Sjulian
359107120Sjulian	switch (argc) {
360107120Sjulian	case 1:
361107120Sjulian		/* parse BD_ADDR */
362121054Semax		if (!bt_aton(argv[0], &cp.bdaddr)) {
363121054Semax			struct hostent	*he = NULL;
364107120Sjulian
365121054Semax			if ((he = bt_gethostbyname(argv[0])) == NULL)
366121054Semax				return (USAGE);
367121054Semax
368121054Semax			memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
369121054Semax		}
370107120Sjulian		break;
371107120Sjulian
372107120Sjulian	default:
373107120Sjulian		cp.delete_all = 1;
374107120Sjulian		break;
375107120Sjulian	}
376107120Sjulian
377107120Sjulian	/* send command */
378107120Sjulian	n = sizeof(cp);
379107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
380107120Sjulian			NG_HCI_OCF_DELETE_STORED_LINK_KEY),
381107120Sjulian			(char const *) &cp, sizeof(cp),
382107120Sjulian			(char *) &rp, &n) == ERROR)
383107120Sjulian		return (ERROR);
384107120Sjulian
385107120Sjulian	if (rp.status != 0x00) {
386107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
387107120Sjulian			hci_status2str(rp.status), rp.status);
388107120Sjulian		return (FAILED);
389107120Sjulian	}
390107120Sjulian
391107120Sjulian	fprintf(stdout, "Number of keys deleted: %d\n", rp.num_keys_deleted);
392107120Sjulian
393107120Sjulian	return (OK);
394107120Sjulian} /* hci_delete_stored_link_key */
395107120Sjulian
396107120Sjulian/* Send Change_Local_Name command to the unit */
397107120Sjulianstatic int
398107120Sjulianhci_change_local_name(int s, int argc, char **argv)
399107120Sjulian{
400107120Sjulian	ng_hci_change_local_name_cp	cp;
401107120Sjulian	ng_hci_change_local_name_rp	rp;
402107120Sjulian	int				n;
403107120Sjulian
404107120Sjulian	/* parse command parameters */
405107120Sjulian	switch (argc) {
406107120Sjulian	case 1:
407107120Sjulian		snprintf(cp.name, sizeof(cp.name), "%s", argv[0]);
408107120Sjulian		break;
409107120Sjulian
410107120Sjulian	default:
411107120Sjulian		return (USAGE);
412107120Sjulian	}
413107120Sjulian
414107120Sjulian	/* send command */
415107120Sjulian	n = sizeof(rp);
416107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
417107120Sjulian			NG_HCI_OCF_CHANGE_LOCAL_NAME),
418107120Sjulian			(char const *) &cp, sizeof(cp),
419107120Sjulian			(char *) &rp, &n) == ERROR)
420107120Sjulian		return (ERROR);
421107120Sjulian
422107120Sjulian	if (rp.status != 0x00) {
423107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
424107120Sjulian			hci_status2str(rp.status), rp.status);
425107120Sjulian		return (FAILED);
426107120Sjulian	}
427107120Sjulian
428107120Sjulian	return (OK);
429107120Sjulian} /* hci_change_local_name */
430107120Sjulian
431107120Sjulian/* Send Read_Local_Name command to the unit */
432107120Sjulianstatic int
433107120Sjulianhci_read_local_name(int s, int argc, char **argv)
434107120Sjulian{
435107120Sjulian	ng_hci_read_local_name_rp	rp;
436107120Sjulian	int				n;
437107120Sjulian
438107120Sjulian	n = sizeof(rp);
439107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
440107120Sjulian			NG_HCI_OCF_READ_LOCAL_NAME),
441107120Sjulian			(char *) &rp, &n) == ERROR)
442107120Sjulian		return (ERROR);
443107120Sjulian
444107120Sjulian	if (rp.status != 0x00) {
445107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
446107120Sjulian			hci_status2str(rp.status), rp.status);
447107120Sjulian		return (FAILED);
448107120Sjulian	}
449107120Sjulian
450107120Sjulian	fprintf(stdout, "Local name: %s\n", rp.name);
451107120Sjulian
452107120Sjulian	return (OK);
453107120Sjulian} /* hci_read_local_name */
454107120Sjulian
455107120Sjulian/* Send Read_Connection_Accept_Timeout to the unit */
456107120Sjulianstatic int
457107120Sjulianhci_read_connection_accept_timeout(int s, int argc, char **argv)
458107120Sjulian{
459107120Sjulian	ng_hci_read_con_accept_timo_rp	rp;
460107120Sjulian	int				n;
461107120Sjulian
462107120Sjulian	n = sizeof(rp);
463107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
464107120Sjulian			NG_HCI_OCF_READ_CON_ACCEPT_TIMO),
465107120Sjulian			(char *) &rp, &n) == ERROR)
466107120Sjulian		return (ERROR);
467107120Sjulian
468107120Sjulian	if (rp.status != 0x00) {
469107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
470107120Sjulian			hci_status2str(rp.status), rp.status);
471107120Sjulian		return (FAILED);
472107120Sjulian	}
473107120Sjulian
474107120Sjulian	rp.timeout = le16toh(rp.timeout);
475107120Sjulian	fprintf(stdout, "Connection accept timeout: %.2f msec [%d slots]\n",
476107120Sjulian			rp.timeout * 0.625, rp.timeout);
477107120Sjulian
478107120Sjulian	return (OK);
479107120Sjulian} /* hci_read_connection_accept_timeout */
480107120Sjulian
481107120Sjulian/* Send Write_Connection_Accept_Timeout to the unit */
482107120Sjulianstatic int
483107120Sjulianhci_write_connection_accept_timeout(int s, int argc, char **argv)
484107120Sjulian{
485107120Sjulian	ng_hci_write_con_accept_timo_cp	cp;
486107120Sjulian	ng_hci_write_con_accept_timo_rp	rp;
487107120Sjulian	int				n;
488107120Sjulian
489107120Sjulian	/* parse command parameters */
490107120Sjulian	switch (argc) {
491107120Sjulian	case 1:
492107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xb540)
493107120Sjulian			return (USAGE);
494107120Sjulian
495128079Semax		cp.timeout = (uint16_t) n;
496107120Sjulian		cp.timeout = htole16(cp.timeout);
497107120Sjulian		break;
498107120Sjulian
499107120Sjulian	default:
500107120Sjulian		return (USAGE);
501107120Sjulian	}
502107120Sjulian
503107120Sjulian	/* send command */
504107120Sjulian	n = sizeof(rp);
505107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
506107120Sjulian			NG_HCI_OCF_WRITE_CON_ACCEPT_TIMO),
507107120Sjulian			(char const *) &cp, sizeof(cp),
508107120Sjulian			(char *) &rp, &n) == ERROR)
509107120Sjulian		return (ERROR);
510107120Sjulian
511107120Sjulian	if (rp.status != 0x00) {
512107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
513107120Sjulian			hci_status2str(rp.status), rp.status);
514107120Sjulian		return (FAILED);
515107120Sjulian	}
516107120Sjulian
517107120Sjulian	return (OK);
518107120Sjulian} /* hci_write_connection_accept_timeout */
519107120Sjulian
520107120Sjulian/* Send Read_Page_Timeout command to the unit */
521107120Sjulianstatic int
522107120Sjulianhci_read_page_timeout(int s, int argc, char **argv)
523107120Sjulian{
524107120Sjulian	ng_hci_read_page_timo_rp	rp;
525107120Sjulian	int				n;
526107120Sjulian
527107120Sjulian	n = sizeof(rp);
528107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
529107120Sjulian			NG_HCI_OCF_READ_PAGE_TIMO),
530107120Sjulian			(char *) &rp, &n) == ERROR)
531107120Sjulian		return (ERROR);
532107120Sjulian
533107120Sjulian	if (rp.status != 0x00) {
534107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
535107120Sjulian			hci_status2str(rp.status), rp.status);
536107120Sjulian		return (FAILED);
537107120Sjulian	}
538107120Sjulian
539107120Sjulian	rp.timeout = le16toh(rp.timeout);
540107120Sjulian	fprintf(stdout, "Page timeout: %.2f msec [%d slots]\n",
541107120Sjulian		rp.timeout * 0.625, rp.timeout);
542107120Sjulian
543107120Sjulian	return (OK);
544107120Sjulian} /* hci_read_page_timeoout */
545107120Sjulian
546107120Sjulian/* Send Write_Page_Timeout command to the unit */
547107120Sjulianstatic int
548107120Sjulianhci_write_page_timeout(int s, int argc, char **argv)
549107120Sjulian{
550107120Sjulian	ng_hci_write_page_timo_cp	cp;
551107120Sjulian	ng_hci_write_page_timo_rp	rp;
552107120Sjulian	int				n;
553107120Sjulian
554107120Sjulian	/* parse command parameters */
555107120Sjulian	switch (argc) {
556107120Sjulian	case 1:
557107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xffff)
558107120Sjulian			return (USAGE);
559107120Sjulian
560128079Semax		cp.timeout = (uint16_t) n;
561107120Sjulian		cp.timeout = htole16(cp.timeout);
562107120Sjulian		break;
563107120Sjulian
564107120Sjulian	default:
565107120Sjulian		return (USAGE);
566107120Sjulian	}
567107120Sjulian
568107120Sjulian	/* send command */
569107120Sjulian	n = sizeof(rp);
570107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
571107120Sjulian			NG_HCI_OCF_WRITE_PAGE_TIMO),
572107120Sjulian			(char const *) &cp, sizeof(cp),
573107120Sjulian			(char *) &rp, &n) == ERROR)
574107120Sjulian		return (ERROR);
575107120Sjulian
576107120Sjulian	if (rp.status != 0x00) {
577107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
578107120Sjulian			hci_status2str(rp.status), rp.status);
579107120Sjulian		return (FAILED);
580107120Sjulian	}
581107120Sjulian
582107120Sjulian	return (OK);
583107120Sjulian} /* hci_write_page_timeout */
584107120Sjulian
585107120Sjulian/* Send Read_Scan_Enable command to the unit */
586107120Sjulianstatic int
587107120Sjulianhci_read_scan_enable(int s, int argc, char **argv)
588107120Sjulian{
589107120Sjulian	ng_hci_read_scan_enable_rp	rp;
590107120Sjulian	int				n;
591107120Sjulian
592107120Sjulian	n = sizeof(rp);
593107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
594107120Sjulian			NG_HCI_OCF_READ_SCAN_ENABLE),
595107120Sjulian			(char *) &rp, &n) == ERROR)
596107120Sjulian		return (ERROR);
597107120Sjulian
598107120Sjulian	if (rp.status != 0x00) {
599107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
600107120Sjulian			hci_status2str(rp.status), rp.status);
601107120Sjulian		return (FAILED);
602107120Sjulian	}
603107120Sjulian
604107120Sjulian	fprintf(stdout, "Scan enable: %s [%#02x]\n",
605107120Sjulian		hci_scan2str(rp.scan_enable), rp.scan_enable);
606107120Sjulian
607107120Sjulian	return (OK);
608107120Sjulian} /* hci_read_scan_enable */
609107120Sjulian
610107120Sjulian/* Send Write_Scan_Enable command to the unit */
611107120Sjulianstatic int
612107120Sjulianhci_write_scan_enable(int s, int argc, char **argv)
613107120Sjulian{
614107120Sjulian	ng_hci_write_scan_enable_cp	cp;
615107120Sjulian	ng_hci_write_scan_enable_rp	rp;
616107120Sjulian	int				n;
617107120Sjulian
618107120Sjulian	/* parse command parameters */
619107120Sjulian	switch (argc) {
620107120Sjulian	case 1:
621107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3)
622107120Sjulian			return (USAGE);
623107120Sjulian
624128079Semax		cp.scan_enable = (uint8_t) n;
625107120Sjulian		break;
626107120Sjulian
627107120Sjulian	default:
628107120Sjulian		return (USAGE);
629107120Sjulian	}
630107120Sjulian
631107120Sjulian	n = sizeof(rp);
632107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
633107120Sjulian			NG_HCI_OCF_WRITE_SCAN_ENABLE),
634107120Sjulian			(char const *) &cp, sizeof(cp),
635107120Sjulian			(char *) &rp, &n) == ERROR)
636107120Sjulian		return (ERROR);
637107120Sjulian
638107120Sjulian	if (rp.status != 0x00) {
639107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
640107120Sjulian			hci_status2str(rp.status), rp.status);
641107120Sjulian		return (FAILED);
642107120Sjulian	}
643107120Sjulian
644107120Sjulian	return (OK);
645107120Sjulian} /* hci_write_scan_enable */
646107120Sjulian
647107120Sjulian/* Send Read_Page_Scan_Activity command to the unit */
648107120Sjulianstatic int
649107120Sjulianhci_read_page_scan_activity(int s, int argc, char **argv)
650107120Sjulian{
651107120Sjulian	ng_hci_read_page_scan_activity_rp	rp;
652107120Sjulian	int					n;
653107120Sjulian
654107120Sjulian	n = sizeof(rp);
655107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
656107120Sjulian			NG_HCI_OCF_READ_PAGE_SCAN_ACTIVITY),
657107120Sjulian			(char *) &rp, &n) == ERROR)
658107120Sjulian		return (ERROR);
659107120Sjulian
660107120Sjulian	if (rp.status != 0x00) {
661107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
662107120Sjulian			hci_status2str(rp.status), rp.status);
663107120Sjulian		return (FAILED);
664107120Sjulian	}
665107120Sjulian
666107120Sjulian	rp.page_scan_interval = le16toh(rp.page_scan_interval);
667107120Sjulian	rp.page_scan_window = le16toh(rp.page_scan_window);
668107120Sjulian
669107120Sjulian	fprintf(stdout, "Page Scan Interval: %.2f msec [%d slots]\n",
670107120Sjulian		rp.page_scan_interval * 0.625, rp.page_scan_interval);
671107120Sjulian	fprintf(stdout, "Page Scan Window: %.2f msec [%d slots]\n",
672107120Sjulian		rp.page_scan_window * 0.625, rp.page_scan_window);
673107120Sjulian
674107120Sjulian	return (OK);
675107120Sjulian} /* hci_read_page_scan_activity */
676107120Sjulian
677107120Sjulian/* Send Write_Page_Scan_Activity command to the unit */
678107120Sjulianstatic int
679107120Sjulianhci_write_page_scan_activity(int s, int argc, char **argv)
680107120Sjulian{
681107120Sjulian	ng_hci_write_page_scan_activity_cp	cp;
682107120Sjulian	ng_hci_write_page_scan_activity_rp	rp;
683107120Sjulian	int					n;
684107120Sjulian
685107120Sjulian	/* parse command parameters */
686107120Sjulian	switch (argc) {
687107120Sjulian	case 2:
688107120Sjulian		/* page scan interval */
689107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
690107120Sjulian			return (USAGE);
691107120Sjulian
692128079Semax		cp.page_scan_interval = (uint16_t) n;
693107120Sjulian
694107120Sjulian		/* page scan window */
695131216Semax		if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
696107120Sjulian			return (USAGE);
697107120Sjulian
698128079Semax		cp.page_scan_window = (uint16_t) n;
699107120Sjulian
700107120Sjulian		if (cp.page_scan_window > cp.page_scan_interval)
701107120Sjulian			return (USAGE);
702107120Sjulian
703107120Sjulian		cp.page_scan_interval = htole16(cp.page_scan_interval);
704107120Sjulian		cp.page_scan_window = htole16(cp.page_scan_window);
705107120Sjulian		break;
706107120Sjulian
707107120Sjulian	default:
708107120Sjulian		return (USAGE);
709107120Sjulian	}
710107120Sjulian
711107120Sjulian	/* send command */
712107120Sjulian	n = sizeof(rp);
713107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
714107120Sjulian			NG_HCI_OCF_WRITE_PAGE_SCAN_ACTIVITY),
715107120Sjulian			(char const *) &cp, sizeof(cp),
716107120Sjulian			(char *) &rp, &n) == ERROR)
717107120Sjulian		return (ERROR);
718107120Sjulian
719107120Sjulian	if (rp.status != 0x00) {
720107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
721107120Sjulian			hci_status2str(rp.status), rp.status);
722107120Sjulian		return (FAILED);
723107120Sjulian	}
724107120Sjulian
725107120Sjulian	return (OK);
726107120Sjulian} /* hci_write_page_scan_activity */
727107120Sjulian
728107120Sjulian/* Send Read_Inquiry_Scan_Activity command to the unit */
729107120Sjulianstatic int
730107120Sjulianhci_read_inquiry_scan_activity(int s, int argc, char **argv)
731107120Sjulian{
732107120Sjulian	ng_hci_read_inquiry_scan_activity_rp	rp;
733107120Sjulian	int					n;
734107120Sjulian
735107120Sjulian	n = sizeof(rp);
736107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
737107120Sjulian			NG_HCI_OCF_READ_INQUIRY_SCAN_ACTIVITY),
738107120Sjulian			(char *) &rp, &n) == ERROR)
739107120Sjulian		return (ERROR);
740107120Sjulian
741107120Sjulian	if (rp.status != 0x00) {
742107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
743107120Sjulian			hci_status2str(rp.status), rp.status);
744107120Sjulian		return (FAILED);
745107120Sjulian	}
746107120Sjulian
747107120Sjulian	rp.inquiry_scan_interval = le16toh(rp.inquiry_scan_interval);
748107120Sjulian	rp.inquiry_scan_window = le16toh(rp.inquiry_scan_window);
749107120Sjulian
750107120Sjulian	fprintf(stdout, "Inquiry Scan Interval: %.2f msec [%d slots]\n",
751107120Sjulian		rp.inquiry_scan_interval * 0.625, rp.inquiry_scan_interval);
752107120Sjulian	fprintf(stdout, "Inquiry Scan Window: %.2f msec [%d slots]\n",
753107120Sjulian		rp.inquiry_scan_window * 0.625, rp.inquiry_scan_interval);
754107120Sjulian
755107120Sjulian	return (OK);
756107120Sjulian} /* hci_read_inquiry_scan_activity */
757107120Sjulian
758107120Sjulian/* Send Write_Inquiry_Scan_Activity command to the unit */
759107120Sjulianstatic int
760107120Sjulianhci_write_inquiry_scan_activity(int s, int argc, char **argv)
761107120Sjulian{
762107120Sjulian	ng_hci_write_inquiry_scan_activity_cp	cp;
763107120Sjulian	ng_hci_write_inquiry_scan_activity_rp	rp;
764107120Sjulian	int					n;
765107120Sjulian
766107120Sjulian	/* parse command parameters */
767107120Sjulian	switch (argc) {
768107120Sjulian	case 2:
769107120Sjulian		/* inquiry scan interval */
770107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
771107120Sjulian			return (USAGE);
772107120Sjulian
773128079Semax		cp.inquiry_scan_interval = (uint16_t) n;
774107120Sjulian
775107120Sjulian		/* inquiry scan window */
776131216Semax		if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000)
777107120Sjulian			return (USAGE);
778107120Sjulian
779128079Semax		cp.inquiry_scan_window = (uint16_t) n;
780107120Sjulian
781107120Sjulian		if (cp.inquiry_scan_window > cp.inquiry_scan_interval)
782107120Sjulian			return (USAGE);
783107120Sjulian
784107120Sjulian		cp.inquiry_scan_interval =
785107120Sjulian			htole16(cp.inquiry_scan_interval);
786107120Sjulian		cp.inquiry_scan_window = htole16(cp.inquiry_scan_window);
787107120Sjulian		break;
788107120Sjulian
789107120Sjulian	default:
790107120Sjulian		return (USAGE);
791107120Sjulian	}
792107120Sjulian
793107120Sjulian	/* send command */
794107120Sjulian	n = sizeof(rp);
795107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
796107120Sjulian			NG_HCI_OCF_WRITE_INQUIRY_SCAN_ACTIVITY),
797107120Sjulian			(char const *) &cp, sizeof(cp),
798107120Sjulian			(char *) &rp, &n) == ERROR)
799107120Sjulian		return (ERROR);
800107120Sjulian
801107120Sjulian	if (rp.status != 0x00) {
802107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
803107120Sjulian			hci_status2str(rp.status), rp.status);
804107120Sjulian		return (FAILED);
805107120Sjulian	}
806107120Sjulian
807107120Sjulian	return (OK);
808107120Sjulian} /* hci_write_inquiry_scan_activity */
809107120Sjulian
810107120Sjulian/* Send Read_Authentication_Enable command to the unit */
811107120Sjulianstatic int
812107120Sjulianhci_read_authentication_enable(int s, int argc, char **argv)
813107120Sjulian{
814107120Sjulian	ng_hci_read_auth_enable_rp	rp;
815107120Sjulian	int				n;
816107120Sjulian
817107120Sjulian	n = sizeof(rp);
818107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
819107120Sjulian			NG_HCI_OCF_READ_AUTH_ENABLE),
820107120Sjulian			(char *) &rp, &n) == ERROR)
821107120Sjulian		return (ERROR);
822107120Sjulian
823107120Sjulian	if (rp.status != 0x00) {
824107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
825107120Sjulian			hci_status2str(rp.status), rp.status);
826107120Sjulian		return (FAILED);
827107120Sjulian	}
828107120Sjulian
829107120Sjulian	fprintf(stdout, "Authentication Enable: %s [%d]\n",
830107120Sjulian		rp.auth_enable? "Enabled" : "Disabled", rp.auth_enable);
831107120Sjulian
832107120Sjulian	return (OK);
833107120Sjulian} /* hci_read_authentication_enable */
834107120Sjulian
835107120Sjulian/* Send Write_Authentication_Enable command to the unit */
836107120Sjulianstatic int
837107120Sjulianhci_write_authentication_enable(int s, int argc, char **argv)
838107120Sjulian{
839107120Sjulian	ng_hci_write_auth_enable_cp	cp;
840107120Sjulian	ng_hci_write_auth_enable_rp	rp;
841107120Sjulian	int				n;
842107120Sjulian
843107120Sjulian	/* parse command parameters */
844107120Sjulian	switch (argc) {
845107120Sjulian	case 1:
846107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)
847107120Sjulian			return (USAGE);
848107120Sjulian
849128079Semax		cp.auth_enable = (uint8_t) n;
850107120Sjulian		break;
851107120Sjulian
852107120Sjulian	default:
853107120Sjulian		return (USAGE);
854107120Sjulian	}
855107120Sjulian
856107120Sjulian	/* send command */
857107120Sjulian	n = sizeof(rp);
858107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
859107120Sjulian			NG_HCI_OCF_WRITE_AUTH_ENABLE),
860107120Sjulian			(char const *) &cp, sizeof(cp),
861107120Sjulian			(char *) &rp, &n) == ERROR)
862107120Sjulian		return (ERROR);
863107120Sjulian
864107120Sjulian	if (rp.status != 0x00) {
865107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
866107120Sjulian			hci_status2str(rp.status), rp.status);
867107120Sjulian		return (FAILED);
868107120Sjulian	}
869107120Sjulian
870107120Sjulian	return (OK);
871107120Sjulian} /* hci_write_authentication_enable */
872107120Sjulian
873107120Sjulian/* Send Read_Encryption_Mode command to the unit */
874107120Sjulianstatic int
875107120Sjulianhci_read_encryption_mode(int s, int argc, char **argv)
876107120Sjulian{
877107120Sjulian	ng_hci_read_encryption_mode_rp	rp;
878107120Sjulian	int				n;
879107120Sjulian
880107120Sjulian	n = sizeof(rp);
881107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
882107120Sjulian			NG_HCI_OCF_READ_ENCRYPTION_MODE),
883107120Sjulian			(char *) &rp, &n) == ERROR)
884107120Sjulian		return (ERROR);
885107120Sjulian
886107120Sjulian	if (rp.status != 0x00) {
887107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
888107120Sjulian			hci_status2str(rp.status), rp.status);
889107120Sjulian		return (FAILED);
890107120Sjulian	}
891107120Sjulian
892107120Sjulian	fprintf(stdout, "Encryption mode: %s [%#02x]\n",
893107120Sjulian		hci_encrypt2str(rp.encryption_mode, 0), rp.encryption_mode);
894107120Sjulian
895107120Sjulian	return (OK);
896107120Sjulian} /* hci_read_encryption_mode */
897107120Sjulian
898107120Sjulian/* Send Write_Encryption_Mode command to the unit */
899107120Sjulianstatic int
900107120Sjulianhci_write_encryption_mode(int s, int argc, char **argv)
901107120Sjulian{
902107120Sjulian	ng_hci_write_encryption_mode_cp	cp;
903107120Sjulian	ng_hci_write_encryption_mode_rp	rp;
904107120Sjulian	int				n;
905107120Sjulian
906107120Sjulian	/* parse command parameters */
907107120Sjulian	switch (argc) {
908107120Sjulian	case 1:
909107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2)
910107120Sjulian			return (USAGE);
911107120Sjulian
912128079Semax		cp.encryption_mode = (uint8_t) n;
913107120Sjulian		break;
914107120Sjulian
915107120Sjulian	default:
916107120Sjulian		return (USAGE);
917107120Sjulian	}
918107120Sjulian
919107120Sjulian	/* send command */
920107120Sjulian	n = sizeof(rp);
921107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
922107120Sjulian			NG_HCI_OCF_WRITE_ENCRYPTION_MODE),
923107120Sjulian			(char const *) &cp, sizeof(cp),
924107120Sjulian			(char *) &rp, &n) == ERROR)
925107120Sjulian		return (ERROR);
926107120Sjulian
927107120Sjulian	if (rp.status != 0x00) {
928107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
929107120Sjulian			hci_status2str(rp.status), rp.status);
930107120Sjulian		return (FAILED);
931107120Sjulian	}
932107120Sjulian
933107120Sjulian	return (OK);
934107120Sjulian} /* hci_write_encryption_mode */
935107120Sjulian
936107120Sjulian/* Send Read_Class_Of_Device command to the unit */
937107120Sjulianstatic int
938107120Sjulianhci_read_class_of_device(int s, int argc, char **argv)
939107120Sjulian{
940107120Sjulian	ng_hci_read_unit_class_rp	rp;
941107120Sjulian	int				n;
942107120Sjulian
943107120Sjulian	n = sizeof(rp);
944107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
945107120Sjulian			NG_HCI_OCF_READ_UNIT_CLASS),
946107120Sjulian			(char *) &rp, &n) == ERROR)
947107120Sjulian		return (ERROR);
948107120Sjulian
949107120Sjulian	if (rp.status != 0x00) {
950107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
951107120Sjulian			hci_status2str(rp.status), rp.status);
952107120Sjulian		return (FAILED);
953107120Sjulian	}
954107120Sjulian
955107120Sjulian	fprintf(stdout, "Class: %02x:%02x:%02x\n",
956107120Sjulian		rp.uclass[2], rp.uclass[1], rp.uclass[0]);
957107120Sjulian
958107120Sjulian	return (0);
959107120Sjulian} /* hci_read_class_of_device */
960107120Sjulian
961107120Sjulian/* Send Write_Class_Of_Device command to the unit */
962107120Sjulianstatic int
963107120Sjulianhci_write_class_of_device(int s, int argc, char **argv)
964107120Sjulian{
965107120Sjulian	ng_hci_write_unit_class_cp	cp;
966107120Sjulian	ng_hci_write_unit_class_rp	rp;
967107120Sjulian	int				n0, n1, n2;
968107120Sjulian
969107120Sjulian	/* parse command parameters */
970107120Sjulian	switch (argc) {
971107120Sjulian	case 1:
972107120Sjulian		if (sscanf(argv[0], "%x:%x:%x", &n2, &n1, &n0) != 3)
973107120Sjulian			return (USAGE);
974107120Sjulian
975107120Sjulian		cp.uclass[0] = (n0 & 0xff);
976107120Sjulian		cp.uclass[1] = (n1 & 0xff);
977107120Sjulian		cp.uclass[2] = (n2 & 0xff);
978107120Sjulian		break;
979107120Sjulian
980107120Sjulian	default:
981107120Sjulian		return (USAGE);
982107120Sjulian	}
983107120Sjulian
984107120Sjulian	/* send command */
985107120Sjulian	n0 = sizeof(rp);
986107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
987107120Sjulian			NG_HCI_OCF_WRITE_UNIT_CLASS),
988107120Sjulian			(char const *) &cp, sizeof(cp),
989107120Sjulian			(char *) &rp, &n0) == ERROR)
990107120Sjulian		return (ERROR);
991107120Sjulian
992107120Sjulian	if (rp.status != 0x00) {
993107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
994107120Sjulian			hci_status2str(rp.status), rp.status);
995107120Sjulian		return (FAILED);
996107120Sjulian	}
997107120Sjulian
998107120Sjulian	return (OK);
999107120Sjulian} /* hci_write_class_of_device */
1000107120Sjulian
1001107120Sjulian/* Send Read_Voice_Settings command to the unit */
1002107120Sjulianstatic int
1003107120Sjulianhci_read_voice_settings(int s, int argc, char **argv)
1004107120Sjulian{
1005107120Sjulian	ng_hci_read_voice_settings_rp	rp;
1006107120Sjulian	int				n,
1007107120Sjulian					input_coding,
1008107120Sjulian					input_data_format,
1009107120Sjulian					input_sample_size;
1010107120Sjulian
1011107120Sjulian	n = sizeof(rp);
1012107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1013107120Sjulian			NG_HCI_OCF_READ_VOICE_SETTINGS),
1014107120Sjulian			(char *) &rp, &n) == ERROR)
1015107120Sjulian		return (ERROR);
1016107120Sjulian
1017107120Sjulian	if (rp.status != 0x00) {
1018107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1019107120Sjulian			hci_status2str(rp.status), rp.status);
1020107120Sjulian		return (FAILED);
1021107120Sjulian	}
1022107120Sjulian
1023107120Sjulian	rp.settings = le16toh(rp.settings);
1024107120Sjulian
1025107120Sjulian	input_coding      = (rp.settings & 0x0300) >> 8;
1026107120Sjulian	input_data_format = (rp.settings & 0x00c0) >> 6;
1027107120Sjulian	input_sample_size = (rp.settings & 0x0020) >> 5;
1028107120Sjulian
1029107120Sjulian	fprintf(stdout, "Voice settings: %#04x\n", rp.settings);
1030107120Sjulian	fprintf(stdout, "Input coding: %s [%d]\n",
1031107120Sjulian		hci_coding2str(input_coding), input_coding);
1032107120Sjulian	fprintf(stdout, "Input data format: %s [%d]\n",
1033107120Sjulian		hci_vdata2str(input_data_format), input_data_format);
1034107120Sjulian
1035107120Sjulian	if (input_coding == 0x00) /* Only for Linear PCM */
1036107120Sjulian		fprintf(stdout, "Input sample size: %d bit [%d]\n",
1037107120Sjulian			input_sample_size? 16 : 8, input_sample_size);
1038107120Sjulian
1039107120Sjulian	return (OK);
1040107120Sjulian} /* hci_read_voice_settings */
1041107120Sjulian
1042107120Sjulian/* Send Write_Voice_Settings command to the unit */
1043107120Sjulianstatic int
1044107120Sjulianhci_write_voice_settings(int s, int argc, char **argv)
1045107120Sjulian{
1046107120Sjulian	ng_hci_write_voice_settings_cp	cp;
1047107120Sjulian	ng_hci_write_voice_settings_rp	rp;
1048107120Sjulian	int				n;
1049107120Sjulian
1050107120Sjulian	/* parse command parameters */
1051107120Sjulian	switch (argc) {
1052107120Sjulian	case 1:
1053107120Sjulian		if (sscanf(argv[0], "%x", &n) != 1)
1054107120Sjulian			return (USAGE);
1055107120Sjulian
1056128079Semax		cp.settings = (uint16_t) n;
1057107120Sjulian		cp.settings = htole16(cp.settings);
1058107120Sjulian		break;
1059107120Sjulian
1060107120Sjulian	default:
1061107120Sjulian		return (USAGE);
1062107120Sjulian	}
1063107120Sjulian
1064107120Sjulian	/* send command */
1065107120Sjulian	n = sizeof(rp);
1066107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1067107120Sjulian			NG_HCI_OCF_WRITE_VOICE_SETTINGS),
1068107120Sjulian			(char const *) &cp, sizeof(cp),
1069107120Sjulian			(char *) &rp, &n) == ERROR)
1070107120Sjulian		return (ERROR);
1071107120Sjulian
1072107120Sjulian	if (rp.status != 0x00) {
1073107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1074107120Sjulian			hci_status2str(rp.status), rp.status);
1075107120Sjulian		return (FAILED);
1076107120Sjulian	}
1077107120Sjulian
1078107120Sjulian	return (OK);
1079107120Sjulian} /* hci_write_voice_settings */
1080107120Sjulian
1081107120Sjulian/* Send Read_Number_Broadcast_Restransmissions */
1082107120Sjulianstatic int
1083107120Sjulianhci_read_number_broadcast_retransmissions(int s, int argc, char **argv)
1084107120Sjulian{
1085107120Sjulian	ng_hci_read_num_broadcast_retrans_rp	rp;
1086107120Sjulian	int					n;
1087107120Sjulian
1088107120Sjulian	n = sizeof(rp);
1089107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1090107120Sjulian			NG_HCI_OCF_READ_NUM_BROADCAST_RETRANS),
1091107120Sjulian			(char *) &rp, &n) == ERROR)
1092107120Sjulian		return (ERROR);
1093107120Sjulian
1094107120Sjulian	if (rp.status != 0x00) {
1095107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1096107120Sjulian			hci_status2str(rp.status), rp.status);
1097107120Sjulian		return (FAILED);
1098107120Sjulian	}
1099107120Sjulian
1100107120Sjulian	fprintf(stdout, "Number of broadcast retransmissions: %d\n",
1101107120Sjulian		rp.counter);
1102107120Sjulian
1103107120Sjulian	return (OK);
1104107120Sjulian} /* hci_read_number_broadcast_retransmissions */
1105107120Sjulian
1106107120Sjulian/* Send Write_Number_Broadcast_Restransmissions */
1107107120Sjulianstatic int
1108107120Sjulianhci_write_number_broadcast_retransmissions(int s, int argc, char **argv)
1109107120Sjulian{
1110107120Sjulian	ng_hci_write_num_broadcast_retrans_cp	cp;
1111107120Sjulian	ng_hci_write_num_broadcast_retrans_rp	rp;
1112107120Sjulian	int					n;
1113107120Sjulian
1114107120Sjulian	/* parse command parameters */
1115107120Sjulian	switch (argc) {
1116107120Sjulian	case 1:
1117107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0xff)
1118107120Sjulian			return (USAGE);
1119107120Sjulian
1120128079Semax		cp.counter = (uint8_t) n;
1121107120Sjulian		break;
1122107120Sjulian
1123107120Sjulian	default:
1124107120Sjulian		return (USAGE);
1125107120Sjulian	}
1126107120Sjulian
1127107120Sjulian	/* send command */
1128107120Sjulian	n = sizeof(rp);
1129107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1130107120Sjulian			NG_HCI_OCF_WRITE_NUM_BROADCAST_RETRANS),
1131107120Sjulian			(char const *) &cp, sizeof(cp),
1132107120Sjulian			(char *) &rp, &n) == ERROR)
1133107120Sjulian		return (ERROR);
1134107120Sjulian
1135107120Sjulian	if (rp.status != 0x00) {
1136107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1137107120Sjulian			hci_status2str(rp.status), rp.status);
1138107120Sjulian		return (FAILED);
1139107120Sjulian	}
1140107120Sjulian
1141107120Sjulian	return (OK);
1142107120Sjulian} /* hci_write_number_broadcast_retransmissions */
1143107120Sjulian
1144107120Sjulian/* Send Read_Hold_Mode_Activity command to the unit */
1145107120Sjulianstatic int
1146107120Sjulianhci_read_hold_mode_activity(int s, int argc, char **argv)
1147107120Sjulian{
1148107120Sjulian	ng_hci_read_hold_mode_activity_rp	rp;
1149107120Sjulian	int					n;
1150107120Sjulian	char					buffer[1024];
1151107120Sjulian
1152107120Sjulian	n = sizeof(rp);
1153107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1154107120Sjulian			NG_HCI_OCF_READ_HOLD_MODE_ACTIVITY),
1155107120Sjulian			(char *) &rp, &n) == ERROR)
1156107120Sjulian		return (ERROR);
1157107120Sjulian
1158107120Sjulian	if (rp.status != 0x00) {
1159107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1160107120Sjulian			hci_status2str(rp.status), rp.status);
1161107120Sjulian		return (FAILED);
1162107120Sjulian	}
1163107120Sjulian
1164107120Sjulian	fprintf(stdout, "Hold Mode Activities: %#02x\n", rp.hold_mode_activity);
1165107120Sjulian	if (rp.hold_mode_activity == 0)
1166107120Sjulian		fprintf(stdout, "Maintain current Power State");
1167107120Sjulian	else
1168107120Sjulian		fprintf(stdout, "%s", hci_hmode2str(rp.hold_mode_activity,
1169107120Sjulian				buffer, sizeof(buffer)));
1170107120Sjulian
1171107120Sjulian	fprintf(stdout, "\n");
1172107120Sjulian
1173107120Sjulian	return (OK);
1174107120Sjulian} /* hci_read_hold_mode_activity */
1175107120Sjulian
1176107120Sjulian/* Send Write_Hold_Mode_Activity command to the unit */
1177107120Sjulianstatic int
1178107120Sjulianhci_write_hold_mode_activity(int s, int argc, char **argv)
1179107120Sjulian{
1180107120Sjulian	ng_hci_write_hold_mode_activity_cp	cp;
1181107120Sjulian	ng_hci_write_hold_mode_activity_rp	rp;
1182107120Sjulian	int					n;
1183107120Sjulian
1184107120Sjulian	/* parse command parameters */
1185107120Sjulian	switch (argc) {
1186107120Sjulian	case 1:
1187107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 4)
1188107120Sjulian			return (USAGE);
1189107120Sjulian
1190128079Semax		cp.hold_mode_activity = (uint8_t) n;
1191107120Sjulian		break;
1192107120Sjulian
1193107120Sjulian	default:
1194107120Sjulian		return (USAGE);
1195107120Sjulian	}
1196107120Sjulian
1197107120Sjulian	/* send command */
1198107120Sjulian	n = sizeof(rp);
1199107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1200107120Sjulian			NG_HCI_OCF_WRITE_HOLD_MODE_ACTIVITY),
1201107120Sjulian			(char const *) &cp, sizeof(cp),
1202107120Sjulian			(char *) &rp, &n) == ERROR)
1203107120Sjulian		return (ERROR);
1204107120Sjulian
1205107120Sjulian	if (rp.status != 0x00) {
1206107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1207107120Sjulian			hci_status2str(rp.status), rp.status);
1208107120Sjulian		return (FAILED);
1209107120Sjulian	}
1210107120Sjulian
1211107120Sjulian	return (OK);
1212107120Sjulian} /* hci_write_hold_mode_activity */
1213107120Sjulian
1214107120Sjulian/* Send Read_SCO_Flow_Control_Enable command to the unit */
1215107120Sjulianstatic int
1216107120Sjulianhci_read_sco_flow_control_enable(int s, int argc, char **argv)
1217107120Sjulian{
1218107120Sjulian	ng_hci_read_sco_flow_control_rp	rp;
1219107120Sjulian	int				n;
1220107120Sjulian
1221107120Sjulian	n = sizeof(rp);
1222107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1223107120Sjulian			NG_HCI_OCF_READ_SCO_FLOW_CONTROL),
1224107120Sjulian			(char *) &rp, &n) == ERROR)
1225107120Sjulian		return (ERROR);
1226107120Sjulian
1227107120Sjulian	if (rp.status != 0x00) {
1228107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1229107120Sjulian			hci_status2str(rp.status), rp.status);
1230107120Sjulian		return (FAILED);
1231107120Sjulian	}
1232107120Sjulian
1233107120Sjulian	fprintf(stdout, "SCO flow control %s [%d]\n",
1234107120Sjulian		rp.flow_control? "enabled" : "disabled", rp.flow_control);
1235107120Sjulian
1236107120Sjulian	return (OK);
1237107120Sjulian} /* hci_read_sco_flow_control_enable */
1238107120Sjulian
1239107120Sjulian/* Send Write_SCO_Flow_Control_Enable command to the unit */
1240107120Sjulianstatic int
1241107120Sjulianhci_write_sco_flow_control_enable(int s, int argc, char **argv)
1242107120Sjulian{
1243107120Sjulian	ng_hci_write_sco_flow_control_cp	cp;
1244107120Sjulian	ng_hci_write_sco_flow_control_rp	rp;
1245107120Sjulian	int					n;
1246107120Sjulian
1247107120Sjulian	/* parse command parameters */
1248107120Sjulian	switch (argc) {
1249107120Sjulian	case 1:
1250107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1)
1251107120Sjulian			return (USAGE);
1252107120Sjulian
1253128079Semax		cp.flow_control = (uint8_t) n;
1254107120Sjulian		break;
1255107120Sjulian
1256107120Sjulian	default:
1257107120Sjulian		return (USAGE);
1258107120Sjulian	}
1259107120Sjulian
1260107120Sjulian	/* send command */
1261107120Sjulian	n = sizeof(rp);
1262107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1263107120Sjulian			NG_HCI_OCF_WRITE_SCO_FLOW_CONTROL),
1264107120Sjulian			(char const *) &cp, sizeof(cp),
1265107120Sjulian			(char *) &rp, &n) == ERROR)
1266107120Sjulian		return (ERROR);
1267107120Sjulian
1268107120Sjulian	if (rp.status != 0x00) {
1269107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1270107120Sjulian			hci_status2str(rp.status), rp.status);
1271107120Sjulian		return (FAILED);
1272107120Sjulian	}
1273107120Sjulian
1274107120Sjulian	return (OK);
1275107120Sjulian} /* hci_write_sco_flow_control_enable */
1276107120Sjulian
1277107120Sjulian/* Send Read_Link_Supervision_Timeout command to the unit */
1278107120Sjulianstatic int
1279107120Sjulianhci_read_link_supervision_timeout(int s, int argc, char **argv)
1280107120Sjulian{
1281107120Sjulian	ng_hci_read_link_supervision_timo_cp	cp;
1282107120Sjulian	ng_hci_read_link_supervision_timo_rp	rp;
1283107120Sjulian	int					n;
1284107120Sjulian
1285107120Sjulian	switch (argc) {
1286107120Sjulian	case 1:
1287107120Sjulian		/* connection handle */
1288107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
1289107120Sjulian			return (USAGE);
1290107120Sjulian
1291128079Semax		cp.con_handle = (uint16_t) (n & 0x0fff);
1292107120Sjulian		cp.con_handle = htole16(cp.con_handle);
1293107120Sjulian		break;
1294107120Sjulian
1295107120Sjulian	default:
1296107120Sjulian		return (USAGE);
1297107120Sjulian	}
1298107120Sjulian
1299107120Sjulian	/* send command */
1300107120Sjulian	n = sizeof(rp);
1301107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1302107120Sjulian			NG_HCI_OCF_READ_LINK_SUPERVISION_TIMO),
1303107120Sjulian			(char const *) &cp, sizeof(cp),
1304107120Sjulian			(char *) &rp, &n) == ERROR)
1305107120Sjulian		return (ERROR);
1306107120Sjulian
1307107120Sjulian	if (rp.status != 0x00) {
1308107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1309107120Sjulian			hci_status2str(rp.status), rp.status);
1310107120Sjulian		return (FAILED);
1311107120Sjulian	}
1312107120Sjulian
1313107120Sjulian	rp.timeout = le16toh(rp.timeout);
1314107120Sjulian
1315107120Sjulian	fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
1316107120Sjulian	fprintf(stdout, "Link supervision timeout: %.2f msec [%d slots]\n",
1317107120Sjulian		rp.timeout * 0.625, rp.timeout);
1318107120Sjulian
1319107120Sjulian	return (OK);
1320107120Sjulian} /* hci_read_link_supervision_timeout */
1321107120Sjulian
1322107120Sjulian/* Send Write_Link_Supervision_Timeout command to the unit */
1323107120Sjulianstatic int
1324107120Sjulianhci_write_link_supervision_timeout(int s, int argc, char **argv)
1325107120Sjulian{
1326107120Sjulian	ng_hci_write_link_supervision_timo_cp	cp;
1327107120Sjulian	ng_hci_write_link_supervision_timo_rp	rp;
1328107120Sjulian	int					n;
1329107120Sjulian
1330107120Sjulian	switch (argc) {
1331107120Sjulian	case 2:
1332107120Sjulian		/* connection handle */
1333107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
1334107120Sjulian			return (USAGE);
1335107120Sjulian
1336128079Semax		cp.con_handle = (uint16_t) (n & 0x0fff);
1337107120Sjulian		cp.con_handle = htole16(cp.con_handle);
1338107120Sjulian
1339107120Sjulian		/* link supervision timeout */
1340131216Semax		if (sscanf(argv[1], "%d", &n) != 1 || n < 0 || n > 0xffff)
1341107120Sjulian			return (USAGE);
1342107120Sjulian
1343128079Semax		cp.timeout = (uint16_t) (n & 0x0fff);
1344107120Sjulian		cp.timeout = htole16(cp.timeout);
1345107120Sjulian		break;
1346107120Sjulian
1347107120Sjulian	default:
1348107120Sjulian		return (USAGE);
1349107120Sjulian	}
1350107120Sjulian
1351107120Sjulian	/* send command */
1352107120Sjulian	n = sizeof(rp);
1353107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1354107120Sjulian			NG_HCI_OCF_WRITE_LINK_SUPERVISION_TIMO),
1355107120Sjulian			(char const *) &cp, sizeof(cp),
1356107120Sjulian			(char *) &rp, &n) == ERROR)
1357107120Sjulian		return (ERROR);
1358107120Sjulian
1359107120Sjulian	if (rp.status != 0x00) {
1360107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
1361107120Sjulian			hci_status2str(rp.status), rp.status);
1362107120Sjulian		return (FAILED);
1363107120Sjulian	}
1364107120Sjulian
1365107120Sjulian	return (OK);
1366107120Sjulian} /* hci_write_link_supervision_timeout */
1367107120Sjulian
1368121054Semax/* Send Read_Page_Scan_Period_Mode command to the unit */
1369121054Semaxstatic int
1370121054Semaxhci_read_page_scan_period_mode(int s, int argc, char **argv)
1371121054Semax{
1372121054Semax	ng_hci_read_page_scan_period_rp	rp;
1373121054Semax	int				n;
1374121054Semax
1375121054Semax	n = sizeof(rp);
1376121054Semax	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1377121054Semax			NG_HCI_OCF_READ_PAGE_SCAN_PERIOD),
1378121054Semax			(char *) &rp, &n) == ERROR)
1379121054Semax		return (ERROR);
1380121054Semax
1381121054Semax	if (rp.status != 0x00) {
1382121054Semax		fprintf(stdout, "Status: %s [%#02x]\n",
1383121054Semax			hci_status2str(rp.status), rp.status);
1384121054Semax		return (FAILED);
1385121054Semax	}
1386121054Semax
1387121054Semax	fprintf(stdout, "Page scan period mode: %#02x\n",
1388121054Semax		rp.page_scan_period_mode);
1389121054Semax
1390121054Semax	return (OK);
1391121054Semax} /* hci_read_page_scan_period_mode */
1392121054Semax
1393121054Semax/* Send Write_Page_Scan_Period_Mode command to the unit */
1394121054Semaxstatic int
1395121054Semaxhci_write_page_scan_period_mode(int s, int argc, char **argv)
1396121054Semax{
1397121054Semax	ng_hci_write_page_scan_period_cp	cp;
1398121054Semax	ng_hci_write_page_scan_period_rp	rp;
1399121054Semax	int					n;
1400121054Semax
1401121054Semax	/* parse command arguments */
1402121054Semax	switch (argc) {
1403121054Semax	case 1:
1404121054Semax		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2)
1405121054Semax			return (USAGE);
1406121054Semax
1407121054Semax		cp.page_scan_period_mode = (n & 0xff);
1408121054Semax		break;
1409121054Semax
1410121054Semax	default:
1411121054Semax		return (USAGE);
1412121054Semax	}
1413121054Semax
1414121054Semax	/* send command */
1415121054Semax	n = sizeof(rp);
1416121054Semax	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1417121054Semax			NG_HCI_OCF_WRITE_PAGE_SCAN_PERIOD),
1418121054Semax			(char const *) &cp, sizeof(cp),
1419121054Semax			(char *) &rp, &n) == ERROR)
1420121054Semax		return (ERROR);
1421121054Semax
1422121054Semax	if (rp.status != 0x00) {
1423121054Semax		fprintf(stdout, "Status: %s [%#02x]\n",
1424121054Semax			hci_status2str(rp.status), rp.status);
1425121054Semax		return (FAILED);
1426121054Semax	}
1427121054Semax
1428121054Semax	return (OK);
1429121054Semax} /* hci_write_page_scan_period_mode */
1430121054Semax
1431121054Semax/* Send Read_Page_Scan_Mode command to the unit */
1432121054Semaxstatic int
1433121054Semaxhci_read_page_scan_mode(int s, int argc, char **argv)
1434121054Semax{
1435121054Semax	ng_hci_read_page_scan_rp	rp;
1436121054Semax	int				n;
1437121054Semax
1438121054Semax	n = sizeof(rp);
1439121054Semax	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1440121054Semax			NG_HCI_OCF_READ_PAGE_SCAN),
1441121054Semax			(char *) &rp, &n) == ERROR)
1442121054Semax		return (ERROR);
1443121054Semax
1444121054Semax	if (rp.status != 0x00) {
1445121054Semax		fprintf(stdout, "Status: %s [%#02x]\n",
1446121054Semax			hci_status2str(rp.status), rp.status);
1447121054Semax		return (FAILED);
1448121054Semax	}
1449121054Semax
1450121054Semax	fprintf(stdout, "Page scan mode: %#02x\n", rp.page_scan_mode);
1451121054Semax
1452121054Semax	return (OK);
1453121054Semax} /* hci_read_page_scan_mode */
1454121054Semax
1455121054Semax/* Send Write_Page_Scan_Mode command to the unit */
1456121054Semaxstatic int
1457121054Semaxhci_write_page_scan_mode(int s, int argc, char **argv)
1458121054Semax{
1459121054Semax	ng_hci_write_page_scan_cp	cp;
1460121054Semax	ng_hci_write_page_scan_rp	rp;
1461121054Semax	int				n;
1462121054Semax
1463121054Semax	/* parse command arguments */
1464121054Semax	switch (argc) {
1465121054Semax	case 1:
1466121054Semax		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3)
1467121054Semax			return (USAGE);
1468121054Semax
1469121054Semax		cp.page_scan_mode = (n & 0xff);
1470121054Semax		break;
1471121054Semax
1472121054Semax	default:
1473121054Semax		return (USAGE);
1474121054Semax	}
1475121054Semax
1476121054Semax	/* send command */
1477121054Semax	n = sizeof(rp);
1478121054Semax	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1479121054Semax			NG_HCI_OCF_WRITE_PAGE_SCAN),
1480121054Semax			(char const *) &cp, sizeof(cp),
1481121054Semax			(char *) &rp, &n) == ERROR)
1482121054Semax		return (ERROR);
1483121054Semax
1484121054Semax	if (rp.status != 0x00) {
1485121054Semax		fprintf(stdout, "Status: %s [%#02x]\n",
1486121054Semax			hci_status2str(rp.status), rp.status);
1487121054Semax		return (FAILED);
1488121054Semax	}
1489121054Semax
1490121054Semax	return (OK);
1491121054Semax} /* hci_write_page_scan_mode */
1492121054Semax
1493281680Stakawatastatic int
1494361185Shselaskyhci_read_le_host_support(int s, int argc, char **argv)
1495281680Stakawata{
1496281684Saraujo	ng_hci_read_le_host_supported_rp rp;
1497281680Stakawata	int n;
1498281680Stakawata	n = sizeof(rp);
1499281680Stakawata	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1500281680Stakawata			NG_HCI_OCF_READ_LE_HOST_SUPPORTED),
1501281680Stakawata			(char *) &rp, &n) == ERROR)
1502281680Stakawata		return (ERROR);
1503281680Stakawata
1504281680Stakawata	if (rp.status != 0x00) {
1505281680Stakawata		fprintf(stdout, "Status: %s [%#02x]\n",
1506281680Stakawata			hci_status2str(rp.status), rp.status);
1507281680Stakawata		return (FAILED);
1508281680Stakawata	}
1509281680Stakawata
1510281680Stakawata	fprintf(stdout, "LE Host support: %#02x\n", rp.le_supported_host);
1511361185Shselasky	fprintf(stdout, "Simultaneous LE Host : %#02x\n", rp.simultaneous_le_host);
1512281680Stakawata
1513281680Stakawata	return (OK);
1514281680Stakawata
1515281680Stakawata}
1516281680Stakawatastatic int
1517361185Shselaskyhci_write_le_host_support(int s, int argc, char **argv)
1518281680Stakawata{
1519281684Saraujo	ng_hci_write_le_host_supported_cp cp;
1520281684Saraujo	ng_hci_write_le_host_supported_rp rp;
1521281680Stakawata
1522281684Saraujo	int n;
1523281680Stakawata
1524281680Stakawata	cp.le_supported_host = 0;
1525281680Stakawata	cp.simultaneous_le_host = 0;
1526281680Stakawata	switch (argc) {
1527281680Stakawata	case 2:
1528281680Stakawata		if (sscanf(argv[1], "%d", &n) != 1 || (n != 0 && n != 1)){
1529281680Stakawata			printf("ARGC2: %d\n", n);
1530281680Stakawata			return (USAGE);
1531281680Stakawata		}
1532281680Stakawata		cp.simultaneous_le_host = (n &1);
1533281680Stakawata
1534281680Stakawata	case 1:
1535281680Stakawata		if (sscanf(argv[0], "%d", &n) != 1 || (n != 0 && n != 1)){
1536281680Stakawata			printf("ARGC1: %d\n", n);
1537281680Stakawata			return (USAGE);
1538281680Stakawata		}
1539281680Stakawata
1540281680Stakawata		cp.le_supported_host = (n &1);
1541281680Stakawata		break;
1542281680Stakawata
1543281680Stakawata	default:
1544281680Stakawata		return (USAGE);
1545281680Stakawata	}
1546281680Stakawata
1547281680Stakawata
1548281680Stakawata	/* send command */
1549281680Stakawata	n = sizeof(rp);
1550281680Stakawata	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
1551281680Stakawata			NG_HCI_OCF_WRITE_LE_HOST_SUPPORTED),
1552281680Stakawata			(char const *) &cp, sizeof(cp),
1553281680Stakawata			(char *) &rp, &n) == ERROR)
1554281680Stakawata		return (ERROR);
1555281680Stakawata
1556281680Stakawata	if (rp.status != 0x00) {
1557281680Stakawata		fprintf(stdout, "Status: %s [%#02x]\n",
1558281680Stakawata			hci_status2str(rp.status), rp.status);
1559281680Stakawata		return (FAILED);
1560281680Stakawata	}
1561281680Stakawata
1562281680Stakawata	return (OK);
1563281680Stakawata}
1564281680Stakawata
1565107120Sjulianstruct hci_command	host_controller_baseband_commands[] = {
1566107120Sjulian{
1567107120Sjulian"reset",
1568107120Sjulian"\nThe Reset command will reset the Host Controller and the Link Manager.\n" \
1569107120Sjulian"After the reset is completed, the current operational state will be lost,\n" \
1570107120Sjulian"the Bluetooth unit will enter standby mode and the Host Controller will\n" \
1571107120Sjulian"automatically revert to the default values for the parameters for which\n" \
1572107120Sjulian"default values are defined in the specification.",
1573107120Sjulian&hci_reset
1574107120Sjulian},
1575107120Sjulian{
1576107120Sjulian"read_pin_type",
1577107120Sjulian"\nThe Read_PIN_Type command is used for the Host to read whether the Link\n" \
1578107120Sjulian"Manager assumes that the Host supports variable PIN codes only a fixed PIN\n" \
1579107120Sjulian"code.",
1580107120Sjulian&hci_read_pin_type
1581107120Sjulian},
1582107120Sjulian{
1583107120Sjulian"write_pin_type <pin_type>",
1584107120Sjulian"\nThe Write_PIN_Type command is used for the Host to write to the Host\n" \
1585107120Sjulian"Controller whether the Host supports variable PIN codes or only a fixed PIN\n"\
1586107120Sjulian"code.\n\n" \
1587107120Sjulian"\t<pin_type> - dd; 0 - Variable; 1 - Fixed",
1588107120Sjulian&hci_write_pin_type
1589107120Sjulian},
1590107120Sjulian{
1591133178Semax"read_stored_link_key [<BD_ADDR>]",
1592107120Sjulian"\nThe Read_Stored_Link_Key command provides the ability to read one or\n" \
1593107120Sjulian"more link keys stored in the Bluetooth Host Controller. The Bluetooth Host\n" \
1594107120Sjulian"Controller can store a limited number of link keys for other Bluetooth\n" \
1595107120Sjulian"devices.\n\n" \
1596133178Semax"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name",
1597107120Sjulian&hci_read_stored_link_key
1598107120Sjulian},
1599107120Sjulian{
1600133178Semax"write_stored_link_key <BD_ADDR> <key>",
1601107120Sjulian"\nThe Write_Stored_Link_Key command provides the ability to write one\n" \
1602107120Sjulian"or more link keys to be stored in the Bluetooth Host Controller. The\n" \
1603107120Sjulian"Bluetooth Host Controller can store a limited number of link keys for other\n"\
1604107120Sjulian"Bluetooth devices. If no additional space is available in the Bluetooth\n"\
1605107120Sjulian"Host Controller then no additional link keys will be stored.\n\n" \
1606133178Semax"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name\n" \
1607133178Semax"\t<key>     - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx up to 16 bytes link key",
1608107120Sjulian&hci_write_stored_link_key
1609107120Sjulian},
1610107120Sjulian{
1611133178Semax"delete_stored_link_key [<BD_ADDR>]",
1612107120Sjulian"\nThe Delete_Stored_Link_Key command provides the ability to remove one\n" \
1613107120Sjulian"or more of the link keys stored in the Bluetooth Host Controller. The\n" \
1614107120Sjulian"Bluetooth Host Controller can store a limited number of link keys for other\n"\
1615107120Sjulian"Bluetooth devices.\n\n" \
1616133178Semax"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name",
1617107120Sjulian&hci_delete_stored_link_key
1618107120Sjulian},
1619107120Sjulian{
1620107120Sjulian"change_local_name <name>",
1621107120Sjulian"\nThe Change_Local_Name command provides the ability to modify the user\n" \
1622107120Sjulian"friendly name for the Bluetooth unit.\n\n" \
1623107120Sjulian"\t<name> - string",
1624107120Sjulian&hci_change_local_name
1625107120Sjulian},
1626107120Sjulian{
1627107120Sjulian"read_local_name",
1628107120Sjulian"\nThe Read_Local_Name command provides the ability to read the\n" \
1629107120Sjulian"stored user-friendly name for the Bluetooth unit.",
1630107120Sjulian&hci_read_local_name
1631107120Sjulian},
1632107120Sjulian{
1633107120Sjulian"read_connection_accept_timeout",
1634107120Sjulian"\nThis command will read the value for the Connection_Accept_Timeout\n" \
1635107120Sjulian"configuration parameter. The Connection_Accept_Timeout configuration\n" \
1636107120Sjulian"parameter allows the Bluetooth hardware to automatically deny a\n" \
1637107120Sjulian"connection request after a specified time period has occurred and\n" \
1638107120Sjulian"the new connection is not accepted. Connection Accept Timeout\n" \
1639107120Sjulian"measured in Number of Baseband slots.",
1640107120Sjulian&hci_read_connection_accept_timeout
1641107120Sjulian},
1642107120Sjulian{
1643107120Sjulian"write_connection_accept_timeout <timeout>",
1644107120Sjulian"\nThis command will write the value for the Connection_Accept_Timeout\n" \
1645107120Sjulian"configuration parameter.\n\n" \
1646107120Sjulian"\t<timeout> - dddd; measured in number of baseband slots.",
1647107120Sjulian&hci_write_connection_accept_timeout
1648107120Sjulian},
1649107120Sjulian{
1650107120Sjulian"read_page_timeout",
1651107120Sjulian"\nThis command will read the value for the Page_Timeout configuration\n" \
1652107120Sjulian"parameter. The Page_Timeout configuration parameter defines the\n" \
1653107120Sjulian"maximum time the local Link Manager will wait for a baseband page\n" \
1654107120Sjulian"response from the remote unit at a locally initiated connection\n" \
1655107120Sjulian"attempt. Page Timeout measured in Number of Baseband slots.",
1656107120Sjulian&hci_read_page_timeout
1657107120Sjulian},
1658107120Sjulian{
1659107120Sjulian"write_page_timeout <timeout>",
1660107120Sjulian"\nThis command will write the value for the Page_Timeout configuration\n" \
1661107120Sjulian"parameter.\n\n" \
1662107120Sjulian"\t<timeout> - dddd; measured in number of baseband slots.",
1663107120Sjulian&hci_write_page_timeout
1664107120Sjulian},
1665107120Sjulian{
1666107120Sjulian"read_scan_enable",
1667107120Sjulian"\nThis command will read the value for the Scan_Enable parameter. The\n" \
1668107120Sjulian"Scan_Enable parameter controls whether or not the Bluetooth uint\n" \
1669107120Sjulian"will periodically scan for page attempts and/or inquiry requests\n" \
1670107120Sjulian"from other Bluetooth unit.\n\n" \
1671107120Sjulian"\t0x00 - No Scans enabled.\n" \
1672107120Sjulian"\t0x01 - Inquiry Scan enabled. Page Scan disabled.\n" \
1673107120Sjulian"\t0x02 - Inquiry Scan disabled. Page Scan enabled.\n" \
1674107120Sjulian"\t0x03 - Inquiry Scan enabled. Page Scan enabled.",
1675107120Sjulian&hci_read_scan_enable
1676107120Sjulian},
1677107120Sjulian{
1678107120Sjulian"write_scan_enable <scan_enable>",
1679107120Sjulian"\nThis command will write the value for the Scan_Enable parameter.\n" \
1680107120Sjulian"The Scan_Enable parameter controls whether or not the Bluetooth\n" \
1681107120Sjulian"unit will periodically scan for page attempts and/or inquiry\n" \
1682107120Sjulian"requests from other Bluetooth unit.\n\n" \
1683107120Sjulian"\t<scan_enable> - dd;\n" \
1684107120Sjulian"\t0 - No Scans enabled.\n" \
1685107120Sjulian"\t1 - Inquiry Scan enabled. Page Scan disabled.\n" \
1686107120Sjulian"\t2 - Inquiry Scan disabled. Page Scan enabled.\n" \
1687107120Sjulian"\t3 - Inquiry Scan enabled. Page Scan enabled.",
1688107120Sjulian&hci_write_scan_enable
1689107120Sjulian},
1690107120Sjulian{
1691107120Sjulian"read_page_scan_activity",
1692107120Sjulian"\nThis command will read the value for Page_Scan_Activity configuration\n" \
1693107120Sjulian"parameters. The Page_Scan_Interval configuration parameter defines the\n" \
1694107120Sjulian"amount of time between consecutive page scans. This time interval is \n" \
1695107120Sjulian"defined from when the Host Controller started its last page scan until\n" \
1696107120Sjulian"it begins the next page scan. The Page_Scan_Window configuration parameter\n" \
1697107120Sjulian"defines the amount of time for the duration of the page scan. The\n" \
1698107120Sjulian"Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.",
1699107120Sjulian&hci_read_page_scan_activity
1700107120Sjulian},
1701107120Sjulian{
1702107120Sjulian"write_page_scan_activity interval(dddd) window(dddd)",
1703107120Sjulian"\nThis command will write the value for Page_Scan_Activity configuration\n" \
1704107120Sjulian"parameter. The Page_Scan_Interval configuration parameter defines the\n" \
1705107120Sjulian"amount of time between consecutive page scans. This is defined as the time\n" \
1706107120Sjulian"interval from when the Host Controller started its last page scan until it\n" \
1707107120Sjulian"begins the next page scan. The Page_Scan_Window configuration parameter\n" \
1708107120Sjulian"defines the amount of time for the duration of the page scan. \n" \
1709107120Sjulian"The Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.\n\n" \
1710228976Suqs"\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \
1711229075Sstefanf"\t<window>   - Range: 0x0012 -- 0x100, Time = N * 0.625 msec",
1712107120Sjulian&hci_write_page_scan_activity
1713107120Sjulian},
1714107120Sjulian{
1715107120Sjulian"read_inquiry_scan_activity",
1716107120Sjulian"\nThis command will read the value for Inquiry_Scan_Activity configuration\n" \
1717107120Sjulian"parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \
1718107120Sjulian"amount of time between consecutive inquiry scans. This is defined as the\n" \
1719107120Sjulian"time interval from when the Host Controller started its last inquiry scan\n" \
1720107120Sjulian"until it begins the next inquiry scan.",
1721107120Sjulian&hci_read_inquiry_scan_activity
1722107120Sjulian},
1723107120Sjulian{
1724107120Sjulian"write_inquiry_scan_activity interval(dddd) window(dddd)",
1725107120Sjulian"\nThis command will write the value for Inquiry_Scan_Activity configuration\n"\
1726107120Sjulian"parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \
1727107120Sjulian"amount of time between consecutive inquiry scans. This is defined as the\n" \
1728107120Sjulian"time interval from when the Host Controller started its last inquiry scan\n" \
1729107120Sjulian"until it begins the next inquiry scan. The Inquiry_Scan_Window configuration\n" \
1730107120Sjulian"parameter defines the amount of time for the duration of the inquiry scan.\n" \
1731107120Sjulian"The Inquiry_Scan_Window can only be less than or equal to the Inquiry_Scan_Interval.\n\n" \
1732228976Suqs"\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \
1733229075Sstefanf"\t<window>   - Range: 0x0012 -- 0x100, Time = N * 0.625 msec",
1734107120Sjulian&hci_write_inquiry_scan_activity
1735107120Sjulian},
1736107120Sjulian{
1737107120Sjulian"read_authentication_enable",
1738107120Sjulian"\nThis command will read the value for the Authentication_Enable parameter.\n"\
1739107120Sjulian"The Authentication_Enable parameter controls if the local unit requires\n"\
1740107120Sjulian"to authenticate the remote unit at connection setup (between the\n" \
1741107120Sjulian"Create_Connection command or acceptance of an incoming ACL connection\n"\
1742107120Sjulian"and the corresponding Connection Complete event). At connection setup, only\n"\
1743107120Sjulian"the unit(s) with the Authentication_Enable parameter enabled will try to\n"\
1744107120Sjulian"authenticate the other unit.",
1745107120Sjulian&hci_read_authentication_enable
1746107120Sjulian},
1747107120Sjulian{
1748107120Sjulian"write_authentication_enable enable(0|1)",
1749107120Sjulian"\nThis command will write the value for the Authentication_Enable parameter.\n"\
1750107120Sjulian"The Authentication_Enable parameter controls if the local unit requires to\n"\
1751107120Sjulian"authenticate the remote unit at connection setup (between the\n" \
1752107120Sjulian"Create_Connection command or acceptance of an incoming ACL connection\n" \
1753107120Sjulian"and the corresponding Connection Complete event). At connection setup, only\n"\
1754107120Sjulian"the unit(s) with the Authentication_Enable parameter enabled will try to\n"\
1755107120Sjulian"authenticate the other unit.",
1756107120Sjulian&hci_write_authentication_enable
1757107120Sjulian},
1758107120Sjulian{
1759107120Sjulian"read_encryption_mode",
1760107120Sjulian"\nThis command will read the value for the Encryption_Mode parameter. The\n" \
1761107120Sjulian"Encryption_Mode parameter controls if the local unit requires encryption\n" \
1762107120Sjulian"to the remote unit at connection setup (between the Create_Connection\n" \
1763107120Sjulian"command or acceptance of an incoming ACL connection and the corresponding\n" \
1764107120Sjulian"Connection Complete event). At connection setup, only the unit(s) with\n" \
1765107120Sjulian"the Authentication_Enable parameter enabled and Encryption_Mode parameter\n" \
1766107120Sjulian"enabled will try to encrypt the connection to the other unit.\n\n" \
1767107120Sjulian"\t<encryption_mode>:\n" \
1768107120Sjulian"\t0x00 - Encryption disabled.\n" \
1769107120Sjulian"\t0x01 - Encryption only for point-to-point packets.\n" \
1770107120Sjulian"\t0x02 - Encryption for both point-to-point and broadcast packets.",
1771107120Sjulian&hci_read_encryption_mode
1772107120Sjulian},
1773107120Sjulian{
1774107120Sjulian"write_encryption_mode mode(0|1|2)",
1775107120Sjulian"\tThis command will write the value for the Encryption_Mode parameter.\n" \
1776107120Sjulian"The Encryption_Mode parameter controls if the local unit requires\n" \
1777107120Sjulian"encryption to the remote unit at connection setup (between the\n" \
1778107120Sjulian"Create_Connection command or acceptance of an incoming ACL connection\n" \
1779107120Sjulian"and the corresponding Connection Complete event). At connection setup,\n" \
1780107120Sjulian"only the unit(s) with the Authentication_Enable parameter enabled and\n" \
1781107120Sjulian"Encryption_Mode parameter enabled will try to encrypt the connection to\n" \
1782107120Sjulian"the other unit.\n\n" \
1783107120Sjulian"\t<encryption_mode> (dd)\n" \
1784107120Sjulian"\t0 - Encryption disabled.\n" \
1785107120Sjulian"\t1 - Encryption only for point-to-point packets.\n" \
1786107120Sjulian"\t2 - Encryption for both point-to-point and broadcast packets.",
1787107120Sjulian&hci_write_encryption_mode
1788107120Sjulian},
1789107120Sjulian{
1790107120Sjulian"read_class_of_device",
1791107120Sjulian"\nThis command will read the value for the Class_of_Device parameter.\n" \
1792107120Sjulian"The Class_of_Device parameter is used to indicate the capabilities of\n" \
1793107120Sjulian"the local unit to other units.",
1794107120Sjulian&hci_read_class_of_device
1795107120Sjulian},
1796107120Sjulian{
1797107120Sjulian"write_class_of_device class(xx:xx:xx)",
1798107120Sjulian"\nThis command will write the value for the Class_of_Device parameter.\n" \
1799107120Sjulian"The Class_of_Device parameter is used to indicate the capabilities of \n" \
1800107120Sjulian"the local unit to other units.\n\n" \
1801107120Sjulian"\t<class> (xx:xx:xx) - class of device",
1802107120Sjulian&hci_write_class_of_device
1803107120Sjulian},
1804107120Sjulian{
1805107120Sjulian"read_voice_settings",
1806107120Sjulian"\nThis command will read the values for the Voice_Setting parameter.\n" \
1807107120Sjulian"The Voice_Setting parameter controls all the various settings for voice\n" \
1808107120Sjulian"connections. These settings apply to all voice connections, and cannot be\n" \
1809107120Sjulian"set for individual voice connections. The Voice_Setting parameter controls\n" \
1810107120Sjulian"the configuration for voice connections: Input Coding, Air coding format,\n" \
1811107120Sjulian"input data format, Input sample size, and linear PCM parameter.",
1812107120Sjulian&hci_read_voice_settings
1813107120Sjulian},
1814107120Sjulian{
1815107120Sjulian"write_voice_settings settings(xxxx)",
1816107120Sjulian"\nThis command will write the values for the Voice_Setting parameter.\n" \
1817107120Sjulian"The Voice_Setting parameter controls all the various settings for voice\n" \
1818107120Sjulian"connections. These settings apply to all voice connections, and cannot be\n" \
1819107120Sjulian"set for individual voice connections. The Voice_Setting parameter controls\n" \
1820107120Sjulian"the configuration for voice connections: Input Coding, Air coding format,\n" \
1821107120Sjulian"input data format, Input sample size, and linear PCM parameter.\n\n" \
1822107120Sjulian"\t<voice_settings> (xxxx) - voice settings",
1823107120Sjulian&hci_write_voice_settings
1824107120Sjulian},
1825107120Sjulian{
1826107120Sjulian"read_number_broadcast_retransmissions",
1827107120Sjulian"\nThis command will read the unit's parameter value for the Number of\n" \
1828107120Sjulian"Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \
1829107120Sjulian"unreliable.",
1830107120Sjulian&hci_read_number_broadcast_retransmissions
1831107120Sjulian},
1832107120Sjulian{
1833107120Sjulian"write_number_broadcast_retransmissions count(dd)",
1834107120Sjulian"\nThis command will write the unit's parameter value for the Number of\n" \
1835107120Sjulian"Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \
1836107120Sjulian"unreliable.\n\n" \
1837107120Sjulian"\t<count> (dd) - number of broadcast retransimissions",
1838107120Sjulian&hci_write_number_broadcast_retransmissions
1839107120Sjulian},
1840107120Sjulian{
1841107120Sjulian"read_hold_mode_activity",
1842107120Sjulian"\nThis command will read the value for the Hold_Mode_Activity parameter.\n" \
1843107120Sjulian"The Hold_Mode_Activity value is used to determine what activities should\n" \
1844107120Sjulian"be suspended when the unit is in hold mode.",
1845107120Sjulian&hci_read_hold_mode_activity
1846107120Sjulian},
1847107120Sjulian{
1848107120Sjulian"write_hold_mode_activity settings(0|1|2|4)",
1849107120Sjulian"\nThis command will write the value for the Hold_Mode_Activity parameter.\n" \
1850107120Sjulian"The Hold_Mode_Activity value is used to determine what activities should\n" \
1851107120Sjulian"be suspended when the unit is in hold mode.\n\n" \
1852107120Sjulian"\t<settings> (dd) - bit mask:\n" \
1853107120Sjulian"\t0 - Maintain current Power State. Default\n" \
1854107120Sjulian"\t1 - Suspend Page Scan.\n" \
1855107120Sjulian"\t2 - Suspend Inquiry Scan.\n" \
1856107120Sjulian"\t4 - Suspend Periodic Inquiries.",
1857107120Sjulian&hci_write_hold_mode_activity
1858107120Sjulian},
1859107120Sjulian{
1860107120Sjulian"read_sco_flow_control_enable",
1861107120Sjulian"\nThe Read_SCO_Flow_Control_Enable command provides the ability to read\n" \
1862107120Sjulian"the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \
1863107120Sjulian"decide if the Host Controller will send Number Of Completed Packets events\n" \
1864107120Sjulian"for SCO Connection Handles. This setting allows the Host to enable and\n" \
1865107120Sjulian"disable SCO flow control.",
1866107120Sjulian&hci_read_sco_flow_control_enable
1867107120Sjulian},
1868107120Sjulian{
1869107120Sjulian"write_sco_flow_control_enable enable(0|1)",
1870107120Sjulian"\nThe Write_SCO_Flow_Control_Enable command provides the ability to write\n" \
1871107120Sjulian"the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \
1872107120Sjulian"decide if the Host Controller will send Number Of Completed Packets events\n" \
1873107120Sjulian"for SCO Connection Handles. This setting allows the Host to enable and\n" \
1874107120Sjulian"disable SCO flow control. The SCO_Flow_Control_Enable setting can only be\n" \
1875107120Sjulian"changed if no connections exist.",
1876107120Sjulian&hci_write_sco_flow_control_enable
1877107120Sjulian},
1878107120Sjulian{
1879107120Sjulian"read_link_supervision_timeout <connection_handle>",
1880107120Sjulian"\nThis command will read the value for the Link_Supervision_Timeout\n" \
1881107120Sjulian"parameter for the device. The Link_Supervision_Timeout parameter is used\n" \
1882107120Sjulian"by the master or slave Bluetooth device to monitor link loss. If, for any\n" \
1883107120Sjulian"reason, no Baseband packets are received from that Connection Handle for a\n" \
1884107120Sjulian"duration longer than the Link_Supervision_Timeout, the connection is\n"
1885107120Sjulian"disconnected.\n\n" \
1886107120Sjulian"\t<connection_handle> - dddd; connection handle\n",
1887107120Sjulian&hci_read_link_supervision_timeout
1888107120Sjulian},
1889107120Sjulian{
1890107120Sjulian"write_link_supervision_timeout <connection_handle> <timeout>",
1891107120Sjulian"\nThis command will write the value for the Link_Supervision_Timeout\n" \
1892107120Sjulian"parameter for the device. The Link_Supervision_Timeout parameter is used\n" \
1893107120Sjulian"by the master or slave Bluetooth device to monitor link loss. If, for any\n" \
1894107120Sjulian"reason, no Baseband packets are received from that connection handle for a\n" \
1895107120Sjulian"duration longer than the Link_Supervision_Timeout, the connection is\n" \
1896107120Sjulian"disconnected.\n\n" \
1897107120Sjulian"\t<connection_handle> - dddd; connection handle\n" \
1898107120Sjulian"\t<timeout>           - dddd; timeout measured in number of baseband slots\n",
1899107120Sjulian&hci_write_link_supervision_timeout
1900107120Sjulian},
1901121054Semax{
1902121054Semax"read_page_scan_period_mode",
1903121054Semax"\nThis command is used to read the mandatory Page_Scan_Period_Mode of the\n" \
1904121054Semax"local Bluetooth device. Every time an inquiry response message is sent, the\n"\
1905121054Semax"Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\
1906121054Semax"is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \
1907121054Semax"expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \
1908121054Semax"following page scans.",
1909121054Semax&hci_read_page_scan_period_mode
1910121054Semax},
1911121054Semax{
1912121054Semax"write_page_scan_period_mode <page_scan_period_mode>",
1913121054Semax"\nThis command is used to write the mandatory Page_Scan_Period_Mode of the\n" \
1914121054Semax"local Bluetooth device. Every time an inquiry response message is sent, the\n"\
1915121054Semax"Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\
1916121054Semax"is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \
1917121054Semax"expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \
1918121054Semax"following page scans.\n\n" \
1919121054Semax"\t<page_scan_period_mode> - dd; page scan period mode:\n" \
1920121054Semax"\t0x00 - P0 (Default)\n" \
1921121054Semax"\t0x01 - P1\n" \
1922121054Semax"\t0x02 - P2",
1923121054Semax&hci_write_page_scan_period_mode
1924121054Semax},
1925121054Semax{
1926121054Semax"read_page_scan_mode",
1927121054Semax"\nThis command is used to read the default page scan mode of the local\n" \
1928121054Semax"Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\
1929121054Semax"that is used for the default page scan. Currently one mandatory page scan\n"\
1930121054Semax"mode and three optional page scan modes are defined. Following an inquiry\n" \
1931121054Semax"response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \
1932121054Semax"mandatory page scan mode must be applied.",
1933121054Semax&hci_read_page_scan_mode
1934121054Semax},
1935121054Semax{
1936121054Semax"write_page_scan_mode <page_scan_mode>",
1937121054Semax"\nThis command is used to write the default page scan mode of the local\n" \
1938121054Semax"Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\
1939121054Semax"that is used for the default page scan. Currently, one mandatory page scan\n"\
1940121054Semax"mode and three optional page scan modes are defined. Following an inquiry\n"\
1941121054Semax"response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \
1942121054Semax"mandatory page scan mode must be applied.\n\n" \
1943121054Semax"\t<page_scan_mode> - dd; page scan mode:\n" \
1944121054Semax"\t0x00 - Mandatory Page Scan Mode (Default)\n" \
1945121054Semax"\t0x01 - Optional Page Scan Mode I\n" \
1946121054Semax"\t0x02 - Optional Page Scan Mode II\n" \
1947121054Semax"\t0x03 - Optional Page Scan Mode III",
1948121054Semax&hci_write_page_scan_mode
1949121054Semax},
1950281680Stakawata{
1951361185Shselasky"read_le_host_support",	\
1952361185Shselasky"Read if this host is in LE supported mode and simultaneous LE supported mode",
1953361185Shselasky&hci_read_le_host_support,
1954281680Stakawata},
1955281680Stakawata{
1956361185Shselasky"write_le_host_support",	\
1957361185Shselasky"write_le_host_support le_host[0|1] simultaneous_le[0|1]",
1958361185Shselasky&hci_write_le_host_support,
1959281680Stakawata},
1960281680Stakawata
1961107120Sjulian{ NULL, }
1962107120Sjulian};
1963107120Sjulian
1964