1 /* 2 * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * 4 * All rights reserved. Distributed under the terms of the MIT License. 5 * 6 */ 7 8 9 #include "BluetoothServer.h" 10 11 #include "LocalDeviceImpl.h" 12 #include "CommandManager.h" 13 #include "Output.h" 14 15 #include <bluetooth/bluetooth_error.h> 16 #include <bluetooth/HCI/btHCI_event.h> 17 18 #include <bluetoothserver_p.h> 19 #include <ConnectionIncoming.h> 20 #include <PincodeWindow.h> 21 22 #include <stdio.h> 23 24 25 #if 0 26 #pragma mark - Class methods - 27 #endif 28 29 30 // Factory methods 31 LocalDeviceImpl* 32 LocalDeviceImpl::CreateControllerAccessor(BPath* path) 33 { 34 HCIDelegate* hd = new HCIControllerAccessor(path); 35 36 if ( hd != NULL) 37 return new LocalDeviceImpl(hd); 38 else 39 return NULL; 40 } 41 42 43 LocalDeviceImpl* 44 LocalDeviceImpl::CreateTransportAccessor(BPath* path) 45 { 46 HCIDelegate* hd = new HCITransportAccessor(path); 47 48 if ( hd != NULL) 49 return new LocalDeviceImpl(hd); 50 else 51 return NULL; 52 } 53 54 55 LocalDeviceImpl::LocalDeviceImpl(HCIDelegate* hd) : LocalDeviceHandler(hd) 56 { 57 58 } 59 60 #if 0 61 #pragma mark - Event handling methods - 62 #endif 63 64 void 65 LocalDeviceImpl::HandleEvent(struct hci_event_header* event) 66 { 67 68 printf("### Event comming: len = %d\n", event->elen); 69 for (int16 index = 0 ; index < event->elen + 2; index++ ) { 70 printf("%x:",((uint8*)event)[index]); 71 } 72 printf("### \n"); 73 74 // Events here might have not been initated by us 75 switch (event->ecode) { 76 case HCI_EVENT_HARDWARE_ERROR: 77 //HardwareError(event); 78 return; 79 case HCI_EVENT_CONN_REQUEST: 80 81 break; 82 83 case HCI_EVENT_CONN_COMPLETE: 84 ConnectionComplete((struct hci_ev_conn_complete*)(event+1), NULL); // should belong to a request? 85 86 break; 87 88 case HCI_EVENT_PIN_CODE_REQ: 89 PinCodeRequest((struct hci_ev_pin_code_req*)(event+1), NULL); 90 break; 91 92 93 default: 94 // lets go on 95 break; 96 } 97 98 99 100 BMessage* request = NULL; 101 102 // Check if its a requested one 103 if ( event->ecode == HCI_EVENT_CMD_COMPLETE ) { 104 105 (Output::Instance()->Post("Incoming Command Complete\n", BLACKBOARD_EVENTS)); 106 request = FindPetition(event->ecode, ((struct hci_ev_cmd_complete*)(event+1))->opcode ); 107 108 } else if ( event->ecode == HCI_EVENT_CMD_STATUS ) { 109 110 (Output::Instance()->Post("Incoming Command Status\n", BLACKBOARD_EVENTS)); 111 request = FindPetition(event->ecode, ((struct hci_ev_cmd_status*)(event+1))->opcode ); 112 113 } else 114 { 115 request = FindPetition(event->ecode); 116 } 117 118 if ( request == NULL) { 119 (Output::Instance()->Post("Event could not be understood or delivered\n", BLACKBOARD_EVENTS)); 120 return; 121 } 122 123 // we are waiting for a reply 124 switch (event->ecode) { 125 case HCI_EVENT_INQUIRY_COMPLETE: 126 InquiryComplete((uint8*)(event+1), request); 127 break; 128 129 case HCI_EVENT_INQUIRY_RESULT: 130 InquiryResult((uint8*)(event+1), request); 131 break; 132 133 case HCI_EVENT_DISCONNECTION_COMPLETE: 134 135 break; 136 137 case HCI_EVENT_AUTH_COMPLETE: 138 break; 139 140 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: 141 RemoteNameRequestComplete((struct hci_remote_name_request_complete_reply*)(event+1), request); 142 break; 143 144 case HCI_EVENT_ENCRYPT_CHANGE: 145 break; 146 147 case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE: 148 break; 149 150 case HCI_EVENT_MASTER_LINK_KEY_COMPL: 151 break; 152 153 case HCI_EVENT_RMT_FEATURES: 154 break; 155 156 case HCI_EVENT_RMT_VERSION: 157 break; 158 159 case HCI_EVENT_QOS_SETUP_COMPLETE: 160 break; 161 162 case HCI_EVENT_CMD_COMPLETE: 163 CommandComplete((struct hci_ev_cmd_complete*)(event+1), request); 164 break; 165 166 case HCI_EVENT_CMD_STATUS: 167 CommandStatus((struct hci_ev_cmd_status*)(event+1), request); 168 break; 169 170 case HCI_EVENT_FLUSH_OCCUR: 171 break; 172 173 case HCI_EVENT_ROLE_CHANGE: 174 break; 175 176 case HCI_EVENT_NUM_COMP_PKTS: 177 break; 178 179 case HCI_EVENT_MODE_CHANGE: 180 break; 181 182 case HCI_EVENT_RETURN_LINK_KEYS: 183 break; 184 185 case HCI_EVENT_LINK_KEY_REQ: 186 break; 187 188 case HCI_EVENT_LINK_KEY_NOTIFY: 189 break; 190 191 case HCI_EVENT_LOOPBACK_COMMAND: 192 break; 193 194 case HCI_EVENT_DATA_BUFFER_OVERFLOW: 195 break; 196 197 case HCI_EVENT_MAX_SLOT_CHANGE: 198 break; 199 200 case HCI_EVENT_READ_CLOCK_OFFSET_COMPL: 201 break; 202 203 case HCI_EVENT_CON_PKT_TYPE_CHANGED: 204 break; 205 206 case HCI_EVENT_QOS_VIOLATION: 207 break; 208 209 case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE: 210 break; 211 212 case HCI_EVENT_FLOW_SPECIFICATION: 213 break; 214 215 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: 216 break; 217 218 case HCI_EVENT_REMOTE_EXTENDED_FEATURES: 219 break; 220 221 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED: 222 break; 223 224 case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED: 225 226 break; 227 } 228 229 } 230 231 232 void 233 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* request) { 234 235 int16 opcodeExpected; 236 BMessage reply; 237 238 Output::Instance()->Post(__FUNCTION__, BLACKBOARD_LD_OFFSET + GetID()); 239 Output::Instance()->Post("\n", BLACKBOARD_LD_OFFSET + GetID()); 240 241 // Handle command complete information 242 // FIX ME! the expected code might me in another 243 // index as is relative to the event not the request 244 request->FindInt16("opcodeExpected", 0 /*REVIEW!*/, &opcodeExpected); 245 246 247 if (request->IsSourceWaiting() == false) 248 Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); 249 250 switch (opcodeExpected) { 251 252 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR): 253 { 254 struct hci_rp_read_bd_addr* readbdaddr = (struct hci_rp_read_bd_addr*)(event+1); 255 256 if (readbdaddr->status == BT_OK) { 257 258 reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr, sizeof(bdaddr_t)); 259 reply.AddInt32("status", readbdaddr->status); 260 261 printf("Sending reply ... %ld\n",request->SendReply(&reply)); 262 reply.PrintToStream(); 263 264 Output::Instance()->Post("Positive reply for getAdress\n", BLACKBOARD_KIT); 265 266 } else { 267 reply.AddInt8("status", readbdaddr->status); 268 request->SendReply(&reply); 269 Output::Instance()->Post("Negative reply for getAdress\n", BLACKBOARD_KIT); 270 } 271 272 // This request is not genna be used anymore 273 ClearWantedEvent(request); 274 } 275 break; 276 277 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME): 278 { 279 struct hci_rp_read_local_name* readLocalName = (struct hci_rp_read_local_name*)(event+1); 280 281 reply.AddInt8("status", readLocalName->status); 282 283 if (readLocalName->status == BT_OK) { 284 285 reply.AddString("friendlyname", (const char*)readLocalName->local_name ); 286 Output::Instance()->Post("Positive reply for friendly name\n", BLACKBOARD_KIT); 287 288 } else { 289 290 Output::Instance()->Post("Negative reply for friendly name\n", BLACKBOARD_KIT); 291 292 } 293 294 printf("Sending reply ... %ld\n",request->SendReply(&reply)); 295 reply.PrintToStream(); 296 297 // This request is not genna be used anymore 298 ClearWantedEvent(request); 299 } 300 break; 301 302 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE): 303 { 304 uint8* statusReply = (uint8*)(event+1); 305 306 reply.AddInt8("status", *statusReply); 307 308 if (*statusReply == BT_OK) { 309 310 Output::Instance()->Post("Positive reply for scanmode\n", BLACKBOARD_KIT); 311 312 } else { 313 314 Output::Instance()->Post("Negative reply for scanmode\n", BLACKBOARD_KIT); 315 316 } 317 318 printf("Sending reply ... %ld\n",request->SendReply(&reply)); 319 reply.PrintToStream(); 320 321 // This request is not genna be used anymore 322 ClearWantedEvent(request); 323 } 324 break; 325 326 default: 327 Output::Instance()->Post("Command Complete not handled\n", BLACKBOARD_KIT); 328 break; 329 330 } 331 } 332 333 334 void 335 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* request) { 336 337 int16 opcodeExpected; 338 BMessage reply; 339 340 Output::Instance()->Post(__FUNCTION__, BLACKBOARD_LD_OFFSET + GetID()); 341 Output::Instance()->Post("\n", BLACKBOARD_LD_OFFSET + GetID()); 342 343 // Handle command complete information 344 request->FindInt16("opcodeExpected", 0 /*REVIEW!*/, &opcodeExpected); 345 346 347 if (request->IsSourceWaiting() == false) 348 Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); 349 350 351 switch (opcodeExpected) { 352 353 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY): 354 { 355 reply.what = BT_MSG_INQUIRY_STARTED; 356 reply.AddInt8("status", event->status); 357 358 if (event->status == BT_OK) { 359 Output::Instance()->Post("Positive reply for inquiry status\n", BLACKBOARD_KIT); 360 } else { 361 Output::Instance()->Post("Negative reply for inquiry status\n", BLACKBOARD_KIT); 362 } 363 364 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 365 reply.PrintToStream(); 366 367 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY)); 368 } 369 break; 370 371 default: 372 Output::Instance()->Post("Command Status not handled\n", BLACKBOARD_KIT); 373 break; 374 } 375 376 } 377 378 379 void 380 LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request) 381 { 382 383 BMessage reply(BT_MSG_INQUIRY_DEVICE); 384 385 386 reply.AddData("info", B_ANY_TYPE, numberOfResponses+1 // skiping here the number of responses 387 , (*numberOfResponses) * sizeof(struct inquiry_info) ); 388 389 printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply)); 390 391 } 392 393 394 void 395 LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request) 396 { 397 BMessage reply(BT_MSG_INQUIRY_COMPLETED); 398 399 reply.AddInt8("status", *status); 400 401 402 printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply)); 403 // (request->ReturnAddress()).SendMessage(&reply); 404 405 ClearWantedEvent(request); 406 } 407 408 409 void 410 LocalDeviceImpl::RemoteNameRequestComplete(struct hci_remote_name_request_complete_reply* remotename, BMessage* request) 411 { 412 BMessage reply; 413 414 reply.AddInt8("status", remotename->status); 415 416 if (remotename->status == BT_OK) { 417 418 reply.AddString("friendlyname", (const char*)remotename->remote_name ); 419 Output::Instance()->Post("Positive reply for remote friendly name\n", BLACKBOARD_KIT); 420 421 } else { 422 423 Output::Instance()->Post("Negative reply for remote friendly name\n", BLACKBOARD_KIT); 424 425 } 426 427 printf("Sending reply ... %ld\n", request->SendReply(&reply)); 428 reply.PrintToStream(); 429 430 // This request is not genna be used anymore 431 // Although there are many middle events that should be tracked todo: ticket 2377 432 ClearWantedEvent(request); 433 434 } 435 436 437 void 438 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, BMessage* request) 439 { 440 ConnectionIncoming* iConnection = new ConnectionIncoming(NULL); 441 iConnection->Show(); 442 443 } 444 445 446 void 447 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event, BMessage* request) 448 { 449 PincodeWindow* iPincode = new PincodeWindow(NULL); 450 iPincode->Show(); 451 452 } 453 454 #if 0 455 #pragma mark - Request Methods - 456 #endif 457 458 459 status_t 460 LocalDeviceImpl::GetAddress(bdaddr_t* bdaddr, BMessage* request) 461 { 462 ssize_t size; 463 464 if (fProperties->FindData("bdaddr", B_ANY_TYPE, 0, (const void **)bdaddr, &size) == B_OK) { 465 466 (Output::Instance()->Post("BDADDR already present in server\n", BLACKBOARD_EVENTS)); 467 /* We have this info, returning back */ 468 return B_OK; 469 470 } else { 471 size_t size; 472 473 void* command = buildReadBdAddr(&size); 474 475 /* Adding a wanted event in the queue */ 476 request->AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 477 request->AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR)); 478 479 printf("Adding request... %p\n", request); 480 AddWantedEvent(request); 481 request->PrintToStream(); 482 483 if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR) 484 (Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS)); 485 486 (Output::Instance()->Post("Command issued for GetAddress\n", BLACKBOARD_EVENTS)); 487 return B_WOULD_BLOCK; 488 } 489 490 } 491 492 493 status_t 494 LocalDeviceImpl::GetFriendlyName(BString str, BMessage* request) 495 { 496 497 if (fProperties->FindString("friendlyname", &str) == B_OK) { 498 499 (Output::Instance()->Post("Friendly name already present in server\n", BLACKBOARD_EVENTS)); 500 /* We have this info, returning back */ 501 return B_OK; 502 503 } else { 504 size_t size; 505 506 void* command = buildReadLocalName(&size); 507 508 /* Adding a wanted event in the queue */ 509 request->AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 510 request->AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME)); 511 512 printf("Adding request... %p\n", request); 513 AddWantedEvent(request); 514 request->PrintToStream(); 515 516 if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR) 517 (Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS)); 518 519 (Output::Instance()->Post("Command issued for GetFriendlyname\n", BLACKBOARD_EVENTS)); 520 521 return B_WOULD_BLOCK; 522 } 523 524 } 525 526 527 status_t 528 LocalDeviceImpl::ProcessSimpleRequest(BMessage* request) 529 { 530 ssize_t size; 531 void* command = NULL; 532 533 if (request->FindData("raw command", B_ANY_TYPE, 0, (const void **)&command, &size) == B_OK) 534 if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR) 535 (Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS)); 536 else 537 { 538 AddWantedEvent(request); 539 return B_OK; 540 } 541 else { 542 (Output::Instance()->Post("No command specified for simple request\n", BLACKBOARD_KIT)); 543 } 544 545 return B_ERROR; 546 } 547