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