1 /*-
2 * node.c
3 *
4 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5 *
6 * Copyright (c) 2001-2002 Maksim Yevmenkin <[email protected]>
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
hci_read_node_state(int s,int argc,char ** argv)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
hci_node_initialize(int s,int argc,char ** argv)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
hci_read_debug_level(int s,int argc,char ** argv)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
hci_write_debug_level(int s,int argc,char ** argv)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
hci_read_node_buffer_size(int s,int argc,char ** argv)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
hci_read_node_bd_addr(int s,int argc,char ** argv)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
hci_read_node_features(int s,int argc,char ** argv)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
hci_read_node_stat(int s,int argc,char ** argv)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
hci_reset_node_stat(int s,int argc,char ** argv)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
hci_flush_neighbor_cache(int s,int argc,char ** argv)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
hci_dump_adv(uint8_t * data,int length)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
hci_read_neighbor_cache(int s,int argc,char ** argv)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
hci_read_connection_list(int s,int argc,char ** argv)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
hci_read_node_link_policy_settings_mask(int s,int argc,char ** argv)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
hci_write_node_link_policy_settings_mask(int s,int argc,char ** argv)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
hci_read_node_packet_mask(int s,int argc,char ** argv)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
hci_write_node_packet_mask(int s,int argc,char ** argv)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
hci_read_node_role_switch(int s,int argc,char ** argv)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
hci_write_node_role_switch(int s,int argc,char ** argv)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
hci_read_node_list(int s,int argc,char ** argv)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