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 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 flowf("EVENT posted in HCI!!!\n"); 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 flowf("ACL parsed in ACL!\n"); 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 DEBUG_ACL 200 if (type == BT_ACL) 201 debugf("ACL Packet not filled size=%ld expected=%ld\n", 202 nbuf->size, bluetoothDevice->fExpectedPacketSize[type]); 203 #endif 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 debugf("to assemble %ld bytes of %ld\n", size, deviceId); 224 225 if (bluetoothDevice != NULL) 226 return Assemble(bluetoothDevice, Bluetooth::CodeHandler::Protocol(code), 227 data, size); 228 else { 229 debugf("Device %ld could not be matched\n", deviceId); 230 } 231 232 return B_ERROR; 233 } 234 235 236 // #pragma mark - 237 238 239 status_t 240 RegisterDriver(bt_hci_transport_hooks* hooks, bluetooth_device** _device) 241 { 242 243 bluetooth_device* device = new (std::nothrow) bluetooth_device; 244 if (device == NULL) 245 return B_NO_MEMORY; 246 247 for (int index = 0; index < HCI_NUM_PACKET_TYPES; index++) { 248 device->fBuffersRx[index] = NULL; 249 device->fExpectedPacketSize[index] = 0; 250 } 251 252 device->info = NULL; // not yet used 253 device->hooks = hooks; 254 device->supportedPacketTypes = (HCI_DM1 | HCI_DH1 | HCI_HV1); 255 device->linkMode = (HCI_LM_ACCEPT); 256 device->mtu = L2CAP_MTU_MINIMUM; // TODO: ensure specs min value 257 258 MutexLocker _(&sListLock); 259 260 if (sDeviceList.IsEmpty()) 261 device->index = HCI_DEVICE_INDEX_OFFSET; // REVIEW: dev index 262 else 263 device->index = (sDeviceList.Tail())->index + 1; // REVIEW! 264 flowf("List not empty\n"); 265 266 sDeviceList.Add(device); 267 268 debugf("Device %lx\n", device->index ); 269 270 *_device = device; 271 272 return B_OK; 273 } 274 275 276 status_t 277 UnregisterDriver(hci_id id) 278 { 279 bluetooth_device* device = FindDeviceByID(id); 280 281 if (device == NULL) 282 return B_ERROR; 283 284 if (device->GetDoublyLinkedListLink()->next != NULL 285 || device->GetDoublyLinkedListLink()->previous != NULL 286 || device == sDeviceList.Head()) 287 sDeviceList.Remove(device); 288 289 delete device; 290 291 return B_OK; 292 } 293 294 295 // PostACL 296 status_t 297 PostACL(hci_id hciId, net_buffer* buffer) 298 { 299 net_buffer* curr_frame = NULL; 300 net_buffer* next_frame = buffer; 301 uint8 flag = HCI_ACL_PACKET_START; 302 303 if (buffer == NULL) 304 panic("passing null buffer"); 305 306 uint16 handle = buffer->type; // TODO: CodeHandler 307 308 bluetooth_device* device = FindDeviceByID(hciId); 309 310 if (device == NULL) { 311 debugf("No device %lx", hciId); 312 return B_ERROR; 313 } 314 315 debugf("index %lx try to send bt packet of %lu bytes (flags %ld):\n", 316 device->index, buffer->size, buffer->flags); 317 318 // TODO: ATOMIC! any other thread should stop here 319 do { 320 // Divide packet if big enough 321 curr_frame = next_frame; 322 323 if (curr_frame->size > device->mtu) { 324 next_frame = gBufferModule->split(curr_frame, device->mtu); 325 } else { 326 next_frame = NULL; 327 } 328 329 // Attach acl header 330 { 331 NetBufferPrepend<struct hci_acl_header> bufferHeader(curr_frame); 332 status_t status = bufferHeader.Status(); 333 if (status < B_OK) { 334 // free the buffer 335 continue; 336 } 337 338 bufferHeader->handle = pack_acl_handle_flags(handle, flag, 0); 339 bufferHeader->alen = curr_frame->size - sizeof(struct hci_acl_header); 340 } 341 342 // Send to driver 343 curr_frame->protocol = BT_ACL; 344 345 debugf("Tolower nbuf %p!\n", curr_frame); 346 // We could pass a cookie and avoid the driver fetch the Id 347 device->hooks->SendACL(device->index, curr_frame); 348 flag = HCI_ACL_PACKET_FRAGMENT; 349 350 } while (next_frame != NULL); 351 352 return B_OK; 353 } 354 355 356 status_t 357 PostSCO(hci_id hciId, net_buffer* buffer) 358 { 359 return B_ERROR; 360 } 361 362 363 status_t 364 PostESCO(hci_id hciId, net_buffer* buffer) 365 { 366 return B_ERROR; 367 } 368 369 370 static int 371 dump_bluetooth_devices(int argc, char** argv) 372 { 373 bluetooth_device* device; 374 375 DoublyLinkedList<bluetooth_device>::Iterator iterator 376 = sDeviceList.GetIterator(); 377 378 while (iterator.HasNext()) { 379 device = iterator.Next(); 380 kprintf("\tindex=%#lx @%p hooks=%p\n",device->index, device, device->hooks); 381 } 382 383 return 0; 384 } 385 386 387 static status_t 388 bluetooth_std_ops(int32 op, ...) 389 { 390 391 flowf("\n"); 392 393 switch (op) { 394 case B_MODULE_INIT: 395 { 396 status_t status; 397 398 status = get_module(NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule); 399 if (status < B_OK) { 400 panic("no way Dude we need that!"); 401 return status; 402 } 403 404 status = get_module(BT_CORE_DATA_MODULE_NAME,(module_info**)&btCoreData); 405 if (status < B_OK) { 406 flowf("problem getting datacore\n"); 407 return status; 408 } 409 410 new (&sDeviceList) DoublyLinkedList<bluetooth_device>; 411 // static C++ objects are not initialized in the module startup 412 413 BluetoothRXPort = new BluetoothRawDataPort(BT_RX_PORT_NAME, 414 (BluetoothRawDataPort::port_listener_func)&HciPacketHandler); 415 416 if (BluetoothRXPort->Launch() != B_OK) { 417 flowf("RX thread creation failed!\n"); 418 // we Cannot do much here ... avoid registering 419 } else { 420 flowf("RX thread launched!\n"); 421 } 422 423 sLinkChangeSemaphore = create_sem(0, "bt sem"); 424 if (sLinkChangeSemaphore < B_OK) { 425 put_module(NET_STACK_MODULE_NAME); 426 flowf("sem failed\n"); 427 return sLinkChangeSemaphore; 428 } 429 430 mutex_init(&sListLock, "bluetooth devices"); 431 432 // status = InitializeAclConnectionThread(); 433 debugf("Connection Thread error=%lx\n", status); 434 435 add_debugger_command("btLocalDevices", &dump_bluetooth_devices, 436 "Lists Bluetooth LocalDevices registered in the Stack"); 437 438 return B_OK; 439 } 440 441 case B_MODULE_UNINIT: 442 { 443 delete_sem(sLinkChangeSemaphore); 444 445 mutex_destroy(&sListLock); 446 put_module(NET_BUFFER_MODULE_NAME); 447 put_module(NET_STACK_MODULE_NAME); 448 put_module(BT_CORE_DATA_MODULE_NAME); 449 remove_debugger_command("btLocalDevices", &dump_bluetooth_devices); 450 // status_t status = QuitAclConnectionThread(); 451 452 return B_OK; 453 } 454 455 default: 456 return B_ERROR; 457 } 458 } 459 460 461 bt_hci_module_info sBluetoothModule = { 462 { 463 BT_HCI_MODULE_NAME, 464 B_KEEP_LOADED, 465 bluetooth_std_ops 466 }, 467 RegisterDriver, 468 UnregisterDriver, 469 FindDeviceByID, 470 PostTransportPacket, 471 PostACL, 472 PostSCO, 473 PostESCO 474 }; 475 476 477 module_info* modules[] = { 478 (module_info*)&sBluetoothModule, 479 NULL 480 }; 481 482