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 #if 0 74 #pragma mark - Event handling methods - 75 #endif 76 77 void 78 LocalDeviceImpl::HandleEvent(struct hci_event_header* event) 79 { 80 81 printf("### Incoming event: len = %d\n", event->elen); 82 for (int16 index = 0; index < event->elen + 2; index++ ) { 83 printf("%x:", ((uint8*)event)[index]); 84 } 85 printf("### \n"); 86 87 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"Incomming %s event\n", 88 GetEvent(event->ecode)); 89 90 // Events here might have not been initated by us 91 // TODO: ML mark as handled pass a reply by parameter and reply in common 92 switch (event->ecode) { 93 case HCI_EVENT_HARDWARE_ERROR: 94 //HardwareError(event); 95 return; 96 break; 97 case HCI_EVENT_CONN_REQUEST: 98 ConnectionRequest((struct hci_ev_conn_request*)(event+1), NULL); 99 return; 100 break; 101 case HCI_EVENT_CONN_COMPLETE: 102 // should belong to a request? can be sporadic or initiated by us¿?... 103 ConnectionComplete((struct hci_ev_conn_complete*)(event+1), NULL); 104 return; 105 break; 106 case HCI_EVENT_PIN_CODE_REQ: 107 PinCodeRequest((struct hci_ev_pin_code_req*)(event+1), NULL); 108 return; 109 break; 110 default: 111 // lets go on 112 break; 113 } 114 115 BMessage* request = NULL; 116 int32 eventIndexLocation; 117 118 // Check if it is a requested one 119 if (event->ecode == HCI_EVENT_CMD_COMPLETE) { 120 request = FindPetition(event->ecode, ((struct hci_ev_cmd_complete*) 121 (event+1))->opcode, &eventIndexLocation); 122 123 } else if (event->ecode == HCI_EVENT_CMD_STATUS) { 124 125 request = FindPetition(event->ecode, ((struct hci_ev_cmd_status*) 126 (event+1))->opcode, &eventIndexLocation); 127 128 } else { 129 request = FindPetition(event->ecode); 130 } 131 132 if (request == NULL) { 133 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 134 "Event %x could not be understood or delivered\n", event->ecode); 135 return; 136 } 137 138 // we are waiting for a reply 139 switch (event->ecode) { 140 case HCI_EVENT_INQUIRY_COMPLETE: 141 InquiryComplete((uint8*)(event+1), request); 142 break; 143 144 case HCI_EVENT_INQUIRY_RESULT: 145 InquiryResult((uint8*)(event+1), request); 146 break; 147 148 case HCI_EVENT_DISCONNECTION_COMPLETE: 149 // should belong to a request? can be sporadic or initiated by us¿?... 150 DisconnectionComplete((struct hci_ev_disconnection_complete_reply*) 151 (event+1), request); 152 break; 153 154 case HCI_EVENT_AUTH_COMPLETE: 155 break; 156 157 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: 158 RemoteNameRequestComplete((struct hci_ev_remote_name_request_complete_reply*) 159 (event+1), request); 160 break; 161 162 case HCI_EVENT_ENCRYPT_CHANGE: 163 break; 164 165 case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE: 166 break; 167 168 case HCI_EVENT_MASTER_LINK_KEY_COMPL: 169 break; 170 171 case HCI_EVENT_RMT_FEATURES: 172 break; 173 174 case HCI_EVENT_RMT_VERSION: 175 break; 176 177 case HCI_EVENT_QOS_SETUP_COMPLETE: 178 break; 179 180 case HCI_EVENT_CMD_COMPLETE: 181 CommandComplete((struct hci_ev_cmd_complete*)(event+1), 182 request, eventIndexLocation); 183 break; 184 185 case HCI_EVENT_CMD_STATUS: 186 CommandStatus((struct hci_ev_cmd_status*)(event+1), request, 187 eventIndexLocation); 188 break; 189 190 case HCI_EVENT_FLUSH_OCCUR: 191 break; 192 193 case HCI_EVENT_ROLE_CHANGE: 194 RoleChange((struct hci_ev_role_change*)(event+1), request, 195 eventIndexLocation); 196 break; 197 198 case HCI_EVENT_NUM_COMP_PKTS: 199 break; 200 201 case HCI_EVENT_MODE_CHANGE: 202 break; 203 204 case HCI_EVENT_RETURN_LINK_KEYS: 205 break; 206 207 case HCI_EVENT_LINK_KEY_REQ: 208 break; 209 210 case HCI_EVENT_LINK_KEY_NOTIFY: 211 LinkKeyNotify((struct hci_ev_link_key_notify*)(event+1), 212 request, eventIndexLocation); 213 break; 214 215 case HCI_EVENT_LOOPBACK_COMMAND: 216 break; 217 218 case HCI_EVENT_DATA_BUFFER_OVERFLOW: 219 break; 220 221 case HCI_EVENT_MAX_SLOT_CHANGE: 222 MaxSlotChange((struct hci_ev_max_slot_change*)(event+1), request, 223 eventIndexLocation); 224 225 break; 226 227 case HCI_EVENT_READ_CLOCK_OFFSET_COMPL: 228 break; 229 230 case HCI_EVENT_CON_PKT_TYPE_CHANGED: 231 break; 232 233 case HCI_EVENT_QOS_VIOLATION: 234 break; 235 236 case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE: 237 PageScanRepetitionModeChange((struct hci_ev_page_scan_rep_mode_change*) 238 (event+1), request, eventIndexLocation); 239 break; 240 241 case HCI_EVENT_FLOW_SPECIFICATION: 242 break; 243 244 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: 245 break; 246 247 case HCI_EVENT_REMOTE_EXTENDED_FEATURES: 248 break; 249 250 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED: 251 break; 252 253 case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED: 254 255 break; 256 } 257 258 } 259 260 261 void 262 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* request, 263 int32 index) { 264 265 int16 opcodeExpected; 266 BMessage reply; 267 268 // Handle command complete information 269 request->FindInt16("opcodeExpected", index, &opcodeExpected); 270 271 if (request->IsSourceWaiting() == false) 272 Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); 273 274 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s(%d) for %s\n",__FUNCTION__, 275 event->ncmd,GetCommand(opcodeExpected)); 276 277 switch ((uint16)opcodeExpected) { 278 279 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION): 280 { 281 struct hci_rp_read_loc_version* version = (struct hci_rp_read_loc_version*)(event+1); 282 283 284 if (version->status == BT_OK) { 285 286 if (!IsPropertyAvailable("hci_version")) 287 fProperties->AddInt8("hci_version", version->hci_version); 288 289 if (!IsPropertyAvailable("hci_revision")) 290 fProperties->AddInt16("hci_revision", version->hci_revision); 291 292 if (!IsPropertyAvailable("lmp_version")) 293 fProperties->AddInt8("lmp_version", version->lmp_version); 294 295 if (!IsPropertyAvailable("lmp_subversion")) 296 fProperties->AddInt16("lmp_subversion", version->lmp_subversion); 297 298 if (!IsPropertyAvailable("manufacturer")) 299 fProperties->AddInt16("manufacturer", version->manufacturer); 300 301 } 302 303 Output::Instance()->Postf(BLACKBOARD_KIT, "Reply for Local Version %x\n", version->status); 304 305 reply.AddInt8("status", version->status); 306 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 307 reply.PrintToStream(); 308 309 // This request is not gonna be used anymore 310 ClearWantedEvent(request); 311 } 312 break; 313 314 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE): 315 { 316 struct hci_rp_read_buffer_size* buffer = (struct hci_rp_read_buffer_size*)(event+1); 317 318 if (buffer->status == BT_OK) { 319 320 if (!IsPropertyAvailable("acl_mtu")) 321 fProperties->AddInt16("acl_mtu", buffer->acl_mtu); 322 323 if (!IsPropertyAvailable("sco_mtu")) 324 fProperties->AddInt8("sco_mtu", buffer->sco_mtu); 325 326 if (!IsPropertyAvailable("acl_max_pkt")) 327 fProperties->AddInt16("acl_max_pkt", buffer->acl_max_pkt); 328 329 if (!IsPropertyAvailable("sco_max_pkt")) 330 fProperties->AddInt16("sco_max_pkt", buffer->sco_max_pkt); 331 332 Output::Instance()->Postf(BLACKBOARD_KIT, 333 "Reply for Read Buffer Size %x\n", buffer->status); 334 } 335 336 reply.AddInt8("status", buffer->status); 337 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 338 reply.PrintToStream(); 339 340 // This request is not gonna be used anymore 341 ClearWantedEvent(request); 342 } 343 break; 344 345 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR): 346 { 347 struct hci_rp_read_bd_addr* readbdaddr = (struct hci_rp_read_bd_addr*)(event+1); 348 349 if (readbdaddr->status == BT_OK) { 350 reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr, sizeof(bdaddr_t)); 351 Output::Instance()->Post("Positive reply for getAddress\n", BLACKBOARD_KIT); 352 } else { 353 Output::Instance()->Post("Negative reply for getAddress\n", BLACKBOARD_KIT); 354 } 355 356 reply.AddInt8("status", readbdaddr->status); 357 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 358 reply.PrintToStream(); 359 360 // This request is not gonna be used anymore 361 ClearWantedEvent(request); 362 } 363 break; 364 365 366 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV): 367 { 368 struct hci_read_dev_class_reply* classDev = (struct hci_read_dev_class_reply*)(event+1); 369 370 if (classDev->status == BT_OK) { 371 reply.AddData("devclass", B_ANY_TYPE, &classDev->dev_class, sizeof(classDev->dev_class)); 372 Output::Instance()->Post("Positive reply for getDeviceClass\n", BLACKBOARD_KIT); 373 374 } else { 375 Output::Instance()->Post("Negative reply for getDeviceClass\n", BLACKBOARD_KIT); 376 } 377 378 reply.AddInt8("status", classDev->status); 379 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 380 reply.PrintToStream(); 381 382 // This request is not gonna be used anymore 383 ClearWantedEvent(request); 384 } 385 break; 386 387 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME): 388 { 389 struct hci_rp_read_local_name* readLocalName = (struct hci_rp_read_local_name*)(event+1); 390 391 if (readLocalName->status == BT_OK) { 392 reply.AddString("friendlyname", (const char*)readLocalName->local_name ); 393 Output::Instance()->Post("Positive reply for friendly name\n", BLACKBOARD_KIT); 394 395 } else { 396 Output::Instance()->Post("Negative reply for friendly name\n", BLACKBOARD_KIT); 397 } 398 399 reply.AddInt8("status", readLocalName->status); 400 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 401 reply.PrintToStream(); 402 403 // This request is not gonna be used anymore 404 ClearWantedEvent(request); 405 } 406 break; 407 408 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY): 409 { 410 uint8* statusReply = (uint8*)(event+1); 411 412 //TODO: This reply has to match the BDADDR of the outgoing message 413 if (*statusReply == BT_OK) { 414 Output::Instance()->Post("Positive reply for pincode accept\n", BLACKBOARD_KIT); 415 } else { 416 Output::Instance()->Post("Negative reply for pincode accept\n", BLACKBOARD_KIT); 417 } 418 419 reply.AddInt8("status", *statusReply); 420 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 421 reply.PrintToStream(); 422 423 // This request is not gonna be used anymore 424 ClearWantedEvent(request); 425 } 426 break; 427 428 429 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY): 430 { 431 uint8* statusReply = (uint8*)(event+1); 432 //TODO: This reply might to match the BDADDR of the outgoing message 433 // xxx:FindPetition should be expanded.... 434 435 if (*statusReply == BT_OK) { 436 Output::Instance()->Post("Positive reply for pincode reject\n", BLACKBOARD_KIT); 437 } else { 438 Output::Instance()->Post("Negative reply for pincode reject\n", BLACKBOARD_KIT); 439 } 440 441 reply.AddInt8("status", *statusReply); 442 printf("Sending reply ... %ld\n",request->SendReply(&reply)); 443 reply.PrintToStream(); 444 445 // This request is not gonna be used anymore 446 ClearWantedEvent(request); 447 } 448 break; 449 450 // place here all CC that just replies a uint8 status 451 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET): 452 case PACK_OPCODE(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR): 453 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE): 454 { 455 reply.AddInt8("status", *(uint8*)(event+1)); 456 457 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s for %s status %x\n", 458 __FUNCTION__,GetCommand(opcodeExpected), *(uint8*)(event+1)); 459 460 request->SendReply(&reply); 461 462 ClearWantedEvent(request); 463 } 464 break; 465 466 default: 467 Output::Instance()->Post("Command Complete not handled\n", BLACKBOARD_KIT); 468 break; 469 470 } 471 } 472 473 474 void 475 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* request, 476 int32 index) { 477 478 int16 opcodeExpected; 479 BMessage reply; 480 481 // Handle command complete information 482 request->FindInt16("opcodeExpected", index, &opcodeExpected); 483 484 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s(%d) %x for %s\n",__FUNCTION__, 485 event->ncmd, event->status, GetCommand(event->opcode)); 486 487 if (request->IsSourceWaiting() == false) 488 Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); 489 490 switch (opcodeExpected) { 491 492 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY): 493 { 494 reply.what = BT_MSG_INQUIRY_STARTED; 495 496 if (event->status == BT_OK) { 497 Output::Instance()->Post("Positive reply for inquiry status\n", BLACKBOARD_KIT); 498 } else { 499 Output::Instance()->Post("Negative reply for inquiry status\n", BLACKBOARD_KIT); 500 } 501 502 reply.AddInt8("status", event->status); 503 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 504 reply.PrintToStream(); 505 506 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 507 PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY)); 508 } 509 break; 510 511 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST): 512 { 513 if (event->status==BT_OK) { 514 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 515 PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST)); 516 } 517 else { 518 Output::Instance()->Post("Wrong Command Status for remote friendly name\n", BLACKBOARD_KIT); 519 520 reply.AddInt8("status", event->status); 521 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 522 reply.PrintToStream(); 523 524 ClearWantedEvent(request); 525 } 526 } 527 break; 528 /* 529 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ): 530 { 531 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 532 PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ)); 533 } 534 break; 535 536 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ): 537 { 538 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, 539 PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ)); 540 } 541 break;*/ 542 543 default: 544 Output::Instance()->Post("Command Status not handled\n", BLACKBOARD_KIT); 545 break; 546 } 547 548 } 549 550 551 void 552 LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request) 553 { 554 555 BMessage reply(BT_MSG_INQUIRY_DEVICE); 556 557 // skipping here the number of responses 558 reply.AddData("info", B_ANY_TYPE, numberOfResponses + 1 559 , (*numberOfResponses) * sizeof(struct inquiry_info) ); 560 561 reply.AddInt8("count", *numberOfResponses); 562 563 printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply)); 564 565 } 566 567 568 void 569 LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request) 570 { 571 BMessage reply(BT_MSG_INQUIRY_COMPLETED); 572 573 reply.AddInt8("status", *status); 574 printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply)); 575 576 ClearWantedEvent(request); 577 } 578 579 580 void 581 LocalDeviceImpl::RemoteNameRequestComplete( 582 struct hci_ev_remote_name_request_complete_reply* remotename, BMessage* request) 583 { 584 BMessage reply; 585 586 if (remotename->status == BT_OK) { 587 588 reply.AddString("friendlyname", (const char*)remotename->remote_name ); 589 Output::Instance()->Post("Positive reply for remote friendly name\n", BLACKBOARD_KIT); 590 } else { 591 Output::Instance()->Post("Negative reply for remote friendly name\n", BLACKBOARD_KIT); 592 } 593 594 reply.AddInt8("status", remotename->status); 595 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 596 reply.PrintToStream(); 597 598 // This request is not gonna be used anymore 599 ClearWantedEvent(request); 600 } 601 602 603 void 604 LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event, BMessage* request) 605 { 606 size_t size; 607 void* command; 608 609 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 610 "Connection Incoming type %x from %s...\n", 611 event->link_type, bdaddrUtils::ToString(event->bdaddr)); 612 613 /* TODO: add a possible request in the queue */ 614 if (true) { // Check Preferences if we are to accept this connection 615 616 command = buildAcceptConnectionRequest(event->bdaddr, 0x01 /*slave*/, &size); 617 618 BMessage* newrequest = new BMessage; 619 newrequest->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS); 620 newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ)); 621 622 newrequest->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ); 623 newrequest->AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE); 624 newrequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY); 625 newrequest->AddInt16("eventExpected", HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE); 626 //newrequest->AddInt16("eventExpected", HCI_EVENT_MAX_SLOT_CHANGE); 627 //newrequest->AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE); 628 629 AddWantedEvent(newrequest); 630 631 if ((fHCIDelegate)->IssueCommand(command, size) == B_ERROR) { 632 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 633 "Command issue error for ConnAccept\n"); 634 // remove the request ¿? 635 } else { 636 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 637 "Command issue for ConnAccept\n"); 638 } 639 } 640 } 641 642 643 void 644 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, BMessage* request) 645 { 646 647 if (event->status == BT_OK) { 648 uint8 cod[3] = {0,0,0}; 649 650 ConnectionIncoming* iConnection = new ConnectionIncoming( 651 new RemoteDevice(event->bdaddr, cod)); 652 iConnection->Show(); 653 654 655 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 656 "%s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__, 657 bdaddrUtils::ToString(event->bdaddr), event->handle, 658 event->link_type, event->encrypt_mode); 659 660 } else { 661 Output::Instance()->Postf(BLACKBOARD_LD(GetID()), 662 "%s: failed with status %#x\n", __FUNCTION__, event->status); 663 } 664 665 666 667 } 668 669 670 void 671 LocalDeviceImpl::DisconnectionComplete(struct hci_ev_disconnection_complete_reply* event, BMessage* request) 672 { 673 Output::Instance()->Post("Disconnected\n", BLACKBOARD_KIT); 674 675 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s: Handle=%#x, reason=%x status=%x\n", 676 __FUNCTION__, event->handle, event->reason, event->status); 677 678 ClearWantedEvent(request); 679 680 } 681 682 683 void 684 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event, BMessage* request) 685 { 686 PincodeWindow* iPincode = new PincodeWindow(event->bdaddr, GetID()); 687 iPincode->Show(); 688 } 689 690 691 void 692 LocalDeviceImpl::RoleChange(hci_ev_role_change *event, BMessage* request, int32 index) 693 { 694 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s: Address %s role=%d status=%d\n", 695 __FUNCTION__, bdaddrUtils::ToString(event->bdaddr), event->role, event->status); 696 } 697 698 699 void 700 LocalDeviceImpl::PageScanRepetitionModeChange(struct hci_ev_page_scan_rep_mode_change* event, 701 BMessage* request, int32 index) 702 { 703 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s: Address %s type=%d\n", 704 __FUNCTION__, bdaddrUtils::ToString(event->bdaddr), event->page_scan_rep_mode); 705 } 706 707 708 void 709 LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify *event, 710 BMessage* request, int32 index) 711 { 712 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s: Address %s, key=%s, type=%d\n", 713 __FUNCTION__, bdaddrUtils::ToString(event->bdaddr), 714 LinkKeyUtils::ToString(event->link_key), event->key_type); 715 } 716 717 718 void 719 LocalDeviceImpl::MaxSlotChange(struct hci_ev_max_slot_change *event, 720 BMessage *request, int32 index) 721 { 722 Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s: Handle=%#x, max slots=%d\n", 723 __FUNCTION__, event->handle, event->lmp_max_slots); 724 } 725 726 727 #if 0 728 #pragma mark - Request Methods - 729 #endif 730 731 732 status_t 733 LocalDeviceImpl::ProcessSimpleRequest(BMessage* request) 734 { 735 ssize_t size; 736 void* command = NULL; 737 738 if (request->FindData("raw command", B_ANY_TYPE, 0, 739 (const void **)&command, &size) == B_OK) { 740 741 AddWantedEvent(request); 742 // LEAK: is command buffer freed within the Message? 743 if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) 744 == B_ERROR) { 745 // TODO: - Reply the request with error! 746 // - Remove the just added request 747 (Output::Instance()->Post("Command issue error\n", BLACKBOARD_KIT)); 748 } else { 749 return B_OK; 750 } 751 } else { 752 (Output::Instance()->Post("No command specified for simple request\n", 753 BLACKBOARD_KIT)); 754 } 755 756 return B_ERROR; 757 } 758