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