xref: /freebsd/usr.sbin/bluetooth/hccontrol/node.c (revision c697fb7f)
1 /*-
2  * node.c
3  *
4  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5  *
6  * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $Id: node.c,v 1.6 2003/07/22 21:14:02 max Exp $
31  * $FreeBSD$
32  */
33 
34 #include <sys/ioctl.h>
35 #define L2CAP_SOCKET_CHECKED
36 #include <bluetooth.h>
37 #include <errno.h>
38 #include <netgraph/ng_message.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include "hccontrol.h"
44 
45 /* Send Read_Node_State command to the node */
46 static int
47 hci_read_node_state(int s, int argc, char **argv)
48 {
49 	struct ng_btsocket_hci_raw_node_state	r;
50 
51 	memset(&r, 0, sizeof(r));
52 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_STATE, &r, sizeof(r)) < 0)
53 		return (ERROR);
54 
55 	fprintf(stdout, "State: %#x\n", r.state);
56 
57 	return (OK);
58 } /* hci_read_node_state */
59 
60 /* Send Intitialize command to the node */
61 static int
62 hci_node_initialize(int s, int argc, char **argv)
63 {
64 	if (ioctl(s, SIOC_HCI_RAW_NODE_INIT) < 0)
65 		return (ERROR);
66 
67 	return (OK);
68 } /* hci_node_initialize */
69 
70 /* Send Read_Debug_Level command to the node */
71 static int
72 hci_read_debug_level(int s, int argc, char **argv)
73 {
74 	struct ng_btsocket_hci_raw_node_debug	r;
75 
76 	memset(&r, 0, sizeof(r));
77 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_DEBUG, &r, sizeof(r)) < 0)
78 		return (ERROR);
79 
80 	fprintf(stdout, "Debug level: %d\n", r.debug);
81 
82 	return (OK);
83 } /* hci_read_debug_level */
84 
85 /* Send Write_Debug_Level command to the node */
86 static int
87 hci_write_debug_level(int s, int argc, char **argv)
88 {
89 	struct ng_btsocket_hci_raw_node_debug	r;
90 
91 	memset(&r, 0, sizeof(r));
92 	switch (argc) {
93 	case 1:
94 		r.debug = atoi(argv[0]);
95 		break;
96 
97 	default:
98 		return (USAGE);
99 	}
100 
101 	if (ioctl(s, SIOC_HCI_RAW_NODE_SET_DEBUG, &r, sizeof(r)) < 0)
102 		return (ERROR);
103 
104 	return (OK);
105 } /* hci_write_debug_level */
106 
107 /* Send Read_Node_Buffer_Size command to the node */
108 static int
109 hci_read_node_buffer_size(int s, int argc, char **argv)
110 {
111 	struct ng_btsocket_hci_raw_node_buffer	r;
112 
113 	memset(&r, 0, sizeof(r));
114 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_BUFFER, &r, sizeof(r)) < 0)
115 		return (ERROR);
116 
117 	fprintf(stdout, "Number of free command buffers: %d\n",
118 		r.buffer.cmd_free);
119 	fprintf(stdout, "Max. ACL packet size: %d\n",
120 		r.buffer.acl_size);
121 	fprintf(stdout, "Numbef of free ACL buffers: %d\n",
122 		r.buffer.acl_free);
123 	fprintf(stdout, "Total number of ACL buffers: %d\n",
124 		r.buffer.acl_pkts);
125 	fprintf(stdout, "Max. SCO packet size: %d\n",
126 		r.buffer.sco_size);
127 	fprintf(stdout, "Numbef of free SCO buffers: %d\n",
128 		r.buffer.sco_free);
129 	fprintf(stdout, "Total number of SCO buffers: %d\n",
130 		r.buffer.sco_pkts);
131 
132 	return (OK);
133 } /* hci_read_node_buffer_size */
134 
135 /* Send Read_Node_BD_ADDR command to the node */
136 static int
137 hci_read_node_bd_addr(int s, int argc, char **argv)
138 {
139 	struct ng_btsocket_hci_raw_node_bdaddr	r;
140 
141 	memset(&r, 0, sizeof(r));
142 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_BDADDR, &r, sizeof(r)) < 0)
143 		return (ERROR);
144 
145 	fprintf(stdout, "BD_ADDR: %s\n", bt_ntoa(&r.bdaddr, NULL));
146 
147 	return (OK);
148 } /* hci_read_node_bd_addr */
149 
150 /* Send Read_Node_Features command to the node */
151 static int
152 hci_read_node_features(int s, int argc, char **argv)
153 {
154 	struct ng_btsocket_hci_raw_node_features	r;
155 	int						n;
156 	char						buffer[1024];
157 
158 	memset(&r, 0, sizeof(r));
159 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_FEATURES, &r, sizeof(r)) < 0)
160 		return (ERROR);
161 
162 	fprintf(stdout, "Features: ");
163 	for (n = 0; n < sizeof(r.features)/sizeof(r.features[0]); n++)
164 		fprintf(stdout, "%#02x ", r.features[n]);
165 	fprintf(stdout, "\n%s\n", hci_features2str(r.features,
166 		buffer, sizeof(buffer)));
167 
168 	return (OK);
169 } /* hci_read_node_features */
170 
171 /* Send Read_Node_Stat command to the node */
172 static int
173 hci_read_node_stat(int s, int argc, char **argv)
174 {
175 	struct ng_btsocket_hci_raw_node_stat	r;
176 
177 	memset(&r, 0, sizeof(r));
178 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_STAT, &r, sizeof(r)) < 0)
179 		return (ERROR);
180 
181 	fprintf(stdout, "Commands sent: %d\n", r.stat.cmd_sent);
182 	fprintf(stdout, "Events received: %d\n", r.stat.evnt_recv);
183 	fprintf(stdout, "ACL packets received: %d\n", r.stat.acl_recv);
184 	fprintf(stdout, "ACL packets sent: %d\n", r.stat.acl_sent);
185 	fprintf(stdout, "SCO packets received: %d\n", r.stat.sco_recv);
186 	fprintf(stdout, "SCO packets sent: %d\n", r.stat.sco_sent);
187 	fprintf(stdout, "Bytes received: %d\n", r.stat.bytes_recv);
188 	fprintf(stdout, "Bytes sent: %d\n", r.stat.bytes_sent);
189 
190 	return (OK);
191 } /* hci_read_node_stat */
192 
193 /* Send Reset_Node_Stat command to the node */
194 static int
195 hci_reset_node_stat(int s, int argc, char **argv)
196 {
197 	if (ioctl(s, SIOC_HCI_RAW_NODE_RESET_STAT) < 0)
198 		return (ERROR);
199 
200 	return (OK);
201 } /* hci_reset_node_stat */
202 
203 /* Send Flush_Neighbor_Cache command to the node */
204 static int
205 hci_flush_neighbor_cache(int s, int argc, char **argv)
206 {
207 	if (ioctl(s, SIOC_HCI_RAW_NODE_FLUSH_NEIGHBOR_CACHE) < 0)
208 		return (ERROR);
209 
210 	return (OK);
211 } /* hci_flush_neighbor_cache */
212 
213 #define MIN(a,b) (((a)>(b)) ? (b) :(a) )
214 
215 static int  hci_dump_adv(uint8_t *data, int length)
216 {
217 	int elemlen;
218 	int type;
219 	int i;
220 
221 	while(length>0){
222 		elemlen = *data;
223 		data++;
224 		length --;
225 		elemlen--;
226 		if(length<=0)
227 			break;
228 		type = *data;
229 		data++;
230 		length --;
231 		elemlen--;
232 		if(length<=0)
233 			break;
234 		switch(type){
235 		case 0x1:
236 			printf("NDflag:%x\n", *data);
237 			break;
238 		case 0x9:
239 			printf("LocalName:");
240 			for(i = 0; i < MIN(length,elemlen); i++){
241 				putchar(data[i]);
242 			}
243 			printf("\n");
244 			break;
245 		default:
246 			printf("Type%d:", type);
247 			for(i=0; i < MIN(length,elemlen); i++){
248 				printf("%02x ",data[i]);
249 			}
250 			printf("\n");
251 			break;
252 		}
253 		data += elemlen;
254 		length -= elemlen;
255 	}
256 	return 0;
257 }
258 #undef MIN
259 /* Send Read_Neighbor_Cache command to the node */
260 static int
261 hci_read_neighbor_cache(int s, int argc, char **argv)
262 {
263 	struct ng_btsocket_hci_raw_node_neighbor_cache	r;
264 	int						n, error = OK;
265 	const char  *addrtype2str[] = {"B", "P", "R", "E"};
266 
267 	memset(&r, 0, sizeof(r));
268 	r.num_entries = NG_HCI_MAX_NEIGHBOR_NUM;
269 	r.entries = calloc(NG_HCI_MAX_NEIGHBOR_NUM,
270 				sizeof(ng_hci_node_neighbor_cache_entry_ep));
271 	if (r.entries == NULL) {
272 		errno = ENOMEM;
273 		return (ERROR);
274 	}
275 
276 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_NEIGHBOR_CACHE, &r,
277 			sizeof(r)) < 0) {
278 		error = ERROR;
279 		goto out;
280 	}
281 
282 	fprintf(stdout,
283 "T " \
284 "BD_ADDR           " \
285 "Features                " \
286 "Clock offset " \
287 "Page scan " \
288 "Rep. scan\n");
289 
290 	for (n = 0; n < r.num_entries; n++) {
291 	        uint8_t addrtype = r.entries[n].addrtype;
292 		if(addrtype >= sizeof(addrtype2str)/sizeof(addrtype2str[0]))
293 			addrtype = sizeof(addrtype2str)/sizeof(addrtype2str[0]) - 1;
294 		fprintf(stdout,
295 "%1s %-17.17s " \
296 "%02x %02x %02x %02x %02x %02x %02x %02x " \
297 "%#12x " \
298 "%#9x " \
299 "%#9x\n",
300 			addrtype2str[addrtype],
301 			hci_bdaddr2str(&r.entries[n].bdaddr),
302 			r.entries[n].features[0], r.entries[n].features[1],
303 			r.entries[n].features[2], r.entries[n].features[3],
304 			r.entries[n].features[4], r.entries[n].features[5],
305 			r.entries[n].features[6], r.entries[n].features[7],
306 			r.entries[n].clock_offset, r.entries[n].page_scan_mode,
307 			r.entries[n].page_scan_rep_mode);
308 		hci_dump_adv(r.entries[n].extinq_data,
309 			     r.entries[n].extinq_size);
310 		fprintf(stdout,"\n");
311 	}
312 out:
313 	free(r.entries);
314 
315 	return (error);
316 } /* hci_read_neightbor_cache */
317 
318 /* Send Read_Connection_List command to the node */
319 static int
320 hci_read_connection_list(int s, int argc, char **argv)
321 {
322 	struct ng_btsocket_hci_raw_con_list	r;
323 	int					n, error = OK;
324 
325 	memset(&r, 0, sizeof(r));
326 	r.num_connections = NG_HCI_MAX_CON_NUM;
327 	r.connections = calloc(NG_HCI_MAX_CON_NUM, sizeof(ng_hci_node_con_ep));
328 	if (r.connections == NULL) {
329 		errno = ENOMEM;
330 		return (ERROR);
331 	}
332 
333 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_CON_LIST, &r, sizeof(r)) < 0) {
334 		error = ERROR;
335 		goto out;
336 	}
337 
338 	fprintf(stdout,
339 "Remote BD_ADDR    " \
340 "Handle " \
341 "Type " \
342 "Mode " \
343 "Role " \
344 "Encrypt " \
345 "Pending " \
346 "Queue " \
347 "State\n");
348 
349 	for (n = 0; n < r.num_connections; n++) {
350 		fprintf(stdout,
351 "%-17.17s " \
352 "%6d " \
353 "%4.4s " \
354 "%4d " \
355 "%4.4s " \
356 "%7.7s " \
357 "%7d " \
358 "%5d " \
359 "%s\n",
360 			hci_bdaddr2str(&r.connections[n].bdaddr),
361 			r.connections[n].con_handle,
362 			(r.connections[n].link_type == NG_HCI_LINK_ACL)?
363 				"ACL" : "SCO",
364 			r.connections[n].mode,
365 			(r.connections[n].role == NG_HCI_ROLE_MASTER)?
366 				"MAST" : "SLAV",
367 			hci_encrypt2str(r.connections[n].encryption_mode, 1),
368 			r.connections[n].pending,
369 			r.connections[n].queue_len,
370 			hci_con_state2str(r.connections[n].state));
371 	}
372 out:
373 	free(r.connections);
374 
375 	return (error);
376 } /* hci_read_connection_list */
377 
378 /* Send Read_Node_Link_Policy_Settings_Mask command to the node */
379 int
380 hci_read_node_link_policy_settings_mask(int s, int argc, char **argv)
381 {
382 	struct ng_btsocket_hci_raw_node_link_policy_mask	r;
383 
384 	memset(&r, 0, sizeof(r));
385 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_LINK_POLICY_MASK, &r, sizeof(r)) < 0)
386 		return (ERROR);
387 
388 	fprintf(stdout, "Link Policy Settings mask: %#04x\n", r.policy_mask);
389 
390 	return (OK);
391 } /* hci_read_node_link_policy_settings_mask */
392 
393 /* Send Write_Node_Link_Policy_Settings_Mask command to the node */
394 int
395 hci_write_node_link_policy_settings_mask(int s, int argc, char **argv)
396 {
397 	struct ng_btsocket_hci_raw_node_link_policy_mask	r;
398 	int							m;
399 
400 	memset(&r, 0, sizeof(r));
401 
402 	switch (argc) {
403 	case 1:
404 		if (sscanf(argv[0], "%x", &m) != 1)
405 			return (USAGE);
406 
407 		r.policy_mask = (m & 0xffff);
408 		break;
409 
410 	default:
411 		return (USAGE);
412 	}
413 
414 	if (ioctl(s, SIOC_HCI_RAW_NODE_SET_LINK_POLICY_MASK, &r, sizeof(r)) < 0)
415 		return (ERROR);
416 
417 	return (OK);
418 } /* hci_write_node_link_policy_settings_mask */
419 
420 /* Send Read_Node_Packet_Mask command to the node */
421 int
422 hci_read_node_packet_mask(int s, int argc, char **argv)
423 {
424 	struct ng_btsocket_hci_raw_node_packet_mask	r;
425 
426 	memset(&r, 0, sizeof(r));
427 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_PACKET_MASK, &r, sizeof(r)) < 0)
428 		return (ERROR);
429 
430 	fprintf(stdout, "Packet mask: %#04x\n", r.packet_mask);
431 
432 	return (OK);
433 } /* hci_read_node_packet_mask */
434 
435 /* Send Write_Node_Packet_Mask command to the node */
436 int
437 hci_write_node_packet_mask(int s, int argc, char **argv)
438 {
439 	struct ng_btsocket_hci_raw_node_packet_mask	r;
440 	int						m;
441 
442 	memset(&r, 0, sizeof(r));
443 
444 	switch (argc) {
445 	case 1:
446 		if (sscanf(argv[0], "%x", &m) != 1)
447 			return (USAGE);
448 
449 		r.packet_mask = (m & 0xffff);
450 		break;
451 
452 	default:
453 		return (USAGE);
454 	}
455 
456 	if (ioctl(s, SIOC_HCI_RAW_NODE_SET_PACKET_MASK, &r, sizeof(r)) < 0)
457 		return (ERROR);
458 
459 	return (OK);
460 } /* hci_write_node_packet_mask */
461 
462 /* Send Read_Node_Role_Switch command to the node */
463 int
464 hci_read_node_role_switch(int s, int argc, char **argv)
465 {
466 	struct ng_btsocket_hci_raw_node_role_switch	r;
467 
468 	memset(&r, 0, sizeof(r));
469 	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_ROLE_SWITCH, &r, sizeof(r)) < 0)
470 		return (ERROR);
471 
472 	fprintf(stdout, "Role switch: %d\n", r.role_switch);
473 
474 	return (OK);
475 } /* hci_read_node_role_switch */
476 
477 /* Send Write_Node_Role_Switch command to the node */
478 int
479 hci_write_node_role_switch(int s, int argc, char **argv)
480 {
481 	struct ng_btsocket_hci_raw_node_role_switch	r;
482 	int						m;
483 
484 	memset(&r, 0, sizeof(r));
485 
486 	switch (argc) {
487 	case 1:
488 		if (sscanf(argv[0], "%d", &m) != 1)
489 			return (USAGE);
490 
491 		r.role_switch = m? 1 : 0;
492 		break;
493 
494 	default:
495 		return (USAGE);
496 	}
497 
498 	if (ioctl(s, SIOC_HCI_RAW_NODE_SET_ROLE_SWITCH, &r, sizeof(r)) < 0)
499 		return (ERROR);
500 
501 	return (OK);
502 } /* hci_write_node_role_switch */
503 
504 /* Send Read_Node_List command to the node */
505 int
506 hci_read_node_list(int s, int argc, char **argv)
507 {
508 	struct ng_btsocket_hci_raw_node_list_names	r;
509 	int						i;
510 
511 	r.num_names = MAX_NODE_NUM;
512 	r.names = (struct nodeinfo*)calloc(MAX_NODE_NUM, sizeof(struct nodeinfo));
513 	if (r.names == NULL)
514 		return (ERROR);
515 
516 	if (ioctl(s, SIOC_HCI_RAW_NODE_LIST_NAMES, &r, sizeof(r)) < 0) {
517 		free(r.names);
518 		return (ERROR);
519 	}
520 
521 	fprintf(stdout, "Name            ID       Num hooks\n");
522 	for (i = 0; i < r.num_names; ++i)
523 		fprintf(stdout, "%-15s %08x %9d\n",
524 		    r.names[i].name, r.names[i].id, r.names[i].hooks);
525 
526 	free(r.names);
527 
528 	return (OK);
529 } /* hci_read_node_list */
530 
531 struct hci_command	node_commands[] = {
532 {
533 "read_node_state",
534 "Get the HCI node state",
535 &hci_read_node_state
536 },
537 {
538 "initialize",
539 "Initialize the HCI node",
540 &hci_node_initialize
541 },
542 {
543 "read_debug_level",
544 "Read the HCI node debug level",
545 &hci_read_debug_level
546 },
547 {
548 "write_debug_level <level>",
549 "Write the HCI node debug level",
550 &hci_write_debug_level
551 },
552 {
553 "read_node_buffer_size",
554 "Read the HCI node buffer information. This will return current state of the\n"\
555 "HCI buffer for the HCI node",
556 &hci_read_node_buffer_size
557 },
558 {
559 "read_node_bd_addr",
560 "Read the HCI node BD_ADDR. Returns device BD_ADDR as cached by the HCI node",
561 &hci_read_node_bd_addr
562 },
563 {
564 "read_node_features",
565 "Read the HCI node features. This will return list of supported features as\n" \
566 "cached by the HCI node",
567 &hci_read_node_features
568 },
569 {
570 "read_node_stat",
571 "Read packets and bytes counters for the HCI node",
572 &hci_read_node_stat
573 },
574 {
575 "reset_node_stat",
576 "Reset packets and bytes counters for the HCI node",
577 &hci_reset_node_stat
578 },
579 {
580 "flush_neighbor_cache",
581 "Flush content of the HCI node neighbor cache",
582 &hci_flush_neighbor_cache
583 },
584 {
585 "read_neighbor_cache",
586 "Read content of the HCI node neighbor cache",
587 &hci_read_neighbor_cache
588 },
589 {
590 "read_connection_list",
591 "Read the baseband connection descriptors list for the HCI node",
592 &hci_read_connection_list
593 },
594 {
595 "read_node_link_policy_settings_mask",
596 "Read the value of the Link Policy Settinngs mask for the HCI node",
597 &hci_read_node_link_policy_settings_mask
598 },
599 {
600 "write_node_link_policy_settings_mask <policy_mask>",
601 "Write the value of the Link Policy Settings mask for the HCI node. By default\n" \
602 "all supported Link Policy modes (as reported by the local device features) are\n"\
603 "enabled. The particular Link Policy mode is enabled if local device supports\n"\
604 "it and correspinding bit in the mask was set\n\n" \
605 "\t<policy_mask> - xxxx; Link Policy mask\n" \
606 "\t\t0x0000 - Disable All LM Modes\n" \
607 "\t\t0x0001 - Enable Master Slave Switch\n" \
608 "\t\t0x0002 - Enable Hold Mode\n" \
609 "\t\t0x0004 - Enable Sniff Mode\n" \
610 "\t\t0x0008 - Enable Park Mode\n",
611 &hci_write_node_link_policy_settings_mask
612 },
613 {
614 "read_node_packet_mask",
615 "Read the value of the Packet mask for the HCI node",
616 &hci_read_node_packet_mask
617 },
618 {
619 "write_node_packet_mask <packet_mask>",
620 "Write the value of the Packet mask for the HCI node. By default all supported\n" \
621 "packet types (as reported by the local device features) are enabled. The\n" \
622 "particular packet type is enabled if local device supports it and corresponding\n" \
623 "bit in the mask was set\n\n" \
624 "\t<packet_mask> - xxxx; packet type mask\n" \
625 "" \
626 "\t\tACL packets\n" \
627 "\t\t-----------\n" \
628 "\t\t0x0008 DM1\n" \
629 "\t\t0x0010 DH1\n" \
630 "\t\t0x0400 DM3\n" \
631 "\t\t0x0800 DH3\n" \
632 "\t\t0x4000 DM5\n" \
633 "\t\t0x8000 DH5\n" \
634 "\n" \
635 "\t\tSCO packets\n" \
636 "\t\t-----------\n" \
637 "\t\t0x0020 HV1\n" \
638 "\t\t0x0040 HV2\n" \
639 "\t\t0x0080 HV3\n",
640 &hci_write_node_packet_mask
641 },
642 {
643 "read_node_role_switch",
644 "Read the value of the Role Switch parameter for the HCI node",
645 &hci_read_node_role_switch
646 },
647 {
648 "write_node_role_switch {0|1}",
649 "Write the value of the Role Switch parameter for the HCI node. By default,\n" \
650 "if Role Switch is supported, local device will try to perform Role Switch\n" \
651 "and become Master on incoming connection. Some devices do not support Role\n" \
652 "Switch and thus incoming connections from such devices will fail. Setting\n" \
653 "this parameter to zero will prevent Role Switch and thus accepting device\n" \
654 "will remain Slave",
655 &hci_write_node_role_switch
656 },
657 {
658 "read_node_list",
659 "Get a list of HCI nodes, their Netgraph IDs and connected hooks.",
660 &hci_read_node_list
661 },
662 {
663 NULL,
664 }};
665 
666