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 171 request.AddInt32("hci_id", fHid); 172 173 174 void* command = buildWriteScan(mode, &size); 175 176 if (command == NULL) { 177 return B_NO_MEMORY; 178 } 179 180 request.AddData("raw command", B_ANY_TYPE, command, size); 181 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 182 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 183 OCF_WRITE_SCAN_ENABLE)); 184 185 if (fMessenger->SendMessage(&request, &reply) == B_OK) { 186 if (reply.FindInt8("status", &bt_status ) == B_OK ) { 187 return bt_status; 188 189 } 190 191 } 192 193 return B_ERROR; 194 } 195 196 197 bdaddr_t 198 LocalDevice::GetBluetoothAddress() 199 { 200 if (fMessenger == NULL) 201 return bdaddrUtils::LocalAddress(); 202 203 size_t size; 204 void* command = buildReadBdAddr(&size); 205 206 if (command == NULL) 207 return bdaddrUtils::LocalAddress(); 208 209 const bdaddr_t* bdaddr; 210 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 211 BMessage reply; 212 ssize_t ssize; 213 214 request.AddInt32("hci_id", fHid); 215 request.AddData("raw command", B_ANY_TYPE, command, size); 216 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 217 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 218 OCF_READ_BD_ADDR)); 219 220 if (fMessenger->SendMessage(&request, &reply) == B_OK) { 221 if (reply.FindData("bdaddr", B_ANY_TYPE, 0, (const void**)&bdaddr, &ssize) == B_OK ) 222 return *bdaddr; 223 } 224 225 return bdaddrUtils::LocalAddress(); 226 } 227 228 229 hci_id 230 LocalDevice::ID(void) const 231 { 232 return fHid; 233 } 234 235 236 BString 237 LocalDevice::GetFriendlyName() 238 { 239 if (fMessenger == NULL) 240 return BString("Unknown|Messenger"); 241 242 size_t size; 243 void* command = buildReadLocalName(&size); 244 if (command == NULL) 245 return BString("Unknown|NoMemory"); 246 247 BString friendlyname; 248 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 249 BMessage reply; 250 251 252 request.AddInt32("hci_id", fHid); 253 request.AddData("raw command", B_ANY_TYPE, command, size); 254 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 255 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 256 OCF_READ_LOCAL_NAME)); 257 258 if (fMessenger->SendMessage(&request, &reply) == B_OK && 259 reply.FindString("friendlyname", &friendlyname) == B_OK){ 260 261 return friendlyname; 262 } 263 264 return BString("Unknown|ServerFailed"); 265 } 266 267 268 DeviceClass 269 LocalDevice::GetDeviceClass() 270 { 271 272 // if (fDeviceClass.IsUnknownDeviceClass()) { 273 274 if (fMessenger == NULL) 275 return fDeviceClass; 276 277 size_t size; 278 void* command = buildReadClassOfDevice(&size); 279 if (command == NULL) 280 return fDeviceClass; 281 282 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 283 BMessage reply; 284 const uint8* bufferRecord; 285 ssize_t ssize; 286 287 request.AddInt32("hci_id", fHid); 288 request.AddData("raw command", B_ANY_TYPE, command, size); 289 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 290 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 291 OCF_READ_CLASS_OF_DEV)); 292 293 if (fMessenger->SendMessage(&request, &reply) == B_OK 294 && reply.FindData("devclass", B_ANY_TYPE, 0, (const void**)&bufferRecord, 295 &ssize) == B_OK) { 296 uint8 record[3] = { bufferRecord[0], bufferRecord[1], bufferRecord[2] }; 297 fDeviceClass.SetRecord(record); 298 } 299 // } 300 301 return fDeviceClass; 302 303 } 304 305 306 status_t 307 LocalDevice::SetDeviceClass(DeviceClass deviceClass) 308 { 309 int8 bt_status = BT_ERROR; 310 311 if (fMessenger == NULL) 312 return bt_status; 313 314 BluetoothCommand<typed_command(hci_write_dev_class)> 315 setDeviceClass(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV); 316 317 setDeviceClass->dev_class[0] = deviceClass.Record() & 0xFF; 318 setDeviceClass->dev_class[1] = (deviceClass.Record() & 0xFF00) >> 8; 319 setDeviceClass->dev_class[2] = (deviceClass.Record() & 0xFF0000) >> 16; 320 321 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 322 BMessage reply; 323 324 request.AddInt32("hci_id", fHid); 325 request.AddData("raw command", B_ANY_TYPE, setDeviceClass.Data(), setDeviceClass.Size()); 326 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 327 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 328 OCF_WRITE_CLASS_OF_DEV)); 329 330 if (fMessenger->SendMessage(&request, &reply) == B_OK) 331 reply.FindInt8("status", &bt_status); 332 333 return bt_status; 334 335 } 336 337 338 status_t 339 LocalDevice::ReadLocalVersion() 340 { 341 int8 bt_status = BT_ERROR; 342 343 BluetoothCommand<> localVersion(OGF_INFORMATIONAL_PARAM,OCF_READ_LOCAL_VERSION); 344 345 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 346 BMessage reply; 347 348 request.AddInt32("hci_id", fHid); 349 request.AddData("raw command", B_ANY_TYPE, 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, BufferSize.Data(), BufferSize.Size()); 374 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 375 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, 376 OCF_READ_BUFFER_SIZE)); 377 378 if (fMessenger->SendMessage(&request, &reply) == B_OK) 379 reply.FindInt8("status", &bt_status); 380 381 return bt_status; 382 } 383 384 385 status_t 386 LocalDevice::Reset() 387 { 388 int8 bt_status = BT_ERROR; 389 390 BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET); 391 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 436 //#define BT_WRITE_BDADDR_FOR_BCM2035 437 #ifdef BT_WRITE_BDADDR_FOR_BCM2035 438 // try write bdaddr to a bcm2035 -> will be moved to an addon 439 int8 bt_status = BT_ERROR; 440 441 BluetoothCommand<typed_command(hci_write_bcm2035_bdaddr)> 442 writeAddress(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR); 443 444 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); 445 BMessage reply; 446 writeAddress->bdaddr.b[0] = 0x3C; 447 writeAddress->bdaddr.b[1] = 0x19; 448 writeAddress->bdaddr.b[2] = 0x30; 449 writeAddress->bdaddr.b[3] = 0xC9; 450 writeAddress->bdaddr.b[4] = 0x03; 451 writeAddress->bdaddr.b[5] = 0x00; 452 453 request.AddInt32("hci_id", fHid); 454 request.AddData("raw command", B_ANY_TYPE, writeAddress.Data(), writeAddress.Size()); 455 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); 456 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_VENDOR_CMD, 457 OCF_WRITE_BCM2035_BDADDR)); 458 459 if (fMessenger->SendMessage(&request, &reply) == B_OK) 460 reply.FindInt8("status", &bt_status); 461 #endif 462 } 463 464 ReadBufferSize(); 465 } 466 467 468 LocalDevice::~LocalDevice() 469 { 470 delete fMessenger; 471 } 472 473 474 } 475