1107120Sjulian/*
2107120Sjulian * node.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 *
28121054Semax * $Id: node.c,v 1.6 2003/07/22 21:14:02 max Exp $
29107120Sjulian * $FreeBSD$
30107120Sjulian */
31107120Sjulian
32107120Sjulian#include <sys/ioctl.h>
33121054Semax#include <bluetooth.h>
34107120Sjulian#include <errno.h>
35158834Smarkus#include <netgraph/ng_message.h>
36107120Sjulian#include <stdio.h>
37107120Sjulian#include <stdlib.h>
38107120Sjulian#include <string.h>
39158834Smarkus#include <unistd.h>
40107120Sjulian#include "hccontrol.h"
41107120Sjulian
42107120Sjulian/* Send Read_Node_State command to the node */
43107120Sjulianstatic int
44107120Sjulianhci_read_node_state(int s, int argc, char **argv)
45107120Sjulian{
46107120Sjulian	struct ng_btsocket_hci_raw_node_state	r;
47107120Sjulian
48107120Sjulian	memset(&r, 0, sizeof(r));
49107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_STATE, &r, sizeof(r)) < 0)
50107120Sjulian		return (ERROR);
51107120Sjulian
52114879Sjulian	fprintf(stdout, "State: %#x\n", r.state);
53107120Sjulian
54107120Sjulian	return (OK);
55107120Sjulian} /* hci_read_node_state */
56107120Sjulian
57107120Sjulian/* Send Intitialize command to the node */
58107120Sjulianstatic int
59107120Sjulianhci_node_initialize(int s, int argc, char **argv)
60107120Sjulian{
61114879Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_INIT) < 0)
62107120Sjulian		return (ERROR);
63107120Sjulian
64107120Sjulian	return (OK);
65107120Sjulian} /* hci_node_initialize */
66107120Sjulian
67107120Sjulian/* Send Read_Debug_Level command to the node */
68107120Sjulianstatic int
69107120Sjulianhci_read_debug_level(int s, int argc, char **argv)
70107120Sjulian{
71107120Sjulian	struct ng_btsocket_hci_raw_node_debug	r;
72107120Sjulian
73107120Sjulian	memset(&r, 0, sizeof(r));
74107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_DEBUG, &r, sizeof(r)) < 0)
75107120Sjulian		return (ERROR);
76107120Sjulian
77114879Sjulian	fprintf(stdout, "Debug level: %d\n", r.debug);
78107120Sjulian
79107120Sjulian	return (OK);
80107120Sjulian} /* hci_read_debug_level */
81107120Sjulian
82107120Sjulian/* Send Write_Debug_Level command to the node */
83107120Sjulianstatic int
84107120Sjulianhci_write_debug_level(int s, int argc, char **argv)
85107120Sjulian{
86107120Sjulian	struct ng_btsocket_hci_raw_node_debug	r;
87107120Sjulian
88107120Sjulian	memset(&r, 0, sizeof(r));
89107120Sjulian	switch (argc) {
90107120Sjulian	case 1:
91107120Sjulian		r.debug = atoi(argv[0]);
92107120Sjulian		break;
93107120Sjulian
94107120Sjulian	default:
95107120Sjulian		return (USAGE);
96107120Sjulian	}
97107120Sjulian
98107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_SET_DEBUG, &r, sizeof(r)) < 0)
99107120Sjulian		return (ERROR);
100107120Sjulian
101107120Sjulian	return (OK);
102107120Sjulian} /* hci_write_debug_level */
103107120Sjulian
104107120Sjulian/* Send Read_Node_Buffer_Size command to the node */
105107120Sjulianstatic int
106107120Sjulianhci_read_node_buffer_size(int s, int argc, char **argv)
107107120Sjulian{
108107120Sjulian	struct ng_btsocket_hci_raw_node_buffer	r;
109107120Sjulian
110107120Sjulian	memset(&r, 0, sizeof(r));
111107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_BUFFER, &r, sizeof(r)) < 0)
112107120Sjulian		return (ERROR);
113107120Sjulian
114107120Sjulian	fprintf(stdout, "Number of free command buffers: %d\n",
115107120Sjulian		r.buffer.cmd_free);
116107120Sjulian	fprintf(stdout, "Max. ACL packet size: %d\n",
117107120Sjulian		r.buffer.acl_size);
118107120Sjulian	fprintf(stdout, "Numbef of free ACL buffers: %d\n",
119107120Sjulian		r.buffer.acl_free);
120107120Sjulian	fprintf(stdout, "Total number of ACL buffers: %d\n",
121107120Sjulian		r.buffer.acl_pkts);
122107120Sjulian	fprintf(stdout, "Max. SCO packet size: %d\n",
123107120Sjulian		r.buffer.sco_size);
124107120Sjulian	fprintf(stdout, "Numbef of free SCO buffers: %d\n",
125107120Sjulian		r.buffer.sco_free);
126107120Sjulian	fprintf(stdout, "Total number of SCO buffers: %d\n",
127107120Sjulian		r.buffer.sco_pkts);
128107120Sjulian
129107120Sjulian	return (OK);
130107120Sjulian} /* hci_read_node_buffer_size */
131107120Sjulian
132107120Sjulian/* Send Read_Node_BD_ADDR command to the node */
133107120Sjulianstatic int
134107120Sjulianhci_read_node_bd_addr(int s, int argc, char **argv)
135107120Sjulian{
136107120Sjulian	struct ng_btsocket_hci_raw_node_bdaddr	r;
137107120Sjulian
138107120Sjulian	memset(&r, 0, sizeof(r));
139107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_BDADDR, &r, sizeof(r)) < 0)
140107120Sjulian		return (ERROR);
141107120Sjulian
142121054Semax	fprintf(stdout, "BD_ADDR: %s\n", bt_ntoa(&r.bdaddr, NULL));
143107120Sjulian
144107120Sjulian	return (OK);
145107120Sjulian} /* hci_read_node_bd_addr */
146107120Sjulian
147107120Sjulian/* Send Read_Node_Features command to the node */
148107120Sjulianstatic int
149107120Sjulianhci_read_node_features(int s, int argc, char **argv)
150107120Sjulian{
151107120Sjulian	struct ng_btsocket_hci_raw_node_features	r;
152107120Sjulian	int						n;
153107120Sjulian	char						buffer[1024];
154107120Sjulian
155107120Sjulian	memset(&r, 0, sizeof(r));
156107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_FEATURES, &r, sizeof(r)) < 0)
157107120Sjulian		return (ERROR);
158107120Sjulian
159114879Sjulian	fprintf(stdout, "Features: ");
160107120Sjulian	for (n = 0; n < sizeof(r.features)/sizeof(r.features[0]); n++)
161107120Sjulian		fprintf(stdout, "%#02x ", r.features[n]);
162107120Sjulian	fprintf(stdout, "\n%s\n", hci_features2str(r.features,
163107120Sjulian		buffer, sizeof(buffer)));
164107120Sjulian
165107120Sjulian	return (OK);
166107120Sjulian} /* hci_read_node_features */
167107120Sjulian
168107120Sjulian/* Send Read_Node_Stat command to the node */
169107120Sjulianstatic int
170107120Sjulianhci_read_node_stat(int s, int argc, char **argv)
171107120Sjulian{
172107120Sjulian	struct ng_btsocket_hci_raw_node_stat	r;
173107120Sjulian
174107120Sjulian	memset(&r, 0, sizeof(r));
175107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_STAT, &r, sizeof(r)) < 0)
176107120Sjulian		return (ERROR);
177107120Sjulian
178107120Sjulian	fprintf(stdout, "Commands sent: %d\n", r.stat.cmd_sent);
179107120Sjulian	fprintf(stdout, "Events received: %d\n", r.stat.evnt_recv);
180107120Sjulian	fprintf(stdout, "ACL packets received: %d\n", r.stat.acl_recv);
181107120Sjulian	fprintf(stdout, "ACL packets sent: %d\n", r.stat.acl_sent);
182107120Sjulian	fprintf(stdout, "SCO packets received: %d\n", r.stat.sco_recv);
183107120Sjulian	fprintf(stdout, "SCO packets sent: %d\n", r.stat.sco_sent);
184107120Sjulian	fprintf(stdout, "Bytes received: %d\n", r.stat.bytes_recv);
185107120Sjulian	fprintf(stdout, "Bytes sent: %d\n", r.stat.bytes_sent);
186107120Sjulian
187107120Sjulian	return (OK);
188107120Sjulian} /* hci_read_node_stat */
189107120Sjulian
190107120Sjulian/* Send Reset_Node_Stat command to the node */
191107120Sjulianstatic int
192107120Sjulianhci_reset_node_stat(int s, int argc, char **argv)
193107120Sjulian{
194114879Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_RESET_STAT) < 0)
195107120Sjulian		return (ERROR);
196107120Sjulian
197107120Sjulian	return (OK);
198107120Sjulian} /* hci_reset_node_stat */
199107120Sjulian
200107120Sjulian/* Send Flush_Neighbor_Cache command to the node */
201107120Sjulianstatic int
202107120Sjulianhci_flush_neighbor_cache(int s, int argc, char **argv)
203107120Sjulian{
204114879Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_FLUSH_NEIGHBOR_CACHE) < 0)
205107120Sjulian		return (ERROR);
206107120Sjulian
207107120Sjulian	return (OK);
208107120Sjulian} /* hci_flush_neighbor_cache */
209107120Sjulian
210107120Sjulian/* Send Read_Neighbor_Cache command to the node */
211107120Sjulianstatic int
212107120Sjulianhci_read_neighbor_cache(int s, int argc, char **argv)
213107120Sjulian{
214107120Sjulian	struct ng_btsocket_hci_raw_node_neighbor_cache	r;
215107120Sjulian	int						n, error = OK;
216107120Sjulian
217107120Sjulian	memset(&r, 0, sizeof(r));
218107120Sjulian	r.num_entries = NG_HCI_MAX_NEIGHBOR_NUM;
219107120Sjulian	r.entries = calloc(NG_HCI_MAX_NEIGHBOR_NUM,
220107120Sjulian				sizeof(ng_hci_node_neighbor_cache_entry_ep));
221107120Sjulian	if (r.entries == NULL) {
222107120Sjulian		errno = ENOMEM;
223107120Sjulian		return (ERROR);
224107120Sjulian	}
225107120Sjulian
226107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_NEIGHBOR_CACHE, &r,
227107120Sjulian			sizeof(r)) < 0) {
228107120Sjulian		error = ERROR;
229107120Sjulian		goto out;
230107120Sjulian	}
231107120Sjulian
232107120Sjulian	fprintf(stdout,
233107120Sjulian"BD_ADDR           " \
234107120Sjulian"Features                " \
235107120Sjulian"Clock offset " \
236107120Sjulian"Page scan " \
237107120Sjulian"Rep. scan\n");
238107120Sjulian
239107120Sjulian	for (n = 0; n < r.num_entries; n++) {
240107120Sjulian		fprintf(stdout,
241121054Semax"%-17.17s " \
242107120Sjulian"%02x %02x %02x %02x %02x %02x %02x %02x " \
243107120Sjulian"%#12x " \
244107120Sjulian"%#9x " \
245107120Sjulian"%#9x\n",
246121054Semax			hci_bdaddr2str(&r.entries[n].bdaddr),
247107120Sjulian			r.entries[n].features[0], r.entries[n].features[1],
248107120Sjulian			r.entries[n].features[2], r.entries[n].features[3],
249107120Sjulian			r.entries[n].features[4], r.entries[n].features[5],
250107120Sjulian			r.entries[n].features[6], r.entries[n].features[7],
251107120Sjulian			r.entries[n].clock_offset, r.entries[n].page_scan_mode,
252107120Sjulian			r.entries[n].page_scan_rep_mode);
253107120Sjulian	}
254107120Sjulianout:
255107120Sjulian	free(r.entries);
256107120Sjulian
257107120Sjulian	return (error);
258107120Sjulian} /* hci_read_neightbor_cache */
259107120Sjulian
260107120Sjulian/* Send Read_Connection_List command to the node */
261107120Sjulianstatic int
262107120Sjulianhci_read_connection_list(int s, int argc, char **argv)
263107120Sjulian{
264107120Sjulian	struct ng_btsocket_hci_raw_con_list	r;
265107120Sjulian	int					n, error = OK;
266107120Sjulian
267107120Sjulian	memset(&r, 0, sizeof(r));
268107120Sjulian	r.num_connections = NG_HCI_MAX_CON_NUM;
269107120Sjulian	r.connections = calloc(NG_HCI_MAX_CON_NUM, sizeof(ng_hci_node_con_ep));
270107120Sjulian	if (r.connections == NULL) {
271107120Sjulian		errno = ENOMEM;
272107120Sjulian		return (ERROR);
273107120Sjulian	}
274107120Sjulian
275107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_CON_LIST, &r, sizeof(r)) < 0) {
276107120Sjulian		error = ERROR;
277107120Sjulian		goto out;
278107120Sjulian	}
279107120Sjulian
280107120Sjulian	fprintf(stdout,
281107120Sjulian"Remote BD_ADDR    " \
282107120Sjulian"Handle " \
283107120Sjulian"Type " \
284107120Sjulian"Mode " \
285107120Sjulian"Role " \
286107120Sjulian"Encrypt " \
287107120Sjulian"Pending " \
288107120Sjulian"Queue " \
289107120Sjulian"State\n");
290107120Sjulian
291107120Sjulian	for (n = 0; n < r.num_connections; n++) {
292107120Sjulian		fprintf(stdout,
293121054Semax"%-17.17s " \
294107120Sjulian"%6d " \
295107120Sjulian"%4.4s " \
296107120Sjulian"%4d " \
297107120Sjulian"%4.4s " \
298107120Sjulian"%7.7s " \
299107120Sjulian"%7d " \
300107120Sjulian"%5d " \
301107120Sjulian"%s\n",
302121054Semax			hci_bdaddr2str(&r.connections[n].bdaddr),
303107120Sjulian			r.connections[n].con_handle,
304107120Sjulian			(r.connections[n].link_type == NG_HCI_LINK_ACL)?
305107120Sjulian				"ACL" : "SCO",
306107120Sjulian			r.connections[n].mode,
307107120Sjulian			(r.connections[n].role == NG_HCI_ROLE_MASTER)?
308107120Sjulian				"MAST" : "SLAV",
309107120Sjulian			hci_encrypt2str(r.connections[n].encryption_mode, 1),
310107120Sjulian			r.connections[n].pending,
311107120Sjulian			r.connections[n].queue_len,
312107120Sjulian			hci_con_state2str(r.connections[n].state));
313107120Sjulian	}
314107120Sjulianout:
315107120Sjulian	free(r.connections);
316107120Sjulian
317107120Sjulian	return (error);
318107120Sjulian} /* hci_read_connection_list */
319107120Sjulian
320114879Sjulian/* Send Read_Node_Link_Policy_Settings_Mask command to the node */
321107120Sjulianint
322114879Sjulianhci_read_node_link_policy_settings_mask(int s, int argc, char **argv)
323107120Sjulian{
324107120Sjulian	struct ng_btsocket_hci_raw_node_link_policy_mask	r;
325107120Sjulian
326107120Sjulian	memset(&r, 0, sizeof(r));
327107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_LINK_POLICY_MASK, &r, sizeof(r)) < 0)
328107120Sjulian		return (ERROR);
329107120Sjulian
330114879Sjulian	fprintf(stdout, "Link Policy Settings mask: %#04x\n", r.policy_mask);
331107120Sjulian
332107120Sjulian	return (OK);
333114879Sjulian} /* hci_read_node_link_policy_settings_mask */
334107120Sjulian
335114879Sjulian/* Send Write_Node_Link_Policy_Settings_Mask command to the node */
336107120Sjulianint
337114879Sjulianhci_write_node_link_policy_settings_mask(int s, int argc, char **argv)
338107120Sjulian{
339107120Sjulian	struct ng_btsocket_hci_raw_node_link_policy_mask	r;
340107120Sjulian	int							m;
341107120Sjulian
342107120Sjulian	memset(&r, 0, sizeof(r));
343107120Sjulian
344107120Sjulian	switch (argc) {
345107120Sjulian	case 1:
346107120Sjulian		if (sscanf(argv[0], "%x", &m) != 1)
347107120Sjulian			return (USAGE);
348107120Sjulian
349107120Sjulian		r.policy_mask = (m & 0xffff);
350107120Sjulian		break;
351107120Sjulian
352107120Sjulian	default:
353107120Sjulian		return (USAGE);
354107120Sjulian	}
355107120Sjulian
356107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_SET_LINK_POLICY_MASK, &r, sizeof(r)) < 0)
357107120Sjulian		return (ERROR);
358107120Sjulian
359107120Sjulian	return (OK);
360114879Sjulian} /* hci_write_node_link_policy_settings_mask */
361107120Sjulian
362114879Sjulian/* Send Read_Node_Packet_Mask command to the node */
363107120Sjulianint
364114879Sjulianhci_read_node_packet_mask(int s, int argc, char **argv)
365107120Sjulian{
366107120Sjulian	struct ng_btsocket_hci_raw_node_packet_mask	r;
367107120Sjulian
368107120Sjulian	memset(&r, 0, sizeof(r));
369107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_PACKET_MASK, &r, sizeof(r)) < 0)
370107120Sjulian		return (ERROR);
371107120Sjulian
372114879Sjulian	fprintf(stdout, "Packet mask: %#04x\n", r.packet_mask);
373107120Sjulian
374107120Sjulian	return (OK);
375114879Sjulian} /* hci_read_node_packet_mask */
376107120Sjulian
377114879Sjulian/* Send Write_Node_Packet_Mask command to the node */
378107120Sjulianint
379114879Sjulianhci_write_node_packet_mask(int s, int argc, char **argv)
380107120Sjulian{
381107120Sjulian	struct ng_btsocket_hci_raw_node_packet_mask	r;
382107120Sjulian	int						m;
383107120Sjulian
384107120Sjulian	memset(&r, 0, sizeof(r));
385107120Sjulian
386107120Sjulian	switch (argc) {
387107120Sjulian	case 1:
388107120Sjulian		if (sscanf(argv[0], "%x", &m) != 1)
389107120Sjulian			return (USAGE);
390107120Sjulian
391107120Sjulian		r.packet_mask = (m & 0xffff);
392107120Sjulian		break;
393107120Sjulian
394107120Sjulian	default:
395107120Sjulian		return (USAGE);
396107120Sjulian	}
397107120Sjulian
398107120Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_SET_PACKET_MASK, &r, sizeof(r)) < 0)
399107120Sjulian		return (ERROR);
400107120Sjulian
401107120Sjulian	return (OK);
402114879Sjulian} /* hci_write_node_packet_mask */
403107120Sjulian
404114879Sjulian/* Send Read_Node_Role_Switch command to the node */
405114879Sjulianint
406114879Sjulianhci_read_node_role_switch(int s, int argc, char **argv)
407114879Sjulian{
408114879Sjulian	struct ng_btsocket_hci_raw_node_role_switch	r;
409114879Sjulian
410114879Sjulian	memset(&r, 0, sizeof(r));
411114879Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_ROLE_SWITCH, &r, sizeof(r)) < 0)
412114879Sjulian		return (ERROR);
413114879Sjulian
414114879Sjulian	fprintf(stdout, "Role switch: %d\n", r.role_switch);
415114879Sjulian
416114879Sjulian	return (OK);
417114879Sjulian} /* hci_read_node_role_switch */
418114879Sjulian
419114879Sjulian/* Send Write_Node_Role_Switch command to the node */
420114879Sjulianint
421114879Sjulianhci_write_node_role_switch(int s, int argc, char **argv)
422114879Sjulian{
423114879Sjulian	struct ng_btsocket_hci_raw_node_role_switch	r;
424114879Sjulian	int						m;
425114879Sjulian
426114879Sjulian	memset(&r, 0, sizeof(r));
427114879Sjulian
428114879Sjulian	switch (argc) {
429114879Sjulian	case 1:
430114879Sjulian		if (sscanf(argv[0], "%d", &m) != 1)
431114879Sjulian			return (USAGE);
432114879Sjulian
433114879Sjulian		r.role_switch = m? 1 : 0;
434114879Sjulian		break;
435114879Sjulian
436114879Sjulian	default:
437114879Sjulian		return (USAGE);
438114879Sjulian	}
439114879Sjulian
440114879Sjulian	if (ioctl(s, SIOC_HCI_RAW_NODE_SET_ROLE_SWITCH, &r, sizeof(r)) < 0)
441114879Sjulian		return (ERROR);
442114879Sjulian
443114879Sjulian	return (OK);
444114879Sjulian} /* hci_write_node_role_switch */
445114879Sjulian
446158834Smarkus/* Send Read_Node_List command to the node */
447158834Smarkusint
448158834Smarkushci_read_node_list(int s, int argc, char **argv)
449158834Smarkus{
450158834Smarkus	struct ng_btsocket_hci_raw_node_list_names	r;
451158834Smarkus	int						i;
452158834Smarkus
453158834Smarkus	r.num_names = MAX_NODE_NUM;
454158834Smarkus	r.names = (struct nodeinfo*)calloc(MAX_NODE_NUM, sizeof(struct nodeinfo));
455158834Smarkus	if (r.names == NULL)
456158834Smarkus		return (ERROR);
457158834Smarkus
458158834Smarkus	if (ioctl(s, SIOC_HCI_RAW_NODE_LIST_NAMES, &r, sizeof(r)) < 0) {
459158834Smarkus		free(r.names);
460158834Smarkus		return (ERROR);
461158834Smarkus	}
462158834Smarkus
463158834Smarkus	fprintf(stdout, "Name            ID       Num hooks\n");
464158834Smarkus	for (i = 0; i < r.num_names; ++i)
465158834Smarkus		fprintf(stdout, "%-15s %08x %9d\n",
466158834Smarkus		    r.names[i].name, r.names[i].id, r.names[i].hooks);
467158834Smarkus
468158834Smarkus	free(r.names);
469158834Smarkus
470158834Smarkus	return (OK);
471158834Smarkus} /* hci_read_node_list */
472158834Smarkus
473107120Sjulianstruct hci_command	node_commands[] = {
474107120Sjulian{
475107120Sjulian"read_node_state",
476114879Sjulian"Get the HCI node state",
477107120Sjulian&hci_read_node_state
478107120Sjulian},
479107120Sjulian{
480107120Sjulian"initialize",
481114879Sjulian"Initialize the HCI node",
482107120Sjulian&hci_node_initialize
483107120Sjulian},
484107120Sjulian{
485107120Sjulian"read_debug_level",
486114879Sjulian"Read the HCI node debug level",
487107120Sjulian&hci_read_debug_level
488107120Sjulian},
489107120Sjulian{
490107120Sjulian"write_debug_level <level>",
491114879Sjulian"Write the HCI node debug level",
492107120Sjulian&hci_write_debug_level
493107120Sjulian},
494107120Sjulian{
495107120Sjulian"read_node_buffer_size",
496114879Sjulian"Read the HCI node buffer information. This will return current state of the\n"\
497114879Sjulian"HCI buffer for the HCI node",
498107120Sjulian&hci_read_node_buffer_size
499107120Sjulian},
500107120Sjulian{
501107120Sjulian"read_node_bd_addr",
502114879Sjulian"Read the HCI node BD_ADDR. Returns device BD_ADDR as cached by the HCI node",
503107120Sjulian&hci_read_node_bd_addr
504107120Sjulian},
505107120Sjulian{
506107120Sjulian"read_node_features",
507114879Sjulian"Read the HCI node features. This will return list of supported features as\n" \
508114879Sjulian"cached by the HCI node",
509107120Sjulian&hci_read_node_features
510107120Sjulian},
511107120Sjulian{
512107120Sjulian"read_node_stat",
513114879Sjulian"Read packets and bytes counters for the HCI node",
514107120Sjulian&hci_read_node_stat
515107120Sjulian},
516107120Sjulian{
517107120Sjulian"reset_node_stat",
518114879Sjulian"Reset packets and bytes counters for the HCI node",
519107120Sjulian&hci_reset_node_stat
520107120Sjulian},
521107120Sjulian{
522107120Sjulian"flush_neighbor_cache",
523114879Sjulian"Flush content of the HCI node neighbor cache",
524107120Sjulian&hci_flush_neighbor_cache
525107120Sjulian},
526107120Sjulian{
527107120Sjulian"read_neighbor_cache",
528114879Sjulian"Read content of the HCI node neighbor cache",
529107120Sjulian&hci_read_neighbor_cache
530107120Sjulian},
531107120Sjulian{
532107120Sjulian"read_connection_list",
533114879Sjulian"Read the baseband connection descriptors list for the HCI node",
534107120Sjulian&hci_read_connection_list
535107120Sjulian},
536107120Sjulian{
537107120Sjulian"read_node_link_policy_settings_mask",
538114879Sjulian"Read the value of the Link Policy Settinngs mask for the HCI node",
539114879Sjulian&hci_read_node_link_policy_settings_mask
540107120Sjulian},
541107120Sjulian{
542107120Sjulian"write_node_link_policy_settings_mask <policy_mask>",
543114879Sjulian"Write the value of the Link Policy Settings mask for the HCI node. By default\n" \
544114879Sjulian"all supported Link Policy modes (as reported by the local device features) are\n"\
545114879Sjulian"enabled. The particular Link Policy mode is enabled if local device supports\n"\
546114879Sjulian"it and correspinding bit in the mask was set\n\n" \
547114879Sjulian"\t<policy_mask> - xxxx; Link Policy mask\n" \
548114879Sjulian"\t\t0x0000 - Disable All LM Modes\n" \
549114879Sjulian"\t\t0x0001 - Enable Master Slave Switch\n" \
550114879Sjulian"\t\t0x0002 - Enable Hold Mode\n" \
551114879Sjulian"\t\t0x0004 - Enable Sniff Mode\n" \
552114879Sjulian"\t\t0x0008 - Enable Park Mode\n",
553114879Sjulian&hci_write_node_link_policy_settings_mask
554107120Sjulian},
555107120Sjulian{
556107120Sjulian"read_node_packet_mask",
557114879Sjulian"Read the value of the Packet mask for the HCI node",
558114879Sjulian&hci_read_node_packet_mask
559107120Sjulian},
560107120Sjulian{
561107120Sjulian"write_node_packet_mask <packet_mask>",
562114879Sjulian"Write the value of the Packet mask for the HCI node. By default all supported\n" \
563114879Sjulian"packet types (as reported by the local device features) are enabled. The\n" \
564114879Sjulian"particular packet type is enabled if local device supports it and corresponding\n" \
565114879Sjulian"bit in the mask was set\n\n" \
566114879Sjulian"\t<packet_mask> - xxxx; packet type mask\n" \
567114879Sjulian"" \
568114879Sjulian"\t\tACL packets\n" \
569114879Sjulian"\t\t-----------\n" \
570114879Sjulian"\t\t0x0008 DM1\n" \
571114879Sjulian"\t\t0x0010 DH1\n" \
572114879Sjulian"\t\t0x0400 DM3\n" \
573114879Sjulian"\t\t0x0800 DH3\n" \
574114879Sjulian"\t\t0x4000 DM5\n" \
575114879Sjulian"\t\t0x8000 DH5\n" \
576114879Sjulian"\n" \
577114879Sjulian"\t\tSCO packets\n" \
578114879Sjulian"\t\t-----------\n" \
579114879Sjulian"\t\t0x0020 HV1\n" \
580114879Sjulian"\t\t0x0040 HV2\n" \
581114879Sjulian"\t\t0x0080 HV3\n",
582114879Sjulian&hci_write_node_packet_mask
583107120Sjulian},
584107120Sjulian{
585114879Sjulian"read_node_role_switch",
586114879Sjulian"Read the value of the Role Switch parameter for the HCI node",
587114879Sjulian&hci_read_node_role_switch
588114879Sjulian},
589114879Sjulian{
590114879Sjulian"write_node_role_switch {0|1}",
591114879Sjulian"Write the value of the Role Switch parameter for the HCI node. By default,\n" \
592114879Sjulian"if Role Switch is supported, local device will try to perform Role Switch\n" \
593114879Sjulian"and become Master on incoming connection. Some devices do not support Role\n" \
594114879Sjulian"Switch and thus incomming connections from such devices will fail. Setting\n" \
595114879Sjulian"this parameter to zero will prevent Role Switch and thus accepting device\n" \
596114879Sjulian"will remain Slave",
597114879Sjulian&hci_write_node_role_switch
598114879Sjulian},
599114879Sjulian{
600158834Smarkus"read_node_list",
601158834Smarkus"Get a list of HCI nodes, their Netgraph IDs and connected hooks.",
602158834Smarkus&hci_read_node_list
603158834Smarkus},
604158834Smarkus{
605107120SjulianNULL,
606107120Sjulian}};
607107120Sjulian
608