4 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $Id: node.c,v 1.6 2003/07/22 21:14:02 max Exp $
32 #include <sys/ioctl.h>
33 #include <bluetooth.h>
35 #include <netgraph/ng_message.h>
40 #include "hccontrol.h"
42 /* Send Read_Node_State command to the node */
44 hci_read_node_state(int s, int argc, char **argv)
46 struct ng_btsocket_hci_raw_node_state r;
48 memset(&r, 0, sizeof(r));
49 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_STATE, &r, sizeof(r)) < 0)
52 fprintf(stdout, "State: %#x\n", r.state);
55 } /* hci_read_node_state */
57 /* Send Intitialize command to the node */
59 hci_node_initialize(int s, int argc, char **argv)
61 if (ioctl(s, SIOC_HCI_RAW_NODE_INIT) < 0)
65 } /* hci_node_initialize */
67 /* Send Read_Debug_Level command to the node */
69 hci_read_debug_level(int s, int argc, char **argv)
71 struct ng_btsocket_hci_raw_node_debug r;
73 memset(&r, 0, sizeof(r));
74 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_DEBUG, &r, sizeof(r)) < 0)
77 fprintf(stdout, "Debug level: %d\n", r.debug);
80 } /* hci_read_debug_level */
82 /* Send Write_Debug_Level command to the node */
84 hci_write_debug_level(int s, int argc, char **argv)
86 struct ng_btsocket_hci_raw_node_debug r;
88 memset(&r, 0, sizeof(r));
91 r.debug = atoi(argv[0]);
98 if (ioctl(s, SIOC_HCI_RAW_NODE_SET_DEBUG, &r, sizeof(r)) < 0)
102 } /* hci_write_debug_level */
104 /* Send Read_Node_Buffer_Size command to the node */
106 hci_read_node_buffer_size(int s, int argc, char **argv)
108 struct ng_btsocket_hci_raw_node_buffer r;
110 memset(&r, 0, sizeof(r));
111 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_BUFFER, &r, sizeof(r)) < 0)
114 fprintf(stdout, "Number of free command buffers: %d\n",
116 fprintf(stdout, "Max. ACL packet size: %d\n",
118 fprintf(stdout, "Numbef of free ACL buffers: %d\n",
120 fprintf(stdout, "Total number of ACL buffers: %d\n",
122 fprintf(stdout, "Max. SCO packet size: %d\n",
124 fprintf(stdout, "Numbef of free SCO buffers: %d\n",
126 fprintf(stdout, "Total number of SCO buffers: %d\n",
130 } /* hci_read_node_buffer_size */
132 /* Send Read_Node_BD_ADDR command to the node */
134 hci_read_node_bd_addr(int s, int argc, char **argv)
136 struct ng_btsocket_hci_raw_node_bdaddr r;
138 memset(&r, 0, sizeof(r));
139 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_BDADDR, &r, sizeof(r)) < 0)
142 fprintf(stdout, "BD_ADDR: %s\n", bt_ntoa(&r.bdaddr, NULL));
145 } /* hci_read_node_bd_addr */
147 /* Send Read_Node_Features command to the node */
149 hci_read_node_features(int s, int argc, char **argv)
151 struct ng_btsocket_hci_raw_node_features r;
155 memset(&r, 0, sizeof(r));
156 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_FEATURES, &r, sizeof(r)) < 0)
159 fprintf(stdout, "Features: ");
160 for (n = 0; n < sizeof(r.features)/sizeof(r.features[0]); n++)
161 fprintf(stdout, "%#02x ", r.features[n]);
162 fprintf(stdout, "\n%s\n", hci_features2str(r.features,
163 buffer, sizeof(buffer)));
166 } /* hci_read_node_features */
168 /* Send Read_Node_Stat command to the node */
170 hci_read_node_stat(int s, int argc, char **argv)
172 struct ng_btsocket_hci_raw_node_stat r;
174 memset(&r, 0, sizeof(r));
175 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_STAT, &r, sizeof(r)) < 0)
178 fprintf(stdout, "Commands sent: %d\n", r.stat.cmd_sent);
179 fprintf(stdout, "Events received: %d\n", r.stat.evnt_recv);
180 fprintf(stdout, "ACL packets received: %d\n", r.stat.acl_recv);
181 fprintf(stdout, "ACL packets sent: %d\n", r.stat.acl_sent);
182 fprintf(stdout, "SCO packets received: %d\n", r.stat.sco_recv);
183 fprintf(stdout, "SCO packets sent: %d\n", r.stat.sco_sent);
184 fprintf(stdout, "Bytes received: %d\n", r.stat.bytes_recv);
185 fprintf(stdout, "Bytes sent: %d\n", r.stat.bytes_sent);
188 } /* hci_read_node_stat */
190 /* Send Reset_Node_Stat command to the node */
192 hci_reset_node_stat(int s, int argc, char **argv)
194 if (ioctl(s, SIOC_HCI_RAW_NODE_RESET_STAT) < 0)
198 } /* hci_reset_node_stat */
200 /* Send Flush_Neighbor_Cache command to the node */
202 hci_flush_neighbor_cache(int s, int argc, char **argv)
204 if (ioctl(s, SIOC_HCI_RAW_NODE_FLUSH_NEIGHBOR_CACHE) < 0)
208 } /* hci_flush_neighbor_cache */
210 /* Send Read_Neighbor_Cache command to the node */
212 hci_read_neighbor_cache(int s, int argc, char **argv)
214 struct ng_btsocket_hci_raw_node_neighbor_cache r;
217 memset(&r, 0, sizeof(r));
218 r.num_entries = NG_HCI_MAX_NEIGHBOR_NUM;
219 r.entries = calloc(NG_HCI_MAX_NEIGHBOR_NUM,
220 sizeof(ng_hci_node_neighbor_cache_entry_ep));
221 if (r.entries == NULL) {
226 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_NEIGHBOR_CACHE, &r,
239 for (n = 0; n < r.num_entries; n++) {
242 "%02x %02x %02x %02x %02x %02x %02x %02x " \
246 hci_bdaddr2str(&r.entries[n].bdaddr),
247 r.entries[n].features[0], r.entries[n].features[1],
248 r.entries[n].features[2], r.entries[n].features[3],
249 r.entries[n].features[4], r.entries[n].features[5],
250 r.entries[n].features[6], r.entries[n].features[7],
251 r.entries[n].clock_offset, r.entries[n].page_scan_mode,
252 r.entries[n].page_scan_rep_mode);
258 } /* hci_read_neightbor_cache */
260 /* Send Read_Connection_List command to the node */
262 hci_read_connection_list(int s, int argc, char **argv)
264 struct ng_btsocket_hci_raw_con_list r;
267 memset(&r, 0, sizeof(r));
268 r.num_connections = NG_HCI_MAX_CON_NUM;
269 r.connections = calloc(NG_HCI_MAX_CON_NUM, sizeof(ng_hci_node_con_ep));
270 if (r.connections == NULL) {
275 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_CON_LIST, &r, sizeof(r)) < 0) {
291 for (n = 0; n < r.num_connections; n++) {
302 hci_bdaddr2str(&r.connections[n].bdaddr),
303 r.connections[n].con_handle,
304 (r.connections[n].link_type == NG_HCI_LINK_ACL)?
306 r.connections[n].mode,
307 (r.connections[n].role == NG_HCI_ROLE_MASTER)?
309 hci_encrypt2str(r.connections[n].encryption_mode, 1),
310 r.connections[n].pending,
311 r.connections[n].queue_len,
312 hci_con_state2str(r.connections[n].state));
318 } /* hci_read_connection_list */
320 /* Send Read_Node_Link_Policy_Settings_Mask command to the node */
322 hci_read_node_link_policy_settings_mask(int s, int argc, char **argv)
324 struct ng_btsocket_hci_raw_node_link_policy_mask r;
326 memset(&r, 0, sizeof(r));
327 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_LINK_POLICY_MASK, &r, sizeof(r)) < 0)
330 fprintf(stdout, "Link Policy Settings mask: %#04x\n", r.policy_mask);
333 } /* hci_read_node_link_policy_settings_mask */
335 /* Send Write_Node_Link_Policy_Settings_Mask command to the node */
337 hci_write_node_link_policy_settings_mask(int s, int argc, char **argv)
339 struct ng_btsocket_hci_raw_node_link_policy_mask r;
342 memset(&r, 0, sizeof(r));
346 if (sscanf(argv[0], "%x", &m) != 1)
349 r.policy_mask = (m & 0xffff);
356 if (ioctl(s, SIOC_HCI_RAW_NODE_SET_LINK_POLICY_MASK, &r, sizeof(r)) < 0)
360 } /* hci_write_node_link_policy_settings_mask */
362 /* Send Read_Node_Packet_Mask command to the node */
364 hci_read_node_packet_mask(int s, int argc, char **argv)
366 struct ng_btsocket_hci_raw_node_packet_mask r;
368 memset(&r, 0, sizeof(r));
369 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_PACKET_MASK, &r, sizeof(r)) < 0)
372 fprintf(stdout, "Packet mask: %#04x\n", r.packet_mask);
375 } /* hci_read_node_packet_mask */
377 /* Send Write_Node_Packet_Mask command to the node */
379 hci_write_node_packet_mask(int s, int argc, char **argv)
381 struct ng_btsocket_hci_raw_node_packet_mask r;
384 memset(&r, 0, sizeof(r));
388 if (sscanf(argv[0], "%x", &m) != 1)
391 r.packet_mask = (m & 0xffff);
398 if (ioctl(s, SIOC_HCI_RAW_NODE_SET_PACKET_MASK, &r, sizeof(r)) < 0)
402 } /* hci_write_node_packet_mask */
404 /* Send Read_Node_Role_Switch command to the node */
406 hci_read_node_role_switch(int s, int argc, char **argv)
408 struct ng_btsocket_hci_raw_node_role_switch r;
410 memset(&r, 0, sizeof(r));
411 if (ioctl(s, SIOC_HCI_RAW_NODE_GET_ROLE_SWITCH, &r, sizeof(r)) < 0)
414 fprintf(stdout, "Role switch: %d\n", r.role_switch);
417 } /* hci_read_node_role_switch */
419 /* Send Write_Node_Role_Switch command to the node */
421 hci_write_node_role_switch(int s, int argc, char **argv)
423 struct ng_btsocket_hci_raw_node_role_switch r;
426 memset(&r, 0, sizeof(r));
430 if (sscanf(argv[0], "%d", &m) != 1)
433 r.role_switch = m? 1 : 0;
440 if (ioctl(s, SIOC_HCI_RAW_NODE_SET_ROLE_SWITCH, &r, sizeof(r)) < 0)
444 } /* hci_write_node_role_switch */
446 /* Send Read_Node_List command to the node */
448 hci_read_node_list(int s, int argc, char **argv)
450 struct ng_btsocket_hci_raw_node_list_names r;
453 r.num_names = MAX_NODE_NUM;
454 r.names = (struct nodeinfo*)calloc(MAX_NODE_NUM, sizeof(struct nodeinfo));
458 if (ioctl(s, SIOC_HCI_RAW_NODE_LIST_NAMES, &r, sizeof(r)) < 0) {
463 fprintf(stdout, "Name ID Num hooks\n");
464 for (i = 0; i < r.num_names; ++i)
465 fprintf(stdout, "%-15s %08x %9d\n",
466 r.names[i].name, r.names[i].id, r.names[i].hooks);
471 } /* hci_read_node_list */
473 struct hci_command node_commands[] = {
476 "Get the HCI node state",
481 "Initialize the HCI node",
486 "Read the HCI node debug level",
487 &hci_read_debug_level
490 "write_debug_level <level>",
491 "Write the HCI node debug level",
492 &hci_write_debug_level
495 "read_node_buffer_size",
496 "Read the HCI node buffer information. This will return current state of the\n"\
497 "HCI buffer for the HCI node",
498 &hci_read_node_buffer_size
502 "Read the HCI node BD_ADDR. Returns device BD_ADDR as cached by the HCI node",
503 &hci_read_node_bd_addr
506 "read_node_features",
507 "Read the HCI node features. This will return list of supported features as\n" \
508 "cached by the HCI node",
509 &hci_read_node_features
513 "Read packets and bytes counters for the HCI node",
518 "Reset packets and bytes counters for the HCI node",
522 "flush_neighbor_cache",
523 "Flush content of the HCI node neighbor cache",
524 &hci_flush_neighbor_cache
527 "read_neighbor_cache",
528 "Read content of the HCI node neighbor cache",
529 &hci_read_neighbor_cache
532 "read_connection_list",
533 "Read the baseband connection descriptors list for the HCI node",
534 &hci_read_connection_list
537 "read_node_link_policy_settings_mask",
538 "Read the value of the Link Policy Settinngs mask for the HCI node",
539 &hci_read_node_link_policy_settings_mask
542 "write_node_link_policy_settings_mask <policy_mask>",
543 "Write the value of the Link Policy Settings mask for the HCI node. By default\n" \
544 "all supported Link Policy modes (as reported by the local device features) are\n"\
545 "enabled. The particular Link Policy mode is enabled if local device supports\n"\
546 "it and correspinding bit in the mask was set\n\n" \
547 "\t<policy_mask> - xxxx; Link Policy mask\n" \
548 "\t\t0x0000 - Disable All LM Modes\n" \
549 "\t\t0x0001 - Enable Master Slave Switch\n" \
550 "\t\t0x0002 - Enable Hold Mode\n" \
551 "\t\t0x0004 - Enable Sniff Mode\n" \
552 "\t\t0x0008 - Enable Park Mode\n",
553 &hci_write_node_link_policy_settings_mask
556 "read_node_packet_mask",
557 "Read the value of the Packet mask for the HCI node",
558 &hci_read_node_packet_mask
561 "write_node_packet_mask <packet_mask>",
562 "Write the value of the Packet mask for the HCI node. By default all supported\n" \
563 "packet types (as reported by the local device features) are enabled. The\n" \
564 "particular packet type is enabled if local device supports it and corresponding\n" \
565 "bit in the mask was set\n\n" \
566 "\t<packet_mask> - xxxx; packet type mask\n" \
568 "\t\tACL packets\n" \
569 "\t\t-----------\n" \
577 "\t\tSCO packets\n" \
578 "\t\t-----------\n" \
582 &hci_write_node_packet_mask
585 "read_node_role_switch",
586 "Read the value of the Role Switch parameter for the HCI node",
587 &hci_read_node_role_switch
590 "write_node_role_switch {0|1}",
591 "Write the value of the Role Switch parameter for the HCI node. By default,\n" \
592 "if Role Switch is supported, local device will try to perform Role Switch\n" \
593 "and become Master on incoming connection. Some devices do not support Role\n" \
594 "Switch and thus incoming connections from such devices will fail. Setting\n" \
595 "this parameter to zero will prevent Role Switch and thus accepting device\n" \
597 &hci_write_node_role_switch
601 "Get a list of HCI nodes, their Netgraph IDs and connected hooks.",