1 /* 2 * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com 4 * Copyright 2012 Fredrik Modéen, [firstname]@[lastname] 5 * All rights reserved. Distributed under the terms of the MIT License. 6 */ 7 8 9 #include <bluetooth/bluetooth_error.h> 10 11 #include <bluetooth/HCI/btHCI_command.h> 12 #include <bluetooth/HCI/btHCI_event.h> 13 14 #include <bluetooth/DeviceClass.h> 15 #include <bluetooth/DiscoveryAgent.h> 16 #include <bluetooth/LocalDevice.h> 17 #include <bluetooth/RemoteDevice.h> 18 19 #include <bluetooth/bdaddrUtils.h> 20 #include <bluetoothserver_p.h> 21 #include <CommandManager.h> 22 23 #include <new> 24 25 #include "KitSupport.h" 26 27 28 namespace Bluetooth { 29 30 31 LocalDevice* 32 LocalDevice::RequestLocalDeviceID(BMessage* request) 33 { 34 BMessage reply; 35 hci_id hid; 36 LocalDevice* lDevice = NULL; 37 38 BMessenger* messenger = _RetrieveBluetoothMessenger(); 39 40 if (messenger == NULL) 41 return NULL; 42 43 if (messenger->SendMessage(request, &reply) == B_OK 44 && reply.FindInt32("hci_id", &hid) == B_OK ) { 45 46 if (hid >= 0) 47 lDevice = new (std::nothrow)LocalDevice(hid); 48 } 49 50 delete messenger; 51 return lDevice; 52 } 53 54 55 #if 0 56 #pragma - 57 #endif 58 59 60 LocalDevice* 61 LocalDevice::GetLocalDevice() 62 { 63 BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE); 64 65 return RequestLocalDeviceID(&request); 66 } 67 68 69 LocalDevice* 70 LocalDevice::GetLocalDevice(const hci_id hid) 71 { 72 BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE); 73 request.AddInt32("hci_id", hid); 74 75 return RequestLocalDeviceID(&request); 76 } 77 78 79 LocalDevice* 80 LocalDevice::GetLocalDevice(const bdaddr_t bdaddr) 81 { 82 BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE); 83 request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t)); 84 85 return RequestLocalDeviceID(&request); 86 } 87 88 89 uint32 90 LocalDevice::GetLocalDeviceCount() 91 { 92 BMessenger* messenger = _RetrieveBluetoothMessenger(); 93 uint32 count = 0; 94 95 if (messenger != NULL) { 96 97 BMessage request(BT_MSG_COUNT_LOCAL_DEVICES); 98 BMessage reply; 99 100 if (messenger->SendMessage(&request, &reply) == B_OK) 101 count = reply.FindInt32("count"); 102 103 delete messenger; 104 } 105 106 return count; 107 108 } 109 110 111 DiscoveryAgent* 112 LocalDevice::GetDiscoveryAgent() 113 { 114 // TODO: Study a singleton here 115 return new (std::nothrow)DiscoveryAgent(this); 116 } 117 118 119 BString 120 LocalDevice::GetProperty(const char* property) 121 { 122 return NULL; 123 124 } 125 126 127 status_t 128 LocalDevice::GetProperty(const char* property, uint32* value) 129 { 130 if (fMessenger == NULL) 131 return B_ERROR; 132 133 BMessage request(BT_MSG_GET_PROPERTY); 134 BMessage reply; 135 136 request.AddInt32("hci_id", fHid); 137 request.AddString("property", property); 138 139 if (fMessenger->SendMessage(&request, &reply) == B_OK) { 140 if (reply.FindInt32("result", (int32*)value ) == B_OK ) { 141 return B_OK; 142 143 } 144 } 145 146 return B_ERROR; 147 } 148 149 150 int 151 LocalDevice::GetDiscoverable() 152 { 153 if (fMessenger == NULL) 154 return -1; 155 156 size_t size; 157 void* command = buildReadScan(&size); 158 if (command == NULL) 159 return -1; 160 161 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 162 request.AddInt32("hci_id", fHid); 163 request.AddData("raw command", B_ANY_TYPE, command, size); 164 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 165 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 166 OCF_READ_SCAN_ENABLE)); 167 168 int8 discoverable; 169 BMessage reply; 170 if (fMessenger->SendMessage(&request, &reply) == B_OK 171 && reply.FindInt8("scan_enable", &discoverable) == B_OK) 172 return discoverable; 173 174 return -1; 175 } 176 177 178 status_t 179 LocalDevice::SetDiscoverable(int mode) 180 { 181 if (fMessenger == NULL) 182 return B_ERROR; 183 184 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 185 BMessage reply; 186 187 size_t size; 188 int8 bt_status = BT_ERROR; 189 190 request.AddInt32("hci_id", fHid); 191 192 193 void* command = buildWriteScan(mode, &size); 194 195 if (command == NULL) { 196 return B_NO_MEMORY; 197 } 198 199 request.AddData("raw command", B_ANY_TYPE, command, size); 200 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 201 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 202 OCF_WRITE_SCAN_ENABLE)); 203 204 if (fMessenger->SendMessage(&request, &reply) == B_OK) { 205 if (reply.FindInt8("status", &bt_status ) == B_OK ) { 206 return bt_status; 207 208 } 209 } 210 211 return B_ERROR; 212 } 213 214 215 struct authentication_t { 216 uint8 param; 217 }; 218 219 220 status_t 221 LocalDevice::SetAuthentication(bool authentication) 222 { 223 return SingleParameterCommandRequest<struct authentication_t, uint8> 224 (OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE, authentication, 225 NULL, fHid, fMessenger); 226 } 227 228 229 bdaddr_t 230 LocalDevice::GetBluetoothAddress() 231 { 232 if (fMessenger == NULL) 233 return bdaddrUtils::LocalAddress(); 234 235 size_t size; 236 void* command = buildReadBdAddr(&size); 237 238 if (command == NULL) 239 return bdaddrUtils::LocalAddress(); 240 241 const bdaddr_t* bdaddr; 242 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 243 BMessage reply; 244 ssize_t ssize; 245 246 request.AddInt32("hci_id", fHid); 247 request.AddData("raw command", B_ANY_TYPE, command, size); 248 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 249 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 250 OCF_READ_BD_ADDR)); 251 252 if (fMessenger->SendMessage(&request, &reply) == B_OK 253 && reply.FindData("bdaddr", B_ANY_TYPE, 0, 254 (const void**)&bdaddr, &ssize) == B_OK) 255 return *bdaddr; 256 257 return bdaddrUtils::LocalAddress(); 258 } 259 260 261 hci_id 262 LocalDevice::ID(void) const 263 { 264 return fHid; 265 } 266 267 268 BString 269 LocalDevice::GetFriendlyName() 270 { 271 if (fMessenger == NULL) 272 return BString("Unknown|Messenger"); 273 274 size_t size; 275 void* command = buildReadLocalName(&size); 276 if (command == NULL) 277 return BString("Unknown|NoMemory"); 278 279 BString friendlyname; 280 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 281 BMessage reply; 282 283 284 request.AddInt32("hci_id", fHid); 285 request.AddData("raw command", B_ANY_TYPE, command, size); 286 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 287 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 288 OCF_READ_LOCAL_NAME)); 289 290 if (fMessenger->SendMessage(&request, &reply) == B_OK 291 && reply.FindString("friendlyname", &friendlyname) == B_OK) 292 return friendlyname; 293 294 return BString("Unknown|ServerFailed"); 295 } 296 297 298 status_t 299 LocalDevice::SetFriendlyName(BString& name) 300 { 301 int8 btStatus = BT_ERROR; 302 303 if (fMessenger == NULL) 304 return btStatus; 305 306 BluetoothCommand<typed_command(hci_write_local_name)> 307 writeName(OGF_CONTROL_BASEBAND, OCF_WRITE_LOCAL_NAME); 308 309 strcpy(writeName->local_name, name.String()); 310 311 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 312 BMessage reply; 313 314 request.AddInt32("hci_id", fHid); 315 request.AddData("raw command", B_ANY_TYPE, 316 writeName.Data(), writeName.Size()); 317 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 318 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 319 OCF_WRITE_LOCAL_NAME)); 320 321 if (fMessenger->SendMessage(&request, &reply) == B_OK) 322 reply.FindInt8("status", &btStatus); 323 324 return btStatus; 325 } 326 327 328 DeviceClass 329 LocalDevice::GetDeviceClass() 330 { 331 332 // if (fDeviceClass.IsUnknownDeviceClass()) { 333 334 if (fMessenger == NULL) 335 return fDeviceClass; 336 337 size_t size; 338 void* command = buildReadClassOfDevice(&size); 339 if (command == NULL) 340 return fDeviceClass; 341 342 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 343 BMessage reply; 344 const uint8* bufferRecord; 345 ssize_t ssize; 346 347 request.AddInt32("hci_id", fHid); 348 request.AddData("raw command", B_ANY_TYPE, command, size); 349 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 350 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 351 OCF_READ_CLASS_OF_DEV)); 352 353 if (fMessenger->SendMessage(&request, &reply) == B_OK 354 && reply.FindData("devclass", B_ANY_TYPE, 0, (const void**)&bufferRecord, 355 &ssize) == B_OK) { 356 uint8 record[3] = { bufferRecord[0], bufferRecord[1], bufferRecord[2] }; 357 fDeviceClass.SetRecord(record); 358 } 359 // } 360 361 return fDeviceClass; 362 363 } 364 365 366 status_t 367 LocalDevice::SetDeviceClass(DeviceClass deviceClass) 368 { 369 int8 bt_status = BT_ERROR; 370 371 if (fMessenger == NULL) 372 return bt_status; 373 374 BluetoothCommand<typed_command(hci_write_dev_class)> 375 setDeviceClass(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV); 376 377 setDeviceClass->dev_class[0] = deviceClass.Record() & 0xFF; 378 setDeviceClass->dev_class[1] = (deviceClass.Record() & 0xFF00) >> 8; 379 setDeviceClass->dev_class[2] = (deviceClass.Record() & 0xFF0000) >> 16; 380 381 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 382 BMessage reply; 383 384 request.AddInt32("hci_id", fHid); 385 request.AddData("raw command", B_ANY_TYPE, 386 setDeviceClass.Data(), setDeviceClass.Size()); 387 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 388 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 389 OCF_WRITE_CLASS_OF_DEV)); 390 391 if (fMessenger->SendMessage(&request, &reply) == B_OK) 392 reply.FindInt8("status", &bt_status); 393 394 return bt_status; 395 396 } 397 398 399 status_t 400 LocalDevice::_ReadLocalVersion() 401 { 402 int8 bt_status = BT_ERROR; 403 404 BluetoothCommand<> localVersion(OGF_INFORMATIONAL_PARAM, 405 OCF_READ_LOCAL_VERSION); 406 407 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 408 BMessage reply; 409 410 request.AddInt32("hci_id", fHid); 411 request.AddData("raw command", B_ANY_TYPE, 412 localVersion.Data(), localVersion.Size()); 413 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 414 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 415 OCF_READ_LOCAL_VERSION)); 416 417 if (fMessenger->SendMessage(&request, &reply) == B_OK) 418 reply.FindInt8("status", &bt_status); 419 420 return bt_status; 421 } 422 423 424 status_t 425 LocalDevice::_ReadBufferSize() 426 { 427 int8 bt_status = BT_ERROR; 428 429 BluetoothCommand<> BufferSize(OGF_INFORMATIONAL_PARAM, 430 OCF_READ_BUFFER_SIZE); 431 432 433 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 434 BMessage reply; 435 436 request.AddInt32("hci_id", fHid); 437 request.AddData("raw command", B_ANY_TYPE, 438 BufferSize.Data(), BufferSize.Size()); 439 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 440 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 441 OCF_READ_BUFFER_SIZE)); 442 443 if (fMessenger->SendMessage(&request, &reply) == B_OK) 444 reply.FindInt8("status", &bt_status); 445 446 return bt_status; 447 } 448 449 450 status_t 451 LocalDevice::_ReadLocalFeatures() 452 { 453 int8 bt_status = BT_ERROR; 454 455 BluetoothCommand<> LocalFeatures(OGF_INFORMATIONAL_PARAM, 456 OCF_READ_LOCAL_FEATURES); 457 458 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 459 BMessage reply; 460 461 request.AddInt32("hci_id", fHid); 462 request.AddData("raw command", B_ANY_TYPE, 463 LocalFeatures.Data(), LocalFeatures.Size()); 464 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 465 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 466 OCF_READ_LOCAL_FEATURES)); 467 468 if (fMessenger->SendMessage(&request, &reply) == B_OK) 469 reply.FindInt8("status", &bt_status); 470 471 return bt_status; 472 } 473 474 475 status_t 476 LocalDevice::_ReadLinkKeys() 477 { 478 int8 bt_status = BT_ERROR; 479 480 BluetoothCommand<> LocalFeatures(OGF_CONTROL_BASEBAND, 481 OCF_READ_STORED_LINK_KEY); 482 483 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 484 BMessage reply; 485 486 request.AddInt32("hci_id", fHid); 487 request.AddData("raw command", B_ANY_TYPE, 488 LocalFeatures.Data(), LocalFeatures.Size()); 489 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 490 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 491 OCF_READ_STORED_LINK_KEY)); 492 493 request.AddInt16("eventExpected", HCI_EVENT_RETURN_LINK_KEYS); 494 495 496 if (fMessenger->SendMessage(&request, &reply) == B_OK) 497 reply.FindInt8("status", &bt_status); 498 499 return bt_status; 500 } 501 502 503 struct pageTimeout_t { 504 uint16 param; 505 }; 506 507 508 status_t 509 LocalDevice::_ReadTimeouts() 510 { 511 512 // Read PageTimeout 513 NonParameterCommandRequest(OGF_CONTROL_BASEBAND, 514 OCF_READ_PG_TIMEOUT, NULL, fHid, fMessenger); 515 516 // Write PageTimeout 517 SingleParameterCommandRequest<struct pageTimeout_t, uint16> 518 (OGF_CONTROL_BASEBAND, OCF_WRITE_PG_TIMEOUT, 0x8000, NULL, 519 fHid, fMessenger); 520 521 // Write PageTimeout 522 return SingleParameterCommandRequest<struct pageTimeout_t, uint16> 523 (OGF_CONTROL_BASEBAND, OCF_WRITE_CA_TIMEOUT, 0x7d00, NULL, 524 fHid, fMessenger); 525 } 526 527 528 status_t 529 LocalDevice::Reset() 530 { 531 int8 bt_status = BT_ERROR; 532 533 BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET); 534 535 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 536 BMessage reply; 537 538 request.AddInt32("hci_id", fHid); 539 request.AddData("raw command", B_ANY_TYPE, Reset.Data(), Reset.Size()); 540 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 541 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 542 OCF_RESET)); 543 544 if (fMessenger->SendMessage(&request, &reply) == B_OK) 545 reply.FindInt8("status", &bt_status); 546 547 return bt_status; 548 549 } 550 551 552 /* 553 ServiceRecord 554 LocalDevice::getRecord(Connection notifier) { 555 556 } 557 558 void 559 LocalDevice::updateRecord(ServiceRecord srvRecord) { 560 561 } 562 */ 563 564 565 LocalDevice::LocalDevice(hci_id hid) 566 : 567 BluetoothDevice(), 568 fHid(hid) 569 { 570 fMessenger = _RetrieveBluetoothMessenger(); 571 572 _ReadBufferSize(); 573 _ReadLocalFeatures(); 574 _ReadLocalVersion(); 575 _ReadTimeouts(); 576 _ReadLinkKeys(); 577 578 // Uncomment this if you want your device to have a nicer default name 579 // BString name("HaikuBluetooth"); 580 // SetFriendlyName(name); 581 582 583 uint32 value; 584 585 // HARDCODE -> move this to addons 586 if (GetProperty("manufacturer", &value) == B_OK 587 && value == 15) { 588 589 // Uncomment this out if your Broadcom dongle is not working properly 590 // Reset(); // Perform a reset to Broadcom buggyland 591 592 // Uncomment this out if your Broadcom dongle has a null bdaddr 593 //#define BT_WRITE_BDADDR_FOR_BCM2035 594 #ifdef BT_WRITE_BDADDR_FOR_BCM2035 595 #warning Writting broadcom bdaddr @ init. 596 // try write bdaddr to a bcm2035 -> will be moved to an addon 597 int8 bt_status = BT_ERROR; 598 599 BluetoothCommand<typed_command(hci_write_bcm2035_bdaddr)> 600 writeAddress(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR); 601 602 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 603 BMessage reply; 604 writeAddress->bdaddr.b[0] = 0x3C; 605 writeAddress->bdaddr.b[1] = 0x19; 606 writeAddress->bdaddr.b[2] = 0x30; 607 writeAddress->bdaddr.b[3] = 0xC9; 608 writeAddress->bdaddr.b[4] = 0x03; 609 writeAddress->bdaddr.b[5] = 0x00; 610 611 request.AddInt32("hci_id", fHid); 612 request.AddData("raw command", B_ANY_TYPE, 613 writeAddress.Data(), writeAddress.Size()); 614 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 615 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_VENDOR_CMD, 616 OCF_WRITE_BCM2035_BDADDR)); 617 618 if (fMessenger->SendMessage(&request, &reply) == B_OK) 619 reply.FindInt8("status", &bt_status); 620 #endif 621 } 622 } 623 624 625 LocalDevice::~LocalDevice() 626 { 627 delete fMessenger; 628 } 629 630 631 } /* end namespace Bluetooth */ 632