1 /* 2 * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * Copyright 2008 Mika Lindqvist 4 * All rights reserved. Distributed under the terms of the MIT License. 5 */ 6 7 8 #include "CommandManager.h" 9 10 #include <bluetooth/bluetooth_error.h> 11 #include <bluetooth/debug.h> 12 13 #include "CompanyIdentifiers.h" 14 15 16 inline void* 17 buildCommand(uint8 ogf, uint8 ocf, void** param, size_t psize, 18 size_t* outsize) 19 { 20 CALLED(); 21 struct hci_command_header* header; 22 23 header = (struct hci_command_header*) malloc(psize 24 + sizeof(struct hci_command_header)); 25 *outsize = psize + sizeof(struct hci_command_header); 26 27 if (header != NULL) { 28 header->opcode = B_HOST_TO_LENDIAN_INT16(PACK_OPCODE(ogf, ocf)); 29 header->clen = psize; 30 31 if (param != NULL && psize != 0) { 32 *param = ((uint8*)header) + sizeof(struct hci_command_header); 33 } 34 } 35 return header; 36 } 37 38 39 // This is for request that only require a Command complete in reply. 40 41 // Propagate to ReadBufferSize => reply stored in server side 42 // ReadLocalVersion => reply stored in server side 43 // Reset => no reply 44 45 // Request that do not need any input parameter 46 // Output reply can be fit in 32 bits field without talking status into account 47 status_t 48 NonParameterCommandRequest(uint8 ofg, uint8 ocf, int32* result, hci_id hId, 49 BMessenger* messenger) 50 { 51 CALLED(); 52 int8 bt_status = BT_ERROR; 53 54 BluetoothCommand<> simpleCommand(ofg, ocf); 55 56 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 57 BMessage reply; 58 59 request.AddInt32("hci_id", hId); 60 request.AddData("raw command", B_ANY_TYPE, 61 simpleCommand.Data(), simpleCommand.Size()); 62 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 63 request.AddInt16("opcodeExpected", PACK_OPCODE(ofg, ocf)); 64 65 if (messenger->SendMessage(&request, &reply) == B_OK) { 66 reply.FindInt8("status", &bt_status); 67 if (result != NULL) 68 reply.FindInt32("result", result); 69 } 70 71 return bt_status; 72 } 73 74 75 #if 0 76 #pragma mark - CONTROL BASEBAND - 77 #endif 78 79 80 void* 81 buildReset(size_t* outsize) 82 { 83 CALLED(); 84 return buildCommand(OGF_CONTROL_BASEBAND, OCF_RESET, 85 NULL, 0, outsize); 86 } 87 88 89 void* 90 buildReadLocalName(size_t* outsize) 91 { 92 CALLED(); 93 return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME, 94 NULL, 0, outsize); 95 } 96 97 98 void* 99 buildReadClassOfDevice(size_t* outsize) 100 { 101 CALLED(); 102 return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV, 103 NULL, 0, outsize); 104 } 105 106 107 void* 108 buildReadScan(size_t* outsize) 109 { 110 CALLED(); 111 return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_SCAN_ENABLE, 112 NULL, 0, outsize); 113 } 114 115 116 void* 117 buildWriteScan(uint8 scanmode, size_t* outsize) 118 { 119 CALLED(); 120 struct hci_write_scan_enable* param; 121 void* command = buildCommand(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE, 122 (void**) ¶m, sizeof(struct hci_write_scan_enable), outsize); 123 124 125 if (command != NULL) { 126 param->scan = scanmode; 127 } 128 129 return command; 130 } 131 132 133 #if 0 134 #pragma mark - LINK CONTROL - 135 #endif 136 137 138 void* 139 buildRemoteNameRequest(bdaddr_t bdaddr, uint8 pscan_rep_mode, 140 uint16 clock_offset, size_t* outsize) 141 { 142 CALLED(); 143 struct hci_remote_name_request* param; 144 void* command = buildCommand(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST, 145 (void**)¶m, sizeof(struct hci_remote_name_request), outsize); 146 147 if (command != NULL) { 148 param->bdaddr = bdaddr; 149 param->pscan_rep_mode = pscan_rep_mode; 150 param->clock_offset = clock_offset; 151 } 152 153 return command; 154 } 155 156 157 void* 158 buildInquiry(uint32 lap, uint8 length, uint8 num_rsp, size_t* outsize) 159 { 160 CALLED(); 161 struct hci_cp_inquiry* param; 162 void* command = buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY, 163 (void**) ¶m, sizeof(struct hci_cp_inquiry), outsize); 164 165 if (command != NULL) { 166 167 param->lap[2] = (lap >> 16) & 0xFF; 168 param->lap[1] = (lap >> 8) & 0xFF; 169 param->lap[0] = (lap >> 0) & 0xFF; 170 param->length = length; 171 param->num_rsp = num_rsp; 172 } 173 174 return command; 175 } 176 177 178 void* 179 buildInquiryCancel(size_t* outsize) 180 { 181 CALLED(); 182 return buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL, NULL, 0, outsize); 183 } 184 185 186 void* 187 buildPinCodeRequestReply(bdaddr_t bdaddr, uint8 length, char pincode[16], 188 size_t* outsize) 189 { 190 CALLED(); 191 struct hci_cp_pin_code_reply* param; 192 193 if (length > HCI_PIN_SIZE) // PinCode cannot be longer than 16 194 return NULL; 195 196 void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY, 197 (void**)¶m, sizeof(struct hci_cp_pin_code_reply), outsize); 198 199 if (command != NULL) { 200 param->bdaddr = bdaddr; 201 param->pin_len = length; 202 memcpy(¶m->pin_code, pincode, length); 203 } 204 205 return command; 206 } 207 208 209 void* 210 buildPinCodeRequestNegativeReply(bdaddr_t bdaddr, size_t* outsize) 211 { 212 CALLED(); 213 struct hci_cp_pin_code_neg_reply* param; 214 215 void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY, 216 (void**) ¶m, sizeof(struct hci_cp_pin_code_neg_reply), outsize); 217 218 if (command != NULL) { 219 220 param->bdaddr = bdaddr; 221 222 } 223 224 return command; 225 } 226 227 228 void* 229 buildAcceptConnectionRequest(bdaddr_t bdaddr, uint8 role, size_t* outsize) 230 { 231 CALLED(); 232 struct hci_cp_accept_conn_req* param; 233 234 void* command = buildCommand(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ, 235 (void**) ¶m, sizeof(struct hci_cp_accept_conn_req), outsize); 236 237 if (command != NULL) { 238 param->bdaddr = bdaddr; 239 param->role = role; 240 } 241 242 return command; 243 } 244 245 246 void* 247 buildRejectConnectionRequest(bdaddr_t bdaddr, size_t* outsize) 248 { 249 CALLED(); 250 struct hci_cp_reject_conn_req* param; 251 252 void* command = buildCommand(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ, 253 (void**)¶m, sizeof(struct hci_cp_reject_conn_req), 254 outsize); 255 256 if (command != NULL) { 257 param->bdaddr = bdaddr; 258 } 259 260 return command; 261 } 262 263 264 #if 0 265 #pragma mark - INFORMATIONAL_PARAM - 266 #endif 267 268 269 void* 270 buildReadLocalVersionInformation(size_t* outsize) 271 { 272 CALLED(); 273 return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION, 274 NULL, 0, outsize); 275 } 276 277 278 void* 279 buildReadBufferSize(size_t* outsize) 280 { 281 CALLED(); 282 return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE, 283 NULL, 0, outsize); 284 } 285 286 287 void* 288 buildReadBdAddr(size_t* outsize) 289 { 290 CALLED(); 291 return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR, 292 NULL, 0, outsize); 293 } 294 295 296 const char* linkControlCommands[] = { 297 "Inquiry", 298 "Inquiry Cancel", 299 "Periodic Inquiry Mode", 300 "Exit Periodic Inquiry Mode", 301 "Create Connection", 302 "Disconnect", 303 "Add SCO Connection", // not on 2.1 304 "Cancel Create Connection", 305 "Accept Connection Request", 306 "Reject Connection Request", 307 "Link Key Request Reply", 308 "Link Key Request Negative Reply", 309 "PIN Code Request Reply", 310 "PIN Code Request Negative Reply", 311 "Change Connection Packet Type", 312 "Reserved", // not on 2.1", 313 "Authentication Requested", 314 "Reserved", // not on 2.1", 315 "Set Connection Encryption", 316 "Reserved", // not on 2.1", 317 "Change Connection Link Key", 318 "Reserved", // not on 2.1", 319 "Master Link Key", 320 "Reserved", // not on 2.1", 321 "Remote Name Request", 322 "Cancel Remote Name Request", 323 "Read Remote Supported Features", 324 "Read Remote Extended Features", 325 "Read Remote Version Information", 326 "Reserved", // not on 2.1", 327 "Read Clock Offset", 328 "Read LMP Handle", 329 "Reserved", 330 "Reserved", 331 "Reserved", 332 "Reserved", 333 "Reserved", 334 "Reserved", 335 "Reserved", 336 "Setup Synchronous Connection", 337 "Accept Synchronous Connection", 338 "Reject Synchronous Connection", 339 "IO Capability Request Reply", 340 "User Confirmation Request Reply", 341 "User Confirmation Request Negative Reply", 342 "User Passkey Request Reply", 343 "User Passkey Request Negative Reply", 344 "Remote OOB Data Request Reply", 345 "Reserved", 346 "Reserved", 347 "Remote OOB Data Request Negative Reply", 348 "IO Capabilities Response Negative Reply" 349 }; 350 351 352 const char* linkPolicyCommands[] = { 353 "Hold Mode", 354 "Reserved", 355 "Sniff Mode", 356 "Exit Sniff Mode", 357 "Park State", 358 "Exit Park State", 359 "QoS Setup", 360 "Reserved", 361 "Role Discovery", 362 "Reserved", 363 "Switch Role", 364 "Read Link Policy Settings", 365 "Write Link Policy Settings", 366 "Read Default Link Policy Settings", 367 "Write Default Link Policy Settings", 368 "Flow Specification", 369 "Sniff Subrating" 370 }; 371 372 373 const char* controllerBasebandCommands[] = { 374 "Set Event Mask", 375 "Reserved", 376 "Reset", 377 "Reserved", 378 "Set Event Filter", 379 "Reserved", 380 "Reserved", 381 "Flush", 382 "Read PIN Type", 383 "Write PIN Type", 384 "Create New Unit Key", 385 "Reserved", 386 "Read Stored Link Key", 387 "Reserved", 388 "Reserved", 389 "Reserved", 390 "Write Stored Link Key", 391 "Delete Stored Link Key", 392 "Write Local Name", 393 "Read Local Name", 394 "Read Connection Accept Timeout", 395 "Write Connection Accept Timeout", 396 "Read Page Timeout", 397 "Write Page Timeout", 398 "Read Scan Enable", 399 "Write Scan Enable", 400 "Read Page Scan Activity", 401 "Write Page Scan Activity", 402 "Read Inquiry Scan Activity", 403 "Write Inquiry Scan Activity", 404 "Read Authentication Enable", 405 "Write Authentication Enable", 406 "Read Encryption Mode", // not 2.1 407 "Write Encryption Mode",// not 2.1 408 "Read Class Of Device", 409 "Write Class Of Device", 410 "Read Voice Setting", 411 "Write Voice Setting", 412 "Read Automatic Flush Timeout", 413 "Write Automatic Flush Timeout", 414 "Read Num Broadcast Retransmissions", 415 "Write Num Broadcast Retransmissions", 416 "Read Hold Mode Activity", 417 "Write Hold Mode Activity", 418 "Read Transmit Power Level", 419 "Read Synchronous Flow Control Enable", 420 "Write Synchronous Flow Control Enable", 421 "Reserved", 422 "Set Host Controller To Host Flow Control", 423 "Reserved", 424 "Host Buffer Size", 425 "Reserved", 426 "Host Number Of Completed Packets", 427 "Read Link Supervision Timeout", 428 "Write Link Supervision Timeout", 429 "Read Number of Supported IAC", 430 "Read Current IAC LAP", 431 "Write Current IAC LAP", 432 "Read Page Scan Period Mode", // not 2.1 433 "Write Page Scan Period Mode", // not 2.1 434 "Read Page Scan Mode", // not 2.1 435 "Write Page Scan Mode", // not 2.1 436 "Set AFH Channel Classification", 437 "Reserved", 438 "Reserved", 439 "Read Inquiry Scan Type", 440 "Write Inquiry Scan Type", 441 "Read Inquiry Mode", 442 "Write Inquiry Mode", 443 "Read Page Scan Type", 444 "Write Page Scan Type", 445 "Read AFH Channel Assessment Mode", 446 "Write AFH Channel Assessment Mode", 447 "Reserved", 448 "Reserved", 449 "Reserved", 450 "Reserved", 451 "Reserved", 452 "Reserved", 453 "Reserved", 454 "Read Extended Inquiry Response", 455 "Write Extended Inquiry Response", 456 "Refresh Encryption Key", 457 "Reserved", 458 "Read Simple Pairing Mode", 459 "Write Simple Pairing Mode", 460 "Read Local OOB Data", 461 "Read Inquiry Transmit Power Level", 462 "Write Inquiry Transmit Power Level", 463 "Read Default Erroneous Data Reporting", 464 "Write Default Erroneous Data Reporting", 465 "Reserved", 466 "Reserved", 467 "Reserved", 468 "Enhanced Flush", 469 "Send Keypress Notification" 470 }; 471 472 473 const char* informationalParametersCommands[] = { 474 "Read Local Version Information", 475 "Read Local Supported Commands", 476 "Read Local Supported Features", 477 "Read Local Extended Features", 478 "Read Buffer Size", 479 "Reserved", 480 "Read Country Code", // not 2.1 481 "Reserved", 482 "Read BD ADDR" 483 }; 484 485 486 const char* statusParametersCommands[] = { 487 "Read Failed Contact Counter", 488 "Reset Failed Contact Counter", 489 "Read Link Quality", 490 "Reserved", 491 "Read RSSI", 492 "Read AFH Channel Map", 493 "Read Clock", 494 }; 495 496 497 const char* testingCommands[] = { 498 "Read Loopback Mode", 499 "Write Loopback Mode", 500 "Enable Device Under Test Mode", 501 "Write Simple Pairing Debug Mode", 502 }; 503 504 505 const char* bluetoothEvents[] = { 506 "Inquiry Complete", 507 "Inquiry Result", 508 "Conn Complete", 509 "Conn Request", 510 "Disconnection Complete", 511 "Auth Complete", 512 "Remote Name Request Complete", 513 "Encrypt Change", 514 "Change Conn Link Key Complete", 515 "Master Link Key Compl", 516 "Rmt Features", 517 "Rmt Version", 518 "Qos Setup Complete", 519 "Command Complete", 520 "Command Status", 521 "Hardware Error", 522 "Flush Occur", 523 "Role Change", 524 "Num Comp Pkts", 525 "Mode Change", 526 "Return Link Keys", 527 "Pin Code Req", 528 "Link Key Req", 529 "Link Key Notify", 530 "Loopback Command", 531 "Data Buffer Overflow", 532 "Max Slot Change", 533 "Read Clock Offset Compl", 534 "Con Pkt Type Changed", 535 "Qos Violation", 536 "Reserved", 537 "Page Scan Rep Mode Change", 538 "Flow Specification", 539 "Inquiry Result With Rssi", 540 "Remote Extended Features", 541 "Reserved", 542 "Reserved", 543 "Reserved", 544 "Reserved", 545 "Reserved", 546 "Reserved", 547 "Reserved", 548 "Reserved", 549 "Synchronous Connection Completed", 550 "Synchronous Connection Changed", 551 "Reserved", 552 "Extended Inquiry Result", 553 "Encryption Key Refresh Complete", 554 "Io Capability Request", 555 "Io Capability Response", 556 "User Confirmation Request", 557 "User Passkey Request", 558 "Oob Data Request", 559 "Simple Pairing Complete", 560 "Reserved", 561 "Link Supervision Timeout Changed", 562 "Enhanced Flush Complete", 563 "Reserved", 564 "Reserved", 565 "Keypress Notification", 566 "Remote Host Supported Features Notification" 567 }; 568 569 570 const char* bluetoothErrors[] = { 571 "No Error", 572 "Unknown Command", 573 "No Connection", 574 "Hardware Failure", 575 "Page Timeout", 576 "Authentication Failure", 577 "Pin Or Key Missing", 578 "Memory Full", 579 "Connection Timeout", 580 "Max Number Of Connections", 581 "Max Number Of Sco Connections", 582 "Acl Connection Exists", 583 "Command Disallowed", 584 "Rejected Limited Resources", 585 "Rejected Security", 586 "Rejected Personal", 587 "Host Timeout", 588 "Unsupported Feature", 589 "Invalid Parameters", 590 "Remote User Ended Connection", 591 "Remote Low Resources", 592 "Remote Power Off", 593 "Connection Terminated", 594 "Repeated Attempts", 595 "Pairing Not Allowed", 596 "Unknown Lmp Pdu", 597 "Unsupported Remote Feature", 598 "Sco Offset Rejected", 599 "Sco Interval Rejected", 600 "Air Mode Rejected", 601 "Invalid Lmp Parameters", 602 "Unspecified Error", 603 "Unsupported Lmp Parameter Value", 604 "Role Change Not Allowed", 605 "Lmp Response Timeout", 606 "Lmp Error Transaction Collision", 607 "Lmp Pdu Not Allowed", 608 "Encryption Mode Not Accepted", 609 "Unit Link Key Used", 610 "Qos Not Supported", 611 "Instant Passed", 612 "Pairing With Unit Key Not Supported", 613 "Different Transaction Collision", 614 "Qos Unacceptable Parameter", 615 "Qos Rejected", 616 "Classification Not Supported", 617 "Insufficient Security", 618 "Parameter Out Of Range", 619 "Reserved", 620 "Role Switch Pending", 621 "Reserved", 622 "Slot Violation", 623 "Role Switch Failed", 624 "Extended Inquiry Response Too Large", 625 "Simple Pairing Not Supported By Host", 626 "Host Busy Pairing" 627 }; 628 629 630 const char* hciVersion[] = { "1.0B" , "1.1" , "1.2" , "2.0" , "2.1", 631 "3.0", "4.0", "4.1", "4.2", "5.0", "5.1", "5.2"}; 632 const char* lmpVersion[] = { "1.0" , "1.1" , "1.2" , "2.0" , "2.1", 633 "3.0", "4.0", "4.1", "4.2", "5.0", "5.1", "5.2"}; 634 635 #if 0 636 #pragma mark - 637 #endif 638 639 640 const char* 641 BluetoothHciVersion(uint16 ver) 642 { 643 CALLED(); 644 return hciVersion[ver]; 645 } 646 647 648 const char* 649 BluetoothLmpVersion(uint16 ver) 650 { 651 CALLED(); 652 return lmpVersion[ver]; 653 } 654 655 656 const char* 657 BluetoothCommandOpcode(uint16 opcode) 658 { 659 CALLED(); 660 // NOTE: BT implementations beyond 2.1 661 // could specify new commands with OCF numbers 662 // beyond the boundaries of the arrays and crash. 663 // But only our stack could issue them so its under 664 // our control. 665 switch (GET_OPCODE_OGF(opcode)) { 666 case OGF_LINK_CONTROL: 667 return linkControlCommands[GET_OPCODE_OCF(opcode) - 1]; 668 break; 669 670 case OGF_LINK_POLICY: 671 return linkPolicyCommands[GET_OPCODE_OCF(opcode) - 1]; 672 break; 673 674 case OGF_CONTROL_BASEBAND: 675 return controllerBasebandCommands[GET_OPCODE_OCF(opcode) - 1]; 676 break; 677 678 case OGF_INFORMATIONAL_PARAM: 679 return informationalParametersCommands[GET_OPCODE_OCF(opcode) - 1]; 680 break; 681 682 case OGF_STATUS_PARAM: 683 return statusParametersCommands[GET_OPCODE_OCF(opcode) - 1]; 684 break; 685 686 case OGF_TESTING_CMD: 687 return testingCommands[GET_OPCODE_OCF(opcode) - 1]; 688 break; 689 case OGF_VENDOR_CMD: 690 return "Vendor specific command"; 691 break; 692 default: 693 return "Unknown command"; 694 break; 695 } 696 697 } 698 699 700 const char* 701 BluetoothEvent(uint8 event) 702 { 703 CALLED(); 704 if (event < sizeof(bluetoothEvents) / sizeof(const char*)) 705 return bluetoothEvents[event - 1]; 706 else 707 return "Event out of Range!"; 708 } 709 710 711 const char* 712 BluetoothManufacturer(uint16 manufacturer) 713 { 714 CALLED(); 715 if (manufacturer < sizeof(bluetoothManufacturers) / sizeof(const char*)) 716 return bluetoothManufacturers[manufacturer]; 717 else if (manufacturer == 0xFFFF) 718 return "internal use"; 719 else 720 return "not assigned"; 721 } 722 723 724 const char* 725 BluetoothError(uint8 error) 726 { 727 CALLED(); 728 if (error < sizeof(bluetoothErrors) / sizeof(const char*)) 729 return bluetoothErrors[error]; 730 else 731 return "not specified"; 732 } 733