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