1 /* 2 * Copyright 2008, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 7 */ 8 9 #include <new> 10 #include <errno.h> 11 #include <stdlib.h> 12 #include <string.h> 13 14 #include <KernelExport.h> 15 #include <lock.h> 16 #include <SupportDefs.h> 17 #include <util/AutoLock.h> 18 #include <util/DoublyLinkedList.h> 19 20 #include <net_buffer.h> 21 #include <net_device.h> 22 #include <net_stack.h> 23 #include <NetBufferUtilities.h> 24 25 #define BT_DEBUG_THIS_MODULE 26 #define SUBMODULE_NAME "hci" 27 #define SUBMODULE_COLOR 34 28 #include <btDebug.h> 29 #include <btCoreData.h> 30 #include <btModules.h> 31 #include <CodeHandler.h> 32 #define KERNEL_LAND 33 #include <PortListener.h> 34 #undef KERNEL_LAND 35 36 #include <bluetooth/HCI/btHCI.h> 37 #include <bluetooth/HCI/btHCI_acl.h> 38 #include <bluetooth/HCI/btHCI_command.h> 39 #include <bluetooth/HCI/btHCI_event.h> 40 #include <bluetooth/HCI/btHCI_transport.h> 41 #include <bluetooth/HCI/btHCI_sco.h> 42 #include <bluetooth/bdaddrUtils.h> 43 44 #include "acl.h" 45 46 47 namespace BPrivate { 48 49 const bdaddr_t kBdNullAddress = {{0, 0, 0, 0, 0, 0}}; 50 const bdaddr_t kBdLocalAddress = {{0, 0, 0, 0xff, 0xff, 0xff}}; 51 const bdaddr_t kBdBroadcastAddress = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; 52 53 } 54 55 56 typedef PortListener<void, 57 HCI_MAX_FRAME_SIZE, // Event Body can hold max 255 + 2 header 58 24 // Some devices have sent chunks of 24 events(inquiry result) 59 > BluetoothRawDataPort; 60 61 62 // Modules references 63 net_buffer_module_info* gBufferModule = NULL; 64 struct bluetooth_core_data_module_info* btCoreData = NULL; 65 66 static mutex sListLock; 67 static sem_id sLinkChangeSemaphore; 68 static DoublyLinkedList<bluetooth_device> sDeviceList; 69 70 BluetoothRawDataPort* BluetoothRXPort; 71 72 // forward declarations 73 status_t HciPacketHandler(void* data, int32 code, size_t size); 74 75 76 bluetooth_device* 77 FindDeviceByID(hci_id hid) 78 { 79 bluetooth_device* device; 80 81 DoublyLinkedList<bluetooth_device>::Iterator iterator 82 = sDeviceList.GetIterator(); 83 84 while (iterator.HasNext()) { 85 device = iterator.Next(); 86 if (device->index == hid) 87 return device; 88 } 89 90 return NULL; 91 } 92 93 94 status_t 95 PostTransportPacket(hci_id hid, bt_packet_t type, void* data, size_t count) 96 { 97 uint32 code = 0; 98 99 Bluetooth::CodeHandler::SetDevice(&code, hid); 100 Bluetooth::CodeHandler::SetProtocol(&code, type); 101 102 return BluetoothRXPort->Trigger(code, data, count); 103 } 104 105 106 status_t 107 Assemble(bluetooth_device* bluetoothDevice, bt_packet_t type, void* data, 108 size_t count) 109 { 110 net_buffer* nbuf = bluetoothDevice->fBuffersRx[type]; 111 112 size_t currentPacketLen = 0; 113 114 while (count) { 115 116 if (nbuf == NULL) { 117 // new buffer incoming 118 switch (type) { 119 case BT_EVENT: 120 if (count >= HCI_EVENT_HDR_SIZE) { 121 struct hci_event_header* headerPacket 122 = (struct hci_event_header*)data; 123 bluetoothDevice->fExpectedPacketSize[type] 124 = HCI_EVENT_HDR_SIZE + headerPacket->elen; 125 126 if (count >= bluetoothDevice->fExpectedPacketSize[type]) { 127 // the whole packet is here so it can be already posted. 128 flowf("EVENT posted in HCI!!!\n"); 129 btCoreData->PostEvent(bluetoothDevice, data, 130 bluetoothDevice->fExpectedPacketSize[type]); 131 132 } else { 133 nbuf = gBufferModule->create( 134 bluetoothDevice->fExpectedPacketSize[type]); 135 bluetoothDevice->fBuffersRx[type] = nbuf; 136 137 nbuf->protocol = type; 138 } 139 140 } else { 141 panic("EVENT frame corrupted\n"); 142 return EILSEQ; 143 } 144 break; 145 146 case BT_ACL: 147 if (count >= HCI_ACL_HDR_SIZE) { 148 struct hci_acl_header* headerPkt = (struct hci_acl_header*)data; 149 150 bluetoothDevice->fExpectedPacketSize[type] = HCI_ACL_HDR_SIZE 151 + B_LENDIAN_TO_HOST_INT16(headerPkt->alen); 152 153 // Create the buffer -> TODO: this allocation can fail 154 nbuf = gBufferModule->create( 155 bluetoothDevice->fExpectedPacketSize[type]); 156 bluetoothDevice->fBuffersRx[type] = nbuf; 157 158 nbuf->protocol = type; 159 } else { 160 panic("ACL frame corrupted\n"); 161 return EILSEQ; 162 } 163 break; 164 165 case BT_SCO: 166 167 break; 168 169 default: 170 panic("unknown packet type in assembly"); 171 break; 172 } 173 174 currentPacketLen = bluetoothDevice->fExpectedPacketSize[type]; 175 176 } else { 177 // Continuation of a packet 178 currentPacketLen = bluetoothDevice->fExpectedPacketSize[type] - nbuf->size; 179 } 180 if (nbuf != NULL) { 181 currentPacketLen = min_c(currentPacketLen, count); 182 183 gBufferModule->append(nbuf, data, currentPacketLen); 184 185 if ((bluetoothDevice->fExpectedPacketSize[type] - nbuf->size) == 0) { 186 187 switch (nbuf->protocol) { 188 case BT_EVENT: 189 panic("need to send full buffer to btdatacore!\n"); 190 btCoreData->PostEvent(bluetoothDevice, data, 191 bluetoothDevice->fExpectedPacketSize[type]); 192 193 break; 194 case BT_ACL: 195 // TODO: device descriptor has been fetched better not 196 // pass id again 197 flowf("ACL parsed in ACL!\n"); 198 AclAssembly(nbuf, bluetoothDevice->index); 199 break; 200 default: 201 202 break; 203 } 204 205 bluetoothDevice->fBuffersRx[type] = nbuf = NULL; 206 bluetoothDevice->fExpectedPacketSize[type] = 0; 207 } else { 208 #if DEBUG_ACL 209 if (type == BT_ACL) 210 debugf("ACL Packet not filled size=%ld expected=%ld\n", 211 nbuf->size, bluetoothDevice->fExpectedPacketSize[type]); 212 #endif 213 } 214 215 } 216 // in case in the pipe there is info about the next buffer 217 count -= currentPacketLen; 218 data = (void*)((uint8*)data + currentPacketLen); 219 } 220 221 return B_OK; 222 } 223 224 225 status_t 226 HciPacketHandler(void* data, int32 code, size_t size) 227 { 228 hci_id deviceId = Bluetooth::CodeHandler::Device(code); 229 230 bluetooth_device* bluetoothDevice = FindDeviceByID(deviceId); 231 232 debugf("to assemble %ld bytes of %ld\n", size, deviceId); 233 234 if (bluetoothDevice != NULL) 235 return Assemble(bluetoothDevice, Bluetooth::CodeHandler::Protocol(code), 236 data, size); 237 else { 238 debugf("Device %ld could not be matched\n", deviceId); 239 } 240 241 return B_ERROR; 242 } 243 244 245 // #pragma mark - 246 247 248 status_t 249 RegisterDriver(bt_hci_transport_hooks* hooks, bluetooth_device** _device) 250 { 251 252 bluetooth_device* device = new (std::nothrow) bluetooth_device; 253 if (device == NULL) 254 return B_NO_MEMORY; 255 256 for (int index = 0; index < HCI_NUM_PACKET_TYPES; index++) { 257 device->fBuffersRx[index] = NULL; 258 device->fExpectedPacketSize[index] = 0; 259 } 260 261 device->info = NULL; // not yet used 262 device->hooks = hooks; 263 device->supportedPacketTypes = (HCI_DM1 | HCI_DH1 | HCI_HV1); 264 device->linkMode = (HCI_LM_ACCEPT); 265 device->mtu = L2CAP_MTU_MINIMUM; // TODO: ensure specs min value 266 267 MutexLocker _(&sListLock); 268 269 if (sDeviceList.IsEmpty()) 270 device->index = HCI_DEVICE_INDEX_OFFSET; // REVIEW: dev index 271 else 272 device->index = (sDeviceList.Tail())->index + 1; // REVIEW! 273 flowf("List not empty\n"); 274 275 sDeviceList.Add(device); 276 277 debugf("Device %lx\n", device->index ); 278 279 *_device = device; 280 281 return B_OK; 282 } 283 284 285 status_t 286 UnregisterDriver(hci_id id) 287 { 288 bluetooth_device* device = FindDeviceByID(id); 289 290 if (device == NULL) 291 return B_ERROR; 292 293 if (device->GetDoublyLinkedListLink()->next != NULL 294 || device->GetDoublyLinkedListLink()->previous != NULL 295 || device == sDeviceList.Head()) 296 sDeviceList.Remove(device); 297 298 delete device; 299 300 return B_OK; 301 } 302 303 304 // PostACL 305 status_t 306 PostACL(hci_id hciId, net_buffer* buffer) 307 { 308 net_buffer* curr_frame = NULL; 309 net_buffer* next_frame = buffer; 310 uint8 flag = HCI_ACL_PACKET_START; 311 312 if (buffer == NULL) 313 panic("passing null buffer"); 314 315 uint16 handle = buffer->type; // TODO: CodeHandler 316 317 bluetooth_device* device = FindDeviceByID(hciId); 318 319 if (device == NULL) { 320 debugf("No device %lx", hciId); 321 return B_ERROR; 322 } 323 324 debugf("index %lx try to send bt packet of %lu bytes (flags %ld):\n", 325 device->index, buffer->size, buffer->flags); 326 327 // TODO: ATOMIC! any other thread should stop here 328 do { 329 // Divide packet if big enough 330 curr_frame = next_frame; 331 332 if (curr_frame->size > device->mtu) { 333 next_frame = gBufferModule->split(curr_frame, device->mtu); 334 } else { 335 next_frame = NULL; 336 } 337 338 // Attach acl header 339 { 340 NetBufferPrepend<struct hci_acl_header> bufferHeader(curr_frame); 341 status_t status = bufferHeader.Status(); 342 if (status < B_OK) { 343 // free the buffer 344 continue; 345 } 346 347 bufferHeader->handle = pack_acl_handle_flags(handle, flag, 0); 348 bufferHeader->alen = curr_frame->size - sizeof(struct hci_acl_header); 349 } 350 351 // Send to driver 352 curr_frame->protocol = BT_ACL; 353 354 debugf("Tolower nbuf %p!\n", curr_frame); 355 // We could pass a cookie and avoid the driver fetch the Id 356 device->hooks->SendACL(device->index, curr_frame); 357 flag = HCI_ACL_PACKET_FRAGMENT; 358 359 } while (next_frame != NULL); 360 361 return B_OK; 362 } 363 364 365 status_t 366 PostSCO(hci_id hciId, net_buffer* buffer) 367 { 368 return B_ERROR; 369 } 370 371 372 status_t 373 PostESCO(hci_id hciId, net_buffer* buffer) 374 { 375 return B_ERROR; 376 } 377 378 379 static int 380 dump_bluetooth_devices(int argc, char** argv) 381 { 382 bluetooth_device* device; 383 384 DoublyLinkedList<bluetooth_device>::Iterator iterator 385 = sDeviceList.GetIterator(); 386 387 while (iterator.HasNext()) { 388 device = iterator.Next(); 389 kprintf("\tindex=%#lx @%p hooks=%p\n",device->index, device, device->hooks); 390 } 391 392 return 0; 393 } 394 395 396 static status_t 397 bluetooth_std_ops(int32 op, ...) 398 { 399 400 flowf("\n"); 401 402 switch (op) { 403 case B_MODULE_INIT: 404 { 405 status_t status; 406 407 status = get_module(NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule); 408 if (status < B_OK) { 409 panic("no way Dude we need that!"); 410 return status; 411 } 412 413 status = get_module(BT_CORE_DATA_MODULE_NAME,(module_info**)&btCoreData); 414 if (status < B_OK) { 415 flowf("problem getting datacore\n"); 416 return status; 417 } 418 419 new (&sDeviceList) DoublyLinkedList<bluetooth_device>; 420 // static C++ objects are not initialized in the module startup 421 422 BluetoothRXPort = new BluetoothRawDataPort(BT_RX_PORT_NAME, 423 (BluetoothRawDataPort::port_listener_func)&HciPacketHandler); 424 425 if (BluetoothRXPort->Launch() != B_OK) { 426 flowf("RX thread creation failed!\n"); 427 // we Cannot do much here ... avoid registering 428 } else { 429 flowf("RX thread launched!\n"); 430 } 431 432 sLinkChangeSemaphore = create_sem(0, "bt sem"); 433 if (sLinkChangeSemaphore < B_OK) { 434 put_module(NET_STACK_MODULE_NAME); 435 flowf("sem failed\n"); 436 return sLinkChangeSemaphore; 437 } 438 439 mutex_init(&sListLock, "bluetooth devices"); 440 441 // status = InitializeAclConnectionThread(); 442 debugf("Connection Thread error=%lx\n", status); 443 444 add_debugger_command("btLocalDevices", &dump_bluetooth_devices, 445 "Lists Bluetooth LocalDevices registered in the Stack"); 446 447 return B_OK; 448 } 449 450 case B_MODULE_UNINIT: 451 { 452 delete_sem(sLinkChangeSemaphore); 453 454 mutex_destroy(&sListLock); 455 put_module(NET_BUFFER_MODULE_NAME); 456 put_module(NET_STACK_MODULE_NAME); 457 put_module(BT_CORE_DATA_MODULE_NAME); 458 remove_debugger_command("btLocalDevices", &dump_bluetooth_devices); 459 // status_t status = QuitAclConnectionThread(); 460 461 return B_OK; 462 } 463 464 default: 465 return B_ERROR; 466 } 467 } 468 469 470 bt_hci_module_info sBluetoothModule = { 471 { 472 BT_HCI_MODULE_NAME, 473 B_KEEP_LOADED, 474 bluetooth_std_ops 475 }, 476 RegisterDriver, 477 UnregisterDriver, 478 FindDeviceByID, 479 PostTransportPacket, 480 PostACL, 481 PostSCO, 482 PostESCO 483 }; 484 485 486 module_info* modules[] = { 487 (module_info*)&sBluetoothModule, 488 NULL 489 }; 490 491