1 /*- 2 * host_controller_baseband.c 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 * 6 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com> 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * $Id: host_controller_baseband.c,v 1.4 2003/08/18 19:19:53 max Exp $ 31 * $FreeBSD$ 32 */ 33 34 #define L2CAP_SOCKET_CHECKED 35 #include <bluetooth.h> 36 #include <errno.h> 37 #include <stdio.h> 38 #include <string.h> 39 #include "hccontrol.h" 40 41 /* Convert hex ASCII to int4 */ 42 static int 43 hci_hexa2int4(const char *a) 44 { 45 if ('0' <= *a && *a <= '9') 46 return (*a - '0'); 47 48 if ('A' <= *a && *a <= 'F') 49 return (*a - 'A' + 0xa); 50 51 if ('a' <= *a && *a <= 'f') 52 return (*a - 'a' + 0xa); 53 54 return (-1); 55 } 56 57 /* Convert hex ASCII to int8 */ 58 static int 59 hci_hexa2int8(const char *a) 60 { 61 int hi = hci_hexa2int4(a); 62 int lo = hci_hexa2int4(a + 1); 63 64 if (hi < 0 || lo < 0) 65 return (-1); 66 67 return ((hi << 4) | lo); 68 } 69 70 /* Convert ascii hex string to the uint8_t[] */ 71 static int 72 hci_hexstring2array(char const *s, uint8_t *a, int asize) 73 { 74 int i, l, b; 75 76 l = strlen(s) / 2; 77 if (l > asize) 78 l = asize; 79 80 for (i = 0; i < l; i++) { 81 b = hci_hexa2int8(s + i * 2); 82 if (b < 0) 83 return (-1); 84 85 a[i] = (b & 0xff); 86 } 87 88 return (0); 89 } 90 91 /* Send RESET to the unit */ 92 static int 93 hci_reset(int s, int argc, char **argv) 94 { 95 ng_hci_status_rp rp; 96 int n; 97 98 n = sizeof(rp); 99 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 100 NG_HCI_OCF_RESET), (char *) &rp, &n) == ERROR) 101 return (ERROR); 102 103 if (rp.status != 0x00) { 104 fprintf(stdout, "Status: %s [%#02x]\n", 105 hci_status2str(rp.status), rp.status); 106 return (FAILED); 107 } 108 109 return (OK); 110 } /* hci_reset */ 111 112 /* Send Read_PIN_Type command to the unit */ 113 static int 114 hci_read_pin_type(int s, int argc, char **argv) 115 { 116 ng_hci_read_pin_type_rp rp; 117 int n; 118 119 n = sizeof(rp); 120 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 121 NG_HCI_OCF_READ_PIN_TYPE), 122 (char *) &rp, &n) == ERROR) 123 return (ERROR); 124 125 if (rp.status != 0x00) { 126 fprintf(stdout, "Status: %s [%#02x]\n", 127 hci_status2str(rp.status), rp.status); 128 return (FAILED); 129 } 130 131 fprintf(stdout, "PIN type: %s [%#02x]\n", 132 hci_pin2str(rp.pin_type), rp.pin_type); 133 134 return (OK); 135 } /* hci_read_pin_type */ 136 137 /* Send Write_PIN_Type command to the unit */ 138 static int 139 hci_write_pin_type(int s, int argc, char **argv) 140 { 141 ng_hci_write_pin_type_cp cp; 142 ng_hci_write_pin_type_rp rp; 143 int n; 144 145 /* parse command parameters */ 146 switch (argc) { 147 case 1: 148 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1) 149 return (USAGE); 150 151 cp.pin_type = (uint8_t) n; 152 break; 153 154 default: 155 return (USAGE); 156 } 157 158 /* send command */ 159 n = sizeof(rp); 160 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 161 NG_HCI_OCF_WRITE_PIN_TYPE), 162 (char const *) &cp, sizeof(cp), 163 (char *) &rp , &n) == ERROR) 164 return (ERROR); 165 166 if (rp.status != 0x00) { 167 fprintf(stdout, "Status: %s [%#02x]\n", 168 hci_status2str(rp.status), rp.status); 169 return (FAILED); 170 } 171 172 return (OK); 173 } /* hci_write_pin_type */ 174 175 /* Send Read_Stored_Link_Key command to the unit */ 176 static int 177 hci_read_stored_link_key(int s, int argc, char **argv) 178 { 179 struct { 180 ng_hci_cmd_pkt_t hdr; 181 ng_hci_read_stored_link_key_cp cp; 182 } __attribute__ ((packed)) cmd; 183 184 struct { 185 ng_hci_event_pkt_t hdr; 186 union { 187 ng_hci_command_compl_ep cc; 188 ng_hci_return_link_keys_ep key; 189 uint8_t b[NG_HCI_EVENT_PKT_SIZE]; 190 } ep; 191 } __attribute__ ((packed)) event; 192 193 int n, n1; 194 195 /* Send command */ 196 memset(&cmd, 0, sizeof(cmd)); 197 cmd.hdr.type = NG_HCI_CMD_PKT; 198 cmd.hdr.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 199 NG_HCI_OCF_READ_STORED_LINK_KEY)); 200 cmd.hdr.length = sizeof(cmd.cp); 201 202 switch (argc) { 203 case 1: 204 /* parse BD_ADDR */ 205 if (!bt_aton(argv[0], &cmd.cp.bdaddr)) { 206 struct hostent *he = NULL; 207 208 if ((he = bt_gethostbyname(argv[0])) == NULL) 209 return (USAGE); 210 211 memcpy(&cmd.cp.bdaddr, he->h_addr, sizeof(cmd.cp.bdaddr)); 212 } 213 break; 214 215 default: 216 cmd.cp.read_all = 1; 217 break; 218 } 219 220 if (hci_send(s, (char const *) &cmd, sizeof(cmd)) != OK) 221 return (ERROR); 222 223 /* Receive events */ 224 again: 225 memset(&event, 0, sizeof(event)); 226 n = sizeof(event); 227 if (hci_recv(s, (char *) &event, &n) != OK) 228 return (ERROR); 229 230 if (n <= sizeof(event.hdr)) { 231 errno = EMSGSIZE; 232 return (ERROR); 233 } 234 235 if (event.hdr.type != NG_HCI_EVENT_PKT) { 236 errno = EIO; 237 return (ERROR); 238 } 239 240 /* Parse event */ 241 switch (event.hdr.event) { 242 case NG_HCI_EVENT_COMMAND_COMPL: { 243 ng_hci_read_stored_link_key_rp *rp = NULL; 244 245 if (event.ep.cc.opcode == 0x0000 || 246 event.ep.cc.opcode != cmd.hdr.opcode) 247 goto again; 248 249 rp = (ng_hci_read_stored_link_key_rp *)(event.ep.b + 250 sizeof(event.ep.cc)); 251 252 fprintf(stdout, "Complete: Status: %s [%#x]\n", 253 hci_status2str(rp->status), rp->status); 254 fprintf(stdout, "Maximum Number of keys: %d\n", 255 le16toh(rp->max_num_keys)); 256 fprintf(stdout, "Number of keys read: %d\n", 257 le16toh(rp->num_keys_read)); 258 } break; 259 260 case NG_HCI_EVENT_RETURN_LINK_KEYS: { 261 struct _key { 262 bdaddr_t bdaddr; 263 uint8_t key[NG_HCI_KEY_SIZE]; 264 } __attribute__ ((packed)) *k = NULL; 265 266 fprintf(stdout, "Event: Number of keys: %d\n", 267 event.ep.key.num_keys); 268 269 k = (struct _key *)(event.ep.b + sizeof(event.ep.key)); 270 for (n = 0; n < event.ep.key.num_keys; n++) { 271 fprintf(stdout, "\t%d: %s ", 272 n + 1, hci_bdaddr2str(&k->bdaddr)); 273 274 for (n1 = 0; n1 < sizeof(k->key); n1++) 275 fprintf(stdout, "%02x", k->key[n1]); 276 fprintf(stdout, "\n"); 277 278 k ++; 279 } 280 281 goto again; 282 283 } break; 284 285 default: 286 goto again; 287 } 288 289 return (OK); 290 } /* hci_read_store_link_key */ 291 292 /* Send Write_Stored_Link_Key command to the unit */ 293 static int 294 hci_write_stored_link_key(int s, int argc, char **argv) 295 { 296 struct { 297 ng_hci_write_stored_link_key_cp p; 298 bdaddr_t bdaddr; 299 uint8_t key[NG_HCI_KEY_SIZE]; 300 } cp; 301 ng_hci_write_stored_link_key_rp rp; 302 int32_t n; 303 304 memset(&cp, 0, sizeof(cp)); 305 306 switch (argc) { 307 case 2: 308 cp.p.num_keys_write = 1; 309 310 /* parse BD_ADDR */ 311 if (!bt_aton(argv[0], &cp.bdaddr)) { 312 struct hostent *he = NULL; 313 314 if ((he = bt_gethostbyname(argv[0])) == NULL) 315 return (USAGE); 316 317 memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr)); 318 } 319 320 /* parse key */ 321 if (hci_hexstring2array(argv[1], cp.key, sizeof(cp.key)) < 0) 322 return (USAGE); 323 break; 324 325 default: 326 return (USAGE); 327 } 328 329 /* send command */ 330 n = sizeof(rp); 331 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 332 NG_HCI_OCF_WRITE_STORED_LINK_KEY), 333 (char const *) &cp, sizeof(cp), 334 (char *) &rp, &n) == ERROR) 335 return (ERROR); 336 337 if (rp.status != 0x00) { 338 fprintf(stdout, "Status: %s [%#02x]\n", 339 hci_status2str(rp.status), rp.status); 340 return (FAILED); 341 } 342 343 fprintf(stdout, "Number of keys written: %d\n", rp.num_keys_written); 344 345 return (OK); 346 } /* hci_write_stored_link_key */ 347 348 349 /* Send Delete_Stored_Link_Key command to the unit */ 350 static int 351 hci_delete_stored_link_key(int s, int argc, char **argv) 352 { 353 ng_hci_delete_stored_link_key_cp cp; 354 ng_hci_delete_stored_link_key_rp rp; 355 int32_t n; 356 357 memset(&cp, 0, sizeof(cp)); 358 359 switch (argc) { 360 case 1: 361 /* parse BD_ADDR */ 362 if (!bt_aton(argv[0], &cp.bdaddr)) { 363 struct hostent *he = NULL; 364 365 if ((he = bt_gethostbyname(argv[0])) == NULL) 366 return (USAGE); 367 368 memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr)); 369 } 370 break; 371 372 default: 373 cp.delete_all = 1; 374 break; 375 } 376 377 /* send command */ 378 n = sizeof(cp); 379 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 380 NG_HCI_OCF_DELETE_STORED_LINK_KEY), 381 (char const *) &cp, sizeof(cp), 382 (char *) &rp, &n) == ERROR) 383 return (ERROR); 384 385 if (rp.status != 0x00) { 386 fprintf(stdout, "Status: %s [%#02x]\n", 387 hci_status2str(rp.status), rp.status); 388 return (FAILED); 389 } 390 391 fprintf(stdout, "Number of keys deleted: %d\n", rp.num_keys_deleted); 392 393 return (OK); 394 } /* hci_delete_stored_link_key */ 395 396 /* Send Change_Local_Name command to the unit */ 397 static int 398 hci_change_local_name(int s, int argc, char **argv) 399 { 400 ng_hci_change_local_name_cp cp; 401 ng_hci_change_local_name_rp rp; 402 int n; 403 404 /* parse command parameters */ 405 switch (argc) { 406 case 1: 407 snprintf(cp.name, sizeof(cp.name), "%s", argv[0]); 408 break; 409 410 default: 411 return (USAGE); 412 } 413 414 /* send command */ 415 n = sizeof(rp); 416 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 417 NG_HCI_OCF_CHANGE_LOCAL_NAME), 418 (char const *) &cp, sizeof(cp), 419 (char *) &rp, &n) == ERROR) 420 return (ERROR); 421 422 if (rp.status != 0x00) { 423 fprintf(stdout, "Status: %s [%#02x]\n", 424 hci_status2str(rp.status), rp.status); 425 return (FAILED); 426 } 427 428 return (OK); 429 } /* hci_change_local_name */ 430 431 /* Send Read_Local_Name command to the unit */ 432 static int 433 hci_read_local_name(int s, int argc, char **argv) 434 { 435 ng_hci_read_local_name_rp rp; 436 int n; 437 438 n = sizeof(rp); 439 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 440 NG_HCI_OCF_READ_LOCAL_NAME), 441 (char *) &rp, &n) == ERROR) 442 return (ERROR); 443 444 if (rp.status != 0x00) { 445 fprintf(stdout, "Status: %s [%#02x]\n", 446 hci_status2str(rp.status), rp.status); 447 return (FAILED); 448 } 449 450 fprintf(stdout, "Local name: %s\n", rp.name); 451 452 return (OK); 453 } /* hci_read_local_name */ 454 455 /* Send Read_Connection_Accept_Timeout to the unit */ 456 static int 457 hci_read_connection_accept_timeout(int s, int argc, char **argv) 458 { 459 ng_hci_read_con_accept_timo_rp rp; 460 int n; 461 462 n = sizeof(rp); 463 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 464 NG_HCI_OCF_READ_CON_ACCEPT_TIMO), 465 (char *) &rp, &n) == ERROR) 466 return (ERROR); 467 468 if (rp.status != 0x00) { 469 fprintf(stdout, "Status: %s [%#02x]\n", 470 hci_status2str(rp.status), rp.status); 471 return (FAILED); 472 } 473 474 rp.timeout = le16toh(rp.timeout); 475 fprintf(stdout, "Connection accept timeout: %.2f msec [%d slots]\n", 476 rp.timeout * 0.625, rp.timeout); 477 478 return (OK); 479 } /* hci_read_connection_accept_timeout */ 480 481 /* Send Write_Connection_Accept_Timeout to the unit */ 482 static int 483 hci_write_connection_accept_timeout(int s, int argc, char **argv) 484 { 485 ng_hci_write_con_accept_timo_cp cp; 486 ng_hci_write_con_accept_timo_rp rp; 487 int n; 488 489 /* parse command parameters */ 490 switch (argc) { 491 case 1: 492 if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xb540) 493 return (USAGE); 494 495 cp.timeout = (uint16_t) n; 496 cp.timeout = htole16(cp.timeout); 497 break; 498 499 default: 500 return (USAGE); 501 } 502 503 /* send command */ 504 n = sizeof(rp); 505 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 506 NG_HCI_OCF_WRITE_CON_ACCEPT_TIMO), 507 (char const *) &cp, sizeof(cp), 508 (char *) &rp, &n) == ERROR) 509 return (ERROR); 510 511 if (rp.status != 0x00) { 512 fprintf(stdout, "Status: %s [%#02x]\n", 513 hci_status2str(rp.status), rp.status); 514 return (FAILED); 515 } 516 517 return (OK); 518 } /* hci_write_connection_accept_timeout */ 519 520 /* Send Read_Page_Timeout command to the unit */ 521 static int 522 hci_read_page_timeout(int s, int argc, char **argv) 523 { 524 ng_hci_read_page_timo_rp rp; 525 int n; 526 527 n = sizeof(rp); 528 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 529 NG_HCI_OCF_READ_PAGE_TIMO), 530 (char *) &rp, &n) == ERROR) 531 return (ERROR); 532 533 if (rp.status != 0x00) { 534 fprintf(stdout, "Status: %s [%#02x]\n", 535 hci_status2str(rp.status), rp.status); 536 return (FAILED); 537 } 538 539 rp.timeout = le16toh(rp.timeout); 540 fprintf(stdout, "Page timeout: %.2f msec [%d slots]\n", 541 rp.timeout * 0.625, rp.timeout); 542 543 return (OK); 544 } /* hci_read_page_timeoout */ 545 546 /* Send Write_Page_Timeout command to the unit */ 547 static int 548 hci_write_page_timeout(int s, int argc, char **argv) 549 { 550 ng_hci_write_page_timo_cp cp; 551 ng_hci_write_page_timo_rp rp; 552 int n; 553 554 /* parse command parameters */ 555 switch (argc) { 556 case 1: 557 if (sscanf(argv[0], "%d", &n) != 1 || n < 1 || n > 0xffff) 558 return (USAGE); 559 560 cp.timeout = (uint16_t) n; 561 cp.timeout = htole16(cp.timeout); 562 break; 563 564 default: 565 return (USAGE); 566 } 567 568 /* send command */ 569 n = sizeof(rp); 570 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 571 NG_HCI_OCF_WRITE_PAGE_TIMO), 572 (char const *) &cp, sizeof(cp), 573 (char *) &rp, &n) == ERROR) 574 return (ERROR); 575 576 if (rp.status != 0x00) { 577 fprintf(stdout, "Status: %s [%#02x]\n", 578 hci_status2str(rp.status), rp.status); 579 return (FAILED); 580 } 581 582 return (OK); 583 } /* hci_write_page_timeout */ 584 585 /* Send Read_Scan_Enable command to the unit */ 586 static int 587 hci_read_scan_enable(int s, int argc, char **argv) 588 { 589 ng_hci_read_scan_enable_rp rp; 590 int n; 591 592 n = sizeof(rp); 593 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 594 NG_HCI_OCF_READ_SCAN_ENABLE), 595 (char *) &rp, &n) == ERROR) 596 return (ERROR); 597 598 if (rp.status != 0x00) { 599 fprintf(stdout, "Status: %s [%#02x]\n", 600 hci_status2str(rp.status), rp.status); 601 return (FAILED); 602 } 603 604 fprintf(stdout, "Scan enable: %s [%#02x]\n", 605 hci_scan2str(rp.scan_enable), rp.scan_enable); 606 607 return (OK); 608 } /* hci_read_scan_enable */ 609 610 /* Send Write_Scan_Enable command to the unit */ 611 static int 612 hci_write_scan_enable(int s, int argc, char **argv) 613 { 614 ng_hci_write_scan_enable_cp cp; 615 ng_hci_write_scan_enable_rp rp; 616 int n; 617 618 /* parse command parameters */ 619 switch (argc) { 620 case 1: 621 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3) 622 return (USAGE); 623 624 cp.scan_enable = (uint8_t) n; 625 break; 626 627 default: 628 return (USAGE); 629 } 630 631 n = sizeof(rp); 632 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 633 NG_HCI_OCF_WRITE_SCAN_ENABLE), 634 (char const *) &cp, sizeof(cp), 635 (char *) &rp, &n) == ERROR) 636 return (ERROR); 637 638 if (rp.status != 0x00) { 639 fprintf(stdout, "Status: %s [%#02x]\n", 640 hci_status2str(rp.status), rp.status); 641 return (FAILED); 642 } 643 644 return (OK); 645 } /* hci_write_scan_enable */ 646 647 /* Send Read_Page_Scan_Activity command to the unit */ 648 static int 649 hci_read_page_scan_activity(int s, int argc, char **argv) 650 { 651 ng_hci_read_page_scan_activity_rp rp; 652 int n; 653 654 n = sizeof(rp); 655 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 656 NG_HCI_OCF_READ_PAGE_SCAN_ACTIVITY), 657 (char *) &rp, &n) == ERROR) 658 return (ERROR); 659 660 if (rp.status != 0x00) { 661 fprintf(stdout, "Status: %s [%#02x]\n", 662 hci_status2str(rp.status), rp.status); 663 return (FAILED); 664 } 665 666 rp.page_scan_interval = le16toh(rp.page_scan_interval); 667 rp.page_scan_window = le16toh(rp.page_scan_window); 668 669 fprintf(stdout, "Page Scan Interval: %.2f msec [%d slots]\n", 670 rp.page_scan_interval * 0.625, rp.page_scan_interval); 671 fprintf(stdout, "Page Scan Window: %.2f msec [%d slots]\n", 672 rp.page_scan_window * 0.625, rp.page_scan_window); 673 674 return (OK); 675 } /* hci_read_page_scan_activity */ 676 677 /* Send Write_Page_Scan_Activity command to the unit */ 678 static int 679 hci_write_page_scan_activity(int s, int argc, char **argv) 680 { 681 ng_hci_write_page_scan_activity_cp cp; 682 ng_hci_write_page_scan_activity_rp rp; 683 int n; 684 685 /* parse command parameters */ 686 switch (argc) { 687 case 2: 688 /* page scan interval */ 689 if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000) 690 return (USAGE); 691 692 cp.page_scan_interval = (uint16_t) n; 693 694 /* page scan window */ 695 if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000) 696 return (USAGE); 697 698 cp.page_scan_window = (uint16_t) n; 699 700 if (cp.page_scan_window > cp.page_scan_interval) 701 return (USAGE); 702 703 cp.page_scan_interval = htole16(cp.page_scan_interval); 704 cp.page_scan_window = htole16(cp.page_scan_window); 705 break; 706 707 default: 708 return (USAGE); 709 } 710 711 /* send command */ 712 n = sizeof(rp); 713 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 714 NG_HCI_OCF_WRITE_PAGE_SCAN_ACTIVITY), 715 (char const *) &cp, sizeof(cp), 716 (char *) &rp, &n) == ERROR) 717 return (ERROR); 718 719 if (rp.status != 0x00) { 720 fprintf(stdout, "Status: %s [%#02x]\n", 721 hci_status2str(rp.status), rp.status); 722 return (FAILED); 723 } 724 725 return (OK); 726 } /* hci_write_page_scan_activity */ 727 728 /* Send Read_Inquiry_Scan_Activity command to the unit */ 729 static int 730 hci_read_inquiry_scan_activity(int s, int argc, char **argv) 731 { 732 ng_hci_read_inquiry_scan_activity_rp rp; 733 int n; 734 735 n = sizeof(rp); 736 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 737 NG_HCI_OCF_READ_INQUIRY_SCAN_ACTIVITY), 738 (char *) &rp, &n) == ERROR) 739 return (ERROR); 740 741 if (rp.status != 0x00) { 742 fprintf(stdout, "Status: %s [%#02x]\n", 743 hci_status2str(rp.status), rp.status); 744 return (FAILED); 745 } 746 747 rp.inquiry_scan_interval = le16toh(rp.inquiry_scan_interval); 748 rp.inquiry_scan_window = le16toh(rp.inquiry_scan_window); 749 750 fprintf(stdout, "Inquiry Scan Interval: %.2f msec [%d slots]\n", 751 rp.inquiry_scan_interval * 0.625, rp.inquiry_scan_interval); 752 fprintf(stdout, "Inquiry Scan Window: %.2f msec [%d slots]\n", 753 rp.inquiry_scan_window * 0.625, rp.inquiry_scan_interval); 754 755 return (OK); 756 } /* hci_read_inquiry_scan_activity */ 757 758 /* Send Write_Inquiry_Scan_Activity command to the unit */ 759 static int 760 hci_write_inquiry_scan_activity(int s, int argc, char **argv) 761 { 762 ng_hci_write_inquiry_scan_activity_cp cp; 763 ng_hci_write_inquiry_scan_activity_rp rp; 764 int n; 765 766 /* parse command parameters */ 767 switch (argc) { 768 case 2: 769 /* inquiry scan interval */ 770 if (sscanf(argv[0], "%d", &n) != 1 || n < 0x12 || n > 0x1000) 771 return (USAGE); 772 773 cp.inquiry_scan_interval = (uint16_t) n; 774 775 /* inquiry scan window */ 776 if (sscanf(argv[1], "%d", &n) != 1 || n < 0x12 || n > 0x1000) 777 return (USAGE); 778 779 cp.inquiry_scan_window = (uint16_t) n; 780 781 if (cp.inquiry_scan_window > cp.inquiry_scan_interval) 782 return (USAGE); 783 784 cp.inquiry_scan_interval = 785 htole16(cp.inquiry_scan_interval); 786 cp.inquiry_scan_window = htole16(cp.inquiry_scan_window); 787 break; 788 789 default: 790 return (USAGE); 791 } 792 793 /* send command */ 794 n = sizeof(rp); 795 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 796 NG_HCI_OCF_WRITE_INQUIRY_SCAN_ACTIVITY), 797 (char const *) &cp, sizeof(cp), 798 (char *) &rp, &n) == ERROR) 799 return (ERROR); 800 801 if (rp.status != 0x00) { 802 fprintf(stdout, "Status: %s [%#02x]\n", 803 hci_status2str(rp.status), rp.status); 804 return (FAILED); 805 } 806 807 return (OK); 808 } /* hci_write_inquiry_scan_activity */ 809 810 /* Send Read_Authentication_Enable command to the unit */ 811 static int 812 hci_read_authentication_enable(int s, int argc, char **argv) 813 { 814 ng_hci_read_auth_enable_rp rp; 815 int n; 816 817 n = sizeof(rp); 818 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 819 NG_HCI_OCF_READ_AUTH_ENABLE), 820 (char *) &rp, &n) == ERROR) 821 return (ERROR); 822 823 if (rp.status != 0x00) { 824 fprintf(stdout, "Status: %s [%#02x]\n", 825 hci_status2str(rp.status), rp.status); 826 return (FAILED); 827 } 828 829 fprintf(stdout, "Authentication Enable: %s [%d]\n", 830 rp.auth_enable? "Enabled" : "Disabled", rp.auth_enable); 831 832 return (OK); 833 } /* hci_read_authentication_enable */ 834 835 /* Send Write_Authentication_Enable command to the unit */ 836 static int 837 hci_write_authentication_enable(int s, int argc, char **argv) 838 { 839 ng_hci_write_auth_enable_cp cp; 840 ng_hci_write_auth_enable_rp rp; 841 int n; 842 843 /* parse command parameters */ 844 switch (argc) { 845 case 1: 846 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1) 847 return (USAGE); 848 849 cp.auth_enable = (uint8_t) n; 850 break; 851 852 default: 853 return (USAGE); 854 } 855 856 /* send command */ 857 n = sizeof(rp); 858 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 859 NG_HCI_OCF_WRITE_AUTH_ENABLE), 860 (char const *) &cp, sizeof(cp), 861 (char *) &rp, &n) == ERROR) 862 return (ERROR); 863 864 if (rp.status != 0x00) { 865 fprintf(stdout, "Status: %s [%#02x]\n", 866 hci_status2str(rp.status), rp.status); 867 return (FAILED); 868 } 869 870 return (OK); 871 } /* hci_write_authentication_enable */ 872 873 /* Send Read_Encryption_Mode command to the unit */ 874 static int 875 hci_read_encryption_mode(int s, int argc, char **argv) 876 { 877 ng_hci_read_encryption_mode_rp rp; 878 int n; 879 880 n = sizeof(rp); 881 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 882 NG_HCI_OCF_READ_ENCRYPTION_MODE), 883 (char *) &rp, &n) == ERROR) 884 return (ERROR); 885 886 if (rp.status != 0x00) { 887 fprintf(stdout, "Status: %s [%#02x]\n", 888 hci_status2str(rp.status), rp.status); 889 return (FAILED); 890 } 891 892 fprintf(stdout, "Encryption mode: %s [%#02x]\n", 893 hci_encrypt2str(rp.encryption_mode, 0), rp.encryption_mode); 894 895 return (OK); 896 } /* hci_read_encryption_mode */ 897 898 /* Send Write_Encryption_Mode command to the unit */ 899 static int 900 hci_write_encryption_mode(int s, int argc, char **argv) 901 { 902 ng_hci_write_encryption_mode_cp cp; 903 ng_hci_write_encryption_mode_rp rp; 904 int n; 905 906 /* parse command parameters */ 907 switch (argc) { 908 case 1: 909 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2) 910 return (USAGE); 911 912 cp.encryption_mode = (uint8_t) n; 913 break; 914 915 default: 916 return (USAGE); 917 } 918 919 /* send command */ 920 n = sizeof(rp); 921 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 922 NG_HCI_OCF_WRITE_ENCRYPTION_MODE), 923 (char const *) &cp, sizeof(cp), 924 (char *) &rp, &n) == ERROR) 925 return (ERROR); 926 927 if (rp.status != 0x00) { 928 fprintf(stdout, "Status: %s [%#02x]\n", 929 hci_status2str(rp.status), rp.status); 930 return (FAILED); 931 } 932 933 return (OK); 934 } /* hci_write_encryption_mode */ 935 936 /* Send Read_Class_Of_Device command to the unit */ 937 static int 938 hci_read_class_of_device(int s, int argc, char **argv) 939 { 940 ng_hci_read_unit_class_rp rp; 941 int n; 942 943 n = sizeof(rp); 944 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 945 NG_HCI_OCF_READ_UNIT_CLASS), 946 (char *) &rp, &n) == ERROR) 947 return (ERROR); 948 949 if (rp.status != 0x00) { 950 fprintf(stdout, "Status: %s [%#02x]\n", 951 hci_status2str(rp.status), rp.status); 952 return (FAILED); 953 } 954 955 fprintf(stdout, "Class: %02x:%02x:%02x\n", 956 rp.uclass[2], rp.uclass[1], rp.uclass[0]); 957 958 return (0); 959 } /* hci_read_class_of_device */ 960 961 /* Send Write_Class_Of_Device command to the unit */ 962 static int 963 hci_write_class_of_device(int s, int argc, char **argv) 964 { 965 ng_hci_write_unit_class_cp cp; 966 ng_hci_write_unit_class_rp rp; 967 int n0, n1, n2; 968 969 /* parse command parameters */ 970 switch (argc) { 971 case 1: 972 if (sscanf(argv[0], "%x:%x:%x", &n2, &n1, &n0) != 3) 973 return (USAGE); 974 975 cp.uclass[0] = (n0 & 0xff); 976 cp.uclass[1] = (n1 & 0xff); 977 cp.uclass[2] = (n2 & 0xff); 978 break; 979 980 default: 981 return (USAGE); 982 } 983 984 /* send command */ 985 n0 = sizeof(rp); 986 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 987 NG_HCI_OCF_WRITE_UNIT_CLASS), 988 (char const *) &cp, sizeof(cp), 989 (char *) &rp, &n0) == ERROR) 990 return (ERROR); 991 992 if (rp.status != 0x00) { 993 fprintf(stdout, "Status: %s [%#02x]\n", 994 hci_status2str(rp.status), rp.status); 995 return (FAILED); 996 } 997 998 return (OK); 999 } /* hci_write_class_of_device */ 1000 1001 /* Send Read_Voice_Settings command to the unit */ 1002 static int 1003 hci_read_voice_settings(int s, int argc, char **argv) 1004 { 1005 ng_hci_read_voice_settings_rp rp; 1006 int n, 1007 input_coding, 1008 input_data_format, 1009 input_sample_size; 1010 1011 n = sizeof(rp); 1012 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1013 NG_HCI_OCF_READ_VOICE_SETTINGS), 1014 (char *) &rp, &n) == ERROR) 1015 return (ERROR); 1016 1017 if (rp.status != 0x00) { 1018 fprintf(stdout, "Status: %s [%#02x]\n", 1019 hci_status2str(rp.status), rp.status); 1020 return (FAILED); 1021 } 1022 1023 rp.settings = le16toh(rp.settings); 1024 1025 input_coding = (rp.settings & 0x0300) >> 8; 1026 input_data_format = (rp.settings & 0x00c0) >> 6; 1027 input_sample_size = (rp.settings & 0x0020) >> 5; 1028 1029 fprintf(stdout, "Voice settings: %#04x\n", rp.settings); 1030 fprintf(stdout, "Input coding: %s [%d]\n", 1031 hci_coding2str(input_coding), input_coding); 1032 fprintf(stdout, "Input data format: %s [%d]\n", 1033 hci_vdata2str(input_data_format), input_data_format); 1034 1035 if (input_coding == 0x00) /* Only for Linear PCM */ 1036 fprintf(stdout, "Input sample size: %d bit [%d]\n", 1037 input_sample_size? 16 : 8, input_sample_size); 1038 1039 return (OK); 1040 } /* hci_read_voice_settings */ 1041 1042 /* Send Write_Voice_Settings command to the unit */ 1043 static int 1044 hci_write_voice_settings(int s, int argc, char **argv) 1045 { 1046 ng_hci_write_voice_settings_cp cp; 1047 ng_hci_write_voice_settings_rp rp; 1048 int n; 1049 1050 /* parse command parameters */ 1051 switch (argc) { 1052 case 1: 1053 if (sscanf(argv[0], "%x", &n) != 1) 1054 return (USAGE); 1055 1056 cp.settings = (uint16_t) n; 1057 cp.settings = htole16(cp.settings); 1058 break; 1059 1060 default: 1061 return (USAGE); 1062 } 1063 1064 /* send command */ 1065 n = sizeof(rp); 1066 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1067 NG_HCI_OCF_WRITE_VOICE_SETTINGS), 1068 (char const *) &cp, sizeof(cp), 1069 (char *) &rp, &n) == ERROR) 1070 return (ERROR); 1071 1072 if (rp.status != 0x00) { 1073 fprintf(stdout, "Status: %s [%#02x]\n", 1074 hci_status2str(rp.status), rp.status); 1075 return (FAILED); 1076 } 1077 1078 return (OK); 1079 } /* hci_write_voice_settings */ 1080 1081 /* Send Read_Number_Broadcast_Restransmissions */ 1082 static int 1083 hci_read_number_broadcast_retransmissions(int s, int argc, char **argv) 1084 { 1085 ng_hci_read_num_broadcast_retrans_rp rp; 1086 int n; 1087 1088 n = sizeof(rp); 1089 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1090 NG_HCI_OCF_READ_NUM_BROADCAST_RETRANS), 1091 (char *) &rp, &n) == ERROR) 1092 return (ERROR); 1093 1094 if (rp.status != 0x00) { 1095 fprintf(stdout, "Status: %s [%#02x]\n", 1096 hci_status2str(rp.status), rp.status); 1097 return (FAILED); 1098 } 1099 1100 fprintf(stdout, "Number of broadcast retransmissions: %d\n", 1101 rp.counter); 1102 1103 return (OK); 1104 } /* hci_read_number_broadcast_retransmissions */ 1105 1106 /* Send Write_Number_Broadcast_Restransmissions */ 1107 static int 1108 hci_write_number_broadcast_retransmissions(int s, int argc, char **argv) 1109 { 1110 ng_hci_write_num_broadcast_retrans_cp cp; 1111 ng_hci_write_num_broadcast_retrans_rp rp; 1112 int n; 1113 1114 /* parse command parameters */ 1115 switch (argc) { 1116 case 1: 1117 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 0xff) 1118 return (USAGE); 1119 1120 cp.counter = (uint8_t) n; 1121 break; 1122 1123 default: 1124 return (USAGE); 1125 } 1126 1127 /* send command */ 1128 n = sizeof(rp); 1129 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1130 NG_HCI_OCF_WRITE_NUM_BROADCAST_RETRANS), 1131 (char const *) &cp, sizeof(cp), 1132 (char *) &rp, &n) == ERROR) 1133 return (ERROR); 1134 1135 if (rp.status != 0x00) { 1136 fprintf(stdout, "Status: %s [%#02x]\n", 1137 hci_status2str(rp.status), rp.status); 1138 return (FAILED); 1139 } 1140 1141 return (OK); 1142 } /* hci_write_number_broadcast_retransmissions */ 1143 1144 /* Send Read_Hold_Mode_Activity command to the unit */ 1145 static int 1146 hci_read_hold_mode_activity(int s, int argc, char **argv) 1147 { 1148 ng_hci_read_hold_mode_activity_rp rp; 1149 int n; 1150 char buffer[1024]; 1151 1152 n = sizeof(rp); 1153 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1154 NG_HCI_OCF_READ_HOLD_MODE_ACTIVITY), 1155 (char *) &rp, &n) == ERROR) 1156 return (ERROR); 1157 1158 if (rp.status != 0x00) { 1159 fprintf(stdout, "Status: %s [%#02x]\n", 1160 hci_status2str(rp.status), rp.status); 1161 return (FAILED); 1162 } 1163 1164 fprintf(stdout, "Hold Mode Activities: %#02x\n", rp.hold_mode_activity); 1165 if (rp.hold_mode_activity == 0) 1166 fprintf(stdout, "Maintain current Power State"); 1167 else 1168 fprintf(stdout, "%s", hci_hmode2str(rp.hold_mode_activity, 1169 buffer, sizeof(buffer))); 1170 1171 fprintf(stdout, "\n"); 1172 1173 return (OK); 1174 } /* hci_read_hold_mode_activity */ 1175 1176 /* Send Write_Hold_Mode_Activity command to the unit */ 1177 static int 1178 hci_write_hold_mode_activity(int s, int argc, char **argv) 1179 { 1180 ng_hci_write_hold_mode_activity_cp cp; 1181 ng_hci_write_hold_mode_activity_rp rp; 1182 int n; 1183 1184 /* parse command parameters */ 1185 switch (argc) { 1186 case 1: 1187 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 4) 1188 return (USAGE); 1189 1190 cp.hold_mode_activity = (uint8_t) n; 1191 break; 1192 1193 default: 1194 return (USAGE); 1195 } 1196 1197 /* send command */ 1198 n = sizeof(rp); 1199 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1200 NG_HCI_OCF_WRITE_HOLD_MODE_ACTIVITY), 1201 (char const *) &cp, sizeof(cp), 1202 (char *) &rp, &n) == ERROR) 1203 return (ERROR); 1204 1205 if (rp.status != 0x00) { 1206 fprintf(stdout, "Status: %s [%#02x]\n", 1207 hci_status2str(rp.status), rp.status); 1208 return (FAILED); 1209 } 1210 1211 return (OK); 1212 } /* hci_write_hold_mode_activity */ 1213 1214 /* Send Read_SCO_Flow_Control_Enable command to the unit */ 1215 static int 1216 hci_read_sco_flow_control_enable(int s, int argc, char **argv) 1217 { 1218 ng_hci_read_sco_flow_control_rp rp; 1219 int n; 1220 1221 n = sizeof(rp); 1222 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1223 NG_HCI_OCF_READ_SCO_FLOW_CONTROL), 1224 (char *) &rp, &n) == ERROR) 1225 return (ERROR); 1226 1227 if (rp.status != 0x00) { 1228 fprintf(stdout, "Status: %s [%#02x]\n", 1229 hci_status2str(rp.status), rp.status); 1230 return (FAILED); 1231 } 1232 1233 fprintf(stdout, "SCO flow control %s [%d]\n", 1234 rp.flow_control? "enabled" : "disabled", rp.flow_control); 1235 1236 return (OK); 1237 } /* hci_read_sco_flow_control_enable */ 1238 1239 /* Send Write_SCO_Flow_Control_Enable command to the unit */ 1240 static int 1241 hci_write_sco_flow_control_enable(int s, int argc, char **argv) 1242 { 1243 ng_hci_write_sco_flow_control_cp cp; 1244 ng_hci_write_sco_flow_control_rp rp; 1245 int n; 1246 1247 /* parse command parameters */ 1248 switch (argc) { 1249 case 1: 1250 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 1) 1251 return (USAGE); 1252 1253 cp.flow_control = (uint8_t) n; 1254 break; 1255 1256 default: 1257 return (USAGE); 1258 } 1259 1260 /* send command */ 1261 n = sizeof(rp); 1262 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1263 NG_HCI_OCF_WRITE_SCO_FLOW_CONTROL), 1264 (char const *) &cp, sizeof(cp), 1265 (char *) &rp, &n) == ERROR) 1266 return (ERROR); 1267 1268 if (rp.status != 0x00) { 1269 fprintf(stdout, "Status: %s [%#02x]\n", 1270 hci_status2str(rp.status), rp.status); 1271 return (FAILED); 1272 } 1273 1274 return (OK); 1275 } /* hci_write_sco_flow_control_enable */ 1276 1277 /* Send Read_Link_Supervision_Timeout command to the unit */ 1278 static int 1279 hci_read_link_supervision_timeout(int s, int argc, char **argv) 1280 { 1281 ng_hci_read_link_supervision_timo_cp cp; 1282 ng_hci_read_link_supervision_timo_rp rp; 1283 int n; 1284 1285 switch (argc) { 1286 case 1: 1287 /* connection handle */ 1288 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff) 1289 return (USAGE); 1290 1291 cp.con_handle = (uint16_t) (n & 0x0fff); 1292 cp.con_handle = htole16(cp.con_handle); 1293 break; 1294 1295 default: 1296 return (USAGE); 1297 } 1298 1299 /* send command */ 1300 n = sizeof(rp); 1301 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1302 NG_HCI_OCF_READ_LINK_SUPERVISION_TIMO), 1303 (char const *) &cp, sizeof(cp), 1304 (char *) &rp, &n) == ERROR) 1305 return (ERROR); 1306 1307 if (rp.status != 0x00) { 1308 fprintf(stdout, "Status: %s [%#02x]\n", 1309 hci_status2str(rp.status), rp.status); 1310 return (FAILED); 1311 } 1312 1313 rp.timeout = le16toh(rp.timeout); 1314 1315 fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle)); 1316 fprintf(stdout, "Link supervision timeout: %.2f msec [%d slots]\n", 1317 rp.timeout * 0.625, rp.timeout); 1318 1319 return (OK); 1320 } /* hci_read_link_supervision_timeout */ 1321 1322 /* Send Write_Link_Supervision_Timeout command to the unit */ 1323 static int 1324 hci_write_link_supervision_timeout(int s, int argc, char **argv) 1325 { 1326 ng_hci_write_link_supervision_timo_cp cp; 1327 ng_hci_write_link_supervision_timo_rp rp; 1328 int n; 1329 1330 switch (argc) { 1331 case 2: 1332 /* connection handle */ 1333 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff) 1334 return (USAGE); 1335 1336 cp.con_handle = (uint16_t) (n & 0x0fff); 1337 cp.con_handle = htole16(cp.con_handle); 1338 1339 /* link supervision timeout */ 1340 if (sscanf(argv[1], "%d", &n) != 1 || n < 0 || n > 0xffff) 1341 return (USAGE); 1342 1343 cp.timeout = (uint16_t) (n & 0x0fff); 1344 cp.timeout = htole16(cp.timeout); 1345 break; 1346 1347 default: 1348 return (USAGE); 1349 } 1350 1351 /* send command */ 1352 n = sizeof(rp); 1353 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1354 NG_HCI_OCF_WRITE_LINK_SUPERVISION_TIMO), 1355 (char const *) &cp, sizeof(cp), 1356 (char *) &rp, &n) == ERROR) 1357 return (ERROR); 1358 1359 if (rp.status != 0x00) { 1360 fprintf(stdout, "Status: %s [%#02x]\n", 1361 hci_status2str(rp.status), rp.status); 1362 return (FAILED); 1363 } 1364 1365 return (OK); 1366 } /* hci_write_link_supervision_timeout */ 1367 1368 /* Send Read_Page_Scan_Period_Mode command to the unit */ 1369 static int 1370 hci_read_page_scan_period_mode(int s, int argc, char **argv) 1371 { 1372 ng_hci_read_page_scan_period_rp rp; 1373 int n; 1374 1375 n = sizeof(rp); 1376 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1377 NG_HCI_OCF_READ_PAGE_SCAN_PERIOD), 1378 (char *) &rp, &n) == ERROR) 1379 return (ERROR); 1380 1381 if (rp.status != 0x00) { 1382 fprintf(stdout, "Status: %s [%#02x]\n", 1383 hci_status2str(rp.status), rp.status); 1384 return (FAILED); 1385 } 1386 1387 fprintf(stdout, "Page scan period mode: %#02x\n", 1388 rp.page_scan_period_mode); 1389 1390 return (OK); 1391 } /* hci_read_page_scan_period_mode */ 1392 1393 /* Send Write_Page_Scan_Period_Mode command to the unit */ 1394 static int 1395 hci_write_page_scan_period_mode(int s, int argc, char **argv) 1396 { 1397 ng_hci_write_page_scan_period_cp cp; 1398 ng_hci_write_page_scan_period_rp rp; 1399 int n; 1400 1401 /* parse command arguments */ 1402 switch (argc) { 1403 case 1: 1404 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2) 1405 return (USAGE); 1406 1407 cp.page_scan_period_mode = (n & 0xff); 1408 break; 1409 1410 default: 1411 return (USAGE); 1412 } 1413 1414 /* send command */ 1415 n = sizeof(rp); 1416 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1417 NG_HCI_OCF_WRITE_PAGE_SCAN_PERIOD), 1418 (char const *) &cp, sizeof(cp), 1419 (char *) &rp, &n) == ERROR) 1420 return (ERROR); 1421 1422 if (rp.status != 0x00) { 1423 fprintf(stdout, "Status: %s [%#02x]\n", 1424 hci_status2str(rp.status), rp.status); 1425 return (FAILED); 1426 } 1427 1428 return (OK); 1429 } /* hci_write_page_scan_period_mode */ 1430 1431 /* Send Read_Page_Scan_Mode command to the unit */ 1432 static int 1433 hci_read_page_scan_mode(int s, int argc, char **argv) 1434 { 1435 ng_hci_read_page_scan_rp rp; 1436 int n; 1437 1438 n = sizeof(rp); 1439 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1440 NG_HCI_OCF_READ_PAGE_SCAN), 1441 (char *) &rp, &n) == ERROR) 1442 return (ERROR); 1443 1444 if (rp.status != 0x00) { 1445 fprintf(stdout, "Status: %s [%#02x]\n", 1446 hci_status2str(rp.status), rp.status); 1447 return (FAILED); 1448 } 1449 1450 fprintf(stdout, "Page scan mode: %#02x\n", rp.page_scan_mode); 1451 1452 return (OK); 1453 } /* hci_read_page_scan_mode */ 1454 1455 /* Send Write_Page_Scan_Mode command to the unit */ 1456 static int 1457 hci_write_page_scan_mode(int s, int argc, char **argv) 1458 { 1459 ng_hci_write_page_scan_cp cp; 1460 ng_hci_write_page_scan_rp rp; 1461 int n; 1462 1463 /* parse command arguments */ 1464 switch (argc) { 1465 case 1: 1466 if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3) 1467 return (USAGE); 1468 1469 cp.page_scan_mode = (n & 0xff); 1470 break; 1471 1472 default: 1473 return (USAGE); 1474 } 1475 1476 /* send command */ 1477 n = sizeof(rp); 1478 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1479 NG_HCI_OCF_WRITE_PAGE_SCAN), 1480 (char const *) &cp, sizeof(cp), 1481 (char *) &rp, &n) == ERROR) 1482 return (ERROR); 1483 1484 if (rp.status != 0x00) { 1485 fprintf(stdout, "Status: %s [%#02x]\n", 1486 hci_status2str(rp.status), rp.status); 1487 return (FAILED); 1488 } 1489 1490 return (OK); 1491 } /* hci_write_page_scan_mode */ 1492 1493 static int 1494 hci_read_le_host_support(int s, int argc, char **argv) 1495 { 1496 ng_hci_read_le_host_supported_rp rp; 1497 int n; 1498 n = sizeof(rp); 1499 if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1500 NG_HCI_OCF_READ_LE_HOST_SUPPORTED), 1501 (char *) &rp, &n) == ERROR) 1502 return (ERROR); 1503 1504 if (rp.status != 0x00) { 1505 fprintf(stdout, "Status: %s [%#02x]\n", 1506 hci_status2str(rp.status), rp.status); 1507 return (FAILED); 1508 } 1509 1510 fprintf(stdout, "LE Host support: %#02x\n", rp.le_supported_host); 1511 fprintf(stdout, "Simultaneous LE Host : %#02x\n", rp.simultaneous_le_host); 1512 1513 return (OK); 1514 1515 } 1516 static int 1517 hci_write_le_host_support(int s, int argc, char **argv) 1518 { 1519 ng_hci_write_le_host_supported_cp cp; 1520 ng_hci_write_le_host_supported_rp rp; 1521 1522 int n; 1523 1524 cp.le_supported_host = 0; 1525 cp.simultaneous_le_host = 0; 1526 switch (argc) { 1527 case 2: 1528 if (sscanf(argv[1], "%d", &n) != 1 || (n != 0 && n != 1)){ 1529 printf("-ARGC2: %d\n", n); 1530 return (USAGE); 1531 } 1532 cp.simultaneous_le_host = (n &1); 1533 1534 case 1: 1535 if (sscanf(argv[0], "%d", &n) != 1 || (n != 0 && n != 1)){ 1536 printf("+ARGC1: %d\n", n); 1537 return (USAGE); 1538 } 1539 1540 cp.le_supported_host = (n &1); 1541 break; 1542 1543 default: 1544 return (USAGE); 1545 } 1546 1547 1548 /* send command */ 1549 n = sizeof(rp); 1550 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, 1551 NG_HCI_OCF_WRITE_LE_HOST_SUPPORTED), 1552 (char const *) &cp, sizeof(cp), 1553 (char *) &rp, &n) == ERROR) 1554 return (ERROR); 1555 1556 if (rp.status != 0x00) { 1557 fprintf(stdout, "Status: %s [%#02x]\n", 1558 hci_status2str(rp.status), rp.status); 1559 return (FAILED); 1560 } 1561 1562 return (OK); 1563 } 1564 1565 struct hci_command host_controller_baseband_commands[] = { 1566 { 1567 "reset", 1568 "\nThe Reset command will reset the Host Controller and the Link Manager.\n" \ 1569 "After the reset is completed, the current operational state will be lost,\n" \ 1570 "the Bluetooth unit will enter standby mode and the Host Controller will\n" \ 1571 "automatically revert to the default values for the parameters for which\n" \ 1572 "default values are defined in the specification.", 1573 &hci_reset 1574 }, 1575 { 1576 "read_pin_type", 1577 "\nThe Read_PIN_Type command is used for the Host to read whether the Link\n" \ 1578 "Manager assumes that the Host supports variable PIN codes only a fixed PIN\n" \ 1579 "code.", 1580 &hci_read_pin_type 1581 }, 1582 { 1583 "write_pin_type <pin_type>", 1584 "\nThe Write_PIN_Type command is used for the Host to write to the Host\n" \ 1585 "Controller whether the Host supports variable PIN codes or only a fixed PIN\n"\ 1586 "code.\n\n" \ 1587 "\t<pin_type> - dd; 0 - Variable; 1 - Fixed", 1588 &hci_write_pin_type 1589 }, 1590 { 1591 "read_stored_link_key [<BD_ADDR>]", 1592 "\nThe Read_Stored_Link_Key command provides the ability to read one or\n" \ 1593 "more link keys stored in the Bluetooth Host Controller. The Bluetooth Host\n" \ 1594 "Controller can store a limited number of link keys for other Bluetooth\n" \ 1595 "devices.\n\n" \ 1596 "\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name", 1597 &hci_read_stored_link_key 1598 }, 1599 { 1600 "write_stored_link_key <BD_ADDR> <key>", 1601 "\nThe Write_Stored_Link_Key command provides the ability to write one\n" \ 1602 "or more link keys to be stored in the Bluetooth Host Controller. The\n" \ 1603 "Bluetooth Host Controller can store a limited number of link keys for other\n"\ 1604 "Bluetooth devices. If no additional space is available in the Bluetooth\n"\ 1605 "Host Controller then no additional link keys will be stored.\n\n" \ 1606 "\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name\n" \ 1607 "\t<key> - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx up to 16 bytes link key", 1608 &hci_write_stored_link_key 1609 }, 1610 { 1611 "delete_stored_link_key [<BD_ADDR>]", 1612 "\nThe Delete_Stored_Link_Key command provides the ability to remove one\n" \ 1613 "or more of the link keys stored in the Bluetooth Host Controller. The\n" \ 1614 "Bluetooth Host Controller can store a limited number of link keys for other\n"\ 1615 "Bluetooth devices.\n\n" \ 1616 "\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name", 1617 &hci_delete_stored_link_key 1618 }, 1619 { 1620 "change_local_name <name>", 1621 "\nThe Change_Local_Name command provides the ability to modify the user\n" \ 1622 "friendly name for the Bluetooth unit.\n\n" \ 1623 "\t<name> - string", 1624 &hci_change_local_name 1625 }, 1626 { 1627 "read_local_name", 1628 "\nThe Read_Local_Name command provides the ability to read the\n" \ 1629 "stored user-friendly name for the Bluetooth unit.", 1630 &hci_read_local_name 1631 }, 1632 { 1633 "read_connection_accept_timeout", 1634 "\nThis command will read the value for the Connection_Accept_Timeout\n" \ 1635 "configuration parameter. The Connection_Accept_Timeout configuration\n" \ 1636 "parameter allows the Bluetooth hardware to automatically deny a\n" \ 1637 "connection request after a specified time period has occurred and\n" \ 1638 "the new connection is not accepted. Connection Accept Timeout\n" \ 1639 "measured in Number of Baseband slots.", 1640 &hci_read_connection_accept_timeout 1641 }, 1642 { 1643 "write_connection_accept_timeout <timeout>", 1644 "\nThis command will write the value for the Connection_Accept_Timeout\n" \ 1645 "configuration parameter.\n\n" \ 1646 "\t<timeout> - dddd; measured in number of baseband slots.", 1647 &hci_write_connection_accept_timeout 1648 }, 1649 { 1650 "read_page_timeout", 1651 "\nThis command will read the value for the Page_Timeout configuration\n" \ 1652 "parameter. The Page_Timeout configuration parameter defines the\n" \ 1653 "maximum time the local Link Manager will wait for a baseband page\n" \ 1654 "response from the remote unit at a locally initiated connection\n" \ 1655 "attempt. Page Timeout measured in Number of Baseband slots.", 1656 &hci_read_page_timeout 1657 }, 1658 { 1659 "write_page_timeout <timeout>", 1660 "\nThis command will write the value for the Page_Timeout configuration\n" \ 1661 "parameter.\n\n" \ 1662 "\t<timeout> - dddd; measured in number of baseband slots.", 1663 &hci_write_page_timeout 1664 }, 1665 { 1666 "read_scan_enable", 1667 "\nThis command will read the value for the Scan_Enable parameter. The\n" \ 1668 "Scan_Enable parameter controls whether or not the Bluetooth uint\n" \ 1669 "will periodically scan for page attempts and/or inquiry requests\n" \ 1670 "from other Bluetooth unit.\n\n" \ 1671 "\t0x00 - No Scans enabled.\n" \ 1672 "\t0x01 - Inquiry Scan enabled. Page Scan disabled.\n" \ 1673 "\t0x02 - Inquiry Scan disabled. Page Scan enabled.\n" \ 1674 "\t0x03 - Inquiry Scan enabled. Page Scan enabled.", 1675 &hci_read_scan_enable 1676 }, 1677 { 1678 "write_scan_enable <scan_enable>", 1679 "\nThis command will write the value for the Scan_Enable parameter.\n" \ 1680 "The Scan_Enable parameter controls whether or not the Bluetooth\n" \ 1681 "unit will periodically scan for page attempts and/or inquiry\n" \ 1682 "requests from other Bluetooth unit.\n\n" \ 1683 "\t<scan_enable> - dd;\n" \ 1684 "\t0 - No Scans enabled.\n" \ 1685 "\t1 - Inquiry Scan enabled. Page Scan disabled.\n" \ 1686 "\t2 - Inquiry Scan disabled. Page Scan enabled.\n" \ 1687 "\t3 - Inquiry Scan enabled. Page Scan enabled.", 1688 &hci_write_scan_enable 1689 }, 1690 { 1691 "read_page_scan_activity", 1692 "\nThis command will read the value for Page_Scan_Activity configuration\n" \ 1693 "parameters. The Page_Scan_Interval configuration parameter defines the\n" \ 1694 "amount of time between consecutive page scans. This time interval is \n" \ 1695 "defined from when the Host Controller started its last page scan until\n" \ 1696 "it begins the next page scan. The Page_Scan_Window configuration parameter\n" \ 1697 "defines the amount of time for the duration of the page scan. The\n" \ 1698 "Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.", 1699 &hci_read_page_scan_activity 1700 }, 1701 { 1702 "write_page_scan_activity interval(dddd) window(dddd)", 1703 "\nThis command will write the value for Page_Scan_Activity configuration\n" \ 1704 "parameter. The Page_Scan_Interval configuration parameter defines the\n" \ 1705 "amount of time between consecutive page scans. This is defined as the time\n" \ 1706 "interval from when the Host Controller started its last page scan until it\n" \ 1707 "begins the next page scan. The Page_Scan_Window configuration parameter\n" \ 1708 "defines the amount of time for the duration of the page scan. \n" \ 1709 "The Page_Scan_Window can only be less than or equal to the Page_Scan_Interval.\n\n" \ 1710 "\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \ 1711 "\t<window> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec", 1712 &hci_write_page_scan_activity 1713 }, 1714 { 1715 "read_inquiry_scan_activity", 1716 "\nThis command will read the value for Inquiry_Scan_Activity configuration\n" \ 1717 "parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \ 1718 "amount of time between consecutive inquiry scans. This is defined as the\n" \ 1719 "time interval from when the Host Controller started its last inquiry scan\n" \ 1720 "until it begins the next inquiry scan.", 1721 &hci_read_inquiry_scan_activity 1722 }, 1723 { 1724 "write_inquiry_scan_activity interval(dddd) window(dddd)", 1725 "\nThis command will write the value for Inquiry_Scan_Activity configuration\n"\ 1726 "parameter. The Inquiry_Scan_Interval configuration parameter defines the\n" \ 1727 "amount of time between consecutive inquiry scans. This is defined as the\n" \ 1728 "time interval from when the Host Controller started its last inquiry scan\n" \ 1729 "until it begins the next inquiry scan. The Inquiry_Scan_Window configuration\n" \ 1730 "parameter defines the amount of time for the duration of the inquiry scan.\n" \ 1731 "The Inquiry_Scan_Window can only be less than or equal to the Inquiry_Scan_Interval.\n\n" \ 1732 "\t<interval> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec\n" \ 1733 "\t<window> - Range: 0x0012 -- 0x100, Time = N * 0.625 msec", 1734 &hci_write_inquiry_scan_activity 1735 }, 1736 { 1737 "read_authentication_enable", 1738 "\nThis command will read the value for the Authentication_Enable parameter.\n"\ 1739 "The Authentication_Enable parameter controls if the local unit requires\n"\ 1740 "to authenticate the remote unit at connection setup (between the\n" \ 1741 "Create_Connection command or acceptance of an incoming ACL connection\n"\ 1742 "and the corresponding Connection Complete event). At connection setup, only\n"\ 1743 "the unit(s) with the Authentication_Enable parameter enabled will try to\n"\ 1744 "authenticate the other unit.", 1745 &hci_read_authentication_enable 1746 }, 1747 { 1748 "write_authentication_enable enable(0|1)", 1749 "\nThis command will write the value for the Authentication_Enable parameter.\n"\ 1750 "The Authentication_Enable parameter controls if the local unit requires to\n"\ 1751 "authenticate the remote unit at connection setup (between the\n" \ 1752 "Create_Connection command or acceptance of an incoming ACL connection\n" \ 1753 "and the corresponding Connection Complete event). At connection setup, only\n"\ 1754 "the unit(s) with the Authentication_Enable parameter enabled will try to\n"\ 1755 "authenticate the other unit.", 1756 &hci_write_authentication_enable 1757 }, 1758 { 1759 "read_encryption_mode", 1760 "\nThis command will read the value for the Encryption_Mode parameter. The\n" \ 1761 "Encryption_Mode parameter controls if the local unit requires encryption\n" \ 1762 "to the remote unit at connection setup (between the Create_Connection\n" \ 1763 "command or acceptance of an incoming ACL connection and the corresponding\n" \ 1764 "Connection Complete event). At connection setup, only the unit(s) with\n" \ 1765 "the Authentication_Enable parameter enabled and Encryption_Mode parameter\n" \ 1766 "enabled will try to encrypt the connection to the other unit.\n\n" \ 1767 "\t<encryption_mode>:\n" \ 1768 "\t0x00 - Encryption disabled.\n" \ 1769 "\t0x01 - Encryption only for point-to-point packets.\n" \ 1770 "\t0x02 - Encryption for both point-to-point and broadcast packets.", 1771 &hci_read_encryption_mode 1772 }, 1773 { 1774 "write_encryption_mode mode(0|1|2)", 1775 "\tThis command will write the value for the Encryption_Mode parameter.\n" \ 1776 "The Encryption_Mode parameter controls if the local unit requires\n" \ 1777 "encryption to the remote unit at connection setup (between the\n" \ 1778 "Create_Connection command or acceptance of an incoming ACL connection\n" \ 1779 "and the corresponding Connection Complete event). At connection setup,\n" \ 1780 "only the unit(s) with the Authentication_Enable parameter enabled and\n" \ 1781 "Encryption_Mode parameter enabled will try to encrypt the connection to\n" \ 1782 "the other unit.\n\n" \ 1783 "\t<encryption_mode> (dd)\n" \ 1784 "\t0 - Encryption disabled.\n" \ 1785 "\t1 - Encryption only for point-to-point packets.\n" \ 1786 "\t2 - Encryption for both point-to-point and broadcast packets.", 1787 &hci_write_encryption_mode 1788 }, 1789 { 1790 "read_class_of_device", 1791 "\nThis command will read the value for the Class_of_Device parameter.\n" \ 1792 "The Class_of_Device parameter is used to indicate the capabilities of\n" \ 1793 "the local unit to other units.", 1794 &hci_read_class_of_device 1795 }, 1796 { 1797 "write_class_of_device class(xx:xx:xx)", 1798 "\nThis command will write the value for the Class_of_Device parameter.\n" \ 1799 "The Class_of_Device parameter is used to indicate the capabilities of \n" \ 1800 "the local unit to other units.\n\n" \ 1801 "\t<class> (xx:xx:xx) - class of device", 1802 &hci_write_class_of_device 1803 }, 1804 { 1805 "read_voice_settings", 1806 "\nThis command will read the values for the Voice_Setting parameter.\n" \ 1807 "The Voice_Setting parameter controls all the various settings for voice\n" \ 1808 "connections. These settings apply to all voice connections, and cannot be\n" \ 1809 "set for individual voice connections. The Voice_Setting parameter controls\n" \ 1810 "the configuration for voice connections: Input Coding, Air coding format,\n" \ 1811 "input data format, Input sample size, and linear PCM parameter.", 1812 &hci_read_voice_settings 1813 }, 1814 { 1815 "write_voice_settings settings(xxxx)", 1816 "\nThis command will write the values for the Voice_Setting parameter.\n" \ 1817 "The Voice_Setting parameter controls all the various settings for voice\n" \ 1818 "connections. These settings apply to all voice connections, and cannot be\n" \ 1819 "set for individual voice connections. The Voice_Setting parameter controls\n" \ 1820 "the configuration for voice connections: Input Coding, Air coding format,\n" \ 1821 "input data format, Input sample size, and linear PCM parameter.\n\n" \ 1822 "\t<voice_settings> (xxxx) - voice settings", 1823 &hci_write_voice_settings 1824 }, 1825 { 1826 "read_number_broadcast_retransmissions", 1827 "\nThis command will read the unit's parameter value for the Number of\n" \ 1828 "Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \ 1829 "unreliable.", 1830 &hci_read_number_broadcast_retransmissions 1831 }, 1832 { 1833 "write_number_broadcast_retransmissions count(dd)", 1834 "\nThis command will write the unit's parameter value for the Number of\n" \ 1835 "Broadcast Retransmissions. Broadcast packets are not acknowledged and are\n" \ 1836 "unreliable.\n\n" \ 1837 "\t<count> (dd) - number of broadcast retransimissions", 1838 &hci_write_number_broadcast_retransmissions 1839 }, 1840 { 1841 "read_hold_mode_activity", 1842 "\nThis command will read the value for the Hold_Mode_Activity parameter.\n" \ 1843 "The Hold_Mode_Activity value is used to determine what activities should\n" \ 1844 "be suspended when the unit is in hold mode.", 1845 &hci_read_hold_mode_activity 1846 }, 1847 { 1848 "write_hold_mode_activity settings(0|1|2|4)", 1849 "\nThis command will write the value for the Hold_Mode_Activity parameter.\n" \ 1850 "The Hold_Mode_Activity value is used to determine what activities should\n" \ 1851 "be suspended when the unit is in hold mode.\n\n" \ 1852 "\t<settings> (dd) - bit mask:\n" \ 1853 "\t0 - Maintain current Power State. Default\n" \ 1854 "\t1 - Suspend Page Scan.\n" \ 1855 "\t2 - Suspend Inquiry Scan.\n" \ 1856 "\t4 - Suspend Periodic Inquiries.", 1857 &hci_write_hold_mode_activity 1858 }, 1859 { 1860 "read_sco_flow_control_enable", 1861 "\nThe Read_SCO_Flow_Control_Enable command provides the ability to read\n" \ 1862 "the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \ 1863 "decide if the Host Controller will send Number Of Completed Packets events\n" \ 1864 "for SCO Connection Handles. This setting allows the Host to enable and\n" \ 1865 "disable SCO flow control.", 1866 &hci_read_sco_flow_control_enable 1867 }, 1868 { 1869 "write_sco_flow_control_enable enable(0|1)", 1870 "\nThe Write_SCO_Flow_Control_Enable command provides the ability to write\n" \ 1871 "the SCO_Flow_Control_Enable setting. By using this setting, the Host can\n" \ 1872 "decide if the Host Controller will send Number Of Completed Packets events\n" \ 1873 "for SCO Connection Handles. This setting allows the Host to enable and\n" \ 1874 "disable SCO flow control. The SCO_Flow_Control_Enable setting can only be\n" \ 1875 "changed if no connections exist.", 1876 &hci_write_sco_flow_control_enable 1877 }, 1878 { 1879 "read_link_supervision_timeout <connection_handle>", 1880 "\nThis command will read the value for the Link_Supervision_Timeout\n" \ 1881 "parameter for the device. The Link_Supervision_Timeout parameter is used\n" \ 1882 "by the master or slave Bluetooth device to monitor link loss. If, for any\n" \ 1883 "reason, no Baseband packets are received from that Connection Handle for a\n" \ 1884 "duration longer than the Link_Supervision_Timeout, the connection is\n" 1885 "disconnected.\n\n" \ 1886 "\t<connection_handle> - dddd; connection handle\n", 1887 &hci_read_link_supervision_timeout 1888 }, 1889 { 1890 "write_link_supervision_timeout <connection_handle> <timeout>", 1891 "\nThis command will write the value for the Link_Supervision_Timeout\n" \ 1892 "parameter for the device. The Link_Supervision_Timeout parameter is used\n" \ 1893 "by the master or slave Bluetooth device to monitor link loss. If, for any\n" \ 1894 "reason, no Baseband packets are received from that connection handle for a\n" \ 1895 "duration longer than the Link_Supervision_Timeout, the connection is\n" \ 1896 "disconnected.\n\n" \ 1897 "\t<connection_handle> - dddd; connection handle\n" \ 1898 "\t<timeout> - dddd; timeout measured in number of baseband slots\n", 1899 &hci_write_link_supervision_timeout 1900 }, 1901 { 1902 "read_page_scan_period_mode", 1903 "\nThis command is used to read the mandatory Page_Scan_Period_Mode of the\n" \ 1904 "local Bluetooth device. Every time an inquiry response message is sent, the\n"\ 1905 "Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\ 1906 "is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \ 1907 "expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \ 1908 "following page scans.", 1909 &hci_read_page_scan_period_mode 1910 }, 1911 { 1912 "write_page_scan_period_mode <page_scan_period_mode>", 1913 "\nThis command is used to write the mandatory Page_Scan_Period_Mode of the\n" \ 1914 "local Bluetooth device. Every time an inquiry response message is sent, the\n"\ 1915 "Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\ 1916 "is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \ 1917 "expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \ 1918 "following page scans.\n\n" \ 1919 "\t<page_scan_period_mode> - dd; page scan period mode:\n" \ 1920 "\t0x00 - P0 (Default)\n" \ 1921 "\t0x01 - P1\n" \ 1922 "\t0x02 - P2", 1923 &hci_write_page_scan_period_mode 1924 }, 1925 { 1926 "read_page_scan_mode", 1927 "\nThis command is used to read the default page scan mode of the local\n" \ 1928 "Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\ 1929 "that is used for the default page scan. Currently one mandatory page scan\n"\ 1930 "mode and three optional page scan modes are defined. Following an inquiry\n" \ 1931 "response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \ 1932 "mandatory page scan mode must be applied.", 1933 &hci_read_page_scan_mode 1934 }, 1935 { 1936 "write_page_scan_mode <page_scan_mode>", 1937 "\nThis command is used to write the default page scan mode of the local\n" \ 1938 "Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\ 1939 "that is used for the default page scan. Currently, one mandatory page scan\n"\ 1940 "mode and three optional page scan modes are defined. Following an inquiry\n"\ 1941 "response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \ 1942 "mandatory page scan mode must be applied.\n\n" \ 1943 "\t<page_scan_mode> - dd; page scan mode:\n" \ 1944 "\t0x00 - Mandatory Page Scan Mode (Default)\n" \ 1945 "\t0x01 - Optional Page Scan Mode I\n" \ 1946 "\t0x02 - Optional Page Scan Mode II\n" \ 1947 "\t0x03 - Optional Page Scan Mode III", 1948 &hci_write_page_scan_mode 1949 }, 1950 { 1951 "read_le_host_support", \ 1952 "Read if this host is in LE supported mode and simultaneous LE supported mode", 1953 &hci_read_le_host_support, 1954 }, 1955 { 1956 "write_le_host_support", \ 1957 "write_le_host_support le_host[0|1] simultaneous_le[0|1]", 1958 &hci_write_le_host_support, 1959 }, 1960 1961 { NULL, } 1962 }; 1963 1964