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