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