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