link_control.c revision 107120
1107120Sjulian/*
2107120Sjulian * link_control.c
3107120Sjulian *
4107120Sjulian * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5107120Sjulian * All rights reserved.
6107120Sjulian *
7107120Sjulian * Redistribution and use in source and binary forms, with or without
8107120Sjulian * modification, are permitted provided that the following conditions
9107120Sjulian * are met:
10107120Sjulian * 1. Redistributions of source code must retain the above copyright
11107120Sjulian *    notice, this list of conditions and the following disclaimer.
12107120Sjulian * 2. Redistributions in binary form must reproduce the above copyright
13107120Sjulian *    notice, this list of conditions and the following disclaimer in the
14107120Sjulian *    documentation and/or other materials provided with the distribution.
15107120Sjulian *
16107120Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17107120Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18107120Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19107120Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20107120Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21107120Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22107120Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23107120Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24107120Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25107120Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26107120Sjulian * SUCH DAMAGE.
27107120Sjulian *
28107120Sjulian * $Id: link_control.c,v 1.12 2002/09/17 16:36:46 max Exp $
29107120Sjulian * $FreeBSD: head/usr.sbin/bluetooth/hccontrol/link_control.c 107120 2002-11-20 23:01:59Z julian $
30107120Sjulian */
31107120Sjulian
32107120Sjulian#include <sys/types.h>
33107120Sjulian#include <sys/endian.h>
34107120Sjulian#include <errno.h>
35107120Sjulian#include <ng_hci.h>
36107120Sjulian#include <stdio.h>
37107120Sjulian#include <string.h>
38107120Sjulian#include "hccontrol.h"
39107120Sjulian
40107120Sjulianstatic void hci_inquiry_response (int n, u_int8_t **b);
41107120Sjulian
42107120Sjulian/* Send Inquiry command to the unit */
43107120Sjulianstatic int
44107120Sjulianhci_inquiry(int s, int argc, char **argv)
45107120Sjulian{
46107120Sjulian	int			 n0, n1, n2, timo;
47107120Sjulian	u_int8_t		 b[512];
48107120Sjulian	ng_hci_inquiry_cp	 cp;
49107120Sjulian	ng_hci_event_pkt_t	*e = (ng_hci_event_pkt_t *) b;
50107120Sjulian
51107120Sjulian	/* set defaults */
52107120Sjulian	cp.lap[2] = 0x9e;
53107120Sjulian	cp.lap[1] = 0x8b;
54107120Sjulian	cp.lap[0] = 0x33;
55107120Sjulian	cp.inquiry_length = 5;
56107120Sjulian	cp.num_responses = 8;
57107120Sjulian
58107120Sjulian	/* parse command parameters */
59107120Sjulian	switch (argc) {
60107120Sjulian	case 3:
61107120Sjulian		/* LAP */
62107120Sjulian		if (sscanf(argv[0], "%x:%x:%x", &n2, &n1, &n0) != 3)
63107120Sjulian			return (USAGE);
64107120Sjulian
65107120Sjulian		cp.lap[0] = (n0 & 0xff);
66107120Sjulian		cp.lap[1] = (n1 & 0xff);
67107120Sjulian		cp.lap[2] = (n2 & 0xff);
68107120Sjulian
69107120Sjulian	/* inquiry length (N * 1.28) sec, range 0x01 - 0x30 */
70107120Sjulian	case 2:
71107120Sjulian		if (sscanf(argv[1], "%d", &n0) != 1 || n0 < 0x1 || n0 > 0x30)
72107120Sjulian			return (USAGE);
73107120Sjulian
74107120Sjulian		cp.inquiry_length = (n0 & 0xff);
75107120Sjulian
76107120Sjulian	/* number of responses, range 0x00 - 0xff */
77107120Sjulian	case 1:
78107120Sjulian		if (sscanf(argv[2], "%d", &n0) != 1 || n0 > 0xff)
79107120Sjulian			return (USAGE);
80107120Sjulian
81107120Sjulian		cp.num_responses = (n0 & 0xff);
82107120Sjulian
83107120Sjulian	/* use defaults */
84107120Sjulian	case 0:
85107120Sjulian		break;
86107120Sjulian
87107120Sjulian	default:
88107120Sjulian		return (USAGE);
89107120Sjulian	}
90107120Sjulian
91107120Sjulian	/* send request and expect status back */
92107120Sjulian	n0 = sizeof(b);
93107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
94107120Sjulian			NG_HCI_OCF_INQUIRY), (char const *) &cp, sizeof(cp),
95107120Sjulian			b, &n0) == ERROR)
96107120Sjulian		return (ERROR);
97107120Sjulian
98107120Sjulian	if (*b != 0x00)
99107120Sjulian		return (FAILED);
100107120Sjulian
101107120Sjulian	timo = timeout;
102107120Sjulian	timeout = cp.inquiry_length * 1.28 + 1;
103107120Sjulian
104107120Sjulianwait_for_more:
105107120Sjulian	/* wait for inquiry events */
106107120Sjulian	n0 = sizeof(b);
107107120Sjulian	if (hci_recv(s, b, &n0) == ERROR) {
108107120Sjulian		timeout = timo;
109107120Sjulian		return (ERROR);
110107120Sjulian	}
111107120Sjulian
112107120Sjulian	if (n0 < sizeof(*e)) {
113107120Sjulian		timeout = timo;
114107120Sjulian		errno = EIO;
115107120Sjulian		return (ERROR);
116107120Sjulian	}
117107120Sjulian
118107120Sjulian	switch (e->event) {
119107120Sjulian	case NG_HCI_EVENT_INQUIRY_RESULT: {
120107120Sjulian		ng_hci_inquiry_result_ep	*ir =
121107120Sjulian				(ng_hci_inquiry_result_ep *)(e + 1);
122107120Sjulian		u_int8_t			*r = (u_int8_t *)(ir + 1);
123107120Sjulian
124107120Sjulian		fprintf(stdout, "Inquiry result, num_responses=%d\n",
125107120Sjulian			ir->num_responses);
126107120Sjulian
127107120Sjulian		for (n0 = 0; n0 < ir->num_responses; n0++)
128107120Sjulian			hci_inquiry_response(n0, &r);
129107120Sjulian
130107120Sjulian		goto wait_for_more;
131107120Sjulian		}
132107120Sjulian
133107120Sjulian	case NG_HCI_EVENT_INQUIRY_COMPL:
134107120Sjulian		fprintf(stdout, "Inquiry complete. Status: %s [%#02x]\n",
135107120Sjulian			hci_status2str(*(b + sizeof(*e))), *(b + sizeof(*e)));
136107120Sjulian		break;
137107120Sjulian
138107120Sjulian	default:
139107120Sjulian		goto wait_for_more;
140107120Sjulian	}
141107120Sjulian
142107120Sjulian	timeout = timo;
143107120Sjulian
144107120Sjulian	return (OK);
145107120Sjulian} /* hci_inquiry */
146107120Sjulian
147107120Sjulian/* Print Inquiry_Result event */
148107120Sjulianstatic void
149107120Sjulianhci_inquiry_response(int n, u_int8_t **b)
150107120Sjulian{
151107120Sjulian	struct inquiry_response {
152107120Sjulian		bdaddr_t	bdaddr;
153107120Sjulian		u_int8_t	page_scan_rep_mode;
154107120Sjulian		u_int8_t	page_scan_period_mode;
155107120Sjulian		u_int8_t	page_scan_mode;
156107120Sjulian		u_int8_t	class[NG_HCI_CLASS_SIZE];
157107120Sjulian		u_int16_t	clock_offset;
158107120Sjulian	}			*ir = (struct inquiry_response *)(*b);
159107120Sjulian
160107120Sjulian	fprintf(stdout, "Inquiry result #%d\n", n);
161107120Sjulian	fprintf(stdout, "\tBD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
162107120Sjulian		ir->bdaddr.b[5], ir->bdaddr.b[4], ir->bdaddr.b[3],
163107120Sjulian		ir->bdaddr.b[2], ir->bdaddr.b[1], ir->bdaddr.b[0]);
164107120Sjulian	fprintf(stdout, "\tPage Scan Rep. Mode: %#02x\n",
165107120Sjulian		ir->page_scan_rep_mode);
166107120Sjulian	fprintf(stdout, "\tPage Scan Period Mode: %#02x\n",
167107120Sjulian		ir->page_scan_period_mode);
168107120Sjulian	fprintf(stdout, "\tPage Scan Mode: %#02x\n",
169107120Sjulian		ir->page_scan_mode);
170107120Sjulian	fprintf(stdout, "\tClass: %02x:%02x:%02x\n",
171107120Sjulian		ir->class[2], ir->class[1], ir->class[0]);
172107120Sjulian	fprintf(stdout, "\tClock offset: %#04x\n",
173107120Sjulian		le16toh(ir->clock_offset));
174107120Sjulian
175107120Sjulian	*b += sizeof(*ir);
176107120Sjulian} /* hci_inquiry_response */
177107120Sjulian
178107120Sjulian/* Send Create_Connection command to the unit */
179107120Sjulianstatic int
180107120Sjulianhci_create_connection(int s, int argc, char **argv)
181107120Sjulian{
182107120Sjulian	int			 n0, n1, n2, n3, n4, n5;
183107120Sjulian	char			 b[512];
184107120Sjulian	ng_hci_create_con_cp	 cp;
185107120Sjulian	ng_hci_event_pkt_t	*e = (ng_hci_event_pkt_t *) b;
186107120Sjulian
187107120Sjulian	/* Set defaults */
188107120Sjulian	memset(&cp, 0, sizeof(cp));
189107120Sjulian	cp.pkt_type = htole16(	NG_HCI_PKT_DM1 | NG_HCI_PKT_DH1 |
190107120Sjulian				NG_HCI_PKT_DM3 | NG_HCI_PKT_DH3 |
191107120Sjulian				NG_HCI_PKT_DM5);
192107120Sjulian	cp.page_scan_rep_mode = NG_HCI_SCAN_REP_MODE0;
193107120Sjulian	cp.page_scan_mode = NG_HCI_MANDATORY_PAGE_SCAN_MODE;
194107120Sjulian	cp.clock_offset = 0;
195107120Sjulian	cp.accept_role_switch = 1;
196107120Sjulian
197107120Sjulian	/* parse command parameters */
198107120Sjulian	switch (argc) {
199107120Sjulian	case 6:
200107120Sjulian		/* accept role switch */
201107120Sjulian		if (sscanf(argv[2], "%d", &n0) != 1)
202107120Sjulian			return (USAGE);
203107120Sjulian
204107120Sjulian		cp.accept_role_switch = n0 ? 1 : 0;
205107120Sjulian
206107120Sjulian	case 5:
207107120Sjulian		/* clock offset */
208107120Sjulian		if (sscanf(argv[2], "%d", &n0) != 1)
209107120Sjulian			return (USAGE);
210107120Sjulian
211107120Sjulian		cp.clock_offset = (n0 & 0xffff);
212107120Sjulian		cp.clock_offset = htole16(cp.clock_offset);
213107120Sjulian
214107120Sjulian	case 4:
215107120Sjulian		/* page scan mode */
216107120Sjulian		if (sscanf(argv[2], "%d", &n0) != 1 || n0 < 0 || n0 > 3)
217107120Sjulian			return (USAGE);
218107120Sjulian
219107120Sjulian		cp.page_scan_mode = (n0 & 0xff);
220107120Sjulian
221107120Sjulian	case 3:
222107120Sjulian		/* page scan rep mode */
223107120Sjulian		if (sscanf(argv[2], "%d", &n0) != 1 || n0 < 0 || n0 > 2)
224107120Sjulian			return (USAGE);
225107120Sjulian
226107120Sjulian		cp.page_scan_rep_mode = (n0 & 0xff);
227107120Sjulian
228107120Sjulian	case 2:
229107120Sjulian		/* packet type */
230107120Sjulian		if (sscanf(argv[1], "%x", &n0) != 1)
231107120Sjulian			return (USAGE);
232107120Sjulian
233107120Sjulian		n0 &= (	NG_HCI_PKT_DM1 | NG_HCI_PKT_DH1 |
234107120Sjulian			NG_HCI_PKT_DM3 | NG_HCI_PKT_DH3 |
235107120Sjulian			NG_HCI_PKT_DM5);
236107120Sjulian		if (n0 == 0)
237107120Sjulian			return (USAGE);
238107120Sjulian
239107120Sjulian		cp.pkt_type = (n0 & 0xffff);
240107120Sjulian		cp.pkt_type = htole16(cp.pkt_type);
241107120Sjulian
242107120Sjulian	case 1:
243107120Sjulian		/* BD_ADDR */
244107120Sjulian		if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x",
245107120Sjulian				&n5, &n4, &n3, &n2, &n1, &n0) != 6)
246107120Sjulian			return (USAGE);
247107120Sjulian
248107120Sjulian		cp.bdaddr.b[0] = (n0 & 0xff);
249107120Sjulian		cp.bdaddr.b[1] = (n1 & 0xff);
250107120Sjulian		cp.bdaddr.b[2] = (n2 & 0xff);
251107120Sjulian		cp.bdaddr.b[3] = (n3 & 0xff);
252107120Sjulian		cp.bdaddr.b[4] = (n4 & 0xff);
253107120Sjulian		cp.bdaddr.b[5] = (n5 & 0xff);
254107120Sjulian		break;
255107120Sjulian
256107120Sjulian	default:
257107120Sjulian		return (USAGE);
258107120Sjulian	}
259107120Sjulian
260107120Sjulian	/* send request and expect status response */
261107120Sjulian	n0 = sizeof(b);
262107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
263107120Sjulian			NG_HCI_OCF_CREATE_CON),
264107120Sjulian			(char const *) &cp, sizeof(cp), b, &n0) == ERROR)
265107120Sjulian		return (ERROR);
266107120Sjulian
267107120Sjulian	if (*b != 0x00)
268107120Sjulian		return (FAILED);
269107120Sjulian
270107120Sjulian	/* wait for event */
271107120Sjulianagain:
272107120Sjulian	n0 = sizeof(b);
273107120Sjulian	if (hci_recv(s, b, &n0) == ERROR)
274107120Sjulian		return (ERROR);
275107120Sjulian	if (n0 < sizeof(*e)) {
276107120Sjulian		errno = EIO;
277107120Sjulian		return (ERROR);
278107120Sjulian	}
279107120Sjulian
280107120Sjulian	if (e->event == NG_HCI_EVENT_CON_COMPL) {
281107120Sjulian		ng_hci_con_compl_ep	*ep = (ng_hci_con_compl_ep *)(e + 1);
282107120Sjulian
283107120Sjulian		if (ep->status != 0x00) {
284107120Sjulian			fprintf(stdout, "Status: %s [%#02x]\n",
285107120Sjulian				hci_status2str(ep->status), ep->status);
286107120Sjulian			return (FAILED);
287107120Sjulian		}
288107120Sjulian
289107120Sjulian		fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
290107120Sjulian			ep->bdaddr.b[5], ep->bdaddr.b[4], ep->bdaddr.b[3],
291107120Sjulian			ep->bdaddr.b[2], ep->bdaddr.b[1], ep->bdaddr.b[0]);
292107120Sjulian		fprintf(stdout, "Connection handle: %d\n",
293107120Sjulian			le16toh(ep->con_handle));
294107120Sjulian		fprintf(stdout, "Encryption mode: %s [%d]\n",
295107120Sjulian			hci_encrypt2str(ep->encryption_mode, 0),
296107120Sjulian			ep->encryption_mode);
297107120Sjulian	} else
298107120Sjulian		goto again;
299107120Sjulian
300107120Sjulian	return (OK);
301107120Sjulian} /* hci_create_connection */
302107120Sjulian
303107120Sjulian/* Send Disconnect command to the unit */
304107120Sjulianstatic int
305107120Sjulianhci_disconnect(int s, int argc, char **argv)
306107120Sjulian{
307107120Sjulian	int			 n;
308107120Sjulian	char			 b[512];
309107120Sjulian	ng_hci_discon_cp	 cp;
310107120Sjulian	ng_hci_event_pkt_t	*e = (ng_hci_event_pkt_t *) b;
311107120Sjulian
312107120Sjulian	/* Set defaults */
313107120Sjulian	memset(&cp, 0, sizeof(cp));
314107120Sjulian	cp.reason = 0x13;
315107120Sjulian
316107120Sjulian	/* parse command parameters */
317107120Sjulian	switch (argc) {
318107120Sjulian	case 2:
319107120Sjulian		/* reason */
320107120Sjulian		if (sscanf(argv[1], "%d", &n) != 1 || n <= 0x00 || n > 0xff)
321107120Sjulian			return (USAGE);
322107120Sjulian
323107120Sjulian		cp.reason = (u_int8_t) (n & 0xff);
324107120Sjulian
325107120Sjulian	case 1:
326107120Sjulian		/* connection handle */
327107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
328107120Sjulian			return (USAGE);
329107120Sjulian
330107120Sjulian		cp.con_handle = (u_int16_t) (n & 0x0fff);
331107120Sjulian		cp.con_handle = htole16(cp.con_handle);
332107120Sjulian		break;
333107120Sjulian
334107120Sjulian	default:
335107120Sjulian		return (USAGE);
336107120Sjulian	}
337107120Sjulian
338107120Sjulian	/* send request and expect status response */
339107120Sjulian	n = sizeof(b);
340107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
341107120Sjulian			NG_HCI_OCF_DISCON),
342107120Sjulian			(char const *) &cp, sizeof(cp), b, &n) == ERROR)
343107120Sjulian		return (ERROR);
344107120Sjulian
345107120Sjulian	if (*b != 0x00)
346107120Sjulian		return (FAILED);
347107120Sjulian
348107120Sjulian	/* wait for event */
349107120Sjulianagain:
350107120Sjulian	n = sizeof(b);
351107120Sjulian	if (hci_recv(s, b, &n) == ERROR)
352107120Sjulian		return (ERROR);
353107120Sjulian	if (n < sizeof(*e)) {
354107120Sjulian		errno = EIO;
355107120Sjulian		return (ERROR);
356107120Sjulian	}
357107120Sjulian
358107120Sjulian	if (e->event == NG_HCI_EVENT_DISCON_COMPL) {
359107120Sjulian		ng_hci_discon_compl_ep	*ep = (ng_hci_discon_compl_ep *)(e + 1);
360107120Sjulian
361107120Sjulian		if (ep->status != 0x00) {
362107120Sjulian			fprintf(stdout, "Status: %s [%#02x]\n",
363107120Sjulian				hci_status2str(ep->status), ep->status);
364107120Sjulian			return (FAILED);
365107120Sjulian		}
366107120Sjulian
367107120Sjulian		fprintf(stdout, "Connection handle: %d\n",
368107120Sjulian			le16toh(ep->con_handle));
369107120Sjulian		fprintf(stdout, "Reason: %s [%#02x]\n",
370107120Sjulian			hci_status2str(ep->reason), ep->reason);
371107120Sjulian	} else
372107120Sjulian		goto again;
373107120Sjulian
374107120Sjulian	return (OK);
375107120Sjulian} /* hci_diconnect */
376107120Sjulian
377107120Sjulian/* Send Add_SCO_Connection command to the unit */
378107120Sjulianstatic int
379107120Sjulianhci_add_sco_connection(int s, int argc, char **argv)
380107120Sjulian{
381107120Sjulian	int			 n;
382107120Sjulian	char			 b[512];
383107120Sjulian	ng_hci_add_sco_con_cp	 cp;
384107120Sjulian	ng_hci_event_pkt_t	*e = (ng_hci_event_pkt_t *) b;
385107120Sjulian
386107120Sjulian	/* Set defaults */
387107120Sjulian	memset(&cp, 0, sizeof(cp));
388107120Sjulian	cp.pkt_type = htole16(NG_HCI_PKT_HV1 | NG_HCI_PKT_HV2 | NG_HCI_PKT_HV3);
389107120Sjulian
390107120Sjulian	/* parse command parameters */
391107120Sjulian	switch (argc) {
392107120Sjulian	case 2:
393107120Sjulian		/* packet type */
394107120Sjulian		if (sscanf(argv[0], "%x", &n) != 1)
395107120Sjulian			return (USAGE);
396107120Sjulian
397107120Sjulian		n &= (NG_HCI_PKT_HV1 | NG_HCI_PKT_HV2 | NG_HCI_PKT_HV3);
398107120Sjulian		if (n == 0)
399107120Sjulian			return (USAGE);
400107120Sjulian
401107120Sjulian		cp.pkt_type = (u_int16_t) (n & 0x0fff);
402107120Sjulian		cp.pkt_type = htole16(cp.pkt_type);
403107120Sjulian
404107120Sjulian	case 1:
405107120Sjulian		/* acl connection handle */
406107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
407107120Sjulian			return (USAGE);
408107120Sjulian
409107120Sjulian		cp.con_handle = (u_int16_t) (n & 0x0fff);
410107120Sjulian		cp.con_handle = htole16(cp.con_handle);
411107120Sjulian		break;
412107120Sjulian
413107120Sjulian	default:
414107120Sjulian		return (USAGE);
415107120Sjulian	}
416107120Sjulian
417107120Sjulian	/* send request and expect status response */
418107120Sjulian	n = sizeof(b);
419107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
420107120Sjulian			NG_HCI_OCF_ADD_SCO_CON),
421107120Sjulian			(char const *) &cp, sizeof(cp), b, &n) == ERROR)
422107120Sjulian		return (ERROR);
423107120Sjulian
424107120Sjulian	if (*b != 0x00)
425107120Sjulian		return (FAILED);
426107120Sjulian
427107120Sjulian	/* wait for event */
428107120Sjulianagain:
429107120Sjulian	n = sizeof(b);
430107120Sjulian	if (hci_recv(s, b, &n) == ERROR)
431107120Sjulian		return (ERROR);
432107120Sjulian	if (n < sizeof(*e)) {
433107120Sjulian		errno = EIO;
434107120Sjulian		return (ERROR);
435107120Sjulian	}
436107120Sjulian
437107120Sjulian	if (e->event == NG_HCI_EVENT_CON_COMPL) {
438107120Sjulian		ng_hci_con_compl_ep	*ep = (ng_hci_con_compl_ep *)(e + 1);
439107120Sjulian
440107120Sjulian		if (ep->status != 0x00) {
441107120Sjulian			fprintf(stdout, "Status: %s [%#02x]\n",
442107120Sjulian				hci_status2str(ep->status), ep->status);
443107120Sjulian			return (FAILED);
444107120Sjulian		}
445107120Sjulian
446107120Sjulian		fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
447107120Sjulian			ep->bdaddr.b[5], ep->bdaddr.b[4], ep->bdaddr.b[3],
448107120Sjulian			ep->bdaddr.b[2], ep->bdaddr.b[1], ep->bdaddr.b[0]);
449107120Sjulian		fprintf(stdout, "Connection handle: %d\n",
450107120Sjulian			le16toh(ep->con_handle));
451107120Sjulian		fprintf(stdout, "Encryption mode: %s [%d]\n",
452107120Sjulian			hci_encrypt2str(ep->encryption_mode, 0),
453107120Sjulian			ep->encryption_mode);
454107120Sjulian	} else
455107120Sjulian		goto again;
456107120Sjulian
457107120Sjulian	return (OK);
458107120Sjulian} /* Add_SCO_Connection */
459107120Sjulian
460107120Sjulian/* Send Change_Connection_Packet_Type command to the unit */
461107120Sjulianstatic int
462107120Sjulianhci_change_connection_packet_type(int s, int argc, char **argv)
463107120Sjulian{
464107120Sjulian	int				 n;
465107120Sjulian	char				 b[512];
466107120Sjulian	ng_hci_change_con_pkt_type_cp	 cp;
467107120Sjulian	ng_hci_event_pkt_t		*e = (ng_hci_event_pkt_t *) b;
468107120Sjulian
469107120Sjulian	switch (argc) {
470107120Sjulian	case 2:
471107120Sjulian		/* connection handle */
472107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
473107120Sjulian			return (USAGE);
474107120Sjulian
475107120Sjulian		cp.con_handle = (u_int16_t) (n & 0x0fff);
476107120Sjulian		cp.con_handle = htole16(cp.con_handle);
477107120Sjulian
478107120Sjulian		/* packet type */
479107120Sjulian		if (sscanf(argv[1], "%x", &n) != 1)
480107120Sjulian			return (USAGE);
481107120Sjulian
482107120Sjulian		cp.pkt_type = (u_int16_t) (n & 0xffff);
483107120Sjulian		cp.pkt_type = htole16(cp.pkt_type);
484107120Sjulian		break;
485107120Sjulian
486107120Sjulian	default:
487107120Sjulian		return (USAGE);
488107120Sjulian	}
489107120Sjulian
490107120Sjulian	/* send request and expect status response */
491107120Sjulian	n = sizeof(b);
492107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
493107120Sjulian			NG_HCI_OCF_CHANGE_CON_PKT_TYPE),
494107120Sjulian			(char const *) &cp, sizeof(cp), b, &n) == ERROR)
495107120Sjulian		return (ERROR);
496107120Sjulian
497107120Sjulian	if (*b != 0x00)
498107120Sjulian		return (FAILED);
499107120Sjulian
500107120Sjulian	/* wait for event */
501107120Sjulianagain:
502107120Sjulian	n = sizeof(b);
503107120Sjulian	if (hci_recv(s, b, &n) == ERROR)
504107120Sjulian		return (ERROR);
505107120Sjulian	if (n < sizeof(*e)) {
506107120Sjulian		errno = EIO;
507107120Sjulian		return (ERROR);
508107120Sjulian	}
509107120Sjulian
510107120Sjulian	if (e->event == NG_HCI_EVENT_CON_PKT_TYPE_CHANGED) {
511107120Sjulian		ng_hci_con_pkt_type_changed_ep	*ep =
512107120Sjulian				(ng_hci_con_pkt_type_changed_ep *)(e + 1);
513107120Sjulian
514107120Sjulian		if (ep->status != 0x00) {
515107120Sjulian			fprintf(stdout, "Status: %s [%#02x]\n",
516107120Sjulian				hci_status2str(ep->status), ep->status);
517107120Sjulian			return (FAILED);
518107120Sjulian		}
519107120Sjulian
520107120Sjulian		fprintf(stdout, "Connection handle: %d\n",
521107120Sjulian			le16toh(ep->con_handle));
522107120Sjulian		fprintf(stdout, "Packet type: %#04x\n",
523107120Sjulian			le16toh(ep->pkt_type));
524107120Sjulian	} else
525107120Sjulian		goto again;
526107120Sjulian
527107120Sjulian	return (OK);
528107120Sjulian} /* hci_change_connection_packet_type */
529107120Sjulian
530107120Sjulian/* Send Remote_Name_Request command to the unit */
531107120Sjulianstatic int
532107120Sjulianhci_remote_name_request(int s, int argc, char **argv)
533107120Sjulian{
534107120Sjulian	int				 n0, n1, n2, n3, n4, n5;
535107120Sjulian	char				 b[512];
536107120Sjulian	ng_hci_remote_name_req_cp	 cp;
537107120Sjulian	ng_hci_event_pkt_t		*e = (ng_hci_event_pkt_t *) b;
538107120Sjulian
539107120Sjulian	/* parse command parameters */
540107120Sjulian	switch (argc) {
541107120Sjulian	case 4:
542107120Sjulian		/* BD_ADDR */
543107120Sjulian		if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x",
544107120Sjulian				&n5, &n4, &n3, &n2, &n1, &n0) != 6)
545107120Sjulian			return (USAGE);
546107120Sjulian
547107120Sjulian		cp.bdaddr.b[0] = (n0 & 0xff);
548107120Sjulian		cp.bdaddr.b[1] = (n1 & 0xff);
549107120Sjulian		cp.bdaddr.b[2] = (n2 & 0xff);
550107120Sjulian		cp.bdaddr.b[3] = (n3 & 0xff);
551107120Sjulian		cp.bdaddr.b[4] = (n4 & 0xff);
552107120Sjulian		cp.bdaddr.b[5] = (n5 & 0xff);
553107120Sjulian
554107120Sjulian		/* page_scan_rep_mode */
555107120Sjulian		if (sscanf(argv[1], "%d", &n0) != 1 || n0 < 0x00 || n0 > 0x02)
556107120Sjulian			return (USAGE);
557107120Sjulian
558107120Sjulian		cp.page_scan_rep_mode = (n0 & 0xff);
559107120Sjulian
560107120Sjulian		/* page_scan_mode */
561107120Sjulian		if (sscanf(argv[2], "%d", &n0) != 1 || n0 < 0x00 || n0 > 0x03)
562107120Sjulian			return (USAGE);
563107120Sjulian
564107120Sjulian		cp.page_scan_mode = (n0 & 0xff);
565107120Sjulian
566107120Sjulian		/* clock_offset */
567107120Sjulian		if (sscanf(argv[3], "%x", &n0) != 1)
568107120Sjulian			return (USAGE);
569107120Sjulian
570107120Sjulian		cp.clock_offset = (n0 & 0xffff);
571107120Sjulian		cp.clock_offset = htole16(cp.clock_offset);
572107120Sjulian		break;
573107120Sjulian
574107120Sjulian	default:
575107120Sjulian		return (USAGE);
576107120Sjulian	}
577107120Sjulian
578107120Sjulian	/* send request and expect status response */
579107120Sjulian	n0 = sizeof(b);
580107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
581107120Sjulian			NG_HCI_OCF_REMOTE_NAME_REQ),
582107120Sjulian			(char const *) &cp, sizeof(cp), b, &n0) == ERROR)
583107120Sjulian		return (ERROR);
584107120Sjulian
585107120Sjulian	if (*b != 0x00)
586107120Sjulian		return (FAILED);
587107120Sjulian
588107120Sjulian	/* wait for event */
589107120Sjulianagain:
590107120Sjulian	n0 = sizeof(b);
591107120Sjulian	if (hci_recv(s, b, &n0) == ERROR)
592107120Sjulian		return (ERROR);
593107120Sjulian	if (n0 < sizeof(*e)) {
594107120Sjulian		errno = EIO;
595107120Sjulian		return (ERROR);
596107120Sjulian	}
597107120Sjulian
598107120Sjulian	if (e->event == NG_HCI_EVENT_REMOTE_NAME_REQ_COMPL) {
599107120Sjulian		ng_hci_remote_name_req_compl_ep	*ep =
600107120Sjulian				(ng_hci_remote_name_req_compl_ep *)(e + 1);
601107120Sjulian
602107120Sjulian		if (ep->status != 0x00) {
603107120Sjulian			fprintf(stdout, "Status: %s [%#02x]\n",
604107120Sjulian				hci_status2str(ep->status), ep->status);
605107120Sjulian			return (FAILED);
606107120Sjulian		}
607107120Sjulian
608107120Sjulian		fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
609107120Sjulian			ep->bdaddr.b[5], ep->bdaddr.b[4], ep->bdaddr.b[3],
610107120Sjulian			ep->bdaddr.b[2], ep->bdaddr.b[1], ep->bdaddr.b[0]);
611107120Sjulian		fprintf(stdout, "Name: %s\n", ep->name);
612107120Sjulian	} else
613107120Sjulian		goto again;
614107120Sjulian
615107120Sjulian	return (OK);
616107120Sjulian} /* hci_remote_name_request */
617107120Sjulian
618107120Sjulian/* Send Read_Remote_Supported_Features command to the unit */
619107120Sjulianstatic int
620107120Sjulianhci_read_remote_supported_features(int s, int argc, char **argv)
621107120Sjulian{
622107120Sjulian	int				 n;
623107120Sjulian	char				 b[512];
624107120Sjulian	ng_hci_read_remote_features_cp	 cp;
625107120Sjulian	ng_hci_event_pkt_t		*e = (ng_hci_event_pkt_t *) b;
626107120Sjulian	char				 buffer[1024];
627107120Sjulian
628107120Sjulian	/* parse command parameters */
629107120Sjulian	switch (argc) {
630107120Sjulian	case 1:
631107120Sjulian		/* connecton handle */
632107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0x0eff)
633107120Sjulian			return (USAGE);
634107120Sjulian
635107120Sjulian		cp.con_handle = (n & 0x0fff);
636107120Sjulian		cp.con_handle = htole16(cp.con_handle);
637107120Sjulian		break;
638107120Sjulian
639107120Sjulian	default:
640107120Sjulian		return (USAGE);
641107120Sjulian	}
642107120Sjulian
643107120Sjulian	/* send request and expect status response */
644107120Sjulian	n = sizeof(b);
645107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
646107120Sjulian			NG_HCI_OCF_READ_REMOTE_FEATURES),
647107120Sjulian			(char const *) &cp, sizeof(cp), b, &n) == ERROR)
648107120Sjulian		return (ERROR);
649107120Sjulian
650107120Sjulian	if (*b != 0x00)
651107120Sjulian		return (FAILED);
652107120Sjulian
653107120Sjulian	/* wait for event */
654107120Sjulianagain:
655107120Sjulian	n = sizeof(b);
656107120Sjulian	if (hci_recv(s, b, &n) == ERROR)
657107120Sjulian		return (ERROR);
658107120Sjulian
659107120Sjulian	if (n < sizeof(*e)) {
660107120Sjulian		errno = EIO;
661107120Sjulian		return (ERROR);
662107120Sjulian	}
663107120Sjulian
664107120Sjulian	if (e->event == NG_HCI_EVENT_READ_REMOTE_FEATURES_COMPL) {
665107120Sjulian		ng_hci_read_remote_features_compl_ep	*ep =
666107120Sjulian				(ng_hci_read_remote_features_compl_ep *)(e + 1);
667107120Sjulian
668107120Sjulian		if (ep->status != 0x00) {
669107120Sjulian			fprintf(stdout, "Status: %s [%#02x]\n",
670107120Sjulian				hci_status2str(ep->status), ep->status);
671107120Sjulian			return (FAILED);
672107120Sjulian		}
673107120Sjulian
674107120Sjulian		fprintf(stdout, "Connection handle: %d\n",
675107120Sjulian			le16toh(ep->con_handle));
676107120Sjulian		fprintf(stdout, "Features: ");
677107120Sjulian		for (n = 0; n < sizeof(ep->features); n++)
678107120Sjulian			fprintf(stdout, "%#02x ", ep->features[n]);
679107120Sjulian		fprintf(stdout, "\n%s\n", hci_features2str(ep->features,
680107120Sjulian			buffer, sizeof(buffer)));
681107120Sjulian	} else
682107120Sjulian		goto again;
683107120Sjulian
684107120Sjulian	return (OK);
685107120Sjulian} /* hci_read_remote_supported_features */
686107120Sjulian
687107120Sjulian/* Send Read_Remote_Version_Information command to the unit */
688107120Sjulianstatic int
689107120Sjulianhci_read_remote_version_information(int s, int argc, char **argv)
690107120Sjulian{
691107120Sjulian	int				 n;
692107120Sjulian	char				 b[512];
693107120Sjulian	ng_hci_read_remote_ver_info_cp	 cp;
694107120Sjulian	ng_hci_event_pkt_t		*e = (ng_hci_event_pkt_t *) b;
695107120Sjulian
696107120Sjulian	/* parse command parameters */
697107120Sjulian	switch (argc) {
698107120Sjulian	case 1:
699107120Sjulian		/* connecton handle */
700107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0x0eff)
701107120Sjulian			return (USAGE);
702107120Sjulian
703107120Sjulian		cp.con_handle = (n & 0x0fff);
704107120Sjulian		cp.con_handle = htole16(cp.con_handle);
705107120Sjulian		break;
706107120Sjulian
707107120Sjulian	default:
708107120Sjulian		return (USAGE);
709107120Sjulian	}
710107120Sjulian
711107120Sjulian	/* send request and expect status response */
712107120Sjulian	n = sizeof(b);
713107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
714107120Sjulian			NG_HCI_OCF_READ_REMOTE_VER_INFO),
715107120Sjulian			(char const *) &cp, sizeof(cp), b, &n) == ERROR)
716107120Sjulian		return (ERROR);
717107120Sjulian
718107120Sjulian	if (*b != 0x00)
719107120Sjulian		return (FAILED);
720107120Sjulian
721107120Sjulian	/* wait for event */
722107120Sjulianagain:
723107120Sjulian	n = sizeof(b);
724107120Sjulian	if (hci_recv(s, b, &n) == ERROR)
725107120Sjulian		return (ERROR);
726107120Sjulian
727107120Sjulian	if (n < sizeof(*e)) {
728107120Sjulian		errno = EIO;
729107120Sjulian		return (ERROR);
730107120Sjulian	}
731107120Sjulian
732107120Sjulian	if (e->event == NG_HCI_EVENT_READ_REMOTE_VER_INFO_COMPL) {
733107120Sjulian		ng_hci_read_remote_ver_info_compl_ep	*ep =
734107120Sjulian				(ng_hci_read_remote_ver_info_compl_ep *)(e + 1);
735107120Sjulian
736107120Sjulian		if (ep->status != 0x00) {
737107120Sjulian			fprintf(stdout, "Status: %s [%#02x]\n",
738107120Sjulian				hci_status2str(ep->status), ep->status);
739107120Sjulian			return (FAILED);
740107120Sjulian		}
741107120Sjulian
742107120Sjulian		ep->manufacturer = le16toh(ep->manufacturer);
743107120Sjulian
744107120Sjulian		fprintf(stdout, "Connection handle: %d\n",
745107120Sjulian			le16toh(ep->con_handle));
746107120Sjulian		fprintf(stdout, "LMP version: %#02x\n", ep->lmp_version);
747107120Sjulian		fprintf(stdout, "LMP sub-version: %#04x\n",
748107120Sjulian			le16toh(ep->lmp_subversion));
749107120Sjulian		fprintf(stdout, "Manufacturer: %s [%#04x]\n",
750107120Sjulian			hci_manufacturer2str(ep->manufacturer),
751107120Sjulian			ep->manufacturer);
752107120Sjulian	} else
753107120Sjulian		goto again;
754107120Sjulian
755107120Sjulian	return (OK);
756107120Sjulian} /* hci_read_remote_version_information */
757107120Sjulian
758107120Sjulian/* Send Read_Clock_Offset command to the unit */
759107120Sjulianstatic int
760107120Sjulianhci_read_clock_offset(int s, int argc, char **argv)
761107120Sjulian{
762107120Sjulian	int				 n;
763107120Sjulian	char				 b[512];
764107120Sjulian	ng_hci_read_clock_offset_cp	 cp;
765107120Sjulian	ng_hci_event_pkt_t		*e = (ng_hci_event_pkt_t *) b;
766107120Sjulian
767107120Sjulian	/* parse command parameters */
768107120Sjulian	switch (argc) {
769107120Sjulian	case 1:
770107120Sjulian		/* connecton handle */
771107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0x0eff)
772107120Sjulian			return (USAGE);
773107120Sjulian
774107120Sjulian		cp.con_handle = (n & 0x0fff);
775107120Sjulian		cp.con_handle = htole16(cp.con_handle);
776107120Sjulian		break;
777107120Sjulian
778107120Sjulian	default:
779107120Sjulian		return (USAGE);
780107120Sjulian	}
781107120Sjulian
782107120Sjulian	/* send request and expect status response */
783107120Sjulian	n = sizeof(b);
784107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
785107120Sjulian			NG_HCI_OCF_READ_CLOCK_OFFSET),
786107120Sjulian			(char const *) &cp, sizeof(cp), b, &n) == ERROR)
787107120Sjulian		return (ERROR);
788107120Sjulian
789107120Sjulian	if (*b != 0x00)
790107120Sjulian		return (FAILED);
791107120Sjulian
792107120Sjulian	/* wait for event */
793107120Sjulianagain:
794107120Sjulian	n = sizeof(b);
795107120Sjulian	if (hci_recv(s, b, &n) == ERROR)
796107120Sjulian		return (ERROR);
797107120Sjulian
798107120Sjulian	if (n < sizeof(*e)) {
799107120Sjulian		errno = EIO;
800107120Sjulian		return (ERROR);
801107120Sjulian	}
802107120Sjulian
803107120Sjulian	if (e->event == NG_HCI_EVENT_READ_CLOCK_OFFSET_COMPL) {
804107120Sjulian		ng_hci_read_clock_offset_compl_ep	*ep =
805107120Sjulian				(ng_hci_read_clock_offset_compl_ep *)(e + 1);
806107120Sjulian
807107120Sjulian		if (ep->status != 0x00) {
808107120Sjulian			fprintf(stdout, "Status: %s [%#02x]\n",
809107120Sjulian				hci_status2str(ep->status), ep->status);
810107120Sjulian			return (FAILED);
811107120Sjulian		}
812107120Sjulian
813107120Sjulian		fprintf(stdout, "Connection handle: %d\n",
814107120Sjulian			le16toh(ep->con_handle));
815107120Sjulian		fprintf(stdout, "Clock offset: %#04x\n",
816107120Sjulian			le16toh(ep->clock_offset));
817107120Sjulian	} else
818107120Sjulian		goto again;
819107120Sjulian
820107120Sjulian	return (OK);
821107120Sjulian} /* hci_read_clock_offset */
822107120Sjulian
823107120Sjulianstruct hci_command	link_control_commands[] = {
824107120Sjulian{
825107120Sjulian"inquiry <LAP> <inquiry_length> <num_reponses>",
826107120Sjulian"\nThis command will cause the Bluetooth unit to enter Inquiry Mode.\n" \
827107120Sjulian"Inquiry Mode is used to discover other nearby Bluetooth units. The LAP\n" \
828107120Sjulian"input parameter contains the LAP from which the inquiry access code shall\n" \
829107120Sjulian"be derived when the inquiry procedure is made. The Inquiry_Length parameter\n"\
830107120Sjulian"specifies the total duration of the Inquiry Mode and, when this time\n" \
831107120Sjulian"expires, Inquiry will be halted. The Num_Responses parameter specifies the\n" \
832107120Sjulian"number of responses that can be received before the Inquiry is halted.\n\n" \
833107120Sjulian"\t<LAP>            - xx:xx:xx; 9e:8b:33 (GIAC), 93:8b:00 (LDIAC)\n" \
834107120Sjulian"\t<inquiry_length> - dd; total length == dd * 1.28 sec\n" \
835107120Sjulian"\t<num_responses>  - dd",
836107120Sjulian&hci_inquiry
837107120Sjulian},
838107120Sjulian{
839107120Sjulian"create_connection <BD_ADDR> <pkt> <rep_mode> <ps_mode> <clck_off> <role_sw>",
840107120Sjulian"" \
841107120Sjulian"\t<BD_ADDR> - remote unit address\n\n" \
842107120Sjulian"\t<pkt>     - xxxx; packet type\n" \
843107120Sjulian"" \
844107120Sjulian"\t\tACL packets\n" \
845107120Sjulian"\t\t-----------\n" \
846107120Sjulian"\t\t0x0008 DM1\n" \
847107120Sjulian"\t\t0x0010 DH1\n" \
848107120Sjulian"\t\t0x0400 DM3\n" \
849107120Sjulian"\t\t0x0800 DH3\n" \
850107120Sjulian"\t\t0x4000 DM5\n" \
851107120Sjulian"\t\t0x8000 DH5\n\n" \
852107120Sjulian"" \
853107120Sjulian"\trep_mode  - d; page scan repetition mode\n" \
854107120Sjulian"" \
855107120Sjulian"\t\tPage scan repetition modes\n" \
856107120Sjulian"\t\t--------------------------\n" \
857107120Sjulian"\t\t0 Page scan repetition mode 0\n" \
858107120Sjulian"\t\t1 Page scan repetition mode 1\n" \
859107120Sjulian"\t\t2 Page scan repetition mode 2\n" \
860107120Sjulian"\n" \
861107120Sjulian"\tps_mode   - d; Page scan mode\n" \
862107120Sjulian"" \
863107120Sjulian"\t\tPage scan modes\n" \
864107120Sjulian"\t\t---------------\n" \
865107120Sjulian"\t\t0 Mandatory page scan mode\n" \
866107120Sjulian"\t\t1 Optional page scan mode1\n" \
867107120Sjulian"\t\t2 Optional page scan mode2\n" \
868107120Sjulian"\t\t3 Optional page scan mode3\n" \
869107120Sjulian"\n" \
870107120Sjulian"\tclck_off  - dddd; clock offset. Use 0 if unknown\n\n" \
871107120Sjulian"\trole_sw   - d; allow (1) or deny role switch\n",
872107120Sjulian&hci_create_connection
873107120Sjulian},
874107120Sjulian{
875107120Sjulian"disconnect <connection_handle> <reason>",
876107120Sjulian"\nThe Disconnection command is used to terminate an existing connection.\n" \
877107120Sjulian"The connection handle command parameter indicates which connection is to\n" \
878107120Sjulian"be disconnected. The Reason command parameter indicates the reason for\n" \
879107120Sjulian"ending the connection.\n\n" \
880107120Sjulian"\t<connection_handle> - dddd; connection handle\n" \
881107120Sjulian"\t<reason>            - dd; reason; usually 19 (0x13) - user ended;\n" \
882107120Sjulian"\t                      also 0x05, 0x13-0x15, 0x1A, 0x29",
883107120Sjulian&hci_disconnect
884107120Sjulian},
885107120Sjulian{
886107120Sjulian"add_sco_connection <acl connection handle> <packet type>",
887107120Sjulian"This command will cause the link manager to create a SCO connection using\n" \
888107120Sjulian"the ACL connection specified by the connection handle command parameter.\n" \
889107120Sjulian"The Link Manager will determine how the new connection is established. This\n"\
890107120Sjulian"connection is determined by the current state of the device, its piconet,\n" \
891107120Sjulian"and the state of the device to be connected. The packet type command parameter\n" \
892107120Sjulian"specifies which packet types the Link Manager should use for the connection.\n"\
893107120Sjulian"The Link Manager must only use the packet type(s) specified by the packet\n" \
894107120Sjulian"type command parameter for sending HCI SCO data packets. Multiple packet\n" \
895107120Sjulian"types may be specified for the packet type command parameter by performing\n" \
896107120Sjulian"a bitwise OR operation of the different packet types. Note: An SCO connection\n" \
897107120Sjulian"can only be created when an ACL connection already exists and when it is\n" \
898107120Sjulian"not put in park mode.\n\n" \
899107120Sjulian"\t<connection_handle> - dddd; ACL connection handle\n" \
900107120Sjulian"\t<packet_type>       - xxxx; packet type\n" \
901107120Sjulian"" \
902107120Sjulian"\t\tSCO packets\n" \
903107120Sjulian"\t\t-----------\n" \
904107120Sjulian"\t\t0x0020 HV1\n" \
905107120Sjulian"\t\t0x0040 HV2\n" \
906107120Sjulian"\t\t0x0080 HV3\n",
907107120Sjulian&hci_add_sco_connection
908107120Sjulian},
909107120Sjulian{
910107120Sjulian"change_connection_packet_type <connection_hande> <packet_type>",
911107120Sjulian"The Change_Connection_Packet_Type command is used to change which packet\n" \
912107120Sjulian"types can be used for a connection that is currently established. This\n" \
913107120Sjulian"allows current connections to be dynamically modified to support different\n" \
914107120Sjulian"types of user data. The Packet_Type command parameter specifies which\n" \
915107120Sjulian"packet types the Link Manager can use for the connection. Multiple packet\n" \
916107120Sjulian"types may be specified for the Packet_Type command parameter by bitwise OR\n" \
917107120Sjulian"operation of the different packet types.\n\n" \
918107120Sjulian"\t<connection_handle> - dddd; connection handle\n" \
919107120Sjulian"\t<packet_type>       - xxxx; packet type mask\n" \
920107120Sjulian"" \
921107120Sjulian"\t\tACL packets\n" \
922107120Sjulian"\t\t-----------\n" \
923107120Sjulian"\t\t0x0008 DM1\n" \
924107120Sjulian"\t\t0x0010 DH1\n" \
925107120Sjulian"\t\t0x0400 DM3\n" \
926107120Sjulian"\t\t0x0800 DH3\n" \
927107120Sjulian"\t\t0x4000 DM5\n" \
928107120Sjulian"\t\t0x8000 DH5\n\n" \
929107120Sjulian"" \
930107120Sjulian"\t\tSCO packets\n" \
931107120Sjulian"\t\t-----------\n" \
932107120Sjulian"\t\t0x0020 HV1\n" \
933107120Sjulian"\t\t0x0040 HV2\n" \
934107120Sjulian"\t\t0x0080 HV3\n" \
935107120Sjulian"",
936107120Sjulian&hci_change_connection_packet_type
937107120Sjulian},
938107120Sjulian{
939107120Sjulian"remote_name_request <bdaddr> <ps_rep_mode> <ps_mode> <clock_offset>",
940107120Sjulian"\nThe Remote_Name_Request command is used to obtain the user-friendly\n" \
941107120Sjulian"name of another Bluetooth unit.\n\n" \
942107120Sjulian"\t<bdaddr>       - xx:xx:xx:xx:xx:xx remote unit BD_ADDR\n" \
943107120Sjulian"\t<ps_rep_mode>  - dd; page scan repetition mode [0-2]\n" \
944107120Sjulian"\t<ps_mode>      - dd; page scan mode [0-3]\n" \
945107120Sjulian"\t<clock_offset> - xxxx; clock offset [0 - 0xffff]",
946107120Sjulian&hci_remote_name_request
947107120Sjulian},
948107120Sjulian{
949107120Sjulian"read_remote_supported_features <connection_handle>",
950107120Sjulian"\nThis command requests a list of the supported features for the remote\n" \
951107120Sjulian"unit identified by the connection handle parameter. The connection handle\n" \
952107120Sjulian"must be a connection handle for an ACL connection.\n\n" \
953107120Sjulian"\t<connection_handle> - dddd; connection handle",
954107120Sjulian&hci_read_remote_supported_features
955107120Sjulian},
956107120Sjulian{
957107120Sjulian"read_remote_version_information <connection_handle>",
958107120Sjulian"\nThis command will obtain the values for the version information for the\n" \
959107120Sjulian"remote Bluetooth unit identified by the connection handle parameter. The\n" \
960107120Sjulian"connection handle must be a connection handle for an ACL connection.\n\n" \
961107120Sjulian"\t<conneciton_handle> - dddd; connection handle",
962107120Sjulian&hci_read_remote_version_information
963107120Sjulian},
964107120Sjulian{
965107120Sjulian"read_clock_offset <connection_handle>",
966107120Sjulian"\nThis command allows the Host to read clock offset to remote unit.\n" \
967107120Sjulian"\t<conneciton_handle> - dddd; connection handle",
968107120Sjulian&hci_read_clock_offset
969107120Sjulian},
970107120Sjulian{
971107120SjulianNULL,
972107120Sjulian}};
973107120Sjulian
974