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_CONN_COMPLETE: 123 // should belong to a request? can be sporadic or initiated by us 124 ConnectionComplete( 125 JumpEventHeader<struct hci_ev_conn_complete>(event), NULL); 126 break; 127 128 case HCI_EVENT_PIN_CODE_REQ: 129 PinCodeRequest( 130 JumpEventHeader<struct hci_ev_pin_code_req>(event), NULL); 131 break; 132 } 133 } 134 135 136 void 137 LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event, BMessage* request) 138 { 139 // we are waiting for a reply 140 switch (event->ecode) { 141 case HCI_EVENT_INQUIRY_COMPLETE: 142 InquiryComplete(JumpEventHeader<uint8>(event), request); 143 break; 144 145 case HCI_EVENT_INQUIRY_RESULT: 146 InquiryResult(JumpEventHeader<uint8>(event), request); 147 break; 148 149 case HCI_EVENT_DISCONNECTION_COMPLETE: 150 // should belong to a request? can be sporadic or initiated by us¿?... 151 DisconnectionComplete( 152 JumpEventHeader<struct hci_ev_disconnection_complete_reply>(event), 153 request); 154 break; 155 156 case HCI_EVENT_AUTH_COMPLETE: 157 158 break; 159 160 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: 161 RemoteNameRequestComplete( 162 JumpEventHeader<struct hci_ev_remote_name_request_complete_reply> 163 (event), request); 164 break; 165 166 case HCI_EVENT_ENCRYPT_CHANGE: 167 break; 168 169 case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE: 170 break; 171 172 case HCI_EVENT_MASTER_LINK_KEY_COMPL: 173 break; 174 175 case HCI_EVENT_RMT_FEATURES: 176 break; 177 178 case HCI_EVENT_RMT_VERSION: 179 break; 180 181 case HCI_EVENT_QOS_SETUP_COMPLETE: 182 break; 183 184 case HCI_EVENT_FLUSH_OCCUR: 185 break; 186 187 case HCI_EVENT_ROLE_CHANGE: 188 RoleChange(JumpEventHeader<struct hci_ev_role_change>(event), request); 189 break; 190 191 case HCI_EVENT_NUM_COMP_PKTS: 192 break; 193 194 case HCI_EVENT_MODE_CHANGE: 195 break; 196 197 case HCI_EVENT_RETURN_LINK_KEYS: 198 break; 199 200 case HCI_EVENT_LINK_KEY_REQ: 201 break; 202 203 case HCI_EVENT_LINK_KEY_NOTIFY: 204 LinkKeyNotify(JumpEventHeader<struct hci_ev_link_key_notify> 205 (event), request); 206 break; 207 208 case HCI_EVENT_LOOPBACK_COMMAND: 209 break; 210 211 case HCI_EVENT_DATA_BUFFER_OVERFLOW: 212 break; 213 214 case HCI_EVENT_MAX_SLOT_CHANGE: 215 MaxSlotChange(JumpEventHeader<struct hci_ev_max_slot_change>(event), 216 request); 217 break; 218 219 case HCI_EVENT_READ_CLOCK_OFFSET_COMPL: 220 break; 221 222 case HCI_EVENT_CON_PKT_TYPE_CHANGED: 223 break; 224 225 case HCI_EVENT_QOS_VIOLATION: 226 break; 227 228 case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE: 229 PageScanRepetitionModeChange( 230 JumpEventHeader<struct hci_ev_page_scan_rep_mode_change>(event), 231 request); 232 break; 233 234 case HCI_EVENT_FLOW_SPECIFICATION: 235 break; 236 237 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: 238 break; 239 240 case HCI_EVENT_REMOTE_EXTENDED_FEATURES: 241 break; 242 243 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED: 244 break; 245 246 case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED: 247 break; 248 } 249 } 250 251 252 void 253 LocalDeviceImpl::HandleEvent(struct hci_event_header* event) 254 { 255 256 printf("### Incoming event: len = %d\n", event->elen); 257 for (int16 index = 0; index < event->elen + 2; index++) { 258 printf("%x:", ((uint8*)event)[index]); 259 } 260 printf("### \n"); 261 262 BMessage* request = NULL; 263 int32 eventIndexLocation; 264 265 // Check if it is a requested one 266 switch (event->ecode) { 267 case HCI_EVENT_CMD_COMPLETE: 268 { 269 struct hci_ev_cmd_complete* commandComplete 270 = JumpEventHeader<struct hci_ev_cmd_complete>(event); 271 272 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 273 "Incomming CommandComplete for %s\n", 274 BluetoothCommandOpcode(commandComplete->opcode)); 275 276 request = FindPetition(event->ecode, commandComplete->opcode, 277 &eventIndexLocation); 278 279 if (request != NULL) 280 CommandComplete(commandComplete, request, eventIndexLocation); 281 282 break; 283 } 284 case HCI_EVENT_CMD_STATUS: 285 { 286 struct hci_ev_cmd_status* commandStatus 287 = JumpEventHeader<struct hci_ev_cmd_status>(event); 288 289 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 290 "Incomming CommandStatus for %s\n", 291 BluetoothCommandOpcode(commandStatus->opcode)); 292 293 request = FindPetition(event->ecode, commandStatus->opcode, 294 &eventIndexLocation); 295 if (request != NULL) 296 CommandStatus(commandStatus, request, eventIndexLocation); 297 298 break; 299 } 300 default: 301 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"Incomming %s event\n", 302 BluetoothEvent(event->ecode)); 303 304 request = FindPetition(event->ecode); 305 if (request != NULL) 306 HandleExpectedRequest(event, request); 307 308 break; 309 } 310 311 if (request == NULL) 312 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 313 "Event %s could not be understood or delivered\n", 314 BluetoothEvent(event->ecode)); 315 316 HandleUnexpectedEvent(event); 317 318 } 319 320 321 #if 0 322 #pragma mark - 323 #endif 324 325 326 void 327 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, 328 BMessage* request, 329 int32 index) { 330 331 int16 opcodeExpected; 332 BMessage reply; 333 334 // Handle command complete information 335 request->FindInt16("opcodeExpected", index, &opcodeExpected); 336 337 if (request->IsSourceWaiting() == false) 338 Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); 339 340 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s(%d) for %s\n", 341 __FUNCTION__, event->ncmd, BluetoothCommandOpcode(opcodeExpected)); 342 343 switch ((uint16)opcodeExpected) { 344 345 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION): 346 { 347 struct hci_rp_read_loc_version* version 348 = JumpEventHeader<struct hci_rp_read_loc_version, 349 struct hci_ev_cmd_complete>(event); 350 351 352 if (version->status == BT_OK) { 353 354 if (!IsPropertyAvailable("hci_version")) 355 fProperties->AddInt8("hci_version", version->hci_version); 356 357 if (!IsPropertyAvailable("hci_revision")) 358 fProperties->AddInt16("hci_revision", version->hci_revision); 359 360 if (!IsPropertyAvailable("lmp_version")) 361 fProperties->AddInt8("lmp_version", version->lmp_version); 362 363 if (!IsPropertyAvailable("lmp_subversion")) 364 fProperties->AddInt16("lmp_subversion", version->lmp_subversion); 365 366 if (!IsPropertyAvailable("manufacturer")) 367 fProperties->AddInt16("manufacturer", version->manufacturer); 368 369 } 370 371 Output::Instance()->Postf(BLACKBOARD_KIT, 372 "Reply for Local Version %x\n", version->status); 373 374 reply.AddInt8("status", version->status); 375 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 376 reply.PrintToStream(); 377 378 // This request is not gonna be used anymore 379 ClearWantedEvent(request); 380 break; 381 } 382 383 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_FEATURES): 384 { 385 struct hci_rp_read_loc_features* features 386 = JumpEventHeader<struct hci_rp_read_loc_features, 387 struct hci_ev_cmd_complete>(event); 388 389 if (features->status == BT_OK) { 390 391 if (!IsPropertyAvailable("features")) { 392 fProperties->AddData("features", B_ANY_TYPE, &features->features, 8); 393 394 uint16 packetType = HCI_DM1 | HCI_DH1 | HCI_HV1; 395 bool roleSwitch = (features->features[0] & LMP_RSWITCH) != 0; 396 bool encryptCapable = (features->features[0] & LMP_ENCRYPT) != 0; 397 398 if (features->features[0] & LMP_3SLOT) 399 packetType |= (HCI_DM3 | HCI_DH3); 400 401 if (features->features[0] & LMP_5SLOT) 402 packetType |= (HCI_DM5 | HCI_DH5); 403 404 if (features->features[1] & LMP_HV2) 405 packetType |= (HCI_HV2); 406 407 if (features->features[1] & LMP_HV3) 408 packetType |= (HCI_HV3); 409 410 fProperties->AddInt16("packet_type", packetType); 411 fProperties->AddBool("role_switch_capable", roleSwitch); 412 fProperties->AddBool("encrypt_capable", encryptCapable); 413 414 Output::Instance()->Postf(BLACKBOARD_KIT, 415 "Packet type %x role switch %d encrypt %d\n", 416 packetType, roleSwitch, encryptCapable); 417 } 418 419 } 420 421 Output::Instance()->Postf(BLACKBOARD_KIT, 422 "Reply for Local Features %x\n", features->status); 423 424 reply.AddInt8("status", features->status); 425 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 426 reply.PrintToStream(); 427 428 // This request is not gonna be used anymore 429 ClearWantedEvent(request); 430 break; 431 } 432 433 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE): 434 { 435 struct hci_rp_read_buffer_size* buffer 436 = JumpEventHeader<struct hci_rp_read_buffer_size, 437 struct hci_ev_cmd_complete>(event); 438 439 if (buffer->status == BT_OK) { 440 441 if (!IsPropertyAvailable("acl_mtu")) 442 fProperties->AddInt16("acl_mtu", buffer->acl_mtu); 443 444 if (!IsPropertyAvailable("sco_mtu")) 445 fProperties->AddInt8("sco_mtu", buffer->sco_mtu); 446 447 if (!IsPropertyAvailable("acl_max_pkt")) 448 fProperties->AddInt16("acl_max_pkt", buffer->acl_max_pkt); 449 450 if (!IsPropertyAvailable("sco_max_pkt")) 451 fProperties->AddInt16("sco_max_pkt", buffer->sco_max_pkt); 452 453 } 454 455 Output::Instance()->Postf(BLACKBOARD_KIT, 456 "Reply for Read Buffer Size %x\n", buffer->status); 457 458 459 reply.AddInt8("status", buffer->status); 460 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 461 reply.PrintToStream(); 462 463 // This request is not gonna be used anymore 464 ClearWantedEvent(request); 465 } 466 break; 467 468 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR): 469 { 470 struct hci_rp_read_bd_addr* readbdaddr 471 = JumpEventHeader<struct hci_rp_read_bd_addr, 472 struct hci_ev_cmd_complete>(event); 473 474 if (readbdaddr->status == BT_OK) { 475 reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr, 476 sizeof(bdaddr_t)); 477 } 478 479 Output::Instance()->Postf(BLACKBOARD_KIT, 480 "Read bdaddr status = %x\n", readbdaddr->status); 481 482 reply.AddInt8("status", readbdaddr->status); 483 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 484 reply.PrintToStream(); 485 486 // This request is not gonna be used anymore 487 ClearWantedEvent(request); 488 } 489 break; 490 491 492 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV): 493 { 494 struct hci_read_dev_class_reply* classDev 495 = JumpEventHeader<struct hci_read_dev_class_reply, 496 struct hci_ev_cmd_complete>(event); 497 498 if (classDev->status == BT_OK) { 499 reply.AddData("devclass", B_ANY_TYPE, &classDev->dev_class, 500 sizeof(classDev->dev_class)); 501 } 502 503 Output::Instance()->Postf(BLACKBOARD_KIT, 504 "Read DeviceClass status = %x DeviceClass = [%x][%x][%x]\n", 505 classDev->status, classDev->dev_class[0], 506 classDev->dev_class[1], classDev->dev_class[2]); 507 508 509 reply.AddInt8("status", classDev->status); 510 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 511 reply.PrintToStream(); 512 513 // This request is not gonna be used anymore 514 ClearWantedEvent(request); 515 } 516 break; 517 518 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME): 519 { 520 struct hci_rp_read_local_name* readLocalName 521 = JumpEventHeader<struct hci_rp_read_local_name, 522 struct hci_ev_cmd_complete>(event); 523 524 525 if (readLocalName->status == BT_OK) { 526 reply.AddString("friendlyname", (const char*)readLocalName->local_name); 527 } 528 529 Output::Instance()->Postf(BLACKBOARD_KIT, "Friendly name status %x\n", 530 readLocalName->status); 531 532 reply.AddInt8("status", readLocalName->status); 533 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 534 reply.PrintToStream(); 535 536 // This request is not gonna be used anymore 537 ClearWantedEvent(request); 538 } 539 break; 540 541 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY): 542 { 543 uint8* statusReply = (uint8*)(event + 1); 544 545 // TODO: This reply has to match the BDADDR of the outgoing message 546 Output::Instance()->Postf(BLACKBOARD_KIT, "pincode accept status %x\n", 547 *statusReply); 548 549 reply.AddInt8("status", *statusReply); 550 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 551 reply.PrintToStream(); 552 553 // This request is not gonna be used anymore 554 ClearWantedEvent(request); 555 } 556 break; 557 558 559 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY): 560 { 561 uint8* statusReply = (uint8*)(event + 1); 562 563 // TODO: This reply might to match the BDADDR of the outgoing message 564 // => FindPetition should be expanded.... 565 Output::Instance()->Postf(BLACKBOARD_KIT, "pincode reject status %x\n", 566 *statusReply); 567 568 reply.AddInt8("status", *statusReply); 569 printf("Sending reply ... %ld\n",request->SendReply(&reply)); 570 reply.PrintToStream(); 571 572 // This request is not gonna be used anymore 573 ClearWantedEvent(request); 574 } 575 break; 576 577 // place here all CC that just replies a uint8 status 578 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET): 579 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE): 580 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV): 581 case PACK_OPCODE(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR): 582 { 583 reply.AddInt8("status", *(uint8*)(event + 1)); 584 585 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s for %s status %x\n", 586 __FUNCTION__, BluetoothCommandOpcode(opcodeExpected), *(uint8*)(event + 1)); 587 588 request->SendReply(&reply); 589 590 ClearWantedEvent(request); 591 } 592 break; 593 594 default: 595 Output::Instance()->Post("Command Complete not handled\n", BLACKBOARD_KIT); 596 break; 597 598 } 599 } 600 601 602 void 603 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* request, 604 int32 index) { 605 606 int16 opcodeExpected; 607 BMessage reply; 608 609 // Handle command complete information 610 request->FindInt16("opcodeExpected", index, &opcodeExpected); 611 612 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s(%d) %x for %s\n", 613 __FUNCTION__, event->ncmd, event->status, 614 BluetoothCommandOpcode(event->opcode)); 615 616 if (request->IsSourceWaiting() == false) 617 Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); 618 619 switch (opcodeExpected) { 620 621 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY): 622 { 623 reply.what = BT_MSG_INQUIRY_STARTED; 624 625 Output::Instance()->Postf(BLACKBOARD_KIT, 626 "Inquiry status %x\n", event->status); 627 628 reply.AddInt8("status", event->status); 629 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 630 reply.PrintToStream(); 631 632 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 633 PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY)); 634 } 635 break; 636 637 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST): 638 { 639 if (event->status == BT_OK) { 640 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 641 PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST)); 642 } else { 643 Output::Instance()->Postf(BLACKBOARD_KIT, 644 "Command Status for remote friendly name %x\n", event->status); 645 646 reply.AddInt8("status", event->status); 647 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 648 reply.PrintToStream(); 649 650 ClearWantedEvent(request); 651 } 652 } 653 break; 654 /* 655 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ): 656 { 657 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 658 PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ)); 659 } 660 break; 661 662 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ): 663 { 664 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 665 PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ)); 666 } 667 break;*/ 668 669 default: 670 Output::Instance()->Post("Command Status not handled\n", BLACKBOARD_KIT); 671 break; 672 } 673 674 } 675 676 677 void 678 LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request) 679 { 680 681 BMessage reply(BT_MSG_INQUIRY_DEVICE); 682 683 // skipping here the number of responses 684 reply.AddData("info", B_ANY_TYPE, numberOfResponses + 1, 685 (*numberOfResponses) * sizeof(struct inquiry_info) ); 686 687 reply.AddInt8("count", *numberOfResponses); 688 689 printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply)); 690 691 } 692 693 694 void 695 LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request) 696 { 697 BMessage reply(BT_MSG_INQUIRY_COMPLETED); 698 699 reply.AddInt8("status", *status); 700 printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply)); 701 702 ClearWantedEvent(request); 703 } 704 705 706 void 707 LocalDeviceImpl::RemoteNameRequestComplete( 708 struct hci_ev_remote_name_request_complete_reply* remotename, 709 BMessage* request) 710 { 711 BMessage reply; 712 713 if (remotename->status == BT_OK) { 714 reply.AddString("friendlyname", (const char*)remotename->remote_name ); 715 } 716 717 reply.AddInt8("status", remotename->status); 718 719 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 720 "%s for %s with status %s\n", 721 BluetoothEvent(HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE), 722 bdaddrUtils::ToString(remotename->bdaddr), 723 BluetoothError(remotename->status)); 724 725 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 726 reply.PrintToStream(); 727 728 // This request is not gonna be used anymore 729 ClearWantedEvent(request); 730 } 731 732 733 void 734 LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event, BMessage* request) 735 { 736 size_t size; 737 void* command; 738 739 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 740 "Connection Incoming type %x from %s...\n", 741 event->link_type, bdaddrUtils::ToString(event->bdaddr)); 742 743 // TODO: add a possible request in the queue 744 if (true) { // Check Preferences if we are to accept this connection 745 746 command = buildAcceptConnectionRequest(event->bdaddr, 0x01 /*slave*/, &size); 747 748 BMessage* newrequest = new BMessage; 749 newrequest->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS); 750 newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, 751 OCF_ACCEPT_CONN_REQ)); 752 753 newrequest->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ); 754 newrequest->AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE); 755 newrequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY); 756 newrequest->AddInt16("eventExpected", HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE); 757 //newrequest->AddInt16("eventExpected", HCI_EVENT_MAX_SLOT_CHANGE); 758 //newrequest->AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE); 759 760 AddWantedEvent(newrequest); 761 762 if ((fHCIDelegate)->IssueCommand(command, size) == B_ERROR) { 763 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 764 "Command issue error for ConnAccept\n"); 765 // remove the request? 766 } else { 767 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 768 "Command issue for ConnAccept\n"); 769 } 770 } 771 } 772 773 774 void 775 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, BMessage* request) 776 { 777 778 if (event->status == BT_OK) { 779 uint8 cod[3] = {0, 0, 0}; 780 781 ConnectionIncoming* iConnection = new ConnectionIncoming( 782 new RemoteDevice(event->bdaddr, cod)); 783 iConnection->Show(); 784 785 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 786 "%s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__, 787 bdaddrUtils::ToString(event->bdaddr), event->handle, 788 event->link_type, event->encrypt_mode); 789 790 } else { 791 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 792 "%s: failed with status %#x\n", __FUNCTION__, event->status); 793 } 794 795 } 796 797 798 void 799 LocalDeviceImpl::DisconnectionComplete(struct hci_ev_disconnection_complete_reply* event, BMessage* request) 800 { 801 Output::Instance()->Post("Disconnected\n", BLACKBOARD_KIT); 802 803 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 804 "%s: Handle=%#x, reason=%x status=%x\n", __FUNCTION__, event->handle, 805 event->reason, event->status); 806 807 ClearWantedEvent(request); 808 } 809 810 811 void 812 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event, BMessage* request) 813 { 814 PincodeWindow* iPincode = new PincodeWindow(event->bdaddr, GetID()); 815 iPincode->Show(); 816 } 817 818 819 void 820 LocalDeviceImpl::RoleChange(hci_ev_role_change* event, BMessage* request) 821 { 822 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 823 "%s: Address %s role=%d status=%d\n", __FUNCTION__, 824 bdaddrUtils::ToString(event->bdaddr), event->role, event->status); 825 } 826 827 828 void 829 LocalDeviceImpl::PageScanRepetitionModeChange(struct hci_ev_page_scan_rep_mode_change* event, 830 BMessage* request) 831 { 832 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 833 "%s: Address %s type=%d\n", __FUNCTION__, 834 bdaddrUtils::ToString(event->bdaddr), event->page_scan_rep_mode); 835 } 836 837 838 void 839 LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify* event, 840 BMessage* request) 841 { 842 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 843 "%s: Address %s, key=%s, type=%d\n", __FUNCTION__, 844 bdaddrUtils::ToString(event->bdaddr), 845 LinkKeyUtils::ToString(event->link_key), event->key_type); 846 } 847 848 849 void 850 LocalDeviceImpl::MaxSlotChange(struct hci_ev_max_slot_change* event, 851 BMessage* request) 852 { 853 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 854 "%s: Handle=%#x, max slots=%d\n", __FUNCTION__, 855 event->handle, event->lmp_max_slots); 856 } 857 858 859 void 860 LocalDeviceImpl::HardwareError(struct hci_ev_hardware_error* event) 861 { 862 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 863 "%s: hardware code=%#x\n", __FUNCTION__, event->hardware_code); 864 } 865 866 867 #if 0 868 #pragma mark - Request Methods - 869 #endif 870 871 872 status_t 873 LocalDeviceImpl::ProcessSimpleRequest(BMessage* request) 874 { 875 ssize_t size; 876 void* command = NULL; 877 878 if (request->FindData("raw command", B_ANY_TYPE, 0, 879 (const void **)&command, &size) == B_OK) { 880 881 AddWantedEvent(request); 882 // LEAK: is command buffer freed within the Message? 883 if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) 884 == B_ERROR) { 885 // TODO: 886 // Reply the request with error! 887 // Remove the just added request 888 (Output::Instance()->Post("## ERROR Command issue, REMOVING!\n", 889 BLACKBOARD_KIT)); 890 ClearWantedEvent(request); 891 892 } else { 893 return B_OK; 894 } 895 } else { 896 (Output::Instance()->Post("No command specified for simple request\n", 897 BLACKBOARD_KIT)); 898 } 899 900 return B_ERROR; 901 } 902