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