30 */ 31 32#include <bluetooth.h> 33#include <errno.h> 34#include <stdio.h> 35#include <string.h> 36#include "hccontrol.h" 37 38/* Convert hex ASCII to int4 */ 39static int 40hci_hexa2int4(const char *a) 41{ 42 if ('0' <= *a && *a <= '9') 43 return (*a - '0'); 44 45 if ('A' <= *a && *a <= 'F') 46 return (*a - 'A' + 0xa); 47 48 if ('a' <= *a && *a <= 'f') 49 return (*a - 'a' + 0xa); 50 51 return (-1); 52} 53 54/* Convert hex ASCII to int8 */ 55static int 56hci_hexa2int8(const char *a) 57{ 58 int hi = hci_hexa2int4(a); 59 int lo = hci_hexa2int4(a + 1); 60 61 if (hi < 0 || lo < 0) 62 return (-1); 63 64 return ((hi << 4) | lo); 65} 66 67/* Convert ascii hex string to the uint8_t[] */ 68static int 69hci_hexstring2array(char const *s, uint8_t *a, int asize) 70{ 71 int i, l, b; 72 73 l = strlen(s) / 2; 74 if (l > asize) 75 l = asize; 76 77 for (i = 0; i < l; i++) { 78 b = hci_hexa2int8(s + i * 2); 79 if (b < 0) 80 return (-1); 81 82 a[i] = (b & 0xff); 83 } 84 85 return (0); 86} 87 88/* Send RESET to the unit */ 89static int 90hci_reset(int s, int argc, char **argv) 91{ 92 ng_hci_status_rp rp; 93 int n; 94 95 n = sizeof(rp); 96 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 97 NG_HCI_OCF_RESET), (char *) &rp, &n) == ERROR) 98 return (ERROR); 99 100 if (rp.status != 0x00) { 101 fprintf(stdout, "Status: %s [%#02x]\n", 102 hci_status2str(rp.status), rp.status); 103 return (FAILED); 104 } 105 106 return (OK); 107} /* hci_reset */ 108 109/* Send Read_PIN_Type command to the unit */ 110static int 111hci_read_pin_type(int s, int argc, char **argv) 112{ 113 ng_hci_read_pin_type_rp rp; 114 int n; 115 116 n = sizeof(rp); 117 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 118 NG_HCI_OCF_READ_PIN_TYPE), 119 (char *) &rp, &n) == ERROR) 120 return (ERROR); 121 122 if (rp.status != 0x00) { 123 fprintf(stdout, "Status: %s [%#02x]\n", 124 hci_status2str(rp.status), rp.status); 125 return (FAILED); 126 } 127 128 fprintf(stdout, "PIN type: %s [%#02x]\n", 129 hci_pin2str(rp.pin_type), rp.pin_type); 130 131 return (OK); 132} /* hci_read_pin_type */ 133 134/* Send Write_PIN_Type command to the unit */ 135static int 136hci_write_pin_type(int s, int argc, char **argv) 137{ 138 ng_hci_write_pin_type_cp cp; 139 ng_hci_write_pin_type_rp rp; 140 int n; 141 142 /* parse command parameters */ 143 switch (argc) { 144 case 1: 145 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1) 146 return (USAGE); 147 148 cp.pin_type = (uint8_t) n; 149 break; 150 151 default: 152 return (USAGE); 153 } 154 155 /* send command */ 156 n = sizeof(rp); 157 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 158 NG_HCI_OCF_WRITE_PIN_TYPE), 159 (char const *) &cp, sizeof(cp), 160 (char *) &rp , &n) == ERROR) 161 return (ERROR); 162 163 if (rp.status != 0x00) { 164 fprintf(stdout, "Status: %s [%#02x]\n", 165 hci_status2str(rp.status), rp.status); 166 return (FAILED); 167 } 168 169 return (OK); 170} /* hci_write_pin_type */ 171 172/* Send Read_Stored_Link_Key command to the unit */ 173static int 174hci_read_stored_link_key(int s, int argc, char **argv) 175{ 176 struct { 177 ng_hci_cmd_pkt_t hdr; 178 ng_hci_read_stored_link_key_cp cp; 179 } __attribute__ ((packed)) cmd; 180 181 struct { 182 ng_hci_event_pkt_t hdr; 183 union { 184 ng_hci_command_compl_ep cc; 185 ng_hci_return_link_keys_ep key; 186 uint8_t b[NG_HCI_EVENT_PKT_SIZE]; 187 } ep; 188 } __attribute__ ((packed)) event; 189 190 int n, n1; 191 192 /* Send command */ 193 memset(&cmd, 0, sizeof(cmd)); 194 cmd.hdr.type = NG_HCI_CMD_PKT; 195 cmd.hdr.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 196 NG_HCI_OCF_READ_STORED_LINK_KEY)); 197 cmd.hdr.length = sizeof(cmd.cp); 198 199 switch (argc) { 200 case 1: 201 /* parse BD_ADDR */ 202 if (!bt_aton(argv[0], &cmd.cp.bdaddr)) { 203 struct hostent *he = NULL; 204 205 if ((he = bt_gethostbyname(argv[0])) == NULL) 206 return (USAGE); 207 208 memcpy(&cmd.cp.bdaddr, he->h_addr, sizeof(cmd.cp.bdaddr)); 209 } 210 break; 211 212 default: 213 cmd.cp.read_all = 1; 214 break; 215 } 216 217 if (hci_send(s, (char const *) &cmd, sizeof(cmd)) != OK) 218 return (ERROR); 219 220 /* Receive events */ 221again: 222 memset(&event, 0, sizeof(event)); 223 n = sizeof(event); 224 if (hci_recv(s, (char *) &event, &n) != OK) 225 return (ERROR); 226 227 if (n <= sizeof(event.hdr)) { 228 errno = EMSGSIZE; 229 return (ERROR); 230 } 231 232 if (event.hdr.type != NG_HCI_EVENT_PKT) { 233 errno = EIO; 234 return (ERROR); 235 } 236 237 /* Parse event */ 238 switch (event.hdr.event) { 239 case NG_HCI_EVENT_COMMAND_COMPL: { 240 ng_hci_read_stored_link_key_rp *rp = NULL; 241 242 if (event.ep.cc.opcode == 0x0000 || 243 event.ep.cc.opcode != cmd.hdr.opcode) 244 goto again; 245 246 rp = (ng_hci_read_stored_link_key_rp *)(event.ep.b + 247 sizeof(event.ep.cc)); 248 249 fprintf(stdout, "Complete: Status: %s [%#x]\n", 250 hci_status2str(rp->status), rp->status); 251 fprintf(stdout, "Maximum Number of keys: %d\n", 252 le16toh(rp->max_num_keys)); 253 fprintf(stdout, "Number of keys read: %d\n", 254 le16toh(rp->num_keys_read)); 255 } break; 256 257 case NG_HCI_EVENT_RETURN_LINK_KEYS: { 258 struct _key { 259 bdaddr_t bdaddr; 260 uint8_t key[NG_HCI_KEY_SIZE]; 261 } __attribute__ ((packed)) *k = NULL; 262 263 fprintf(stdout, "Event: Number of keys: %d\n", 264 event.ep.key.num_keys); 265 266 k = (struct _key *)(event.ep.b + sizeof(event.ep.key)); 267 for (n = 0; n < event.ep.key.num_keys; n++) { 268 fprintf(stdout, "\t%d: %s ", 269 n + 1, hci_bdaddr2str(&k->bdaddr)); 270 271 for (n1 = 0; n1 < sizeof(k->key); n1++) 272 fprintf(stdout, "%02x", k->key[n1]); 273 fprintf(stdout, "\n"); 274 275 k ++; 276 } 277 278 goto again; 279 280 } break; 281 282 default: 283 goto again; 284 } 285 286 return (OK); 287} /* hci_read_store_link_key */ 288 289/* Send Write_Stored_Link_Key command to the unit */ 290static int 291hci_write_stored_link_key(int s, int argc, char **argv) 292{ 293 struct { 294 ng_hci_write_stored_link_key_cp p; 295 bdaddr_t bdaddr; 296 uint8_t key[NG_HCI_KEY_SIZE]; 297 } cp; 298 ng_hci_write_stored_link_key_rp rp; 299 int32_t n; 300 301 memset(&cp, 0, sizeof(cp)); 302 303 switch (argc) { 304 case 2: 305 cp.p.num_keys_write = 1; 306 307 /* parse BD_ADDR */ 308 if (!bt_aton(argv[0], &cp.bdaddr)) { 309 struct hostent *he = NULL; 310 311 if ((he = bt_gethostbyname(argv[0])) == NULL) 312 return (USAGE); 313 314 memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr)); 315 } 316 317 /* parse key */ 318 if (hci_hexstring2array(argv[1], cp.key, sizeof(cp.key)) < 0) 319 return (USAGE); 320 break; 321 322 default: 323 return (USAGE); 324 } 325 326 /* send command */ 327 n = sizeof(rp); 328 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 329 NG_HCI_OCF_WRITE_STORED_LINK_KEY), 330 (char const *) &cp, sizeof(cp), 331 (char *) &rp, &n) == ERROR) 332 return (ERROR); 333 334 if (rp.status != 0x00) { 335 fprintf(stdout, "Status: %s [%#02x]\n", 336 hci_status2str(rp.status), rp.status); 337 return (FAILED); 338 } 339 340 fprintf(stdout, "Number of keys written: %d\n", rp.num_keys_written); 341 342 return (OK); 343} /* hci_write_stored_link_key */ 344 345 346/* Send Delete_Stored_Link_Key command to the unit */ 347static int 348hci_delete_stored_link_key(int s, int argc, char **argv) 349{ 350 ng_hci_delete_stored_link_key_cp cp; 351 ng_hci_delete_stored_link_key_rp rp; 352 int32_t n; 353 354 memset(&cp, 0, sizeof(cp)); 355 356 switch (argc) { 357 case 1: 358 /* parse BD_ADDR */ 359 if (!bt_aton(argv[0], &cp.bdaddr)) { 360 struct hostent *he = NULL; 361 362 if ((he = bt_gethostbyname(argv[0])) == NULL) 363 return (USAGE); 364 365 memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr)); 366 } 367 break; 368 369 default: 370 cp.delete_all = 1; 371 break; 372 } 373 374 /* send command */ 375 n = sizeof(cp); 376 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 377 NG_HCI_OCF_DELETE_STORED_LINK_KEY), 378 (char const *) &cp, sizeof(cp), 379 (char *) &rp, &n) == ERROR) 380 return (ERROR); 381 382 if (rp.status != 0x00) { 383 fprintf(stdout, "Status: %s [%#02x]\n", 384 hci_status2str(rp.status), rp.status); 385 return (FAILED); 386 } 387 388 fprintf(stdout, "Number of keys deleted: %d\n", rp.num_keys_deleted); 389 390 return (OK); 391} /* hci_delete_stored_link_key */ 392 393/* Send Change_Local_Name command to the unit */ 394static int 395hci_change_local_name(int s, int argc, char **argv) 396{ 397 ng_hci_change_local_name_cp cp; 398 ng_hci_change_local_name_rp rp; 399 int n; 400 401 /* parse command parameters */ 402 switch (argc) { 403 case 1: 404 snprintf(cp.name, sizeof(cp.name), "%s", argv[0]); 405 break; 406 407 default: 408 return (USAGE); 409 } 410 411 /* send command */ 412 n = sizeof(rp); 413 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 414 NG_HCI_OCF_CHANGE_LOCAL_NAME), 415 (char const *) &cp, sizeof(cp), 416 (char *) &rp, &n) == ERROR) 417 return (ERROR); 418 419 if (rp.status != 0x00) { 420 fprintf(stdout, "Status: %s [%#02x]\n", 421 hci_status2str(rp.status), rp.status); 422 return (FAILED); 423 } 424 425 return (OK); 426} /* hci_change_local_name */ 427 428/* Send Read_Local_Name command to the unit */ 429static int 430hci_read_local_name(int s, int argc, char **argv) 431{ 432 ng_hci_read_local_name_rp rp; 433 int n; 434 435 n = sizeof(rp); 436 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 437 NG_HCI_OCF_READ_LOCAL_NAME), 438 (char *) &rp, &n) == ERROR) 439 return (ERROR); 440 441 if (rp.status != 0x00) { 442 fprintf(stdout, "Status: %s [%#02x]\n", 443 hci_status2str(rp.status), rp.status); 444 return (FAILED); 445 } 446 447 fprintf(stdout, "Local name: %s\n", rp.name); 448 449 return (OK); 450} /* hci_read_local_name */ 451 452/* Send Read_Connection_Accept_Timeout to the unit */ 453static int 454hci_read_connection_accept_timeout(int s, int argc, char **argv) 455{ 456 ng_hci_read_con_accept_timo_rp rp; 457 int n; 458 459 n = sizeof(rp); 460 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 461 NG_HCI_OCF_READ_CON_ACCEPT_TIMO), 462 (char *) &rp, &n) == ERROR) 463 return (ERROR); 464 465 if (rp.status != 0x00) { 466 fprintf(stdout, "Status: %s [%#02x]\n", 467 hci_status2str(rp.status), rp.status); 468 return (FAILED); 469 } 470 471 rp.timeout = le16toh(rp.timeout); 472 fprintf(stdout, "Connection accept timeout: %.2f msec [%d slots]\n", 473 rp.timeout * 0.625, rp.timeout); 474 475 return (OK); 476} /* hci_read_connection_accept_timeout */ 477 478/* Send Write_Connection_Accept_Timeout to the unit */ 479static int 480hci_write_connection_accept_timeout(int s, int argc, char **argv) 481{ 482 ng_hci_write_con_accept_timo_cp cp; 483 ng_hci_write_con_accept_timo_rp rp; 484 int n; 485 486 /* parse command parameters */ 487 switch (argc) { 488 case 1: 489 if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xb540) 490 return (USAGE); 491 492 cp.timeout = (uint16_t) n; 493 cp.timeout = htole16(cp.timeout); 494 break; 495 496 default: 497 return (USAGE); 498 } 499 500 /* send command */ 501 n = sizeof(rp); 502 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 503 NG_HCI_OCF_WRITE_CON_ACCEPT_TIMO), 504 (char const *) &cp, sizeof(cp), 505 (char *) &rp, &n) == ERROR) 506 return (ERROR); 507 508 if (rp.status != 0x00) { 509 fprintf(stdout, "Status: %s [%#02x]\n", 510 hci_status2str(rp.status), rp.status); 511 return (FAILED); 512 } 513 514 return (OK); 515} /* hci_write_connection_accept_timeout */ 516 517/* Send Read_Page_Timeout command to the unit */ 518static int 519hci_read_page_timeout(int s, int argc, char **argv) 520{ 521 ng_hci_read_page_timo_rp rp; 522 int n; 523 524 n = sizeof(rp); 525 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 526 NG_HCI_OCF_READ_PAGE_TIMO), 527 (char *) &rp, &n) == ERROR) 528 return (ERROR); 529 530 if (rp.status != 0x00) { 531 fprintf(stdout, "Status: %s [%#02x]\n", 532 hci_status2str(rp.status), rp.status); 533 return (FAILED); 534 } 535 536 rp.timeout = le16toh(rp.timeout); 537 fprintf(stdout, "Page timeout: %.2f msec [%d slots]\n", 538 rp.timeout * 0.625, rp.timeout); 539 540 return (OK); 541} /* hci_read_page_timeoout */ 542 543/* Send Write_Page_Timeout command to the unit */ 544static int 545hci_write_page_timeout(int s, int argc, char **argv) 546{ 547 ng_hci_write_page_timo_cp cp; 548 ng_hci_write_page_timo_rp rp; 549 int n; 550 551 /* parse command parameters */ 552 switch (argc) { 553 case 1: 554 if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xffff) 555 return (USAGE); 556 557 cp.timeout = (uint16_t) n; 558 cp.timeout = htole16(cp.timeout); 559 break; 560 561 default: 562 return (USAGE); 563 } 564 565 /* send command */ 566 n = sizeof(rp); 567 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 568 NG_HCI_OCF_WRITE_PAGE_TIMO), 569 (char const *) &cp, sizeof(cp), 570 (char *) &rp, &n) == ERROR) 571 return (ERROR); 572 573 if (rp.status != 0x00) { 574 fprintf(stdout, "Status: %s [%#02x]\n", 575 hci_status2str(rp.status), rp.status); 576 return (FAILED); 577 } 578 579 return (OK); 580} /* hci_write_page_timeout */ 581 582/* Send Read_Scan_Enable command to the unit */ 583static int 584hci_read_scan_enable(int s, int argc, char **argv) 585{ 586 ng_hci_read_scan_enable_rp rp; 587 int n; 588 589 n = sizeof(rp); 590 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 591 NG_HCI_OCF_READ_SCAN_ENABLE), 592 (char *) &rp, &n) == ERROR) 593 return (ERROR); 594 595 if (rp.status != 0x00) { 596 fprintf(stdout, "Status: %s [%#02x]\n", 597 hci_status2str(rp.status), rp.status); 598 return (FAILED); 599 } 600 601 fprintf(stdout, "Scan enable: %s [%#02x]\n", 602 hci_scan2str(rp.scan_enable), rp.scan_enable); 603 604 return (OK); 605} /* hci_read_scan_enable */ 606 607/* Send Write_Scan_Enable command to the unit */ 608static int 609hci_write_scan_enable(int s, int argc, char **argv) 610{ 611 ng_hci_write_scan_enable_cp cp; 612 ng_hci_write_scan_enable_rp rp; 613 int n; 614 615 /* parse command parameters */ 616 switch (argc) { 617 case 1: 618 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3) 619 return (USAGE); 620 621 cp.scan_enable = (uint8_t) n; 622 break; 623 624 default: 625 return (USAGE); 626 } 627 628 n = sizeof(rp); 629 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 630 NG_HCI_OCF_WRITE_SCAN_ENABLE), 631 (char const *) &cp, sizeof(cp), 632 (char *) &rp, &n) == ERROR) 633 return (ERROR); 634 635 if (rp.status != 0x00) { 636 fprintf(stdout, "Status: %s [%#02x]\n", 637 hci_status2str(rp.status), rp.status); 638 return (FAILED); 639 } 640 641 return (OK); 642} /* hci_write_scan_enable */ 643 644/* Send Read_Page_Scan_Activity command to the unit */ 645static int 646hci_read_page_scan_activity(int s, int argc, char **argv) 647{ 648 ng_hci_read_page_scan_activity_rp rp; 649 int n; 650 651 n = sizeof(rp); 652 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 653 NG_HCI_OCF_READ_PAGE_SCAN_ACTIVITY), 654 (char *) &rp, &n) == ERROR) 655 return (ERROR); 656 657 if (rp.status != 0x00) { 658 fprintf(stdout, "Status: %s [%#02x]\n", 659 hci_status2str(rp.status), rp.status); 660 return (FAILED); 661 } 662 663 rp.page_scan_interval = le16toh(rp.page_scan_interval); 664 rp.page_scan_window = le16toh(rp.page_scan_window); 665 666 fprintf(stdout, "Page Scan Interval: %.2f msec [%d slots]\n", 667 rp.page_scan_interval * 0.625, rp.page_scan_interval); 668 fprintf(stdout, "Page Scan Window: %.2f msec [%d slots]\n", 669 rp.page_scan_window * 0.625, rp.page_scan_window); 670 671 return (OK); 672} /* hci_read_page_scan_activity */ 673 674/* Send Write_Page_Scan_Activity command to the unit */ 675static int 676hci_write_page_scan_activity(int s, int argc, char **argv) 677{ 678 ng_hci_write_page_scan_activity_cp cp; 679 ng_hci_write_page_scan_activity_rp rp; 680 int n; 681 682 /* parse command parameters */ 683 switch (argc) { 684 case 2: 685 /* page scan interval */ 686 if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000) 687 return (USAGE); 688 689 cp.page_scan_interval = (uint16_t) n; 690 691 /* page scan window */ 692 if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000) 693 return (USAGE); 694 695 cp.page_scan_window = (uint16_t) n; 696 697 if (cp.page_scan_window > cp.page_scan_interval) 698 return (USAGE); 699 700 cp.page_scan_interval = htole16(cp.page_scan_interval); 701 cp.page_scan_window = htole16(cp.page_scan_window); 702 break; 703 704 default: 705 return (USAGE); 706 } 707 708 /* send command */ 709 n = sizeof(rp); 710 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 711 NG_HCI_OCF_WRITE_PAGE_SCAN_ACTIVITY), 712 (char const *) &cp, sizeof(cp), 713 (char *) &rp, &n) == ERROR) 714 return (ERROR); 715 716 if (rp.status != 0x00) { 717 fprintf(stdout, "Status: %s [%#02x]\n", 718 hci_status2str(rp.status), rp.status); 719 return (FAILED); 720 } 721 722 return (OK); 723} /* hci_write_page_scan_activity */ 724 725/* Send Read_Inquiry_Scan_Activity command to the unit */ 726static int 727hci_read_inquiry_scan_activity(int s, int argc, char **argv) 728{ 729 ng_hci_read_inquiry_scan_activity_rp rp; 730 int n; 731 732 n = sizeof(rp); 733 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 734 NG_HCI_OCF_READ_INQUIRY_SCAN_ACTIVITY), 735 (char *) &rp, &n) == ERROR) 736 return (ERROR); 737 738 if (rp.status != 0x00) { 739 fprintf(stdout, "Status: %s [%#02x]\n", 740 hci_status2str(rp.status), rp.status); 741 return (FAILED); 742 } 743 744 rp.inquiry_scan_interval = le16toh(rp.inquiry_scan_interval); 745 rp.inquiry_scan_window = le16toh(rp.inquiry_scan_window); 746 747 fprintf(stdout, "Inquiry Scan Interval: %.2f msec [%d slots]\n", 748 rp.inquiry_scan_interval * 0.625, rp.inquiry_scan_interval); 749 fprintf(stdout, "Inquiry Scan Window: %.2f msec [%d slots]\n", 750 rp.inquiry_scan_window * 0.625, rp.inquiry_scan_interval); 751 752 return (OK); 753} /* hci_read_inquiry_scan_activity */ 754 755/* Send Write_Inquiry_Scan_Activity command to the unit */ 756static int 757hci_write_inquiry_scan_activity(int s, int argc, char **argv) 758{ 759 ng_hci_write_inquiry_scan_activity_cp cp; 760 ng_hci_write_inquiry_scan_activity_rp rp; 761 int n; 762 763 /* parse command parameters */ 764 switch (argc) { 765 case 2: 766 /* inquiry scan interval */ 767 if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000) 768 return (USAGE); 769 770 cp.inquiry_scan_interval = (uint16_t) n; 771 772 /* inquiry scan window */ 773 if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000) 774 return (USAGE); 775 776 cp.inquiry_scan_window = (uint16_t) n; 777 778 if (cp.inquiry_scan_window > cp.inquiry_scan_interval) 779 return (USAGE); 780 781 cp.inquiry_scan_interval = 782 htole16(cp.inquiry_scan_interval); 783 cp.inquiry_scan_window = htole16(cp.inquiry_scan_window); 784 break; 785 786 default: 787 return (USAGE); 788 } 789 790 /* send command */ 791 n = sizeof(rp); 792 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 793 NG_HCI_OCF_WRITE_INQUIRY_SCAN_ACTIVITY), 794 (char const *) &cp, sizeof(cp), 795 (char *) &rp, &n) == ERROR) 796 return (ERROR); 797 798 if (rp.status != 0x00) { 799 fprintf(stdout, "Status: %s [%#02x]\n", 800 hci_status2str(rp.status), rp.status); 801 return (FAILED); 802 } 803 804 return (OK); 805} /* hci_write_inquiry_scan_activity */ 806 807/* Send Read_Authentication_Enable command to the unit */ 808static int 809hci_read_authentication_enable(int s, int argc, char **argv) 810{ 811 ng_hci_read_auth_enable_rp rp; 812 int n; 813 814 n = sizeof(rp); 815 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 816 NG_HCI_OCF_READ_AUTH_ENABLE), 817 (char *) &rp, &n) == ERROR) 818 return (ERROR); 819 820 if (rp.status != 0x00) { 821 fprintf(stdout, "Status: %s [%#02x]\n", 822 hci_status2str(rp.status), rp.status); 823 return (FAILED); 824 } 825 826 fprintf(stdout, "Authentication Enable: %s [%d]\n", 827 rp.auth_enable? "Enabled" : "Disabled", rp.auth_enable); 828 829 return (OK); 830} /* hci_read_authentication_enable */ 831 832/* Send Write_Authentication_Enable command to the unit */ 833static int 834hci_write_authentication_enable(int s, int argc, char **argv) 835{ 836 ng_hci_write_auth_enable_cp cp; 837 ng_hci_write_auth_enable_rp rp; 838 int n; 839 840 /* parse command parameters */ 841 switch (argc) { 842 case 1: 843 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1) 844 return (USAGE); 845 846 cp.auth_enable = (uint8_t) n; 847 break; 848 849 default: 850 return (USAGE); 851 } 852 853 /* send command */ 854 n = sizeof(rp); 855 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 856 NG_HCI_OCF_WRITE_AUTH_ENABLE), 857 (char const *) &cp, sizeof(cp), 858 (char *) &rp, &n) == ERROR) 859 return (ERROR); 860 861 if (rp.status != 0x00) { 862 fprintf(stdout, "Status: %s [%#02x]\n", 863 hci_status2str(rp.status), rp.status); 864 return (FAILED); 865 } 866 867 return (OK); 868} /* hci_write_authentication_enable */ 869 870/* Send Read_Encryption_Mode command to the unit */ 871static int 872hci_read_encryption_mode(int s, int argc, char **argv) 873{ 874 ng_hci_read_encryption_mode_rp rp; 875 int n; 876 877 n = sizeof(rp); 878 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 879 NG_HCI_OCF_READ_ENCRYPTION_MODE), 880 (char *) &rp, &n) == ERROR) 881 return (ERROR); 882 883 if (rp.status != 0x00) { 884 fprintf(stdout, "Status: %s [%#02x]\n", 885 hci_status2str(rp.status), rp.status); 886 return (FAILED); 887 } 888 889 fprintf(stdout, "Encryption mode: %s [%#02x]\n", 890 hci_encrypt2str(rp.encryption_mode, 0), rp.encryption_mode); 891 892 return (OK); 893} /* hci_read_encryption_mode */ 894 895/* Send Write_Encryption_Mode command to the unit */ 896static int 897hci_write_encryption_mode(int s, int argc, char **argv) 898{ 899 ng_hci_write_encryption_mode_cp cp; 900 ng_hci_write_encryption_mode_rp rp; 901 int n; 902 903 /* parse command parameters */ 904 switch (argc) { 905 case 1: 906 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2) 907 return (USAGE); 908 909 cp.encryption_mode = (uint8_t) n; 910 break; 911 912 default: 913 return (USAGE); 914 } 915 916 /* send command */ 917 n = sizeof(rp); 918 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 919 NG_HCI_OCF_WRITE_ENCRYPTION_MODE), 920 (char const *) &cp, sizeof(cp), 921 (char *) &rp, &n) == ERROR) 922 return (ERROR); 923 924 if (rp.status != 0x00) { 925 fprintf(stdout, "Status: %s [%#02x]\n", 926 hci_status2str(rp.status), rp.status); 927 return (FAILED); 928 } 929 930 return (OK); 931} /* hci_write_encryption_mode */ 932 933/* Send Read_Class_Of_Device command to the unit */ 934static int 935hci_read_class_of_device(int s, int argc, char **argv) 936{ 937 ng_hci_read_unit_class_rp rp; 938 int n; 939 940 n = sizeof(rp); 941 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 942 NG_HCI_OCF_READ_UNIT_CLASS), 943 (char *) &rp, &n) == ERROR) 944 return (ERROR); 945 946 if (rp.status != 0x00) { 947 fprintf(stdout, "Status: %s [%#02x]\n", 948 hci_status2str(rp.status), rp.status); 949 return (FAILED); 950 } 951 952 fprintf(stdout, "Class: %02x:%02x:%02x\n", 953 rp.uclass[2], rp.uclass[1], rp.uclass[0]); 954 955 return (0); 956} /* hci_read_class_of_device */ 957 958/* Send Write_Class_Of_Device command to the unit */ 959static int 960hci_write_class_of_device(int s, int argc, char **argv) 961{ 962 ng_hci_write_unit_class_cp cp; 963 ng_hci_write_unit_class_rp rp; 964 int n0, n1, n2; 965 966 /* parse command parameters */ 967 switch (argc) { 968 case 1: 969 if (sscanf(argv[0], "%x:%x:%x", &n2, &n1, &n0) != 3) 970 return (USAGE); 971 972 cp.uclass[0] = (n0 & 0xff); 973 cp.uclass[1] = (n1 & 0xff); 974 cp.uclass[2] = (n2 & 0xff); 975 break; 976 977 default: 978 return (USAGE); 979 } 980 981 /* send command */ 982 n0 = sizeof(rp); 983 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 984 NG_HCI_OCF_WRITE_UNIT_CLASS), 985 (char const *) &cp, sizeof(cp), 986 (char *) &rp, &n0) == ERROR) 987 return (ERROR); 988 989 if (rp.status != 0x00) { 990 fprintf(stdout, "Status: %s [%#02x]\n", 991 hci_status2str(rp.status), rp.status); 992 return (FAILED); 993 } 994 995 return (OK); 996} /* hci_write_class_of_device */ 997 998/* Send Read_Voice_Settings command to the unit */ 999static int 1000hci_read_voice_settings(int s, int argc, char **argv) 1001{ 1002 ng_hci_read_voice_settings_rp rp; 1003 int n, 1004 input_coding, 1005 input_data_format, 1006 input_sample_size; 1007 1008 n = sizeof(rp); 1009 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1010 NG_HCI_OCF_READ_VOICE_SETTINGS), 1011 (char *) &rp, &n) == ERROR) 1012 return (ERROR); 1013 1014 if (rp.status != 0x00) { 1015 fprintf(stdout, "Status: %s [%#02x]\n", 1016 hci_status2str(rp.status), rp.status); 1017 return (FAILED); 1018 } 1019 1020 rp.settings = le16toh(rp.settings); 1021 1022 input_coding = (rp.settings & 0x0300) >> 8; 1023 input_data_format = (rp.settings & 0x00c0) >> 6; 1024 input_sample_size = (rp.settings & 0x0020) >> 5; 1025 1026 fprintf(stdout, "Voice settings: %#04x\n", rp.settings); 1027 fprintf(stdout, "Input coding: %s [%d]\n", 1028 hci_coding2str(input_coding), input_coding); 1029 fprintf(stdout, "Input data format: %s [%d]\n", 1030 hci_vdata2str(input_data_format), input_data_format); 1031 1032 if (input_coding == 0x00) /* Only for Linear PCM */ 1033 fprintf(stdout, "Input sample size: %d bit [%d]\n", 1034 input_sample_size? 16 : 8, input_sample_size); 1035 1036 return (OK); 1037} /* hci_read_voice_settings */ 1038 1039/* Send Write_Voice_Settings command to the unit */ 1040static int 1041hci_write_voice_settings(int s, int argc, char **argv) 1042{ 1043 ng_hci_write_voice_settings_cp cp; 1044 ng_hci_write_voice_settings_rp rp; 1045 int n; 1046 1047 /* parse command parameters */ 1048 switch (argc) { 1049 case 1: 1050 if (sscanf(argv[0], "%x", &n) != 1) 1051 return (USAGE); 1052 1053 cp.settings = (uint16_t) n; 1054 cp.settings = htole16(cp.settings); 1055 break; 1056 1057 default: 1058 return (USAGE); 1059 } 1060 1061 /* send command */ 1062 n = sizeof(rp); 1063 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1064 NG_HCI_OCF_WRITE_VOICE_SETTINGS), 1065 (char const *) &cp, sizeof(cp), 1066 (char *) &rp, &n) == ERROR) 1067 return (ERROR); 1068 1069 if (rp.status != 0x00) { 1070 fprintf(stdout, "Status: %s [%#02x]\n", 1071 hci_status2str(rp.status), rp.status); 1072 return (FAILED); 1073 } 1074 1075 return (OK); 1076} /* hci_write_voice_settings */ 1077 1078/* Send Read_Number_Broadcast_Restransmissions */ 1079static int 1080hci_read_number_broadcast_retransmissions(int s, int argc, char **argv) 1081{ 1082 ng_hci_read_num_broadcast_retrans_rp rp; 1083 int n; 1084 1085 n = sizeof(rp); 1086 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1087 NG_HCI_OCF_READ_NUM_BROADCAST_RETRANS), 1088 (char *) &rp, &n) == ERROR) 1089 return (ERROR); 1090 1091 if (rp.status != 0x00) { 1092 fprintf(stdout, "Status: %s [%#02x]\n", 1093 hci_status2str(rp.status), rp.status); 1094 return (FAILED); 1095 } 1096 1097 fprintf(stdout, "Number of broadcast retransmissions: %d\n", 1098 rp.counter); 1099 1100 return (OK); 1101} /* hci_read_number_broadcast_retransmissions */ 1102 1103/* Send Write_Number_Broadcast_Restransmissions */ 1104static int 1105hci_write_number_broadcast_retransmissions(int s, int argc, char **argv) 1106{ 1107 ng_hci_write_num_broadcast_retrans_cp cp; 1108 ng_hci_write_num_broadcast_retrans_rp rp; 1109 int n; 1110 1111 /* parse command parameters */ 1112 switch (argc) { 1113 case 1: 1114 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0xff) 1115 return (USAGE); 1116 1117 cp.counter = (uint8_t) n; 1118 break; 1119 1120 default: 1121 return (USAGE); 1122 } 1123 1124 /* send command */ 1125 n = sizeof(rp); 1126 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1127 NG_HCI_OCF_WRITE_NUM_BROADCAST_RETRANS), 1128 (char const *) &cp, sizeof(cp), 1129 (char *) &rp, &n) == ERROR) 1130 return (ERROR); 1131 1132 if (rp.status != 0x00) { 1133 fprintf(stdout, "Status: %s [%#02x]\n", 1134 hci_status2str(rp.status), rp.status); 1135 return (FAILED); 1136 } 1137 1138 return (OK); 1139} /* hci_write_number_broadcast_retransmissions */ 1140 1141/* Send Read_Hold_Mode_Activity command to the unit */ 1142static int 1143hci_read_hold_mode_activity(int s, int argc, char **argv) 1144{ 1145 ng_hci_read_hold_mode_activity_rp rp; 1146 int n; 1147 char buffer[1024]; 1148 1149 n = sizeof(rp); 1150 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1151 NG_HCI_OCF_READ_HOLD_MODE_ACTIVITY), 1152 (char *) &rp, &n) == ERROR) 1153 return (ERROR); 1154 1155 if (rp.status != 0x00) { 1156 fprintf(stdout, "Status: %s [%#02x]\n", 1157 hci_status2str(rp.status), rp.status); 1158 return (FAILED); 1159 } 1160 1161 fprintf(stdout, "Hold Mode Activities: %#02x\n", rp.hold_mode_activity); 1162 if (rp.hold_mode_activity == 0) 1163 fprintf(stdout, "Maintain current Power State"); 1164 else 1165 fprintf(stdout, "%s", hci_hmode2str(rp.hold_mode_activity, 1166 buffer, sizeof(buffer))); 1167 1168 fprintf(stdout, "\n"); 1169 1170 return (OK); 1171} /* hci_read_hold_mode_activity */ 1172 1173/* Send Write_Hold_Mode_Activity command to the unit */ 1174static int 1175hci_write_hold_mode_activity(int s, int argc, char **argv) 1176{ 1177 ng_hci_write_hold_mode_activity_cp cp; 1178 ng_hci_write_hold_mode_activity_rp rp; 1179 int n; 1180 1181 /* parse command parameters */ 1182 switch (argc) { 1183 case 1: 1184 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 4) 1185 return (USAGE); 1186 1187 cp.hold_mode_activity = (uint8_t) n; 1188 break; 1189 1190 default: 1191 return (USAGE); 1192 } 1193 1194 /* send command */ 1195 n = sizeof(rp); 1196 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1197 NG_HCI_OCF_WRITE_HOLD_MODE_ACTIVITY), 1198 (char const *) &cp, sizeof(cp), 1199 (char *) &rp, &n) == ERROR) 1200 return (ERROR); 1201 1202 if (rp.status != 0x00) { 1203 fprintf(stdout, "Status: %s [%#02x]\n", 1204 hci_status2str(rp.status), rp.status); 1205 return (FAILED); 1206 } 1207 1208 return (OK); 1209} /* hci_write_hold_mode_activity */ 1210 1211/* Send Read_SCO_Flow_Control_Enable command to the unit */ 1212static int 1213hci_read_sco_flow_control_enable(int s, int argc, char **argv) 1214{ 1215 ng_hci_read_sco_flow_control_rp rp; 1216 int n; 1217 1218 n = sizeof(rp); 1219 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1220 NG_HCI_OCF_READ_SCO_FLOW_CONTROL), 1221 (char *) &rp, &n) == ERROR) 1222 return (ERROR); 1223 1224 if (rp.status != 0x00) { 1225 fprintf(stdout, "Status: %s [%#02x]\n", 1226 hci_status2str(rp.status), rp.status); 1227 return (FAILED); 1228 } 1229 1230 fprintf(stdout, "SCO flow control %s [%d]\n", 1231 rp.flow_control? "enabled" : "disabled", rp.flow_control); 1232 1233 return (OK); 1234} /* hci_read_sco_flow_control_enable */ 1235 1236/* Send Write_SCO_Flow_Control_Enable command to the unit */ 1237static int 1238hci_write_sco_flow_control_enable(int s, int argc, char **argv) 1239{ 1240 ng_hci_write_sco_flow_control_cp cp; 1241 ng_hci_write_sco_flow_control_rp rp; 1242 int n; 1243 1244 /* parse command parameters */ 1245 switch (argc) { 1246 case 1: 1247 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1) 1248 return (USAGE); 1249 1250 cp.flow_control = (uint8_t) n; 1251 break; 1252 1253 default: 1254 return (USAGE); 1255 } 1256 1257 /* send command */ 1258 n = sizeof(rp); 1259 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1260 NG_HCI_OCF_WRITE_SCO_FLOW_CONTROL), 1261 (char const *) &cp, sizeof(cp), 1262 (char *) &rp, &n) == ERROR) 1263 return (ERROR); 1264 1265 if (rp.status != 0x00) { 1266 fprintf(stdout, "Status: %s [%#02x]\n", 1267 hci_status2str(rp.status), rp.status); 1268 return (FAILED); 1269 } 1270 1271 return (OK); 1272} /* hci_write_sco_flow_control_enable */ 1273 1274/* Send Read_Link_Supervision_Timeout command to the unit */ 1275static int 1276hci_read_link_supervision_timeout(int s, int argc, char **argv) 1277{ 1278 ng_hci_read_link_supervision_timo_cp cp; 1279 ng_hci_read_link_supervision_timo_rp rp; 1280 int n; 1281 1282 switch (argc) { 1283 case 1: 1284 /* connection handle */ 1285 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff) 1286 return (USAGE); 1287 1288 cp.con_handle = (uint16_t) (n & 0x0fff); 1289 cp.con_handle = htole16(cp.con_handle); 1290 break; 1291 1292 default: 1293 return (USAGE); 1294 } 1295 1296 /* send command */ 1297 n = sizeof(rp); 1298 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1299 NG_HCI_OCF_READ_LINK_SUPERVISION_TIMO), 1300 (char const *) &cp, sizeof(cp), 1301 (char *) &rp, &n) == ERROR) 1302 return (ERROR); 1303 1304 if (rp.status != 0x00) { 1305 fprintf(stdout, "Status: %s [%#02x]\n", 1306 hci_status2str(rp.status), rp.status); 1307 return (FAILED); 1308 } 1309 1310 rp.timeout = le16toh(rp.timeout); 1311 1312 fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle)); 1313 fprintf(stdout, "Link supervision timeout: %.2f msec [%d slots]\n", 1314 rp.timeout * 0.625, rp.timeout); 1315 1316 return (OK); 1317} /* hci_read_link_supervision_timeout */ 1318 1319/* Send Write_Link_Supervision_Timeout command to the unit */ 1320static int 1321hci_write_link_supervision_timeout(int s, int argc, char **argv) 1322{ 1323 ng_hci_write_link_supervision_timo_cp cp; 1324 ng_hci_write_link_supervision_timo_rp rp; 1325 int n; 1326 1327 switch (argc) { 1328 case 2: 1329 /* connection handle */ 1330 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff) 1331 return (USAGE); 1332 1333 cp.con_handle = (uint16_t) (n & 0x0fff); 1334 cp.con_handle = htole16(cp.con_handle); 1335 1336 /* link supervision timeout */ 1337 if (sscanf(argv[1], "%d", &n) != 1 || n < 0 || n > 0xffff) 1338 return (USAGE); 1339 1340 cp.timeout = (uint16_t) (n & 0x0fff); 1341 cp.timeout = htole16(cp.timeout); 1342 break; 1343 1344 default: 1345 return (USAGE); 1346 } 1347 1348 /* send command */ 1349 n = sizeof(rp); 1350 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1351 NG_HCI_OCF_WRITE_LINK_SUPERVISION_TIMO), 1352 (char const *) &cp, sizeof(cp), 1353 (char *) &rp, &n) == ERROR) 1354 return (ERROR); 1355 1356 if (rp.status != 0x00) { 1357 fprintf(stdout, "Status: %s [%#02x]\n", 1358 hci_status2str(rp.status), rp.status); 1359 return (FAILED); 1360 } 1361 1362 return (OK); 1363} /* hci_write_link_supervision_timeout */ 1364 1365/* Send Read_Page_Scan_Period_Mode command to the unit */ 1366static int 1367hci_read_page_scan_period_mode(int s, int argc, char **argv) 1368{ 1369 ng_hci_read_page_scan_period_rp rp; 1370 int n; 1371 1372 n = sizeof(rp); 1373 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1374 NG_HCI_OCF_READ_PAGE_SCAN_PERIOD), 1375 (char *) &rp, &n) == ERROR) 1376 return (ERROR); 1377 1378 if (rp.status != 0x00) { 1379 fprintf(stdout, "Status: %s [%#02x]\n", 1380 hci_status2str(rp.status), rp.status); 1381 return (FAILED); 1382 } 1383 1384 fprintf(stdout, "Page scan period mode: %#02x\n", 1385 rp.page_scan_period_mode); 1386 1387 return (OK); 1388} /* hci_read_page_scan_period_mode */ 1389 1390/* Send Write_Page_Scan_Period_Mode command to the unit */ 1391static int 1392hci_write_page_scan_period_mode(int s, int argc, char **argv) 1393{ 1394 ng_hci_write_page_scan_period_cp cp; 1395 ng_hci_write_page_scan_period_rp rp; 1396 int n; 1397 1398 /* parse command arguments */ 1399 switch (argc) { 1400 case 1: 1401 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2) 1402 return (USAGE); 1403 1404 cp.page_scan_period_mode = (n & 0xff); 1405 break; 1406 1407 default: 1408 return (USAGE); 1409 } 1410 1411 /* send command */ 1412 n = sizeof(rp); 1413 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1414 NG_HCI_OCF_WRITE_PAGE_SCAN_PERIOD), 1415 (char const *) &cp, sizeof(cp), 1416 (char *) &rp, &n) == ERROR) 1417 return (ERROR); 1418 1419 if (rp.status != 0x00) { 1420 fprintf(stdout, "Status: %s [%#02x]\n", 1421 hci_status2str(rp.status), rp.status); 1422 return (FAILED); 1423 } 1424 1425 return (OK); 1426} /* hci_write_page_scan_period_mode */ 1427 1428/* Send Read_Page_Scan_Mode command to the unit */ 1429static int 1430hci_read_page_scan_mode(int s, int argc, char **argv) 1431{ 1432 ng_hci_read_page_scan_rp rp; 1433 int n; 1434 1435 n = sizeof(rp); 1436 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1437 NG_HCI_OCF_READ_PAGE_SCAN), 1438 (char *) &rp, &n) == ERROR) 1439 return (ERROR); 1440 1441 if (rp.status != 0x00) { 1442 fprintf(stdout, "Status: %s [%#02x]\n", 1443 hci_status2str(rp.status), rp.status); 1444 return (FAILED); 1445 } 1446 1447 fprintf(stdout, "Page scan mode: %#02x\n", rp.page_scan_mode); 1448 1449 return (OK); 1450} /* hci_read_page_scan_mode */ 1451 1452/* Send Write_Page_Scan_Mode command to the unit */ 1453static int 1454hci_write_page_scan_mode(int s, int argc, char **argv) 1455{ 1456 ng_hci_write_page_scan_cp cp; 1457 ng_hci_write_page_scan_rp rp; 1458 int n; 1459 1460 /* parse command arguments */ 1461 switch (argc) { 1462 case 1: 1463 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3) 1464 return (USAGE); 1465 1466 cp.page_scan_mode = (n & 0xff); 1467 break; 1468 1469 default: 1470 return (USAGE); 1471 } 1472 1473 /* send command */ 1474 n = sizeof(rp); 1475 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1476 NG_HCI_OCF_WRITE_PAGE_SCAN), 1477 (char const *) &cp, sizeof(cp), 1478 (char *) &rp, &n) == ERROR) 1479 return (ERROR); 1480 1481 if (rp.status != 0x00) { 1482 fprintf(stdout, "Status: %s [%#02x]\n", 1483 hci_status2str(rp.status), rp.status); 1484 return (FAILED); 1485 } 1486 1487 return (OK); 1488} /* hci_write_page_scan_mode */ 1489 1490struct hci_command host_controller_baseband_commands[] = { 1491{ 1492"reset", 1493"\nThe Reset command will reset the Host Controller and the Link Manager.\n" \ 1494"After the reset is completed, the current operational state will be lost,\n" \ 1495"the Bluetooth unit will enter standby mode and the Host Controller will\n" \ 1496"automatically revert to the default values for the parameters for which\n" \ 1497"default values are defined in the specification.", 1498&hci_reset 1499}, 1500{ 1501"read_pin_type", 1502"\nThe Read_PIN_Type command is used for the Host to read whether the Link\n" \ 1503"Manager assumes that the Host supports variable PIN codes only a fixed PIN\n" \ 1504"code.", 1505&hci_read_pin_type 1506}, 1507{ 1508"write_pin_type <pin_type>", 1509"\nThe Write_PIN_Type command is used for the Host to write to the Host\n" \ 1510"Controller whether the Host supports variable PIN codes or only a fixed PIN\n"\ 1511"code.\n\n" \ 1512"\t<pin_type> - dd; 0 - Variable; 1 - Fixed", 1513&hci_write_pin_type 1514}, 1515{ 1516"read_stored_link_key [<BD_ADDR>]", 1517"\nThe Read_Stored_Link_Key command provides the ability to read one or\n" \ 1518"more link keys stored in the Bluetooth Host Controller. The Bluetooth Host\n" \ 1519"Controller can store a limited number of link keys for other Bluetooth\n" \ 1520"devices.\n\n" \ 1521"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name", 1522&hci_read_stored_link_key 1523}, 1524{ 1525"write_stored_link_key <BD_ADDR> <key>", 1526"\nThe Write_Stored_Link_Key command provides the ability to write one\n" \ 1527"or more link keys to be stored in the Bluetooth Host Controller. The\n" \ 1528"Bluetooth Host Controller can store a limited number of link keys for other\n"\ 1529"Bluetooth devices. If no additional space is available in the Bluetooth\n"\ 1530"Host Controller then no additional link keys will be stored.\n\n" \ 1531"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name\n" \ 1532"\t<key> - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx up to 16 bytes link key", 1533&hci_write_stored_link_key 1534}, 1535{ 1536"delete_stored_link_key [<BD_ADDR>]", 1537"\nThe Delete_Stored_Link_Key command provides the ability to remove one\n" \ 1538"or more of the link keys stored in the Bluetooth Host Controller. The\n" \ 1539"Bluetooth Host Controller can store a limited number of link keys for other\n"\ 1540"Bluetooth devices.\n\n" \ 1541"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name", 1542&hci_delete_stored_link_key 1543}, 1544{ 1545"change_local_name <name>", 1546"\nThe Change_Local_Name command provides the ability to modify the user\n" \ 1547"friendly name for the Bluetooth unit.\n\n" \ 1548"\t<name> - string", 1549&hci_change_local_name 1550}, 1551{ 1552"read_local_name", 1553"\nThe Read_Local_Name command provides the ability to read the\n" \ 1554"stored user-friendly name for the Bluetooth unit.", 1555&hci_read_local_name 1556}, 1557{ 1558"read_connection_accept_timeout", 1559"\nThis command will read the value for the Connection_Accept_Timeout\n" \ 1560"configuration parameter. The Connection_Accept_Timeout configuration\n" \ 1561"parameter allows the Bluetooth hardware to automatically deny a\n" \ 1562"connection request after a specified time period has occurred and\n" \ 1563"the new connection is not accepted. Connection Accept Timeout\n" \ 1564"measured in Number of Baseband slots.", 1565&hci_read_connection_accept_timeout 1566}, 1567{ 1568"write_connection_accept_timeout <timeout>", 1569"\nThis command will write the value for the Connection_Accept_Timeout\n" \ 1570"configuration parameter.\n\n" \ 1571"\t<timeout> - dddd; measured in number of baseband slots.", 1572&hci_write_connection_accept_timeout 1573}, 1574{ 1575"read_page_timeout", 1576"\nThis command will read the value for the Page_Timeout configuration\n" \ 1577"parameter. The Page_Timeout configuration parameter defines the\n" \ 1578"maximum time the local Link Manager will wait for a baseband page\n" \ 1579"response from the remote unit at a locally initiated connection\n" \ 1580"attempt. Page Timeout measured in Number of Baseband slots.", 1581&hci_read_page_timeout 1582}, 1583{ 1584"write_page_timeout <timeout>", 1585"\nThis command will write the value for the Page_Timeout configuration\n" \ 1586"parameter.\n\n" \ 1587"\t<timeout> - dddd; measured in number of baseband slots.", 1588&hci_write_page_timeout 1589}, 1590{ 1591"read_scan_enable", 1592"\nThis command will read the value for the Scan_Enable parameter. The\n" \ 1593"Scan_Enable parameter controls whether or not the Bluetooth uint\n" \ 1594"will periodically scan for page attempts and/or inquiry requests\n" \ 1595"from other Bluetooth unit.\n\n" \ 1596"\t0x00 - No Scans enabled.\n" \ 1597"\t0x01 - Inquiry Scan enabled. Page Scan disabled.\n" \ 1598"\t0x02 - Inquiry Scan disabled. Page Scan enabled.\n" \ 1599"\t0x03 - Inquiry Scan enabled. Page Scan enabled.", 1600&hci_read_scan_enable 1601}, 1602{ 1603"write_scan_enable <scan_enable>", 1604"\nThis command will write the value for the Scan_Enable parameter.\n" \ 1605"The Scan_Enable parameter controls whether or not the Bluetooth\n" \ 1606"unit will periodically scan for page attempts and/or inquiry\n" \ 1607"requests from other Bluetooth unit.\n\n" \ 1608"\t<scan_enable> - dd;\n" \ 1609"\t0 - No Scans enabled.\n" \ 1610"\t1 - Inquiry Scan enabled. Page Scan disabled.\n" \ 1611"\t2 - Inquiry Scan disabled. Page Scan enabled.\n" \ 1612"\t3 - Inquiry Scan enabled. Page Scan enabled.", 1613&hci_write_scan_enable 1614}, 1615{ 1616"read_page_scan_activity", 1617"\nThis command will read the value for Page_Scan_Activity configuration\n" \ 1618"parameters. The Page_Scan_Interval configuration parameter defines the\n" \ 1619"amount of time between consecutive page scans. This time interval is \n" \ 1620"defined from when the Host Controller started its last page scan until\n" \ 1621"it begins the next page scan. The Page_Scan_Window configuration parameter\n" \ 1622"defines the amount of time for the duration of the page scan. The\n" \ 1623"Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.", 1624&hci_read_page_scan_activity 1625}, 1626{ 1627"write_page_scan_activity interval(dddd) window(dddd)", 1628"\nThis command will write the value for Page_Scan_Activity configuration\n" \ 1629"parameter. The Page_Scan_Interval configuration parameter defines the\n" \ 1630"amount of time between consecutive page scans. This is defined as the time\n" \ 1631"interval from when the Host Controller started its last page scan until it\n" \ 1632"begins the next page scan. The Page_Scan_Window configuration parameter\n" \ 1633"defines the amount of time for the duration of the page scan. \n" \ 1634"The Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.\n\n" \
|