1 /* 2 * host_controller_baseband.c 3 * 4 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $Id: host_controller_baseband.c,v 1.4 2003/08/18 19:19:53 max Exp $ 29 * $FreeBSD$ 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 */ 39 static int 40 hci_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 */ 55 static int 56 hci_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[] */ 68 static int 69 hci_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 */ 89 static int 90 hci_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 */ 110 static int 111 hci_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 */ 135 static int 136 hci_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 */ 173 static int 174 hci_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 */ 221 again: 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 */ 290 static int 291 hci_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 */ 347 static int 348 hci_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 */ 394 static int 395 hci_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 */ 429 static int 430 hci_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 */ 453 static int 454 hci_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 */ 479 static int 480 hci_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 */ 518 static int 519 hci_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 */ 544 static int 545 hci_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 */ 583 static int 584 hci_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 */ 608 static int 609 hci_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 */ 645 static int 646 hci_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 */ 675 static int 676 hci_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 */ 726 static int 727 hci_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 */ 756 static int 757 hci_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 */ 808 static int 809 hci_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 */ 833 static int 834 hci_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 */ 871 static int 872 hci_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 */ 896 static int 897 hci_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 */ 934 static int 935 hci_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 */ 959 static int 960 hci_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 */ 999 static int 1000 hci_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 */ 1040 static int 1041 hci_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 */ 1079 static int 1080 hci_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 */ 1104 static int 1105 hci_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 */ 1142 static int 1143 hci_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 */ 1174 static int 1175 hci_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 */ 1212 static int 1213 hci_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 */ 1237 static int 1238 hci_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 */ 1275 static int 1276 hci_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 */ 1320 static int 1321 hci_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 */ 1366 static int 1367 hci_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 */ 1391 static int 1392 hci_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 */ 1429 static int 1430 hci_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 */ 1453 static int 1454 hci_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 1490 struct 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" \ 1635 "\t<interval> - Range: 0x0012 -� 0x100, Time = N * 0.625 msec\n" \ 1636 "\t<window> - Range: 0x0012 -� 0x100, Time = N * 0.625 msen", 1637 &hci_write_page_scan_activity 1638 }, 1639 { 1640 "read_inquiry_scan_activity", 1641 "\nThis command will read the value for Inquiry_Scan_Activity configuration\n" \ 1642 "parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \ 1643 "amount of time between consecutive inquiry scans. This is defined as the\n" \ 1644 "time interval from when the Host Controller started its last inquiry scan\n" \ 1645 "until it begins the next inquiry scan.", 1646 &hci_read_inquiry_scan_activity 1647 }, 1648 { 1649 "write_inquiry_scan_activity interval(dddd) window(dddd)", 1650 "\nThis command will write the value for Inquiry_Scan_Activity configuration\n"\ 1651 "parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \ 1652 "amount of time between consecutive inquiry scans. This is defined as the\n" \ 1653 "time interval from when the Host Controller started its last inquiry scan\n" \ 1654 "until it begins the next inquiry scan. The Inquiry_Scan_Window configuration\n" \ 1655 "parameter defines the amount of time for the duration of the inquiry scan.\n" \ 1656 "The Inquiry_Scan_Window can only be less than or equal to the Inquiry_Scan_Interval.\n\n" \ 1657 "\t<interval> - Range: 0x0012 -� 0x100, Time = N * 0.625 msec\n" \ 1658 "\t<window> - Range: 0x0012 -� 0x100, Time = N * 0.625 msen", 1659 &hci_write_inquiry_scan_activity 1660 }, 1661 { 1662 "read_authentication_enable", 1663 "\nThis command will read the value for the Authentication_Enable parameter.\n"\ 1664 "The Authentication_Enable parameter controls if the local unit requires\n"\ 1665 "to authenticate the remote unit at connection setup (between the\n" \ 1666 "Create_Connection command or acceptance of an incoming ACL connection\n"\ 1667 "and the corresponding Connection Complete event). At connection setup, only\n"\ 1668 "the unit(s) with the Authentication_Enable parameter enabled will try to\n"\ 1669 "authenticate the other unit.", 1670 &hci_read_authentication_enable 1671 }, 1672 { 1673 "write_authentication_enable enable(0|1)", 1674 "\nThis command will write the value for the Authentication_Enable parameter.\n"\ 1675 "The Authentication_Enable parameter controls if the local unit requires to\n"\ 1676 "authenticate the remote unit at connection setup (between the\n" \ 1677 "Create_Connection command or acceptance of an incoming ACL connection\n" \ 1678 "and the corresponding Connection Complete event). At connection setup, only\n"\ 1679 "the unit(s) with the Authentication_Enable parameter enabled will try to\n"\ 1680 "authenticate the other unit.", 1681 &hci_write_authentication_enable 1682 }, 1683 { 1684 "read_encryption_mode", 1685 "\nThis command will read the value for the Encryption_Mode parameter. The\n" \ 1686 "Encryption_Mode parameter controls if the local unit requires encryption\n" \ 1687 "to the remote unit at connection setup (between the Create_Connection\n" \ 1688 "command or acceptance of an incoming ACL connection and the corresponding\n" \ 1689 "Connection Complete event). At connection setup, only the unit(s) with\n" \ 1690 "the Authentication_Enable parameter enabled and Encryption_Mode parameter\n" \ 1691 "enabled will try to encrypt the connection to the other unit.\n\n" \ 1692 "\t<encryption_mode>:\n" \ 1693 "\t0x00 - Encryption disabled.\n" \ 1694 "\t0x01 - Encryption only for point-to-point packets.\n" \ 1695 "\t0x02 - Encryption for both point-to-point and broadcast packets.", 1696 &hci_read_encryption_mode 1697 }, 1698 { 1699 "write_encryption_mode mode(0|1|2)", 1700 "\tThis command will write the value for the Encryption_Mode parameter.\n" \ 1701 "The Encryption_Mode parameter controls if the local unit requires\n" \ 1702 "encryption to the remote unit at connection setup (between the\n" \ 1703 "Create_Connection command or acceptance of an incoming ACL connection\n" \ 1704 "and the corresponding Connection Complete event). At connection setup,\n" \ 1705 "only the unit(s) with the Authentication_Enable parameter enabled and\n" \ 1706 "Encryption_Mode parameter enabled will try to encrypt the connection to\n" \ 1707 "the other unit.\n\n" \ 1708 "\t<encryption_mode> (dd)\n" \ 1709 "\t0 - Encryption disabled.\n" \ 1710 "\t1 - Encryption only for point-to-point packets.\n" \ 1711 "\t2 - Encryption for both point-to-point and broadcast packets.", 1712 &hci_write_encryption_mode 1713 }, 1714 { 1715 "read_class_of_device", 1716 "\nThis command will read the value for the Class_of_Device parameter.\n" \ 1717 "The Class_of_Device parameter is used to indicate the capabilities of\n" \ 1718 "the local unit to other units.", 1719 &hci_read_class_of_device 1720 }, 1721 { 1722 "write_class_of_device class(xx:xx:xx)", 1723 "\nThis command will write the value for the Class_of_Device parameter.\n" \ 1724 "The Class_of_Device parameter is used to indicate the capabilities of \n" \ 1725 "the local unit to other units.\n\n" \ 1726 "\t<class> (xx:xx:xx) - class of device", 1727 &hci_write_class_of_device 1728 }, 1729 { 1730 "read_voice_settings", 1731 "\nThis command will read the values for the Voice_Setting parameter.\n" \ 1732 "The Voice_Setting parameter controls all the various settings for voice\n" \ 1733 "connections. These settings apply to all voice connections, and cannot be\n" \ 1734 "set for individual voice connections. The Voice_Setting parameter controls\n" \ 1735 "the configuration for voice connections: Input Coding, Air coding format,\n" \ 1736 "input data format, Input sample size, and linear PCM parameter.", 1737 &hci_read_voice_settings 1738 }, 1739 { 1740 "write_voice_settings settings(xxxx)", 1741 "\nThis command will write the values for the Voice_Setting parameter.\n" \ 1742 "The Voice_Setting parameter controls all the various settings for voice\n" \ 1743 "connections. These settings apply to all voice connections, and cannot be\n" \ 1744 "set for individual voice connections. The Voice_Setting parameter controls\n" \ 1745 "the configuration for voice connections: Input Coding, Air coding format,\n" \ 1746 "input data format, Input sample size, and linear PCM parameter.\n\n" \ 1747 "\t<voice_settings> (xxxx) - voice settings", 1748 &hci_write_voice_settings 1749 }, 1750 { 1751 "read_number_broadcast_retransmissions", 1752 "\nThis command will read the unit's parameter value for the Number of\n" \ 1753 "Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \ 1754 "unreliable.", 1755 &hci_read_number_broadcast_retransmissions 1756 }, 1757 { 1758 "write_number_broadcast_retransmissions count(dd)", 1759 "\nThis command will write the unit's parameter value for the Number of\n" \ 1760 "Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \ 1761 "unreliable.\n\n" \ 1762 "\t<count> (dd) - number of broadcast retransimissions", 1763 &hci_write_number_broadcast_retransmissions 1764 }, 1765 { 1766 "read_hold_mode_activity", 1767 "\nThis command will read the value for the Hold_Mode_Activity parameter.\n" \ 1768 "The Hold_Mode_Activity value is used to determine what activities should\n" \ 1769 "be suspended when the unit is in hold mode.", 1770 &hci_read_hold_mode_activity 1771 }, 1772 { 1773 "write_hold_mode_activity settings(0|1|2|4)", 1774 "\nThis command will write the value for the Hold_Mode_Activity parameter.\n" \ 1775 "The Hold_Mode_Activity value is used to determine what activities should\n" \ 1776 "be suspended when the unit is in hold mode.\n\n" \ 1777 "\t<settings> (dd) - bit mask:\n" \ 1778 "\t0 - Maintain current Power State. Default\n" \ 1779 "\t1 - Suspend Page Scan.\n" \ 1780 "\t2 - Suspend Inquiry Scan.\n" \ 1781 "\t4 - Suspend Periodic Inquiries.", 1782 &hci_write_hold_mode_activity 1783 }, 1784 { 1785 "read_sco_flow_control_enable", 1786 "\nThe Read_SCO_Flow_Control_Enable command provides the ability to read\n" \ 1787 "the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \ 1788 "decide if the Host Controller will send Number Of Completed Packets events\n" \ 1789 "for SCO Connection Handles. This setting allows the Host to enable and\n" \ 1790 "disable SCO flow control.", 1791 &hci_read_sco_flow_control_enable 1792 }, 1793 { 1794 "write_sco_flow_control_enable enable(0|1)", 1795 "\nThe Write_SCO_Flow_Control_Enable command provides the ability to write\n" \ 1796 "the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \ 1797 "decide if the Host Controller will send Number Of Completed Packets events\n" \ 1798 "for SCO Connection Handles. This setting allows the Host to enable and\n" \ 1799 "disable SCO flow control. The SCO_Flow_Control_Enable setting can only be\n" \ 1800 "changed if no connections exist.", 1801 &hci_write_sco_flow_control_enable 1802 }, 1803 { 1804 "read_link_supervision_timeout <connection_handle>", 1805 "\nThis command will read the value for the Link_Supervision_Timeout\n" \ 1806 "parameter for the device. The Link_Supervision_Timeout parameter is used\n" \ 1807 "by the master or slave Bluetooth device to monitor link loss. If, for any\n" \ 1808 "reason, no Baseband packets are received from that Connection Handle for a\n" \ 1809 "duration longer than the Link_Supervision_Timeout, the connection is\n" 1810 "disconnected.\n\n" \ 1811 "\t<connection_handle> - dddd; connection handle\n", 1812 &hci_read_link_supervision_timeout 1813 }, 1814 { 1815 "write_link_supervision_timeout <connection_handle> <timeout>", 1816 "\nThis command will write the value for the Link_Supervision_Timeout\n" \ 1817 "parameter for the device. The Link_Supervision_Timeout parameter is used\n" \ 1818 "by the master or slave Bluetooth device to monitor link loss. If, for any\n" \ 1819 "reason, no Baseband packets are received from that connection handle for a\n" \ 1820 "duration longer than the Link_Supervision_Timeout, the connection is\n" \ 1821 "disconnected.\n\n" \ 1822 "\t<connection_handle> - dddd; connection handle\n" \ 1823 "\t<timeout> - dddd; timeout measured in number of baseband slots\n", 1824 &hci_write_link_supervision_timeout 1825 }, 1826 { 1827 "read_page_scan_period_mode", 1828 "\nThis command is used to read the mandatory Page_Scan_Period_Mode of the\n" \ 1829 "local Bluetooth device. Every time an inquiry response message is sent, the\n"\ 1830 "Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\ 1831 "is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \ 1832 "expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \ 1833 "following page scans.", 1834 &hci_read_page_scan_period_mode 1835 }, 1836 { 1837 "write_page_scan_period_mode <page_scan_period_mode>", 1838 "\nThis command is used to write the mandatory Page_Scan_Period_Mode of the\n" \ 1839 "local Bluetooth device. Every time an inquiry response message is sent, the\n"\ 1840 "Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\ 1841 "is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \ 1842 "expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \ 1843 "following page scans.\n\n" \ 1844 "\t<page_scan_period_mode> - dd; page scan period mode:\n" \ 1845 "\t0x00 - P0 (Default)\n" \ 1846 "\t0x01 - P1\n" \ 1847 "\t0x02 - P2", 1848 &hci_write_page_scan_period_mode 1849 }, 1850 { 1851 "read_page_scan_mode", 1852 "\nThis command is used to read the default page scan mode of the local\n" \ 1853 "Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\ 1854 "that is used for the default page scan. Currently one mandatory page scan\n"\ 1855 "mode and three optional page scan modes are defined. Following an inquiry\n" \ 1856 "response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \ 1857 "mandatory page scan mode must be applied.", 1858 &hci_read_page_scan_mode 1859 }, 1860 { 1861 "write_page_scan_mode <page_scan_mode>", 1862 "\nThis command is used to write the default page scan mode of the local\n" \ 1863 "Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\ 1864 "that is used for the default page scan. Currently, one mandatory page scan\n"\ 1865 "mode and three optional page scan modes are defined. Following an inquiry\n"\ 1866 "response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \ 1867 "mandatory page scan mode must be applied.\n\n" \ 1868 "\t<page_scan_mode> - dd; page scan mode:\n" \ 1869 "\t0x00 - Mandatory Page Scan Mode (Default)\n" \ 1870 "\t0x01 - Optional Page Scan Mode I\n" \ 1871 "\t0x02 - Optional Page Scan Mode II\n" \ 1872 "\t0x03 - Optional Page Scan Mode III", 1873 &hci_write_page_scan_mode 1874 }, 1875 { NULL, } 1876 }; 1877 1878