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