1/* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2000-2001 Qualcomm Incorporated 6 * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> 7 * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org> 8 * 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 * 24 */ 25 26#ifdef HAVE_CONFIG_H 27#include <config.h> 28#endif 29 30#include <stdio.h> 31#include <errno.h> 32#include <ctype.h> 33#include <unistd.h> 34#include <stdlib.h> 35#include <string.h> 36#include <getopt.h> 37#include <sys/param.h> 38#include <sys/ioctl.h> 39#include <sys/socket.h> 40 41#include <bluetooth/bluetooth.h> 42#include <bluetooth/hci.h> 43#include <bluetooth/hci_lib.h> 44 45#include "textfile.h" 46#include "csr.h" 47 48static struct hci_dev_info di; 49static int all; 50 51static void print_dev_hdr(struct hci_dev_info *di); 52static void print_dev_info(int ctl, struct hci_dev_info *di); 53 54static void print_dev_list(int ctl, int flags) 55{ 56 struct hci_dev_list_req *dl; 57 struct hci_dev_req *dr; 58 int i; 59 60 if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) { 61 perror("Can't allocate memory"); 62 exit(1); 63 } 64 dl->dev_num = HCI_MAX_DEV; 65 dr = dl->dev_req; 66 67 if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) { 68 perror("Can't get device list"); 69 exit(1); 70 } 71 72 for (i = 0; i< dl->dev_num; i++) { 73 di.dev_id = (dr+i)->dev_id; 74 if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0) 75 continue; 76 if (hci_test_bit(HCI_RAW, &di.flags) && 77 !bacmp(&di.bdaddr, BDADDR_ANY)) { 78 int dd = hci_open_dev(di.dev_id); 79 hci_read_bd_addr(dd, &di.bdaddr, 1000); 80 hci_close_dev(dd); 81 } 82 print_dev_info(ctl, &di); 83 } 84} 85 86static void print_pkt_type(struct hci_dev_info *di) 87{ 88 char *str; 89 str = hci_ptypetostr(di->pkt_type); 90 printf("\tPacket type: %s\n", str); 91 bt_free(str); 92} 93 94static void print_link_policy(struct hci_dev_info *di) 95{ 96 printf("\tLink policy: %s\n", hci_lptostr(di->link_policy)); 97} 98 99static void print_link_mode(struct hci_dev_info *di) 100{ 101 char *str; 102 str = hci_lmtostr(di->link_mode); 103 printf("\tLink mode: %s\n", str); 104 bt_free(str); 105} 106 107static void print_dev_features(struct hci_dev_info *di, int format) 108{ 109 printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 110 "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 111 di->features[0], di->features[1], di->features[2], 112 di->features[3], di->features[4], di->features[5], 113 di->features[6], di->features[7]); 114 115 if (format) { 116 char *tmp = lmp_featurestostr(di->features, "\t\t", 63); 117 printf("%s\n", tmp); 118 bt_free(tmp); 119 } 120} 121 122static void cmd_rstat(int ctl, int hdev, char *opt) 123{ 124 /* Reset HCI device stat counters */ 125 if (ioctl(ctl, HCIDEVRESTAT, hdev) < 0) { 126 fprintf(stderr, "Can't reset stats counters hci%d: %s (%d)\n", 127 hdev, strerror(errno), errno); 128 exit(1); 129 } 130} 131 132static void cmd_scan(int ctl, int hdev, char *opt) 133{ 134 struct hci_dev_req dr; 135 136 dr.dev_id = hdev; 137 dr.dev_opt = SCAN_DISABLED; 138 if (!strcmp(opt, "iscan")) 139 dr.dev_opt = SCAN_INQUIRY; 140 else if (!strcmp(opt, "pscan")) 141 dr.dev_opt = SCAN_PAGE; 142 else if (!strcmp(opt, "piscan")) 143 dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; 144 145 if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) { 146 fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n", 147 hdev, strerror(errno), errno); 148 exit(1); 149 } 150} 151 152static void cmd_iac(int ctl, int hdev, char *opt) 153{ 154 int s = hci_open_dev(hdev); 155 156 if (s < 0) { 157 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 158 hdev, strerror(errno), errno); 159 exit(1); 160 } 161 if (opt) { 162 int l = strtoul(opt, 0, 16); 163 uint8_t lap[3]; 164 if (!strcasecmp(opt, "giac")) { 165 l = 0x9e8b33; 166 } else if (!strcasecmp(opt, "liac")) { 167 l = 0x9e8b00; 168 } else if (l < 0x9e8b00 || l > 0x9e8b3f) { 169 printf("Invalid access code 0x%x\n", l); 170 exit(1); 171 } 172 lap[0] = (l & 0xff); 173 lap[1] = (l >> 8) & 0xff; 174 lap[2] = (l >> 16) & 0xff; 175 if (hci_write_current_iac_lap(s, 1, lap, 1000) < 0) { 176 printf("Failed to set IAC on hci%d: %s\n", hdev, strerror(errno)); 177 exit(1); 178 } 179 } else { 180 uint8_t lap[3 * MAX_IAC_LAP]; 181 int i, j; 182 uint8_t n; 183 if (hci_read_current_iac_lap(s, &n, lap, 1000) < 0) { 184 printf("Failed to read IAC from hci%d: %s\n", hdev, strerror(errno)); 185 exit(1); 186 } 187 print_dev_hdr(&di); 188 printf("\tIAC: "); 189 for (i = 0; i < n; i++) { 190 printf("0x"); 191 for (j = 3; j--; ) 192 printf("%02x", lap[j + 3 * i]); 193 if (i < n - 1) 194 printf(", "); 195 } 196 printf("\n"); 197 } 198 close(s); 199} 200 201static void cmd_auth(int ctl, int hdev, char *opt) 202{ 203 struct hci_dev_req dr; 204 205 dr.dev_id = hdev; 206 if (!strcmp(opt, "auth")) 207 dr.dev_opt = AUTH_ENABLED; 208 else 209 dr.dev_opt = AUTH_DISABLED; 210 211 if (ioctl(ctl, HCISETAUTH, (unsigned long) &dr) < 0) { 212 fprintf(stderr, "Can't set auth on hci%d: %s (%d)\n", 213 hdev, strerror(errno), errno); 214 exit(1); 215 } 216} 217 218static void cmd_encrypt(int ctl, int hdev, char *opt) 219{ 220 struct hci_dev_req dr; 221 222 dr.dev_id = hdev; 223 if (!strcmp(opt, "encrypt")) 224 dr.dev_opt = ENCRYPT_P2P; 225 else 226 dr.dev_opt = ENCRYPT_DISABLED; 227 228 if (ioctl(ctl, HCISETENCRYPT, (unsigned long) &dr) < 0) { 229 fprintf(stderr, "Can't set encrypt on hci%d: %s (%d)\n", 230 hdev, strerror(errno), errno); 231 exit(1); 232 } 233} 234 235static void cmd_up(int ctl, int hdev, char *opt) 236{ 237 /* Start HCI device */ 238 if (ioctl(ctl, HCIDEVUP, hdev) < 0) { 239 if (errno == EALREADY) 240 return; 241 fprintf(stderr, "Can't init device hci%d: %s (%d)\n", 242 hdev, strerror(errno), errno); 243 exit(1); 244 } 245} 246 247static void cmd_down(int ctl, int hdev, char *opt) 248{ 249 /* Stop HCI device */ 250 if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) { 251 fprintf(stderr, "Can't down device hci%d: %s (%d)\n", 252 hdev, strerror(errno), errno); 253 exit(1); 254 } 255} 256 257static void cmd_reset(int ctl, int hdev, char *opt) 258{ 259 /* Reset HCI device */ 260#if 0 261 if (ioctl(ctl, HCIDEVRESET, hdev) < 0 ){ 262 fprintf(stderr, "Reset failed for device hci%d: %s (%d)\n", 263 hdev, strerror(errno), errno); 264 exit(1); 265 } 266#endif 267 cmd_down(ctl, hdev, "down"); 268 cmd_up(ctl, hdev, "up"); 269} 270 271static void cmd_ptype(int ctl, int hdev, char *opt) 272{ 273 struct hci_dev_req dr; 274 275 dr.dev_id = hdev; 276 277 if (hci_strtoptype(opt, &dr.dev_opt)) { 278 if (ioctl(ctl, HCISETPTYPE, (unsigned long) &dr) < 0) { 279 fprintf(stderr, "Can't set pkttype on hci%d: %s (%d)\n", 280 hdev, strerror(errno), errno); 281 exit(1); 282 } 283 } else { 284 print_dev_hdr(&di); 285 print_pkt_type(&di); 286 } 287} 288 289static void cmd_lp(int ctl, int hdev, char *opt) 290{ 291 struct hci_dev_req dr; 292 293 dr.dev_id = hdev; 294 295 if (hci_strtolp(opt, &dr.dev_opt)) { 296 if (ioctl(ctl, HCISETLINKPOL, (unsigned long) &dr) < 0) { 297 fprintf(stderr, "Can't set link policy on hci%d: %s (%d)\n", 298 hdev, strerror(errno), errno); 299 exit(1); 300 } 301 } else { 302 print_dev_hdr(&di); 303 print_link_policy(&di); 304 } 305} 306 307static void cmd_lm(int ctl, int hdev, char *opt) 308{ 309 struct hci_dev_req dr; 310 311 dr.dev_id = hdev; 312 313 if (hci_strtolm(opt, &dr.dev_opt)) { 314 if (ioctl(ctl, HCISETLINKMODE, (unsigned long) &dr) < 0) { 315 fprintf(stderr, "Can't set default link mode on hci%d: %s (%d)\n", 316 hdev, strerror(errno), errno); 317 exit(1); 318 } 319 } else { 320 print_dev_hdr(&di); 321 print_link_mode(&di); 322 } 323} 324 325static void cmd_aclmtu(int ctl, int hdev, char *opt) 326{ 327 struct hci_dev_req dr = { dev_id: hdev }; 328 uint16_t mtu, mpkt; 329 330 if (!opt) 331 return; 332 333 if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) 334 return; 335 336 dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16)); 337 338 if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) { 339 fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n", 340 hdev, strerror(errno), errno); 341 exit(1); 342 } 343} 344 345static void cmd_scomtu(int ctl, int hdev, char *opt) 346{ 347 struct hci_dev_req dr = { dev_id: hdev }; 348 uint16_t mtu, mpkt; 349 350 if (!opt) 351 return; 352 353 if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) 354 return; 355 356 dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16)); 357 358 if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) { 359 fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", 360 hdev, strerror(errno), errno); 361 exit(1); 362 } 363} 364 365static void cmd_features(int ctl, int hdev, char *opt) 366{ 367 uint8_t features[8], max_page = 0; 368 char *tmp; 369 int i, dd; 370 371 if (!(di.features[7] & LMP_EXT_FEAT)) { 372 print_dev_hdr(&di); 373 print_dev_features(&di, 1); 374 return; 375 } 376 377 dd = hci_open_dev(hdev); 378 if (dd < 0) { 379 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 380 hdev, strerror(errno), errno); 381 exit(1); 382 } 383 384 if (hci_read_local_ext_features(dd, 0, &max_page, features, 1000) < 0) { 385 fprintf(stderr, "Can't read extended features hci%d: %s (%d)\n", 386 hdev, strerror(errno), errno); 387 exit(1); 388 } 389 390 print_dev_hdr(&di); 391 printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 392 "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 393 (max_page > 0) ? " page 0" : "", 394 features[0], features[1], features[2], features[3], 395 features[4], features[5], features[6], features[7]); 396 397 tmp = lmp_featurestostr(di.features, "\t\t", 63); 398 printf("%s\n", tmp); 399 bt_free(tmp); 400 401 for (i = 1; i <= max_page; i++) { 402 if (hci_read_local_ext_features(dd, i, NULL, 403 features, 1000) < 0) 404 continue; 405 406 printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 407 "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i, 408 features[0], features[1], features[2], features[3], 409 features[4], features[5], features[6], features[7]); 410 } 411 412 hci_close_dev(dd); 413} 414 415static void cmd_name(int ctl, int hdev, char *opt) 416{ 417 int dd; 418 419 dd = hci_open_dev(hdev); 420 if (dd < 0) { 421 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 422 hdev, strerror(errno), errno); 423 exit(1); 424 } 425 426 if (opt) { 427 if (hci_write_local_name(dd, opt, 2000) < 0) { 428 fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n", 429 hdev, strerror(errno), errno); 430 exit(1); 431 } 432 } else { 433 char name[249]; 434 int i; 435 436 if (hci_read_local_name(dd, sizeof(name), name, 1000) < 0) { 437 fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n", 438 hdev, strerror(errno), errno); 439 exit(1); 440 } 441 442 for (i = 0; i < 248 && name[i]; i++) { 443 if ((unsigned char) name[i] < 32 || name[i] == 127) 444 name[i] = '.'; 445 } 446 447 name[248] = '\0'; 448 449 print_dev_hdr(&di); 450 printf("\tName: '%s'\n", name); 451 } 452 453 hci_close_dev(dd); 454} 455 456/* 457 * see http://www.bluetooth.org/assigned-numbers/baseband.htm --- all 458 * strings are reproduced verbatim 459 */ 460static char *get_minor_device_name(int major, int minor) 461{ 462 switch (major) { 463 case 0: /* misc */ 464 return ""; 465 case 1: /* computer */ 466 switch(minor) { 467 case 0: 468 return "Uncategorized"; 469 case 1: 470 return "Desktop workstation"; 471 case 2: 472 return "Server"; 473 case 3: 474 return "Laptop"; 475 case 4: 476 return "Handheld"; 477 case 5: 478 return "Palm"; 479 case 6: 480 return "Wearable"; 481 } 482 break; 483 case 2: /* phone */ 484 switch(minor) { 485 case 0: 486 return "Uncategorized"; 487 case 1: 488 return "Cellular"; 489 case 2: 490 return "Cordless"; 491 case 3: 492 return "Smart phone"; 493 case 4: 494 return "Wired modem or voice gateway"; 495 case 5: 496 return "Common ISDN Access"; 497 case 6: 498 return "Sim Card Reader"; 499 } 500 break; 501 case 3: /* lan access */ 502 if (minor == 0) 503 return "Uncategorized"; 504 switch(minor / 8) { 505 case 0: 506 return "Fully available"; 507 case 1: 508 return "1-17% utilized"; 509 case 2: 510 return "17-33% utilized"; 511 case 3: 512 return "33-50% utilized"; 513 case 4: 514 return "50-67% utilized"; 515 case 5: 516 return "67-83% utilized"; 517 case 6: 518 return "83-99% utilized"; 519 case 7: 520 return "No service available"; 521 } 522 break; 523 case 4: /* audio/video */ 524 switch(minor) { 525 case 0: 526 return "Uncategorized"; 527 case 1: 528 return "Device conforms to the Headset profile"; 529 case 2: 530 return "Hands-free"; 531 /* 3 is reserved */ 532 case 4: 533 return "Microphone"; 534 case 5: 535 return "Loudspeaker"; 536 case 6: 537 return "Headphones"; 538 case 7: 539 return "Portable Audio"; 540 case 8: 541 return "Car Audio"; 542 case 9: 543 return "Set-top box"; 544 case 10: 545 return "HiFi Audio Device"; 546 case 11: 547 return "VCR"; 548 case 12: 549 return "Video Camera"; 550 case 13: 551 return "Camcorder"; 552 case 14: 553 return "Video Monitor"; 554 case 15: 555 return "Video Display and Loudspeaker"; 556 case 16: 557 return "Video Conferencing"; 558 /* 17 is reserved */ 559 case 18: 560 return "Gaming/Toy"; 561 } 562 break; 563 case 5: /* peripheral */ { 564 static char cls_str[48]; 565 566 cls_str[0] = '\0'; 567 568 switch(minor & 48) { 569 case 16: 570 strncpy(cls_str, "Keyboard", sizeof(cls_str)); 571 break; 572 case 32: 573 strncpy(cls_str, "Pointing device", sizeof(cls_str)); 574 break; 575 case 48: 576 strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str)); 577 break; 578 } 579 if((minor & 15) && (strlen(cls_str) > 0)) 580 strcat(cls_str, "/"); 581 582 switch(minor & 15) { 583 case 0: 584 break; 585 case 1: 586 strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str)); 587 break; 588 case 2: 589 strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str)); 590 break; 591 case 3: 592 strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str)); 593 break; 594 case 4: 595 strncat(cls_str, "Sensing device", sizeof(cls_str) - strlen(cls_str)); 596 break; 597 case 5: 598 strncat(cls_str, "Digitizer tablet", sizeof(cls_str) - strlen(cls_str)); 599 break; 600 case 6: 601 strncat(cls_str, "Card reader", sizeof(cls_str) - strlen(cls_str)); 602 break; 603 default: 604 strncat(cls_str, "(reserved)", sizeof(cls_str) - strlen(cls_str)); 605 break; 606 } 607 if(strlen(cls_str) > 0) 608 return cls_str; 609 } 610 case 6: /* imaging */ 611 if (minor & 4) 612 return "Display"; 613 if (minor & 8) 614 return "Camera"; 615 if (minor & 16) 616 return "Scanner"; 617 if (minor & 32) 618 return "Printer"; 619 break; 620 case 7: /* wearable */ 621 switch(minor) { 622 case 1: 623 return "Wrist Watch"; 624 case 2: 625 return "Pager"; 626 case 3: 627 return "Jacket"; 628 case 4: 629 return "Helmet"; 630 case 5: 631 return "Glasses"; 632 } 633 break; 634 case 8: /* toy */ 635 switch(minor) { 636 case 1: 637 return "Robot"; 638 case 2: 639 return "Vehicle"; 640 case 3: 641 return "Doll / Action Figure"; 642 case 4: 643 return "Controller"; 644 case 5: 645 return "Game"; 646 } 647 break; 648 case 63: /* uncategorised */ 649 return ""; 650 } 651 return "Unknown (reserved) minor device class"; 652} 653 654static void cmd_class(int ctl, int hdev, char *opt) 655{ 656 static const char *services[] = { "Positioning", 657 "Networking", 658 "Rendering", 659 "Capturing", 660 "Object Transfer", 661 "Audio", 662 "Telephony", 663 "Information" }; 664 static const char *major_devices[] = { "Miscellaneous", 665 "Computer", 666 "Phone", 667 "LAN Access", 668 "Audio/Video", 669 "Peripheral", 670 "Imaging", 671 "Uncategorized" }; 672 int s = hci_open_dev(hdev); 673 674 if (s < 0) { 675 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 676 hdev, strerror(errno), errno); 677 exit(1); 678 } 679 if (opt) { 680 uint32_t cod = strtoul(opt, NULL, 16); 681 if (hci_write_class_of_dev(s, cod, 2000) < 0) { 682 fprintf(stderr, "Can't write local class of device on hci%d: %s (%d)\n", 683 hdev, strerror(errno), errno); 684 exit(1); 685 } 686 } else { 687 uint8_t cls[3]; 688 if (hci_read_class_of_dev(s, cls, 1000) < 0) { 689 fprintf(stderr, "Can't read class of device on hci%d: %s (%d)\n", 690 hdev, strerror(errno), errno); 691 exit(1); 692 } 693 print_dev_hdr(&di); 694 printf("\tClass: 0x%02x%02x%02x\n", cls[2], cls[1], cls[0]); 695 printf("\tService Classes: "); 696 if (cls[2]) { 697 unsigned int i; 698 int first = 1; 699 for (i = 0; i < (sizeof(services) / sizeof(*services)); i++) 700 if (cls[2] & (1 << i)) { 701 if (!first) 702 printf(", "); 703 printf("%s", services[i]); 704 first = 0; 705 } 706 } else 707 printf("Unspecified"); 708 printf("\n\tDevice Class: "); 709 if ((cls[1] & 0x1f) >= sizeof(major_devices) / sizeof(*major_devices)) 710 printf("Invalid Device Class!\n"); 711 else 712 printf("%s, %s\n", major_devices[cls[1] & 0x1f], 713 get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); 714 } 715} 716 717static void cmd_voice(int ctl, int hdev, char *opt) 718{ 719 static char *icf[] = { "Linear", "u-Law", "A-Law", "Reserved" }; 720 static char *idf[] = { "1's complement", "2's complement", "Sign-Magnitude", "Reserved" }; 721 static char *iss[] = { "8 bit", "16 bit" }; 722 static char *acf[] = { "CVSD", "u-Law", "A-Law", "Reserved" }; 723 int s = hci_open_dev(hdev); 724 725 if (s < 0) { 726 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 727 hdev, strerror(errno), errno); 728 exit(1); 729 } 730 if (opt) { 731 uint16_t vs = htobs(strtoul(opt, NULL, 16)); 732 if (hci_write_voice_setting(s, vs, 2000) < 0) { 733 fprintf(stderr, "Can't write voice setting on hci%d: %s (%d)\n", 734 hdev, strerror(errno), errno); 735 exit(1); 736 } 737 } else { 738 uint16_t vs; 739 uint8_t ic; 740 if (hci_read_voice_setting(s, &vs, 1000) < 0) { 741 fprintf(stderr, "Can't read voice setting on hci%d: %s (%d)\n", 742 hdev, strerror(errno), errno); 743 exit(1); 744 } 745 vs = htobs(vs); 746 ic = (vs & 0x0300) >> 8; 747 print_dev_hdr(&di); 748 printf("\tVoice setting: 0x%04x%s\n", vs, 749 ((vs & 0x03fc) == 0x0060) ? " (Default Condition)" : ""); 750 printf("\tInput Coding: %s\n", icf[ic]); 751 printf("\tInput Data Format: %s\n", idf[(vs & 0xc0) >> 6]); 752 if (!ic) { 753 printf("\tInput Sample Size: %s\n", iss[(vs & 0x20) >> 5]); 754 printf("\t# of bits padding at MSB: %d\n", (vs & 0x1c) >> 2); 755 } 756 printf("\tAir Coding Format: %s\n", acf[vs & 0x03]); 757 } 758} 759 760static int get_link_key(const bdaddr_t *local, const bdaddr_t *peer, uint8_t *key) 761{ 762 char filename[PATH_MAX + 1], addr[18], tmp[3], *str; 763 int i; 764 765 ba2str(local, addr); 766 create_name(filename, PATH_MAX, STORAGEDIR, addr, "linkkeys"); 767 768 ba2str(peer, addr); 769 str = textfile_get(filename, addr); 770 if (!str) 771 return -EIO; 772 773 memset(tmp, 0, sizeof(tmp)); 774 for (i = 0; i < 16; i++) { 775 memcpy(tmp, str + (i * 2), 2); 776 key[i] = (uint8_t) strtol(tmp, NULL, 16); 777 } 778 779 free(str); 780 781 return 0; 782} 783 784static void cmd_putkey(int ctl, int hdev, char *opt) 785{ 786 struct hci_dev_info di; 787 bdaddr_t bdaddr; 788 uint8_t key[16]; 789 int dd; 790 791 if (!opt) 792 return; 793 794 dd = hci_open_dev(hdev); 795 if (dd < 0) { 796 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 797 hdev, strerror(errno), errno); 798 exit(1); 799 } 800 801 if (hci_devinfo(hdev, &di) < 0) { 802 fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", 803 hdev, strerror(errno), errno); 804 exit(1); 805 } 806 807 str2ba(opt, &bdaddr); 808 if (get_link_key(&di.bdaddr, &bdaddr, key) < 0) { 809 fprintf(stderr, "Can't find link key for %s on hci%d\n", opt, hdev); 810 exit(1); 811 } 812 813 if (hci_write_stored_link_key(dd, &bdaddr, key, 1000) < 0) { 814 fprintf(stderr, "Can't write stored link key on hci%d: %s (%d)\n", 815 hdev, strerror(errno), errno); 816 exit(1); 817 } 818 819 hci_close_dev(dd); 820} 821 822static void cmd_delkey(int ctl, int hdev, char *opt) 823{ 824 bdaddr_t bdaddr; 825 uint8_t all; 826 int dd; 827 828 if (!opt) 829 return; 830 831 dd = hci_open_dev(hdev); 832 if (dd < 0) { 833 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 834 hdev, strerror(errno), errno); 835 exit(1); 836 } 837 838 if (!strcasecmp(opt, "all")) { 839 bacpy(&bdaddr, BDADDR_ANY); 840 all = 1; 841 } else { 842 str2ba(opt, &bdaddr); 843 all = 0; 844 } 845 846 if (hci_delete_stored_link_key(dd, &bdaddr, all, 1000) < 0) { 847 fprintf(stderr, "Can't delete stored link key on hci%d: %s (%d)\n", 848 hdev, strerror(errno), errno); 849 exit(1); 850 } 851 852 hci_close_dev(dd); 853} 854 855static void cmd_oob_data(int ctl, int hdev, char *opt) 856{ 857 uint8_t hash[16], randomizer[16]; 858 int i, dd; 859 860 dd = hci_open_dev(hdev); 861 if (dd < 0) { 862 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 863 hdev, strerror(errno), errno); 864 exit(1); 865 } 866 867 if (hci_read_local_oob_data(dd, hash, randomizer, 1000) < 0) { 868 fprintf(stderr, "Can't read local OOB data on hci%d: %s (%d)\n", 869 hdev, strerror(errno), errno); 870 exit(1); 871 } 872 873 print_dev_hdr(&di); 874 printf("\tOOB Hash: "); 875 for (i = 0; i < 16; i++) 876 printf(" %02x", hash[i]); 877 printf("\n\tRandomizer:"); 878 for (i = 0; i < 16; i++) 879 printf(" %02x", randomizer[i]); 880 printf("\n"); 881 882 hci_close_dev(dd); 883} 884 885static void cmd_commands(int ctl, int hdev, char *opt) 886{ 887 uint8_t cmds[64]; 888 char *str; 889 int i, n, dd; 890 891 dd = hci_open_dev(hdev); 892 if (dd < 0) { 893 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 894 hdev, strerror(errno), errno); 895 exit(1); 896 } 897 898 if (hci_read_local_commands(dd, cmds, 1000) < 0) { 899 fprintf(stderr, "Can't read support commands on hci%d: %s (%d)\n", 900 hdev, strerror(errno), errno); 901 exit(1); 902 } 903 904 print_dev_hdr(&di); 905 for (i = 0; i < 64; i++) { 906 if (!cmds[i]) 907 continue; 908 909 printf("%s Octet %-2d = 0x%02x (Bit", 910 i ? "\t\t ": "\tCommands:", i, cmds[i]); 911 for (n = 0; n < 8; n++) 912 if (cmds[i] & (1 << n)) 913 printf(" %d", n); 914 printf(")\n"); 915 } 916 917 str = hci_commandstostr(cmds, "\t", 71); 918 printf("%s\n", str); 919 bt_free(str); 920 921 hci_close_dev(dd); 922} 923 924static void cmd_version(int ctl, int hdev, char *opt) 925{ 926 struct hci_version ver; 927 char *hciver, *lmpver; 928 int dd; 929 930 dd = hci_open_dev(hdev); 931 if (dd < 0) { 932 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 933 hdev, strerror(errno), errno); 934 exit(1); 935 } 936 937 if (hci_read_local_version(dd, &ver, 1000) < 0) { 938 fprintf(stderr, "Can't read version info hci%d: %s (%d)\n", 939 hdev, strerror(errno), errno); 940 exit(1); 941 } 942 943 hciver = hci_vertostr(ver.hci_ver); 944 lmpver = lmp_vertostr(ver.hci_ver); 945 946 print_dev_hdr(&di); 947 printf("\tHCI Version: %s (0x%x) Revision: 0x%x\n" 948 "\tLMP Version: %s (0x%x) Subversion: 0x%x\n" 949 "\tManufacturer: %s (%d)\n", 950 hciver ? hciver : "n/a", ver.hci_ver, ver.hci_rev, 951 lmpver ? lmpver : "n/a", ver.lmp_ver, ver.lmp_subver, 952 bt_compidtostr(ver.manufacturer), ver.manufacturer); 953 954 if (hciver) 955 bt_free(hciver); 956 if (lmpver) 957 bt_free(lmpver); 958 959 hci_close_dev(dd); 960} 961 962static void cmd_inq_tpl(int ctl, int hdev, char *opt) 963{ 964 int dd; 965 966 dd = hci_open_dev(hdev); 967 if (dd < 0) { 968 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 969 hdev, strerror(errno), errno); 970 exit(1); 971 } 972 973 if (opt) { 974 int8_t level = atoi(opt); 975 976 if (hci_write_inquiry_transmit_power_level(dd, level, 2000) < 0) { 977 fprintf(stderr, "Can't set inquiry transmit power level on hci%d: %s (%d)\n", 978 hdev, strerror(errno), errno); 979 exit(1); 980 } 981 } else { 982 int8_t level; 983 984 if (hci_read_inq_response_tx_power_level(dd, &level, 1000) < 0) { 985 fprintf(stderr, "Can't read inquiry transmit power level on hci%d: %s (%d)\n", 986 hdev, strerror(errno), errno); 987 exit(1); 988 } 989 990 print_dev_hdr(&di); 991 printf("\tInquiry transmit power level: %d\n", level); 992 } 993 994 hci_close_dev(dd); 995} 996 997static void cmd_inq_mode(int ctl, int hdev, char *opt) 998{ 999 int dd; 1000 1001 dd = hci_open_dev(hdev); 1002 if (dd < 0) { 1003 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1004 hdev, strerror(errno), errno); 1005 exit(1); 1006 } 1007 1008 if (opt) { 1009 uint8_t mode = atoi(opt); 1010 1011 if (hci_write_inquiry_mode(dd, mode, 2000) < 0) { 1012 fprintf(stderr, "Can't set inquiry mode on hci%d: %s (%d)\n", 1013 hdev, strerror(errno), errno); 1014 exit(1); 1015 } 1016 } else { 1017 uint8_t mode; 1018 1019 if (hci_read_inquiry_mode(dd, &mode, 1000) < 0) { 1020 fprintf(stderr, "Can't read inquiry mode on hci%d: %s (%d)\n", 1021 hdev, strerror(errno), errno); 1022 exit(1); 1023 } 1024 1025 print_dev_hdr(&di); 1026 printf("\tInquiry mode: "); 1027 switch (mode) { 1028 case 0: 1029 printf("Standard Inquiry\n"); 1030 break; 1031 case 1: 1032 printf("Inquiry with RSSI\n"); 1033 break; 1034 case 2: 1035 printf("Inquiry with RSSI or Extended Inquiry\n"); 1036 break; 1037 default: 1038 printf("Unknown (0x%02x)\n", mode); 1039 break; 1040 } 1041 } 1042 1043 hci_close_dev(dd); 1044} 1045 1046static void cmd_inq_data(int ctl, int hdev, char *opt) 1047{ 1048 int i, dd; 1049 1050 dd = hci_open_dev(hdev); 1051 if (dd < 0) { 1052 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1053 hdev, strerror(errno), errno); 1054 exit(1); 1055 } 1056 1057 if (opt) { 1058 uint8_t fec = 0, data[240]; 1059 char tmp[3]; 1060 int i, size; 1061 1062 memset(data, 0, sizeof(data)); 1063 1064 memset(tmp, 0, sizeof(tmp)); 1065 size = (strlen(opt) + 1) / 2; 1066 if (size > 240) 1067 size = 240; 1068 1069 for (i = 0; i < size; i++) { 1070 memcpy(tmp, opt + (i * 2), 2); 1071 data[i] = strtol(tmp, NULL, 16); 1072 } 1073 1074 if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) { 1075 fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n", 1076 hdev, strerror(errno), errno); 1077 exit(1); 1078 } 1079 } else { 1080 uint8_t fec, data[240], len, type, *ptr; 1081 char *str; 1082 1083 if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) < 0) { 1084 fprintf(stderr, "Can't read extended inquiry response on hci%d: %s (%d)\n", 1085 hdev, strerror(errno), errno); 1086 exit(1); 1087 } 1088 1089 print_dev_hdr(&di); 1090 printf("\tFEC %s\n\t\t", fec ? "enabled" : "disabled"); 1091 for (i = 0; i < 240; i++) 1092 printf("%02x%s%s", data[i], (i + 1) % 8 ? "" : " ", 1093 (i + 1) % 16 ? " " : (i < 239 ? "\n\t\t" : "\n")); 1094 1095 ptr = data; 1096 while (*ptr) { 1097 len = *ptr++; 1098 type = *ptr++; 1099 switch (type) { 1100 case 0x01: 1101 printf("\tFlags:"); 1102 for (i = 0; i < len - 1; i++) 1103 printf(" 0x%2.2x", *((uint8_t *) (ptr + i))); 1104 printf("\n"); 1105 break; 1106 case 0x02: 1107 case 0x03: 1108 printf("\t%s service classes:", 1109 type == 0x02 ? "Shortened" : "Complete"); 1110 for (i = 0; i < (len - 1) / 2; i++) { 1111 uint16_t val = btohs(bt_get_unaligned((uint16_t *) (ptr + (i * 2)))); 1112 printf(" 0x%4.4x", val); 1113 } 1114 printf("\n"); 1115 break; 1116 case 0x08: 1117 case 0x09: 1118 str = malloc(len); 1119 if (str) { 1120 snprintf(str, len, "%s", ptr); 1121 for (i = 0; i < len - 1; i++) { 1122 if ((unsigned char) str[i] < 32 || str[i] == 127) 1123 str[i] = '.'; 1124 } 1125 printf("\t%s local name: \'%s\'\n", 1126 type == 0x08 ? "Shortened" : "Complete", str); 1127 free(str); 1128 } 1129 break; 1130 case 0x0a: 1131 printf("\tTX power level: %d\n", *((int8_t *) ptr)); 1132 break; 1133 case 0x10: 1134 printf("\tDevice ID with %d bytes data\n", 1135 len - 1); 1136 break; 1137 default: 1138 printf("\tUnknown type 0x%02x with %d bytes data\n", 1139 type, len - 1); 1140 break; 1141 } 1142 1143 ptr += (len - 1); 1144 } 1145 1146 printf("\n"); 1147 } 1148 1149 hci_close_dev(dd); 1150} 1151 1152static void cmd_inq_type(int ctl, int hdev, char *opt) 1153{ 1154 int dd; 1155 1156 dd = hci_open_dev(hdev); 1157 if (dd < 0) { 1158 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1159 hdev, strerror(errno), errno); 1160 exit(1); 1161 } 1162 1163 if (opt) { 1164 uint8_t type = atoi(opt); 1165 1166 if (hci_write_inquiry_scan_type(dd, type, 2000) < 0) { 1167 fprintf(stderr, "Can't set inquiry scan type on hci%d: %s (%d)\n", 1168 hdev, strerror(errno), errno); 1169 exit(1); 1170 } 1171 } else { 1172 uint8_t type; 1173 1174 if (hci_read_inquiry_scan_type(dd, &type, 1000) < 0) { 1175 fprintf(stderr, "Can't read inquiry scan type on hci%d: %s (%d)\n", 1176 hdev, strerror(errno), errno); 1177 exit(1); 1178 } 1179 1180 print_dev_hdr(&di); 1181 printf("\tInquiry scan type: %s\n", 1182 type == 1 ? "Interlaced Inquiry Scan" : "Standard Inquiry Scan"); 1183 } 1184 1185 hci_close_dev(dd); 1186} 1187 1188static void cmd_inq_parms(int ctl, int hdev, char *opt) 1189{ 1190 struct hci_request rq; 1191 int s; 1192 1193 if ((s = hci_open_dev(hdev)) < 0) { 1194 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1195 hdev, strerror(errno), errno); 1196 exit(1); 1197 } 1198 1199 memset(&rq, 0, sizeof(rq)); 1200 1201 if (opt) { 1202 unsigned int window, interval; 1203 write_inq_activity_cp cp; 1204 1205 if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) { 1206 printf("Invalid argument format\n"); 1207 exit(1); 1208 } 1209 1210 rq.ogf = OGF_HOST_CTL; 1211 rq.ocf = OCF_WRITE_INQ_ACTIVITY; 1212 rq.cparam = &cp; 1213 rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE; 1214 1215 cp.window = htobs((uint16_t) window); 1216 cp.interval = htobs((uint16_t) interval); 1217 1218 if (window < 0x12 || window > 0x1000) 1219 printf("Warning: inquiry window out of range!\n"); 1220 1221 if (interval < 0x12 || interval > 0x1000) 1222 printf("Warning: inquiry interval out of range!\n"); 1223 1224 if (hci_send_req(s, &rq, 2000) < 0) { 1225 fprintf(stderr, "Can't set inquiry parameters name on hci%d: %s (%d)\n", 1226 hdev, strerror(errno), errno); 1227 exit(1); 1228 } 1229 } else { 1230 uint16_t window, interval; 1231 read_inq_activity_rp rp; 1232 1233 rq.ogf = OGF_HOST_CTL; 1234 rq.ocf = OCF_READ_INQ_ACTIVITY; 1235 rq.rparam = &rp; 1236 rq.rlen = READ_INQ_ACTIVITY_RP_SIZE; 1237 1238 if (hci_send_req(s, &rq, 1000) < 0) { 1239 fprintf(stderr, "Can't read inquiry parameters on hci%d: %s (%d)\n", 1240 hdev, strerror(errno), errno); 1241 exit(1); 1242 } 1243 if (rp.status) { 1244 printf("Read inquiry parameters on hci%d returned status %d\n", 1245 hdev, rp.status); 1246 exit(1); 1247 } 1248 print_dev_hdr(&di); 1249 1250 window = btohs(rp.window); 1251 interval = btohs(rp.interval); 1252 printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", 1253 interval, (float)interval * 0.625, window, (float)window * 0.625); 1254 } 1255} 1256 1257static void cmd_page_parms(int ctl, int hdev, char *opt) 1258{ 1259 struct hci_request rq; 1260 int s; 1261 1262 if ((s = hci_open_dev(hdev)) < 0) { 1263 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1264 hdev, strerror(errno), errno); 1265 exit(1); 1266 } 1267 1268 memset(&rq, 0, sizeof(rq)); 1269 1270 if (opt) { 1271 unsigned int window, interval; 1272 write_page_activity_cp cp; 1273 1274 if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) { 1275 printf("Invalid argument format\n"); 1276 exit(1); 1277 } 1278 1279 rq.ogf = OGF_HOST_CTL; 1280 rq.ocf = OCF_WRITE_PAGE_ACTIVITY; 1281 rq.cparam = &cp; 1282 rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE; 1283 1284 cp.window = htobs((uint16_t) window); 1285 cp.interval = htobs((uint16_t) interval); 1286 1287 if (window < 0x12 || window > 0x1000) 1288 printf("Warning: page window out of range!\n"); 1289 1290 if (interval < 0x12 || interval > 0x1000) 1291 printf("Warning: page interval out of range!\n"); 1292 1293 if (hci_send_req(s, &rq, 2000) < 0) { 1294 fprintf(stderr, "Can't set page parameters name on hci%d: %s (%d)\n", 1295 hdev, strerror(errno), errno); 1296 exit(1); 1297 } 1298 } else { 1299 uint16_t window, interval; 1300 read_page_activity_rp rp; 1301 1302 rq.ogf = OGF_HOST_CTL; 1303 rq.ocf = OCF_READ_PAGE_ACTIVITY; 1304 rq.rparam = &rp; 1305 rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE; 1306 1307 if (hci_send_req(s, &rq, 1000) < 0) { 1308 fprintf(stderr, "Can't read page parameters on hci%d: %s (%d)\n", 1309 hdev, strerror(errno), errno); 1310 exit(1); 1311 } 1312 if (rp.status) { 1313 printf("Read page parameters on hci%d returned status %d\n", 1314 hdev, rp.status); 1315 exit(1); 1316 } 1317 print_dev_hdr(&di); 1318 1319 window = btohs(rp.window); 1320 interval = btohs(rp.interval); 1321 printf("\tPage interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", 1322 interval, (float)interval * 0.625, window, (float)window * 0.625); 1323 } 1324} 1325 1326static void cmd_page_to(int ctl, int hdev, char *opt) 1327{ 1328 struct hci_request rq; 1329 int s; 1330 1331 if ((s = hci_open_dev(hdev)) < 0) { 1332 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1333 hdev, strerror(errno), errno); 1334 exit(1); 1335 } 1336 1337 memset(&rq, 0, sizeof(rq)); 1338 1339 if (opt) { 1340 unsigned int timeout; 1341 write_page_timeout_cp cp; 1342 1343 if (sscanf(opt,"%5u", &timeout) != 1) { 1344 printf("Invalid argument format\n"); 1345 exit(1); 1346 } 1347 1348 rq.ogf = OGF_HOST_CTL; 1349 rq.ocf = OCF_WRITE_PAGE_TIMEOUT; 1350 rq.cparam = &cp; 1351 rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE; 1352 1353 cp.timeout = htobs((uint16_t) timeout); 1354 1355 if (timeout < 0x01 || timeout > 0xFFFF) 1356 printf("Warning: page timeout out of range!\n"); 1357 1358 if (hci_send_req(s, &rq, 2000) < 0) { 1359 fprintf(stderr, "Can't set page timeout on hci%d: %s (%d)\n", 1360 hdev, strerror(errno), errno); 1361 exit(1); 1362 } 1363 } else { 1364 uint16_t timeout; 1365 read_page_timeout_rp rp; 1366 1367 rq.ogf = OGF_HOST_CTL; 1368 rq.ocf = OCF_READ_PAGE_TIMEOUT; 1369 rq.rparam = &rp; 1370 rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE; 1371 1372 if (hci_send_req(s, &rq, 1000) < 0) { 1373 fprintf(stderr, "Can't read page timeout on hci%d: %s (%d)\n", 1374 hdev, strerror(errno), errno); 1375 exit(1); 1376 } 1377 if (rp.status) { 1378 printf("Read page timeout on hci%d returned status %d\n", 1379 hdev, rp.status); 1380 exit(1); 1381 } 1382 print_dev_hdr(&di); 1383 1384 timeout = btohs(rp.timeout); 1385 printf("\tPage timeout: %u slots (%.2f ms)\n", 1386 timeout, (float)timeout * 0.625); 1387 } 1388} 1389 1390static void cmd_afh_mode(int ctl, int hdev, char *opt) 1391{ 1392 int dd; 1393 1394 dd = hci_open_dev(hdev); 1395 if (dd < 0) { 1396 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1397 hdev, strerror(errno), errno); 1398 exit(1); 1399 } 1400 1401 if (opt) { 1402 uint8_t mode = atoi(opt); 1403 1404 if (hci_write_afh_mode(dd, mode, 2000) < 0) { 1405 fprintf(stderr, "Can't set AFH mode on hci%d: %s (%d)\n", 1406 hdev, strerror(errno), errno); 1407 exit(1); 1408 } 1409 } else { 1410 uint8_t mode; 1411 1412 if (hci_read_afh_mode(dd, &mode, 1000) < 0) { 1413 fprintf(stderr, "Can't read AFH mode on hci%d: %s (%d)\n", 1414 hdev, strerror(errno), errno); 1415 exit(1); 1416 } 1417 1418 print_dev_hdr(&di); 1419 printf("\tAFH mode: %s\n", mode == 1 ? "Enabled" : "Disabled"); 1420 } 1421} 1422 1423static void cmd_ssp_mode(int ctl, int hdev, char *opt) 1424{ 1425 int dd; 1426 1427 dd = hci_open_dev(hdev); 1428 if (dd < 0) { 1429 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1430 hdev, strerror(errno), errno); 1431 exit(1); 1432 } 1433 1434 if (opt) { 1435 uint8_t mode = atoi(opt); 1436 1437 if (hci_write_simple_pairing_mode(dd, mode, 2000) < 0) { 1438 fprintf(stderr, "Can't set Simple Pairing mode on hci%d: %s (%d)\n", 1439 hdev, strerror(errno), errno); 1440 exit(1); 1441 } 1442 } else { 1443 uint8_t mode; 1444 1445 if (hci_read_simple_pairing_mode(dd, &mode, 1000) < 0) { 1446 fprintf(stderr, "Can't read Simple Pairing mode on hci%d: %s (%d)\n", 1447 hdev, strerror(errno), errno); 1448 exit(1); 1449 } 1450 1451 print_dev_hdr(&di); 1452 printf("\tSimple Pairing mode: %s\n", mode == 1 ? "Enabled" : "Disabled"); 1453 } 1454} 1455 1456static void print_rev_ericsson(int dd) 1457{ 1458 struct hci_request rq; 1459 unsigned char buf[102]; 1460 1461 memset(&rq, 0, sizeof(rq)); 1462 rq.ogf = OGF_VENDOR_CMD; 1463 rq.ocf = 0x000f; 1464 rq.cparam = NULL; 1465 rq.clen = 0; 1466 rq.rparam = &buf; 1467 rq.rlen = sizeof(buf); 1468 1469 if (hci_send_req(dd, &rq, 1000) < 0) { 1470 printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno); 1471 return; 1472 } 1473 1474 printf("\t%s\n", buf + 1); 1475} 1476 1477static void print_rev_csr(int dd, uint16_t rev) 1478{ 1479 uint16_t buildid, chipver, chiprev, maxkeylen, mapsco; 1480 1481 if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { 1482 printf("\t%s\n", csr_buildidtostr(rev)); 1483 return; 1484 } 1485 1486 printf("\t%s\n", csr_buildidtostr(buildid)); 1487 1488 if (!csr_read_varid_uint16(dd, 1, CSR_VARID_CHIPVER, &chipver)) { 1489 if (csr_read_varid_uint16(dd, 2, CSR_VARID_CHIPREV, &chiprev) < 0) 1490 chiprev = 0; 1491 printf("\tChip version: %s\n", csr_chipvertostr(chipver, chiprev)); 1492 } 1493 1494 if (!csr_read_varid_uint16(dd, 3, CSR_VARID_MAX_CRYPT_KEY_LENGTH, &maxkeylen)) 1495 printf("\tMax key size: %d bit\n", maxkeylen * 8); 1496 1497 if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, 0x0000, &mapsco)) 1498 printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); 1499} 1500 1501static void print_rev_digianswer(int dd) 1502{ 1503 struct hci_request rq; 1504 unsigned char req[] = { 0x07 }; 1505 unsigned char buf[102]; 1506 1507 memset(&rq, 0, sizeof(rq)); 1508 rq.ogf = OGF_VENDOR_CMD; 1509 rq.ocf = 0x000e; 1510 rq.cparam = req; 1511 rq.clen = sizeof(req); 1512 rq.rparam = &buf; 1513 rq.rlen = sizeof(buf); 1514 1515 if (hci_send_req(dd, &rq, 1000) < 0) { 1516 printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno); 1517 return; 1518 } 1519 1520 printf("\t%s\n", buf + 1); 1521} 1522 1523static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) 1524{ 1525 printf("\tFirmware %d.%d / %d\n", hci_rev & 0xff, lmp_subver >> 8, lmp_subver & 0xff); 1526} 1527 1528static void print_rev_avm(uint16_t hci_rev, uint16_t lmp_subver) 1529{ 1530 if (lmp_subver == 0x01) 1531 printf("\tFirmware 03.%d.%d\n", hci_rev >> 8, hci_rev & 0xff); 1532 else 1533 printf("\tUnknown type\n"); 1534} 1535 1536static void cmd_revision(int ctl, int hdev, char *opt) 1537{ 1538 struct hci_version ver; 1539 int dd; 1540 1541 dd = hci_open_dev(hdev); 1542 if (dd < 0) { 1543 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1544 hdev, strerror(errno), errno); 1545 return; 1546 } 1547 1548 if (hci_read_local_version(dd, &ver, 1000) < 0) { 1549 fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", 1550 hdev, strerror(errno), errno); 1551 return; 1552 } 1553 1554 print_dev_hdr(&di); 1555 switch (ver.manufacturer) { 1556 case 0: 1557 case 37: 1558 case 48: 1559 print_rev_ericsson(dd); 1560 break; 1561 case 10: 1562 print_rev_csr(dd, ver.hci_rev); 1563 break; 1564 case 12: 1565 print_rev_digianswer(dd); 1566 break; 1567 case 15: 1568 print_rev_broadcom(ver.hci_rev, ver.lmp_subver); 1569 break; 1570 case 31: 1571 print_rev_avm(ver.hci_rev, ver.lmp_subver); 1572 break; 1573 default: 1574 printf("\tUnsupported manufacturer\n"); 1575 break; 1576 } 1577 return; 1578} 1579 1580static void cmd_block(int ctl, int hdev, char *opt) 1581{ 1582 bdaddr_t bdaddr; 1583 int dd; 1584 1585 if (!opt) 1586 return; 1587 1588 dd = hci_open_dev(hdev); 1589 if (dd < 0) { 1590 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1591 hdev, strerror(errno), errno); 1592 exit(1); 1593 } 1594 1595 str2ba(opt, &bdaddr); 1596 1597 if (ioctl(dd, HCIBLOCKADDR, &bdaddr) < 0) { 1598 perror("ioctl(HCIBLOCKADDR)"); 1599 exit(1); 1600 } 1601 1602 hci_close_dev(dd); 1603} 1604 1605static void cmd_unblock(int ctl, int hdev, char *opt) 1606{ 1607 bdaddr_t bdaddr; 1608 int dd; 1609 1610 if (!opt) 1611 return; 1612 1613 dd = hci_open_dev(hdev); 1614 if (dd < 0) { 1615 fprintf(stderr, "Can't open device hci%d: %s (%d)\n", 1616 hdev, strerror(errno), errno); 1617 exit(1); 1618 } 1619 1620 if (!strcasecmp(opt, "all")) 1621 bacpy(&bdaddr, BDADDR_ANY); 1622 else 1623 str2ba(opt, &bdaddr); 1624 1625 if (ioctl(dd, HCIUNBLOCKADDR, &bdaddr) < 0) { 1626 perror("ioctl(HCIUNBLOCKADDR)"); 1627 exit(1); 1628 } 1629 1630 hci_close_dev(dd); 1631} 1632 1633static void print_dev_hdr(struct hci_dev_info *di) 1634{ 1635 static int hdr = -1; 1636 char addr[18]; 1637 1638 if (hdr == di->dev_id) 1639 return; 1640 hdr = di->dev_id; 1641 1642 ba2str(&di->bdaddr, addr); 1643 1644 printf("%s:\tType: %s Bus: %s\n", di->name, 1645 hci_typetostr(di->type >> 4), 1646 hci_bustostr(di->type & 0x0f)); 1647 printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", 1648 addr, di->acl_mtu, di->acl_pkts, 1649 di->sco_mtu, di->sco_pkts); 1650} 1651 1652static void print_dev_info(int ctl, struct hci_dev_info *di) 1653{ 1654 struct hci_dev_stats *st = &di->stat; 1655 char *str; 1656 1657 print_dev_hdr(di); 1658 1659 str = hci_dflagstostr(di->flags); 1660 printf("\t%s\n", str); 1661 bt_free(str); 1662 1663 printf("\tRX bytes:%d acl:%d sco:%d events:%d errors:%d\n", 1664 st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx); 1665 1666 printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n", 1667 st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); 1668 1669 if (all && !hci_test_bit(HCI_RAW, &di->flags) && 1670 bacmp(&di->bdaddr, BDADDR_ANY)) { 1671 print_dev_features(di, 0); 1672 print_pkt_type(di); 1673 print_link_policy(di); 1674 print_link_mode(di); 1675 1676 if (hci_test_bit(HCI_UP, &di->flags)) { 1677 cmd_name(ctl, di->dev_id, NULL); 1678 cmd_class(ctl, di->dev_id, NULL); 1679 cmd_version(ctl, di->dev_id, NULL); 1680 } 1681 } 1682 1683 printf("\n"); 1684} 1685 1686static struct { 1687 char *cmd; 1688 void (*func)(int ctl, int hdev, char *opt); 1689 char *opt; 1690 char *doc; 1691} command[] = { 1692 { "up", cmd_up, 0, "Open and initialize HCI device" }, 1693 { "down", cmd_down, 0, "Close HCI device" }, 1694 { "reset", cmd_reset, 0, "Reset HCI device" }, 1695 { "rstat", cmd_rstat, 0, "Reset statistic counters" }, 1696 { "auth", cmd_auth, 0, "Enable Authentication" }, 1697 { "noauth", cmd_auth, 0, "Disable Authentication" }, 1698 { "encrypt", cmd_encrypt, 0, "Enable Encryption" }, 1699 { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, 1700 { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, 1701 { "noscan", cmd_scan, 0, "Disable scan" }, 1702 { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, 1703 { "pscan", cmd_scan, 0, "Enable Page scan" }, 1704 { "ptype", cmd_ptype, "[type]", "Get/Set default packet type" }, 1705 { "lm", cmd_lm, "[mode]", "Get/Set default link mode" }, 1706 { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, 1707 { "name", cmd_name, "[name]", "Get/Set local name" }, 1708 { "class", cmd_class, "[class]", "Get/Set class of device" }, 1709 { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, 1710 { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, 1711 { "inqtpl", cmd_inq_tpl, "[level]", "Get/Set inquiry transmit power level" }, 1712 { "inqmode", cmd_inq_mode, "[mode]", "Get/Set inquiry mode" }, 1713 { "inqdata", cmd_inq_data, "[data]", "Get/Set inquiry data" }, 1714 { "inqtype", cmd_inq_type, "[type]", "Get/Set inquiry scan type" }, 1715 { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, 1716 { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, 1717 { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, 1718 { "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" }, 1719 { "sspmode", cmd_ssp_mode, "[mode]", "Get/Set Simple Pairing Mode" }, 1720 { "aclmtu", cmd_aclmtu, "<mtu:pkt>", "Set ACL MTU and number of packets" }, 1721 { "scomtu", cmd_scomtu, "<mtu:pkt>", "Set SCO MTU and number of packets" }, 1722 { "putkey", cmd_putkey, "<bdaddr>", "Store link key on the device" }, 1723 { "delkey", cmd_delkey, "<bdaddr>", "Delete link key from the device" }, 1724 { "oobdata", cmd_oob_data, 0, "Display local OOB data" }, 1725 { "commands", cmd_commands, 0, "Display supported commands" }, 1726 { "features", cmd_features, 0, "Display device features" }, 1727 { "version", cmd_version, 0, "Display version information" }, 1728 { "revision", cmd_revision, 0, "Display revision information" }, 1729 { "block", cmd_block, "<bdaddr>", "Add a device to the blacklist" }, 1730 { "unblock", cmd_unblock, "<bdaddr>", "Remove a device from the blacklist" }, 1731 { NULL, NULL, 0 } 1732}; 1733 1734static void usage(void) 1735{ 1736 int i; 1737 1738 printf("hciconfig - HCI device configuration utility\n"); 1739 printf("Usage:\n" 1740 "\thciconfig\n" 1741 "\thciconfig [-a] hciX [command]\n"); 1742 printf("Commands:\n"); 1743 for (i=0; command[i].cmd; i++) 1744 printf("\t%-10s %-8s\t%s\n", command[i].cmd, 1745 command[i].opt ? command[i].opt : " ", 1746 command[i].doc); 1747} 1748 1749static struct option main_options[] = { 1750 { "help", 0, 0, 'h' }, 1751 { "all", 0, 0, 'a' }, 1752 { 0, 0, 0, 0 } 1753}; 1754 1755int main(int argc, char *argv[]) 1756{ 1757 int opt, ctl, i, cmd=0; 1758 1759 while ((opt=getopt_long(argc, argv, "ah", main_options, NULL)) != -1) { 1760 switch(opt) { 1761 case 'a': 1762 all = 1; 1763 break; 1764 1765 case 'h': 1766 default: 1767 usage(); 1768 exit(0); 1769 } 1770 } 1771 1772 argc -= optind; 1773 argv += optind; 1774 optind = 0; 1775 1776 /* Open HCI socket */ 1777 if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { 1778 perror("Can't open HCI socket."); 1779 exit(1); 1780 } 1781 1782 if (argc < 1) { 1783 print_dev_list(ctl, 0); 1784 exit(0); 1785 } 1786 1787 di.dev_id = atoi(argv[0] + 3); 1788 argc--; argv++; 1789 1790 if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) { 1791 perror("Can't get device info"); 1792 exit(1); 1793 } 1794 1795 if (hci_test_bit(HCI_RAW, &di.flags) && 1796 !bacmp(&di.bdaddr, BDADDR_ANY)) { 1797 int dd = hci_open_dev(di.dev_id); 1798 hci_read_bd_addr(dd, &di.bdaddr, 1000); 1799 hci_close_dev(dd); 1800 } 1801 1802 while (argc > 0) { 1803 for (i = 0; command[i].cmd; i++) { 1804 if (strncmp(command[i].cmd, *argv, 5)) 1805 continue; 1806 1807 if (command[i].opt) { 1808 argc--; argv++; 1809 } 1810 1811 command[i].func(ctl, di.dev_id, *argv); 1812 cmd = 1; 1813 break; 1814 } 1815 argc--; argv++; 1816 } 1817 1818 if (!cmd) 1819 print_dev_info(ctl, &di); 1820 1821 close(ctl); 1822 return 0; 1823} 1824