1 /* 2 * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com 4 * All rights reserved. Distributed under the terms of the MIT License. 5 * 6 */ 7 8 #include "BluetoothServer.h" 9 10 #include "LocalDeviceImpl.h" 11 #include "CommandManager.h" 12 #include "Debug.h" 13 14 #include <bluetooth/bdaddrUtils.h> 15 #include <bluetooth/bluetooth_error.h> 16 #include <bluetooth/LinkKeyUtils.h> 17 #include <bluetooth/RemoteDevice.h> 18 #include <bluetooth/HCI/btHCI_event.h> 19 20 #include <bluetoothserver_p.h> 21 #include <ConnectionIncoming.h> 22 #include <PincodeWindow.h> 23 24 #include <stdio.h> 25 #include <new> 26 27 28 #if 0 29 #pragma mark - Class methods - 30 #endif 31 32 33 // Factory methods 34 LocalDeviceImpl* 35 LocalDeviceImpl::CreateControllerAccessor(BPath* path) 36 { 37 HCIDelegate* delegate = new(std::nothrow) HCIControllerAccessor(path); 38 if (delegate == NULL) 39 return NULL; 40 41 LocalDeviceImpl* device = new(std::nothrow) LocalDeviceImpl(delegate); 42 if (device == NULL) { 43 delete delegate; 44 return NULL; 45 } 46 47 return device; 48 } 49 50 51 LocalDeviceImpl* 52 LocalDeviceImpl::CreateTransportAccessor(BPath* path) 53 { 54 HCIDelegate* delegate = new(std::nothrow) HCITransportAccessor(path); 55 if (delegate == NULL) 56 return NULL; 57 58 LocalDeviceImpl* device = new(std::nothrow) LocalDeviceImpl(delegate); 59 if (device == NULL) { 60 delete delegate; 61 return NULL; 62 } 63 64 return device; 65 } 66 67 68 LocalDeviceImpl::LocalDeviceImpl(HCIDelegate* hd) : LocalDeviceHandler(hd) 69 { 70 71 } 72 73 74 LocalDeviceImpl::~LocalDeviceImpl() 75 { 76 77 } 78 79 80 void 81 LocalDeviceImpl::Unregister() 82 { 83 BMessage* msg = new BMessage(BT_MSG_REMOVE_DEVICE); 84 85 msg->AddInt32("hci_id", fHCIDelegate->Id()); 86 87 TRACE_BT("LocalDeviceImpl: Unregistering %" B_PRId32 "\n", 88 fHCIDelegate->Id()); 89 90 be_app_messenger.SendMessage(msg); 91 } 92 93 94 #if 0 95 #pragma mark - Event handling methods - 96 #endif 97 98 template<typename T, typename Header> 99 inline T* 100 JumpEventHeader(Header* event) 101 { 102 return (T*)(event + 1); 103 } 104 105 106 void 107 LocalDeviceImpl::HandleUnexpectedEvent(struct hci_event_header* event) 108 { 109 // Events here might have not been initated by us 110 // TODO: ML mark as handled pass a reply by parameter and reply in common 111 switch (event->ecode) { 112 case HCI_EVENT_HARDWARE_ERROR: 113 HardwareError( 114 JumpEventHeader<struct hci_ev_hardware_error>(event)); 115 break; 116 117 case HCI_EVENT_CONN_REQUEST: 118 ConnectionRequest( 119 JumpEventHeader<struct hci_ev_conn_request>(event), NULL); 120 break; 121 122 case HCI_EVENT_NUM_COMP_PKTS: 123 NumberOfCompletedPackets( 124 JumpEventHeader<struct hci_ev_num_comp_pkts>(event)); 125 break; 126 127 case HCI_EVENT_DISCONNECTION_COMPLETE: 128 // should belong to a request? can be sporadic or initiated by us? 129 DisconnectionComplete( 130 JumpEventHeader 131 <struct hci_ev_disconnection_complete_reply>(event), 132 NULL); 133 break; 134 case HCI_EVENT_PIN_CODE_REQ: 135 PinCodeRequest( 136 JumpEventHeader<struct hci_ev_pin_code_req>(event), NULL); 137 break; 138 default: 139 // TODO: feedback unexpected not handled 140 break; 141 } 142 } 143 144 145 void 146 LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event, 147 BMessage* request) 148 { 149 // we are waiting for a reply 150 switch (event->ecode) { 151 case HCI_EVENT_INQUIRY_COMPLETE: 152 InquiryComplete(JumpEventHeader<uint8>(event), request); 153 break; 154 155 case HCI_EVENT_INQUIRY_RESULT: 156 InquiryResult(JumpEventHeader<uint8>(event), request); 157 break; 158 159 case HCI_EVENT_CONN_COMPLETE: 160 ConnectionComplete( 161 JumpEventHeader<struct hci_ev_conn_complete>(event), request); 162 break; 163 164 case HCI_EVENT_DISCONNECTION_COMPLETE: 165 // should belong to a request? can be sporadic or initiated by us? 166 DisconnectionComplete( 167 JumpEventHeader<struct hci_ev_disconnection_complete_reply> 168 (event), request); 169 break; 170 171 case HCI_EVENT_AUTH_COMPLETE: 172 173 break; 174 175 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: 176 RemoteNameRequestComplete( 177 JumpEventHeader 178 <struct hci_ev_remote_name_request_complete_reply> 179 (event), request); 180 break; 181 182 case HCI_EVENT_ENCRYPT_CHANGE: 183 break; 184 185 case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE: 186 break; 187 188 case HCI_EVENT_MASTER_LINK_KEY_COMPL: 189 break; 190 191 case HCI_EVENT_RMT_FEATURES: 192 break; 193 194 case HCI_EVENT_RMT_VERSION: 195 break; 196 197 case HCI_EVENT_QOS_SETUP_COMPLETE: 198 break; 199 200 case HCI_EVENT_FLUSH_OCCUR: 201 break; 202 203 case HCI_EVENT_ROLE_CHANGE: 204 RoleChange( 205 JumpEventHeader<struct hci_ev_role_change>(event), request); 206 break; 207 208 case HCI_EVENT_MODE_CHANGE: 209 break; 210 211 case HCI_EVENT_RETURN_LINK_KEYS: 212 ReturnLinkKeys( 213 JumpEventHeader<struct hci_ev_return_link_keys>(event)); 214 break; 215 216 case HCI_EVENT_LINK_KEY_REQ: 217 LinkKeyRequested( 218 JumpEventHeader<struct hci_ev_link_key_req>(event), request); 219 break; 220 221 case HCI_EVENT_LINK_KEY_NOTIFY: 222 LinkKeyNotify( 223 JumpEventHeader<struct hci_ev_link_key_notify>(event), request); 224 break; 225 226 case HCI_EVENT_LOOPBACK_COMMAND: 227 break; 228 229 case HCI_EVENT_DATA_BUFFER_OVERFLOW: 230 break; 231 232 case HCI_EVENT_MAX_SLOT_CHANGE: 233 MaxSlotChange(JumpEventHeader<struct hci_ev_max_slot_change>(event), 234 request); 235 break; 236 237 case HCI_EVENT_READ_CLOCK_OFFSET_COMPL: 238 break; 239 240 case HCI_EVENT_CON_PKT_TYPE_CHANGED: 241 break; 242 243 case HCI_EVENT_QOS_VIOLATION: 244 break; 245 246 case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE: 247 PageScanRepetitionModeChange( 248 JumpEventHeader<struct hci_ev_page_scan_rep_mode_change>(event), 249 request); 250 break; 251 252 case HCI_EVENT_FLOW_SPECIFICATION: 253 break; 254 255 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: 256 break; 257 258 case HCI_EVENT_REMOTE_EXTENDED_FEATURES: 259 break; 260 261 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED: 262 break; 263 264 case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED: 265 break; 266 } 267 } 268 269 270 void 271 LocalDeviceImpl::HandleEvent(struct hci_event_header* event) 272 { 273 /* 274 printf("### Incoming event: len = %d\n", event->elen); 275 for (int16 index = 0; index < event->elen + 2; index++) { 276 printf("%x:", ((uint8*)event)[index]); 277 } 278 printf("### \n"); 279 */ 280 BMessage* request = NULL; 281 int32 eventIndexLocation; 282 283 // Check if it is a requested one 284 switch (event->ecode) { 285 case HCI_EVENT_CMD_COMPLETE: 286 { 287 struct hci_ev_cmd_complete* commandComplete 288 = JumpEventHeader<struct hci_ev_cmd_complete>(event); 289 290 TRACE_BT("LocalDeviceImpl: Incoming CommandComplete(%d) for %s\n", commandComplete->ncmd, 291 BluetoothCommandOpcode(commandComplete->opcode)); 292 293 request = FindPetition(event->ecode, commandComplete->opcode, 294 &eventIndexLocation); 295 296 if (request != NULL) 297 CommandComplete(commandComplete, request, eventIndexLocation); 298 299 break; 300 } 301 case HCI_EVENT_CMD_STATUS: 302 { 303 struct hci_ev_cmd_status* commandStatus 304 = JumpEventHeader<struct hci_ev_cmd_status>(event); 305 306 TRACE_BT("LocalDeviceImpl: Incoming CommandStatus(%d)(%s) for %s\n", commandStatus->ncmd, 307 BluetoothError(commandStatus->status), 308 BluetoothCommandOpcode(commandStatus->opcode)); 309 310 request = FindPetition(event->ecode, commandStatus->opcode, 311 &eventIndexLocation); 312 if (request != NULL) 313 CommandStatus(commandStatus, request, eventIndexLocation); 314 315 break; 316 } 317 default: 318 TRACE_BT("LocalDeviceImpl: Incoming %s event\n", BluetoothEvent(event->ecode)); 319 320 request = FindPetition(event->ecode); 321 if (request != NULL) 322 HandleExpectedRequest(event, request); 323 324 break; 325 } 326 327 if (request == NULL) { 328 TRACE_BT("LocalDeviceImpl: Event %s could not be understood or delivered\n", 329 BluetoothEvent(event->ecode)); 330 HandleUnexpectedEvent(event); 331 } 332 } 333 334 335 #if 0 336 #pragma mark - 337 #endif 338 339 340 void 341 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, 342 BMessage* request, int32 index) 343 { 344 int16 opcodeExpected; 345 BMessage reply; 346 status_t status; 347 348 // Handle command complete information 349 request->FindInt16("opcodeExpected", index, &opcodeExpected); 350 351 if (request->IsSourceWaiting() == false) { 352 TRACE_BT("LocalDeviceImpl: Nobody waiting for the event\n"); 353 } 354 355 switch ((uint16)opcodeExpected) { 356 357 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION): 358 { 359 struct hci_rp_read_loc_version* version 360 = JumpEventHeader<struct hci_rp_read_loc_version, 361 struct hci_ev_cmd_complete>(event); 362 363 364 if (version->status == BT_OK) { 365 366 if (!IsPropertyAvailable("hci_version")) 367 fProperties->AddInt8("hci_version", version->hci_version); 368 369 if (!IsPropertyAvailable("hci_revision")) { 370 fProperties->AddInt16("hci_revision", 371 version->hci_revision); 372 } 373 374 if (!IsPropertyAvailable("lmp_version")) 375 fProperties->AddInt8("lmp_version", version->lmp_version); 376 377 if (!IsPropertyAvailable("lmp_subversion")) { 378 fProperties->AddInt16("lmp_subversion", 379 version->lmp_subversion); 380 } 381 382 if (!IsPropertyAvailable("manufacturer")) { 383 fProperties->AddInt16("manufacturer", 384 version->manufacturer); 385 } 386 } 387 388 TRACE_BT("LocalDeviceImpl: Reply for Local Version %x\n", version->status); 389 390 reply.AddInt8("status", version->status); 391 status = request->SendReply(&reply); 392 //printf("Sending reply... %ld\n", status); 393 // debug reply.PrintToStream(); 394 395 // This request is not gonna be used anymore 396 ClearWantedEvent(request); 397 break; 398 } 399 400 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_PG_TIMEOUT): 401 { 402 struct hci_rp_read_page_timeout* pageTimeout 403 = JumpEventHeader<struct hci_rp_read_page_timeout, 404 struct hci_ev_cmd_complete>(event); 405 406 if (pageTimeout->status == BT_OK) { 407 fProperties->AddInt16("page_timeout", 408 pageTimeout->page_timeout); 409 410 TRACE_BT("LocalDeviceImpl: Page Timeout=%x\n", pageTimeout->page_timeout); 411 } 412 413 reply.AddInt8("status", pageTimeout->status); 414 reply.AddInt32("result", pageTimeout->page_timeout); 415 status = request->SendReply(&reply); 416 //printf("Sending reply... %ld\n", status); 417 // debug reply.PrintToStream(); 418 419 // This request is not gonna be used anymore 420 ClearWantedEvent(request); 421 break; 422 } 423 424 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_FEATURES): 425 { 426 struct hci_rp_read_loc_features* features 427 = JumpEventHeader<struct hci_rp_read_loc_features, 428 struct hci_ev_cmd_complete>(event); 429 430 if (features->status == BT_OK) { 431 432 if (!IsPropertyAvailable("features")) { 433 fProperties->AddData("features", B_ANY_TYPE, 434 &features->features, 8); 435 436 uint16 packetType = HCI_DM1 | HCI_DH1 | HCI_HV1; 437 438 bool roleSwitch 439 = (features->features[0] & LMP_RSWITCH) != 0; 440 bool encryptCapable 441 = (features->features[0] & LMP_ENCRYPT) != 0; 442 443 if (features->features[0] & LMP_3SLOT) 444 packetType |= (HCI_DM3 | HCI_DH3); 445 446 if (features->features[0] & LMP_5SLOT) 447 packetType |= (HCI_DM5 | HCI_DH5); 448 449 if (features->features[1] & LMP_HV2) 450 packetType |= (HCI_HV2); 451 452 if (features->features[1] & LMP_HV3) 453 packetType |= (HCI_HV3); 454 455 fProperties->AddInt16("packet_type", packetType); 456 fProperties->AddBool("role_switch_capable", roleSwitch); 457 fProperties->AddBool("encrypt_capable", encryptCapable); 458 459 TRACE_BT("LocalDeviceImpl: Packet type %x role switch %d encrypt %d\n", 460 packetType, roleSwitch, encryptCapable); 461 } 462 463 } 464 465 TRACE_BT("LocalDeviceImpl: Reply for Local Features %x\n", features->status); 466 467 reply.AddInt8("status", features->status); 468 status = request->SendReply(&reply); 469 //printf("Sending reply... %ld\n", status); 470 // debug reply.PrintToStream(); 471 472 // This request is not gonna be used anymore 473 ClearWantedEvent(request); 474 break; 475 } 476 477 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE): 478 { 479 struct hci_rp_read_buffer_size* buffer 480 = JumpEventHeader<struct hci_rp_read_buffer_size, 481 struct hci_ev_cmd_complete>(event); 482 483 if (buffer->status == BT_OK) { 484 485 if (!IsPropertyAvailable("acl_mtu")) 486 fProperties->AddInt16("acl_mtu", buffer->acl_mtu); 487 488 if (!IsPropertyAvailable("sco_mtu")) 489 fProperties->AddInt8("sco_mtu", buffer->sco_mtu); 490 491 if (!IsPropertyAvailable("acl_max_pkt")) 492 fProperties->AddInt16("acl_max_pkt", buffer->acl_max_pkt); 493 494 if (!IsPropertyAvailable("sco_max_pkt")) 495 fProperties->AddInt16("sco_max_pkt", buffer->sco_max_pkt); 496 497 } 498 499 TRACE_BT("LocalDeviceImpl: Reply for Read Buffer Size %x\n", buffer->status); 500 501 502 reply.AddInt8("status", buffer->status); 503 status = request->SendReply(&reply); 504 //printf("Sending reply... %ld\n", status); 505 // debug reply.PrintToStream(); 506 507 // This request is not gonna be used anymore 508 ClearWantedEvent(request); 509 } 510 break; 511 512 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR): 513 { 514 struct hci_rp_read_bd_addr* readbdaddr 515 = JumpEventHeader<struct hci_rp_read_bd_addr, 516 struct hci_ev_cmd_complete>(event); 517 518 if (readbdaddr->status == BT_OK) { 519 reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr, 520 sizeof(bdaddr_t)); 521 } 522 523 TRACE_BT("LocalDeviceImpl: Read bdaddr status = %x\n", readbdaddr->status); 524 525 reply.AddInt8("status", readbdaddr->status); 526 status = request->SendReply(&reply); 527 //printf("Sending reply... %ld\n", status); 528 // debug reply.PrintToStream(); 529 530 // This request is not gonna be used anymore 531 ClearWantedEvent(request); 532 } 533 break; 534 535 536 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV): 537 { 538 struct hci_read_dev_class_reply* classDev 539 = JumpEventHeader<struct hci_read_dev_class_reply, 540 struct hci_ev_cmd_complete>(event); 541 542 if (classDev->status == BT_OK) { 543 reply.AddData("devclass", B_ANY_TYPE, &classDev->dev_class, 544 sizeof(classDev->dev_class)); 545 } 546 547 TRACE_BT("LocalDeviceImpl: Read DeviceClass status = %x DeviceClass = [%x][%x][%x]\n", 548 classDev->status, classDev->dev_class[0], 549 classDev->dev_class[1], classDev->dev_class[2]); 550 551 552 reply.AddInt8("status", classDev->status); 553 status = request->SendReply(&reply); 554 //printf("Sending reply... %ld\n", status); 555 // debug reply.PrintToStream(); 556 557 // This request is not gonna be used anymore 558 ClearWantedEvent(request); 559 break; 560 } 561 562 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME): 563 { 564 struct hci_rp_read_local_name* readLocalName 565 = JumpEventHeader<struct hci_rp_read_local_name, 566 struct hci_ev_cmd_complete>(event); 567 568 569 if (readLocalName->status == BT_OK) { 570 reply.AddString("friendlyname", 571 (const char*)readLocalName->local_name); 572 } 573 574 TRACE_BT("LocalDeviceImpl: Friendly name status %x\n", readLocalName->status); 575 576 reply.AddInt8("status", readLocalName->status); 577 status = request->SendReply(&reply); 578 //printf("Sending reply... %ld\n", status); 579 // debug reply.PrintToStream(); 580 581 // This request is not gonna be used anymore 582 ClearWantedEvent(request); 583 break; 584 } 585 586 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY): 587 { 588 uint8* statusReply = (uint8*)(event + 1); 589 590 // TODO: This reply has to match the BDADDR of the outgoing message 591 TRACE_BT("LocalDeviceImpl: pincode accept status %x\n", *statusReply); 592 593 reply.AddInt8("status", *statusReply); 594 status = request->SendReply(&reply); 595 //printf("Sending reply... %ld\n", status); 596 // debug reply.PrintToStream(); 597 598 // This request is not gonna be used anymore 599 //ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected); 600 ClearWantedEvent(request); 601 break; 602 } 603 604 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY): 605 { 606 uint8* statusReply = (uint8*)(event + 1); 607 608 // TODO: This reply might match the BDADDR of the outgoing message 609 // => FindPetition should be expanded.... 610 TRACE_BT("LocalDeviceImpl: pincode reject status %x\n", *statusReply); 611 612 reply.AddInt8("status", *statusReply); 613 status = request->SendReply(&reply); 614 //printf("Sending reply... %ld\n", status); 615 // debug reply.PrintToStream(); 616 617 // This request is not gonna be used anymore 618 ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected); 619 break; 620 } 621 622 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_STORED_LINK_KEY): 623 { 624 struct hci_read_stored_link_key_reply* linkKeyRetrieval 625 = JumpEventHeader<struct hci_read_stored_link_key_reply, 626 struct hci_ev_cmd_complete>(event); 627 628 TRACE_BT("LocalDeviceImpl: Status %s MaxKeys=%d, KeysRead=%d\n", 629 BluetoothError(linkKeyRetrieval->status), 630 linkKeyRetrieval->max_num_keys, 631 linkKeyRetrieval->num_keys_read); 632 633 reply.AddInt8("status", linkKeyRetrieval->status); 634 status = request->SendReply(&reply); 635 //printf("Sending reply... %ld\n", status); 636 // debug reply.PrintToStream(); 637 638 ClearWantedEvent(request); 639 break; 640 } 641 642 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY): 643 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_REPLY): 644 { 645 struct hci_cp_link_key_reply_reply* linkKeyReply 646 = JumpEventHeader<struct hci_cp_link_key_reply_reply, 647 struct hci_ev_cmd_complete>(event); 648 649 TRACE_BT("LocalDeviceImpl: Status %s addresss=%s\n", BluetoothError(linkKeyReply->status), 650 bdaddrUtils::ToString(linkKeyReply->bdaddr).String()); 651 652 ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected); 653 break; 654 } 655 656 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_SCAN_ENABLE): 657 { 658 struct hci_read_scan_enable* scanEnable 659 = JumpEventHeader<struct hci_read_scan_enable, 660 struct hci_ev_cmd_complete>(event); 661 662 if (scanEnable->status == BT_OK) { 663 fProperties->AddInt8("scan_enable", scanEnable->enable); 664 665 TRACE_BT("LocalDeviceImpl: enable = %x\n", scanEnable->enable); 666 } 667 668 reply.AddInt8("status", scanEnable->status); 669 reply.AddInt8("scan_enable", scanEnable->enable); 670 status = request->SendReply(&reply); 671 printf("Sending reply. scan_enable = %d\n", scanEnable->enable); 672 // debug reply.PrintToStream(); 673 674 // This request is not gonna be used anymore 675 ClearWantedEvent(request); 676 break; 677 } 678 679 // place here all CC that just replies a uint8 status 680 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET): 681 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE): 682 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV): 683 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_PG_TIMEOUT): 684 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CA_TIMEOUT): 685 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE): 686 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_LOCAL_NAME): 687 case PACK_OPCODE(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR): 688 { 689 reply.AddInt8("status", *(uint8*)(event + 1)); 690 691 TRACE_BT("LocalDeviceImpl: %s for %s status %x\n", __FUNCTION__, 692 BluetoothCommandOpcode(opcodeExpected), *(uint8*)(event + 1)); 693 694 status = request->SendReply(&reply); 695 printf("%s: Sending reply write...\n", __func__); 696 if (status < B_OK) 697 printf("%s: Error sending reply write!\n", __func__); 698 699 ClearWantedEvent(request); 700 break; 701 } 702 703 default: 704 TRACE_BT("LocalDeviceImpl: Command Complete not handled\n"); 705 break; 706 } 707 } 708 709 710 void 711 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, 712 BMessage* request, int32 index) 713 { 714 int16 opcodeExpected; 715 BMessage reply; 716 717 // Handle command complete information 718 request->FindInt16("opcodeExpected", index, &opcodeExpected); 719 720 if (request->IsSourceWaiting() == false) { 721 TRACE_BT("LocalDeviceImpl: Nobody waiting for the event\n"); 722 } 723 724 switch (opcodeExpected) { 725 726 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY): 727 { 728 reply.what = BT_MSG_INQUIRY_STARTED; 729 730 TRACE_BT("LocalDeviceImpl: Inquiry status %x\n", event->status); 731 732 reply.AddInt8("status", event->status); 733 request->SendReply(&reply); 734 //printf("Sending reply... %ld\n", status); 735 // debug reply.PrintToStream(); 736 737 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 738 PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY)); 739 } 740 break; 741 742 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST): 743 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_CREATE_CONN): 744 { 745 if (event->status == BT_OK) { 746 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected); 747 } else { 748 TRACE_BT("LocalDeviceImpl: Command Status for remote friendly name %x\n", 749 event->status); 750 751 reply.AddInt8("status", event->status); 752 request->SendReply(&reply); 753 //printf("Sending reply... %ld\n", status); 754 // debug reply.PrintToStream(); 755 756 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected); 757 } 758 } 759 break; 760 /* 761 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ): 762 { 763 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 764 PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ)); 765 } 766 break; 767 768 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ): 769 { 770 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 771 PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ)); 772 } 773 break;*/ 774 775 default: 776 TRACE_BT("LocalDeviceImpl: Command Status not handled\n"); 777 break; 778 } 779 } 780 781 782 void 783 LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request) 784 { 785 BMessage reply(BT_MSG_INQUIRY_DEVICE); 786 787 uint8 responses = *numberOfResponses; 788 789 // skipping here the number of responses 790 reply.AddData("info", B_ANY_TYPE, numberOfResponses + 1, 791 (*numberOfResponses) * sizeof(struct inquiry_info) ); 792 793 reply.AddInt8("count", *numberOfResponses); 794 795 TRACE_BT("LocalDeviceImpl: %s #responses=%d\n", 796 __FUNCTION__, *numberOfResponses); 797 798 struct inquiry_info* info = JumpEventHeader<struct inquiry_info, uint8> 799 (numberOfResponses); 800 801 while (responses > 0) { 802 TRACE_BT("LocalDeviceImpl: page_rep=%d scan_period=%d, scan=%d clock=%d\n", 803 info->pscan_rep_mode, info->pscan_period_mode, info->pscan_mode, 804 info->clock_offset); 805 responses--; 806 info++; 807 } 808 809 printf("%s: Sending reply...\n", __func__); 810 status_t status = request->SendReply(&reply); 811 if (status < B_OK) 812 printf("%s: Error sending reply!\n", __func__); 813 } 814 815 816 void 817 LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request) 818 { 819 BMessage reply(BT_MSG_INQUIRY_COMPLETED); 820 821 reply.AddInt8("status", *status); 822 823 printf("%s: Sending reply...\n", __func__); 824 status_t stat = request->SendReply(&reply); 825 if (stat < B_OK) 826 printf("%s: Error sending reply!\n", __func__); 827 828 ClearWantedEvent(request); 829 } 830 831 832 void 833 LocalDeviceImpl::RemoteNameRequestComplete( 834 struct hci_ev_remote_name_request_complete_reply* remotename, 835 BMessage* request) 836 { 837 BMessage reply; 838 839 if (remotename->status == BT_OK) { 840 reply.AddString("friendlyname", (const char*)remotename->remote_name ); 841 } 842 843 reply.AddInt8("status", remotename->status); 844 845 TRACE_BT("LocalDeviceImpl: %s for %s with status %s\n", 846 BluetoothEvent(HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE), 847 bdaddrUtils::ToString(remotename->bdaddr).String(), 848 BluetoothError(remotename->status)); 849 850 status_t status = request->SendReply(&reply); 851 if (status < B_OK) 852 printf("%s: Error sending reply to BMessage request: %s!\n", 853 __func__, strerror(status)); 854 855 // This request is not gonna be used anymore 856 ClearWantedEvent(request); 857 } 858 859 860 void 861 LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event, 862 BMessage* request) 863 { 864 size_t size; 865 void* command; 866 867 TRACE_BT("LocalDeviceImpl: Connection Incoming type %x from %s...\n", 868 event->link_type, bdaddrUtils::ToString(event->bdaddr).String()); 869 870 // TODO: add a possible request in the queue 871 if (true) { // Check Preferences if we are to accept this connection 872 873 // Keep ourselves as slave 874 command = buildAcceptConnectionRequest(event->bdaddr, 0x01 , &size); 875 876 BMessage* newrequest = new BMessage; 877 newrequest->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS); 878 newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, 879 OCF_ACCEPT_CONN_REQ)); 880 881 newrequest->AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE); 882 newrequest->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ); 883 newrequest->AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE); 884 newrequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY); 885 newrequest->AddInt16("eventExpected", 886 HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE); 887 888 #if 0 889 newrequest->AddInt16("eventExpected", HCI_EVENT_MAX_SLOT_CHANGE); 890 newrequest->AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE); 891 #endif 892 893 AddWantedEvent(newrequest); 894 895 if ((fHCIDelegate)->IssueCommand(command, size) == B_ERROR) { 896 TRACE_BT("LocalDeviceImpl: Command issued error for Accepting connection\n"); 897 // remove the request? 898 } else { 899 TRACE_BT("LocalDeviceImpl: Command issued for Accepting connection\n"); 900 } 901 } 902 } 903 904 905 void 906 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, 907 BMessage* request) 908 { 909 910 if (event->status == BT_OK) { 911 uint8 cod[3] = {0, 0, 0}; 912 913 // TODO: Review, this rDevice is leaked 914 ConnectionIncoming* iConnection = new ConnectionIncoming( 915 new RemoteDevice(event->bdaddr, cod)); 916 iConnection->Show(); 917 918 TRACE_BT("LocalDeviceImpl: %s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__, 919 bdaddrUtils::ToString(event->bdaddr).String(), event->handle, 920 event->link_type, event->encrypt_mode); 921 922 } else { 923 TRACE_BT("LocalDeviceImpl: %s: failed with error %s\n", __FUNCTION__, 924 BluetoothError(event->status)); 925 } 926 927 // it was expected 928 if (request != NULL) { 929 BMessage reply; 930 reply.AddInt8("status", event->status); 931 932 if (event->status == BT_OK) 933 reply.AddInt16("handle", event->handle); 934 935 printf("%s: Sending reply...\n", __func__); 936 status_t status = request->SendReply(&reply); 937 if (status < B_OK) 938 printf("%s: Error sending reply!\n", __func__); 939 // debug reply.PrintToStream(); 940 941 // This request is not gonna be used anymore 942 ClearWantedEvent(request); 943 } 944 945 } 946 947 948 void 949 LocalDeviceImpl::DisconnectionComplete( 950 struct hci_ev_disconnection_complete_reply* event, BMessage* request) 951 { 952 TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, reason=%s status=%x\n", __FUNCTION__, event->handle, 953 BluetoothError(event->reason), event->status); 954 955 if (request != NULL) { 956 BMessage reply; 957 reply.AddInt8("status", event->status); 958 959 printf("%s: Sending reply...\n", __func__); 960 status_t status = request->SendReply(&reply); 961 if (status < B_OK) 962 printf("%s: Error sending reply!\n", __func__); 963 // debug reply.PrintToStream(); 964 965 ClearWantedEvent(request); 966 } 967 } 968 969 970 void 971 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event, 972 BMessage* request) 973 { 974 PincodeWindow* iPincode = new PincodeWindow(event->bdaddr, GetID()); 975 iPincode->Show(); 976 } 977 978 979 void 980 LocalDeviceImpl::RoleChange(hci_ev_role_change* event, BMessage* request) 981 { 982 TRACE_BT("LocalDeviceImpl: %s: Address %s role=%d status=%d\n", __FUNCTION__, 983 bdaddrUtils::ToString(event->bdaddr).String(), event->role, event->status); 984 } 985 986 987 void 988 LocalDeviceImpl::PageScanRepetitionModeChange( 989 struct hci_ev_page_scan_rep_mode_change* event, BMessage* request) 990 { 991 TRACE_BT("LocalDeviceImpl: %s: Address %s type=%d\n", __FUNCTION__, 992 bdaddrUtils::ToString(event->bdaddr).String(), event->page_scan_rep_mode); 993 } 994 995 996 void 997 LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify* event, 998 BMessage* request) 999 { 1000 TRACE_BT("LocalDeviceImpl: %s: Address %s, key=%s, type=%d\n", __FUNCTION__, 1001 bdaddrUtils::ToString(event->bdaddr).String(), 1002 LinkKeyUtils::ToString(event->link_key).String(), event->key_type); 1003 } 1004 1005 1006 void 1007 LocalDeviceImpl::LinkKeyRequested(struct hci_ev_link_key_req* keyRequested, 1008 BMessage* request) 1009 { 1010 TRACE_BT("LocalDeviceImpl: %s: Address %s\n", __FUNCTION__, 1011 bdaddrUtils::ToString(keyRequested->bdaddr).String()); 1012 1013 // TODO: 1014 // Here we are suposed to check the BDADDR received, look into the server 1015 // (RemoteDevice Database) if we have any pas link key interchanged with 1016 // the given address if we have we are to accept it will "Link key Request 1017 // Reply". As we dont not have such database yet, we will always deny it 1018 // forcing the remote device to start a pairing. 1019 1020 BluetoothCommand<typed_command(hci_cp_link_key_neg_reply)> 1021 linkKeyNegativeReply(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY); 1022 1023 bdaddrUtils::Copy(linkKeyNegativeReply->bdaddr, keyRequested->bdaddr); 1024 1025 if ((fHCIDelegate)->IssueCommand(linkKeyNegativeReply.Data(), 1026 linkKeyNegativeReply.Size()) == B_ERROR) { 1027 TRACE_BT("LocalDeviceImpl: Command issued error for reply %s\n", __FUNCTION__); 1028 } else { 1029 TRACE_BT("LocalDeviceImpl: Command issued in reply of %s\n", __FUNCTION__); 1030 } 1031 1032 if (request != NULL) 1033 ClearWantedEvent(request, HCI_EVENT_LINK_KEY_REQ); 1034 1035 } 1036 1037 1038 void 1039 LocalDeviceImpl::ReturnLinkKeys(struct hci_ev_return_link_keys* returnedKeys) 1040 { 1041 TRACE_BT("LocalDeviceImpl: %s: #keys=%d\n", 1042 __FUNCTION__, returnedKeys->num_keys); 1043 1044 uint8 numKeys = returnedKeys->num_keys; 1045 1046 struct link_key_info* linkKeys = &returnedKeys->link_keys; 1047 1048 while (numKeys > 0) { 1049 1050 TRACE_BT("LocalDeviceImpl: Address=%s key=%s\n", 1051 bdaddrUtils::ToString(linkKeys->bdaddr).String(), 1052 LinkKeyUtils::ToString(linkKeys->link_key).String()); 1053 1054 linkKeys++; 1055 } 1056 } 1057 1058 1059 void 1060 LocalDeviceImpl::MaxSlotChange(struct hci_ev_max_slot_change* event, 1061 BMessage* request) 1062 { 1063 TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, max slots=%d\n", __FUNCTION__, 1064 event->handle, event->lmp_max_slots); 1065 } 1066 1067 1068 void 1069 LocalDeviceImpl::HardwareError(struct hci_ev_hardware_error* event) 1070 { 1071 TRACE_BT("LocalDeviceImpl: %s: hardware code=%#x\n", __FUNCTION__, event->hardware_code); 1072 } 1073 1074 1075 void 1076 LocalDeviceImpl::NumberOfCompletedPackets(struct hci_ev_num_comp_pkts* event) 1077 { 1078 TRACE_BT("LocalDeviceImpl: %s: #Handles=%d\n", __FUNCTION__, event->num_hndl); 1079 1080 struct handle_and_number* numberPackets 1081 = JumpEventHeader<handle_and_number, hci_ev_num_comp_pkts>(event); 1082 1083 for (uint8 i = 0; i < event->num_hndl; i++) { 1084 1085 TRACE_BT("LocalDeviceImpl: %s: Handle=%d #packets=%d\n", __FUNCTION__, numberPackets->handle, 1086 numberPackets->num_completed); 1087 1088 numberPackets++; 1089 } 1090 } 1091 1092 1093 #if 0 1094 #pragma mark - Request Methods - 1095 #endif 1096 1097 status_t 1098 LocalDeviceImpl::ProcessSimpleRequest(BMessage* request) 1099 { 1100 ssize_t size; 1101 void* command = NULL; 1102 1103 if (request->FindData("raw command", B_ANY_TYPE, 0, 1104 (const void **)&command, &size) == B_OK) { 1105 1106 // Give the chance of just issuing the command 1107 int16 eventFound; 1108 if (request->FindInt16("eventExpected", &eventFound) == B_OK) 1109 AddWantedEvent(request); 1110 // LEAK: is command buffer freed within the Message? 1111 if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) 1112 == B_ERROR) { 1113 // TODO: 1114 // Reply the request with error! 1115 // Remove the just added request 1116 TRACE_BT("LocalDeviceImpl: ## ERROR Command issue, REMOVING!\n"); 1117 ClearWantedEvent(request); 1118 1119 } else { 1120 return B_OK; 1121 } 1122 } else { 1123 TRACE_BT("LocalDeviceImpl: No command specified for simple request\n"); 1124 } 1125 1126 return B_ERROR; 1127 } 1128