util.c revision 162495
1107120Sjulian/* 2107120Sjulian * util.c 3107120Sjulian * 4107120Sjulian * Copyright (c) 2001 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: util.c,v 1.2 2003/05/19 17:29:29 max Exp $ 29107120Sjulian * $FreeBSD: head/usr.sbin/bluetooth/hccontrol/util.c 162495 2006-09-21 02:41:04Z emax $ 30107120Sjulian */ 31107120Sjulian 32121054Semax#include <sys/param.h> 33121054Semax#include <bluetooth.h> 34121054Semax#include <stdio.h> 35107120Sjulian#include <string.h> 36107120Sjulian 37107120Sjulian#define SIZE(x) (sizeof((x))/sizeof((x)[0])) 38107120Sjulian 39162495Semaxchar const * 40107120Sjulianhci_link2str(int link_type) 41107120Sjulian{ 42107120Sjulian static char const * const t[] = { 43107120Sjulian /* NG_HCI_LINK_SCO */ "SCO", 44107120Sjulian /* NG_HCI_LINK_ACL */ "ACL" 45107120Sjulian }; 46107120Sjulian 47107120Sjulian return (link_type >= SIZE(t)? "?" : t[link_type]); 48107120Sjulian} /* hci_link2str */ 49107120Sjulian 50162495Semaxchar const * 51107120Sjulianhci_pin2str(int type) 52107120Sjulian{ 53107120Sjulian static char const * const t[] = { 54107120Sjulian /* 0x00 */ "Variable PIN", 55107120Sjulian /* 0x01 */ "Fixed PIN" 56107120Sjulian }; 57107120Sjulian 58107120Sjulian return (type >= SIZE(t)? "?" : t[type]); 59107120Sjulian} /* hci_pin2str */ 60107120Sjulian 61162495Semaxchar const * 62107120Sjulianhci_scan2str(int scan) 63107120Sjulian{ 64107120Sjulian static char const * const t[] = { 65107120Sjulian /* 0x00 */ "No Scan enabled", 66107120Sjulian /* 0x01 */ "Inquiry Scan enabled. Page Scan disabled", 67107120Sjulian /* 0x02 */ "Inquiry Scan disabled. Page Scan enabled", 68107120Sjulian /* 0x03 */ "Inquiry Scan enabled. Page Scan enabled" 69107120Sjulian }; 70107120Sjulian 71107120Sjulian return (scan >= SIZE(t)? "?" : t[scan]); 72107120Sjulian} /* hci_scan2str */ 73107120Sjulian 74162495Semaxchar const * 75107120Sjulianhci_encrypt2str(int encrypt, int brief) 76107120Sjulian{ 77107120Sjulian static char const * const t[] = { 78107120Sjulian /* 0x00 */ "Disabled", 79107120Sjulian /* 0x01 */ "Only for point-to-point packets", 80107120Sjulian /* 0x02 */ "Both point-to-point and broadcast packets" 81107120Sjulian }; 82107120Sjulian 83107120Sjulian static char const * const t1[] = { 84107120Sjulian /* NG_HCI_ENCRYPTION_MODE_NONE */ "NONE", 85107120Sjulian /* NG_HCI_ENCRYPTION_MODE_P2P */ "P2P", 86107120Sjulian /* NG_HCI_ENCRYPTION_MODE_ALL */ "ALL", 87107120Sjulian }; 88107120Sjulian 89107120Sjulian if (brief) 90107120Sjulian return (encrypt >= SIZE(t1)? "?" : t1[encrypt]); 91107120Sjulian 92107120Sjulian return (encrypt >= SIZE(t)? "?" : t[encrypt]); 93107120Sjulian} /* hci_encrypt2str */ 94107120Sjulian 95162495Semaxchar const * 96107120Sjulianhci_coding2str(int coding) 97107120Sjulian{ 98107120Sjulian static char const * const t[] = { 99107120Sjulian /* 0x00 */ "Linear", 100107120Sjulian /* 0x01 */ "u-law", 101107120Sjulian /* 0x02 */ "A-law", 102107120Sjulian /* 0x03 */ "Reserved" 103107120Sjulian }; 104107120Sjulian 105107120Sjulian return (coding >= SIZE(t)? "?" : t[coding]); 106107120Sjulian} /* hci_coding2str */ 107107120Sjulian 108162495Semaxchar const * 109107120Sjulianhci_vdata2str(int data) 110107120Sjulian{ 111107120Sjulian static char const * const t[] = { 112107120Sjulian /* 0x00 */ "1's complement", 113107120Sjulian /* 0x01 */ "2's complement", 114107120Sjulian /* 0x02 */ "Sign-Magnitude", 115107120Sjulian /* 0x03 */ "Reserved" 116107120Sjulian }; 117107120Sjulian 118107120Sjulian return (data >= SIZE(t)? "?" : t[data]); 119107120Sjulian} /* hci_vdata2str */ 120107120Sjulian 121162495Semaxchar const * 122107120Sjulianhci_hmode2str(int mode, char *buffer, int size) 123107120Sjulian{ 124107120Sjulian static char const * const t[] = { 125107120Sjulian /* 0x01 */ "Suspend Page Scan ", 126107120Sjulian /* 0x02 */ "Suspend Inquiry Scan ", 127107120Sjulian /* 0x04 */ "Suspend Periodic Inquiries " 128107120Sjulian }; 129107120Sjulian 130107120Sjulian if (buffer != NULL && size > 0) { 131107120Sjulian int n; 132107120Sjulian 133107120Sjulian memset(buffer, 0, size); 134107120Sjulian for (n = 0; n < SIZE(t); n++) { 135107120Sjulian int len = strlen(buffer); 136107120Sjulian 137107120Sjulian if (len >= size) 138107120Sjulian break; 139107120Sjulian if (mode & (1 << n)) 140107120Sjulian strncat(buffer, t[n], size - len); 141107120Sjulian } 142107120Sjulian } 143107120Sjulian 144107120Sjulian return (buffer); 145107120Sjulian} /* hci_hmode2str */ 146107120Sjulian 147162495Semaxchar const * 148107120Sjulianhci_ver2str(int ver) 149107120Sjulian{ 150107120Sjulian static char const * const t[] = { 151155964Smarkus /* 0x00 */ "Bluetooth HCI Specification 1.0B", 152155964Smarkus /* 0x01 */ "Bluetooth HCI Specification 1.1", 153155964Smarkus /* 0x02 */ "Bluetooth HCI Specification 1.2", 154155964Smarkus /* 0x03 */ "Bluetooth HCI Specification 2.0" 155107120Sjulian }; 156107120Sjulian 157107120Sjulian return (ver >= SIZE(t)? "?" : t[ver]); 158107120Sjulian} /* hci_ver2str */ 159107120Sjulian 160162495Semaxchar const * 161155964Smarkushci_lmpver2str(int ver) 162155964Smarkus{ 163155964Smarkus static char const * const t[] = { 164155964Smarkus /* 0x00 */ "Bluetooth LMP 1.0", 165155964Smarkus /* 0x01 */ "Bluetooth LMP 1.1", 166155964Smarkus /* 0x02 */ "Bluetooth LMP 1.2", 167155964Smarkus /* 0x03 */ "Bluetooth LMP 2.0" 168155964Smarkus }; 169155964Smarkus 170155964Smarkus return (ver >= SIZE(t)? "?" : t[ver]); 171155964Smarkus} /* hci_lmpver2str */ 172155964Smarkus 173162495Semaxchar const * 174107120Sjulianhci_manufacturer2str(int m) 175107120Sjulian{ 176107120Sjulian static char const * const t[] = { 177155964Smarkus /* 0000 */ "Ericsson Technology Licensing", 178107120Sjulian /* 0001 */ "Nokia Mobile Phones", 179107120Sjulian /* 0002 */ "Intel Corp.", 180107120Sjulian /* 0003 */ "IBM Corp.", 181107120Sjulian /* 0004 */ "Toshiba Corp.", 182107120Sjulian /* 0005 */ "3Com", 183107120Sjulian /* 0006 */ "Microsoft", 184107120Sjulian /* 0007 */ "Lucent", 185107120Sjulian /* 0008 */ "Motorola", 186107120Sjulian /* 0009 */ "Infineon Technologies AG", 187107120Sjulian /* 0010 */ "Cambridge Silicon Radio", 188107120Sjulian /* 0011 */ "Silicon Wave", 189107120Sjulian /* 0012 */ "Digianswer A/S", 190107120Sjulian /* 0013 */ "Texas Instruments Inc.", 191107120Sjulian /* 0014 */ "Parthus Technologies Inc.", 192107120Sjulian /* 0015 */ "Broadcom Corporation", 193107120Sjulian /* 0016 */ "Mitel Semiconductor", 194107120Sjulian /* 0017 */ "Widcomm, Inc.", 195155964Smarkus /* 0018 */ "Zeevo, Inc.", 196107120Sjulian /* 0019 */ "Atmel Corporation", 197107120Sjulian /* 0020 */ "Mitsubishi Electric Corporation", 198107120Sjulian /* 0021 */ "RTX Telecom A/S", 199107120Sjulian /* 0022 */ "KC Technology Inc.", 200107120Sjulian /* 0023 */ "Newlogic", 201107120Sjulian /* 0024 */ "Transilica, Inc.", 202107120Sjulian /* 0025 */ "Rohde & Schwartz GmbH & Co. KG", 203107120Sjulian /* 0026 */ "TTPCom Limited", 204107120Sjulian /* 0027 */ "Signia Technologies, Inc.", 205107120Sjulian /* 0028 */ "Conexant Systems Inc.", 206107120Sjulian /* 0029 */ "Qualcomm", 207107120Sjulian /* 0030 */ "Inventel", 208107120Sjulian /* 0031 */ "AVM Berlin", 209107120Sjulian /* 0032 */ "BandSpeed, Inc.", 210107120Sjulian /* 0033 */ "Mansella Ltd", 211107120Sjulian /* 0034 */ "NEC Corporation", 212107120Sjulian /* 0035 */ "WavePlus Technology Co., Ltd.", 213107120Sjulian /* 0036 */ "Alcatel", 214107120Sjulian /* 0037 */ "Philips Semiconductors", 215107120Sjulian /* 0038 */ "C Technologies", 216107120Sjulian /* 0039 */ "Open Interface", 217107120Sjulian /* 0040 */ "R F Micro Devices", 218107120Sjulian /* 0041 */ "Hitachi Ltd", 219107120Sjulian /* 0042 */ "Symbol Technologies, Inc.", 220107120Sjulian /* 0043 */ "Tenovis", 221107120Sjulian /* 0044 */ "Macronix International Co. Ltd.", 222107120Sjulian /* 0045 */ "GCT Semiconductor", 223107120Sjulian /* 0046 */ "Norwood Systems", 224155964Smarkus /* 0047 */ "MewTel Technology Inc.", 225155964Smarkus /* 0048 */ "ST Microelectronics", 226155964Smarkus /* 0049 */ "Synopsys", 227155964Smarkus /* 0050 */ "Red-M (Communications) Ltd", 228155964Smarkus /* 0051 */ "Commil Ltd", 229155964Smarkus /* 0052 */ "Computer Access Technology Corporation (CATC)", 230155964Smarkus /* 0053 */ "Eclipse (HQ Espana) S.L.", 231155964Smarkus /* 0054 */ "Renesas Technology Corp.", 232155964Smarkus /* 0055 */ "Mobilian Corporation", 233155964Smarkus /* 0056 */ "Terax", 234155964Smarkus /* 0057 */ "Integrated System Solution Corp.", 235155964Smarkus /* 0058 */ "Matsushita Electric Industrial Co., Ltd.", 236155964Smarkus /* 0059 */ "Gennum Corporation", 237155964Smarkus /* 0060 */ "Research In Motion", 238155964Smarkus /* 0061 */ "IPextreme, Inc.", 239155964Smarkus /* 0062 */ "Systems and Chips, Inc", 240155964Smarkus /* 0063 */ "Bluetooth SIG, Inc", 241155964Smarkus /* 0064 */ "Seiko Epson Corporation" 242107120Sjulian }; 243107120Sjulian 244107120Sjulian return (m >= SIZE(t)? "?" : t[m]); 245107120Sjulian} /* hci_manufacturer2str */ 246107120Sjulian 247162495Semaxchar const * 248128079Semaxhci_features2str(uint8_t *features, char *buffer, int size) 249107120Sjulian{ 250107120Sjulian static char const * const t[][8] = { 251107120Sjulian { /* byte 0 */ 252107120Sjulian /* 0 */ "<3-Slot> ", 253107120Sjulian /* 1 */ "<5-Slot> ", 254107120Sjulian /* 2 */ "<Encryption> ", 255107120Sjulian /* 3 */ "<Slot offset> ", 256107120Sjulian /* 4 */ "<Timing accuracy> ", 257107120Sjulian /* 5 */ "<Switch> ", 258107120Sjulian /* 6 */ "<Hold mode> ", 259107120Sjulian /* 7 */ "<Sniff mode> " 260107120Sjulian }, 261107120Sjulian { /* byte 1 */ 262107120Sjulian /* 0 */ "<Park mode> ", 263107120Sjulian /* 1 */ "<RSSI> ", 264107120Sjulian /* 2 */ "<Channel quality> ", 265107120Sjulian /* 3 */ "<SCO link> ", 266107120Sjulian /* 4 */ "<HV2 packets> ", 267107120Sjulian /* 5 */ "<HV3 packets> ", 268107120Sjulian /* 6 */ "<u-law log> ", 269107120Sjulian /* 7 */ "<A-law log> " 270107120Sjulian }, 271107120Sjulian { /* byte 2 */ 272107120Sjulian /* 0 */ "<CVSD> ", 273107120Sjulian /* 1 */ "<Paging scheme> ", 274107120Sjulian /* 2 */ "<Power control> ", 275107120Sjulian /* 3 */ "<Transparent SCO data> ", 276107120Sjulian /* 4 */ "<Flow control lag (bit0)> ", 277107120Sjulian /* 5 */ "<Flow control lag (bit1)> ", 278107120Sjulian /* 6 */ "<Flow control lag (bit2)> ", 279107120Sjulian /* 7 */ "<Unknown2.7> " 280107120Sjulian }}; 281107120Sjulian 282107120Sjulian if (buffer != NULL && size > 0) { 283107120Sjulian int n, i, len0, len1; 284107120Sjulian 285107120Sjulian memset(buffer, 0, size); 286107120Sjulian len1 = 0; 287107120Sjulian 288107120Sjulian for (n = 0; n < SIZE(t); n++) { 289107120Sjulian for (i = 0; i < SIZE(t[n]); i++) { 290107120Sjulian len0 = strlen(buffer); 291107120Sjulian if (len0 >= size) 292107120Sjulian goto done; 293107120Sjulian 294107120Sjulian if (features[n] & (1 << i)) { 295107120Sjulian if (len1 + strlen(t[n][i]) > 60) { 296107120Sjulian len1 = 0; 297107120Sjulian buffer[len0 - 1] = '\n'; 298107120Sjulian } 299107120Sjulian 300107120Sjulian len1 += strlen(t[n][i]); 301107120Sjulian strncat(buffer, t[n][i], size - len0); 302107120Sjulian } 303107120Sjulian } 304107120Sjulian } 305107120Sjulian } 306107120Sjuliandone: 307107120Sjulian return (buffer); 308107120Sjulian} /* hci_features2str */ 309107120Sjulian 310162495Semaxchar const * 311107120Sjulianhci_cc2str(int cc) 312107120Sjulian{ 313107120Sjulian static char const * const t[] = { 314107120Sjulian /* 0x00 */ "North America, Europe, Japan", 315107120Sjulian /* 0x01 */ "France" 316107120Sjulian }; 317107120Sjulian 318107120Sjulian return (cc >= SIZE(t)? "?" : t[cc]); 319107120Sjulian} /* hci_cc2str */ 320107120Sjulian 321162495Semaxchar const * 322107120Sjulianhci_con_state2str(int state) 323107120Sjulian{ 324107120Sjulian static char const * const t[] = { 325107120Sjulian /* NG_HCI_CON_CLOSED */ "CLOSED", 326107120Sjulian /* NG_HCI_CON_W4_LP_CON_RSP */ "W4_LP_CON_RSP", 327107120Sjulian /* NG_HCI_CON_W4_CONN_COMPLETE */ "W4_CONN_COMPLETE", 328107120Sjulian /* NG_HCI_CON_OPEN */ "OPEN" 329107120Sjulian }; 330107120Sjulian 331107120Sjulian return (state >= SIZE(t)? "UNKNOWN" : t[state]); 332107120Sjulian} /* hci_con_state2str */ 333107120Sjulian 334162495Semaxchar const * 335107120Sjulianhci_status2str(int status) 336107120Sjulian{ 337107120Sjulian static char const * const t[] = { 338107120Sjulian /* 0x00 */ "No error", 339107120Sjulian /* 0x01 */ "Unknown HCI command", 340107120Sjulian /* 0x02 */ "No connection", 341107120Sjulian /* 0x03 */ "Hardware failure", 342107120Sjulian /* 0x04 */ "Page timeout", 343107120Sjulian /* 0x05 */ "Authentication failure", 344107120Sjulian /* 0x06 */ "Key missing", 345107120Sjulian /* 0x07 */ "Memory full", 346107120Sjulian /* 0x08 */ "Connection timeout", 347107120Sjulian /* 0x09 */ "Max number of connections", 348107120Sjulian /* 0x0a */ "Max number of SCO connections to a unit", 349107120Sjulian /* 0x0b */ "ACL connection already exists", 350107120Sjulian /* 0x0c */ "Command disallowed", 351107120Sjulian /* 0x0d */ "Host rejected due to limited resources", 352122451Semax /* 0x0e */ "Host rejected due to security reasons", 353107120Sjulian /* 0x0f */ "Host rejected due to remote unit is a personal unit", 354107120Sjulian /* 0x10 */ "Host timeout", 355107120Sjulian /* 0x11 */ "Unsupported feature or parameter value", 356107120Sjulian /* 0x12 */ "Invalid HCI command parameter", 357107120Sjulian /* 0x13 */ "Other end terminated connection: User ended connection", 358107120Sjulian /* 0x14 */ "Other end terminated connection: Low resources", 359107120Sjulian /* 0x15 */ "Other end terminated connection: About to power off", 360107120Sjulian /* 0x16 */ "Connection terminated by local host", 361107120Sjulian /* 0x17 */ "Repeated attempts", 362107120Sjulian /* 0x18 */ "Pairing not allowed", 363107120Sjulian /* 0x19 */ "Unknown LMP PDU", 364107120Sjulian /* 0x1a */ "Unsupported remote feature", 365107120Sjulian /* 0x1b */ "SCO offset rejected", 366107120Sjulian /* 0x1c */ "SCO interval rejected", 367107120Sjulian /* 0x1d */ "SCO air mode rejected", 368107120Sjulian /* 0x1e */ "Invalid LMP parameters", 369107120Sjulian /* 0x1f */ "Unspecified error", 370107120Sjulian /* 0x20 */ "Unsupported LMP parameter value", 371107120Sjulian /* 0x21 */ "Role change not allowed", 372107120Sjulian /* 0x22 */ "LMP response timeout", 373107120Sjulian /* 0x23 */ "LMP error transaction collision", 374107120Sjulian /* 0x24 */ "LMP PSU not allowed", 375107120Sjulian /* 0x25 */ "Encryption mode not acceptable", 376107120Sjulian /* 0x26 */ "Unit key used", 377107120Sjulian /* 0x27 */ "QoS is not supported", 378107120Sjulian /* 0x28 */ "Instant passed", 379122451Semax /* 0x29 */ "Pairing with unit key not supported" 380107120Sjulian }; 381107120Sjulian 382107120Sjulian return (status >= SIZE(t)? "Unknown error" : t[status]); 383107120Sjulian} /* hci_status2str */ 384107120Sjulian 385162495Semaxchar const * 386121054Semaxhci_bdaddr2str(bdaddr_t const *ba) 387121054Semax{ 388121054Semax extern int numeric_bdaddr; 389121054Semax static char buffer[MAXHOSTNAMELEN]; 390121054Semax struct hostent *he = NULL; 391121054Semax 392121054Semax if (memcmp(ba, NG_HCI_BDADDR_ANY, sizeof(*ba)) == 0) { 393121054Semax buffer[0] = '*'; 394121054Semax buffer[1] = 0; 395121054Semax 396121054Semax return (buffer); 397121054Semax } 398121054Semax 399121054Semax if (!numeric_bdaddr && 400121054Semax (he = bt_gethostbyaddr((char *)ba, sizeof(*ba), AF_BLUETOOTH)) != NULL) { 401121054Semax strlcpy(buffer, he->h_name, sizeof(buffer)); 402121054Semax 403121054Semax return (buffer); 404121054Semax } 405121054Semax 406121054Semax bt_ntoa(ba, buffer); 407121054Semax 408121054Semax return (buffer); 409121054Semax} /* hci_bdaddr2str */ 410121054Semax 411