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