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 bdaddr_t 195 LocalDevice::GetBluetoothAddress() 196 { 197 if (fMessenger == NULL) 198 return bdaddrUtils::LocalAddress(); 199 200 size_t size; 201 void* command = buildReadBdAddr(&size); 202 203 if (command == NULL) 204 return bdaddrUtils::LocalAddress(); 205 206 const bdaddr_t* bdaddr; 207 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 208 BMessage reply; 209 ssize_t ssize; 210 211 request.AddInt32("hci_id", fHid); 212 request.AddData("raw command", B_ANY_TYPE, command, size); 213 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 214 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 215 OCF_READ_BD_ADDR)); 216 217 if (fMessenger->SendMessage(&request, &reply) == B_OK 218 && reply.FindData("bdaddr", B_ANY_TYPE, 0, 219 (const void**)&bdaddr, &ssize) == B_OK) 220 return *bdaddr; 221 222 return bdaddrUtils::LocalAddress(); 223 } 224 225 226 hci_id 227 LocalDevice::ID(void) const 228 { 229 return fHid; 230 } 231 232 233 BString 234 LocalDevice::GetFriendlyName() 235 { 236 if (fMessenger == NULL) 237 return BString("Unknown|Messenger"); 238 239 size_t size; 240 void* command = buildReadLocalName(&size); 241 if (command == NULL) 242 return BString("Unknown|NoMemory"); 243 244 BString friendlyname; 245 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 246 BMessage reply; 247 248 249 request.AddInt32("hci_id", fHid); 250 request.AddData("raw command", B_ANY_TYPE, command, size); 251 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 252 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 253 OCF_READ_LOCAL_NAME)); 254 255 if (fMessenger->SendMessage(&request, &reply) == B_OK 256 && reply.FindString("friendlyname", &friendlyname) == B_OK) 257 return friendlyname; 258 259 return BString("Unknown|ServerFailed"); 260 } 261 262 263 DeviceClass 264 LocalDevice::GetDeviceClass() 265 { 266 267 // if (fDeviceClass.IsUnknownDeviceClass()) { 268 269 if (fMessenger == NULL) 270 return fDeviceClass; 271 272 size_t size; 273 void* command = buildReadClassOfDevice(&size); 274 if (command == NULL) 275 return fDeviceClass; 276 277 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 278 BMessage reply; 279 const uint8* bufferRecord; 280 ssize_t ssize; 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_CLASS_OF_DEV)); 287 288 if (fMessenger->SendMessage(&request, &reply) == B_OK 289 && reply.FindData("devclass", B_ANY_TYPE, 0, (const void**)&bufferRecord, 290 &ssize) == B_OK) { 291 uint8 record[3] = { bufferRecord[0], bufferRecord[1], bufferRecord[2] }; 292 fDeviceClass.SetRecord(record); 293 } 294 // } 295 296 return fDeviceClass; 297 298 } 299 300 301 status_t 302 LocalDevice::SetDeviceClass(DeviceClass deviceClass) 303 { 304 int8 bt_status = BT_ERROR; 305 306 if (fMessenger == NULL) 307 return bt_status; 308 309 BluetoothCommand<typed_command(hci_write_dev_class)> 310 setDeviceClass(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV); 311 312 setDeviceClass->dev_class[0] = deviceClass.Record() & 0xFF; 313 setDeviceClass->dev_class[1] = (deviceClass.Record() & 0xFF00) >> 8; 314 setDeviceClass->dev_class[2] = (deviceClass.Record() & 0xFF0000) >> 16; 315 316 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 317 BMessage reply; 318 319 request.AddInt32("hci_id", fHid); 320 request.AddData("raw command", B_ANY_TYPE, 321 setDeviceClass.Data(), setDeviceClass.Size()); 322 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 323 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 324 OCF_WRITE_CLASS_OF_DEV)); 325 326 if (fMessenger->SendMessage(&request, &reply) == B_OK) 327 reply.FindInt8("status", &bt_status); 328 329 return bt_status; 330 331 } 332 333 334 status_t 335 LocalDevice::_ReadLocalVersion() 336 { 337 int8 bt_status = BT_ERROR; 338 339 BluetoothCommand<> localVersion(OGF_INFORMATIONAL_PARAM, 340 OCF_READ_LOCAL_VERSION); 341 342 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 343 BMessage reply; 344 345 request.AddInt32("hci_id", fHid); 346 request.AddData("raw command", B_ANY_TYPE, 347 localVersion.Data(), localVersion.Size()); 348 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 349 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 350 OCF_READ_LOCAL_VERSION)); 351 352 if (fMessenger->SendMessage(&request, &reply) == B_OK) 353 reply.FindInt8("status", &bt_status); 354 355 return bt_status; 356 } 357 358 359 status_t 360 LocalDevice::_ReadBufferSize() 361 { 362 int8 bt_status = BT_ERROR; 363 364 BluetoothCommand<> BufferSize(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE); 365 366 367 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 368 BMessage reply; 369 370 request.AddInt32("hci_id", fHid); 371 request.AddData("raw command", B_ANY_TYPE, 372 BufferSize.Data(), BufferSize.Size()); 373 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 374 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 375 OCF_READ_BUFFER_SIZE)); 376 377 if (fMessenger->SendMessage(&request, &reply) == B_OK) 378 reply.FindInt8("status", &bt_status); 379 380 return bt_status; 381 } 382 383 384 status_t 385 LocalDevice::_ReadLocalFeatures() 386 { 387 int8 bt_status = BT_ERROR; 388 389 BluetoothCommand<> LocalFeatures(OGF_INFORMATIONAL_PARAM, 390 OCF_READ_LOCAL_FEATURES); 391 392 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 393 BMessage reply; 394 395 request.AddInt32("hci_id", fHid); 396 request.AddData("raw command", B_ANY_TYPE, 397 LocalFeatures.Data(), LocalFeatures.Size()); 398 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 399 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 400 OCF_READ_LOCAL_FEATURES)); 401 402 if (fMessenger->SendMessage(&request, &reply) == B_OK) 403 reply.FindInt8("status", &bt_status); 404 405 return bt_status; 406 } 407 408 409 status_t 410 LocalDevice::Reset() 411 { 412 int8 bt_status = BT_ERROR; 413 414 BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET); 415 416 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 417 BMessage reply; 418 419 request.AddInt32("hci_id", fHid); 420 request.AddData("raw command", B_ANY_TYPE, Reset.Data(), Reset.Size()); 421 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 422 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 423 OCF_RESET)); 424 425 if (fMessenger->SendMessage(&request, &reply) == B_OK) 426 reply.FindInt8("status", &bt_status); 427 428 return bt_status; 429 430 } 431 432 433 /* 434 ServiceRecord 435 LocalDevice::getRecord(Connection notifier) { 436 437 } 438 439 void 440 LocalDevice::updateRecord(ServiceRecord srvRecord) { 441 442 } 443 */ 444 445 446 LocalDevice::LocalDevice(hci_id hid) : fHid(hid) 447 { 448 fMessenger = _RetrieveBluetoothMessenger(); 449 450 _ReadBufferSize(); 451 _ReadLocalFeatures(); 452 _ReadLocalVersion(); 453 454 uint32 value; 455 456 // HARDCODE -> move this to addons 457 if (GetProperty("manufacturer", &value) == B_OK 458 && value == 15) { 459 460 // Uncomment this out if your Broadcom dongle is not working properly 461 // Reset(); // Perform a reset to Broadcom buggyland 462 463 // Uncomment this out if your Broadcom dongle has a null bdaddr 464 // #define BT_WRITE_BDADDR_FOR_BCM2035 465 #ifdef BT_WRITE_BDADDR_FOR_BCM2035 466 #warning Writting broadcom bdaddr @ init. 467 // try write bdaddr to a bcm2035 -> will be moved to an addon 468 int8 bt_status = BT_ERROR; 469 470 BluetoothCommand<typed_command(hci_write_bcm2035_bdaddr)> 471 writeAddress(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR); 472 473 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 474 BMessage reply; 475 writeAddress->bdaddr.b[0] = 0x3C; 476 writeAddress->bdaddr.b[1] = 0x19; 477 writeAddress->bdaddr.b[2] = 0x30; 478 writeAddress->bdaddr.b[3] = 0xC9; 479 writeAddress->bdaddr.b[4] = 0x03; 480 writeAddress->bdaddr.b[5] = 0x00; 481 482 request.AddInt32("hci_id", fHid); 483 request.AddData("raw command", B_ANY_TYPE, 484 writeAddress.Data(), writeAddress.Size()); 485 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 486 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_VENDOR_CMD, 487 OCF_WRITE_BCM2035_BDADDR)); 488 489 if (fMessenger->SendMessage(&request, &reply) == B_OK) 490 reply.FindInt8("status", &bt_status); 491 #endif 492 } 493 } 494 495 496 LocalDevice::~LocalDevice() 497 { 498 delete fMessenger; 499 } 500 501 502 } 503