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