1 /* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "hci_transport_h2_winusb.c" 39 40 /* 41 * hci_transport_usb.c 42 * 43 * HCI Transport API implementation for USB 44 * 45 * Created by Matthias Ringwald on 7/5/09. 46 */ 47 48 // Interface Number - Alternate Setting - suggested Endpoint Address - Endpoint Type - Suggested Max Packet Size 49 // HCI Commands 0 0 0x00 Control 8/16/32/64 50 // HCI Events 0 0 0x81 Interrupt (IN) 16 51 // ACL Data 0 0 0x82 Bulk (IN) 32/64 52 // ACL Data 0 0 0x02 Bulk (OUT) 32/64 53 // SCO Data 0 0 0x83 Isochronous (IN) 54 // SCO Data 0 0 0x03 Isochronous (Out) 55 56 #include <Windows.h> 57 58 #include <stdio.h> 59 #include <string.h> 60 #include <sys/types.h> 61 #include <inttypes.h> // to print long long int (aka 64 bit ints) 62 63 #include "btstack_config.h" 64 65 #include "btstack_debug.h" 66 #include "hci.h" 67 #include "hci_transport.h" 68 #include "hci_transport_usb.h" 69 70 #include <SetupAPI.h> 71 #include <Winusb.h> 72 73 #ifdef ENABLE_SCO_OVER_HCI 74 75 // Isochronous Add-On 76 77 // Function signatures frome https://abi-laboratory.pro/compatibility/Windows_7.0_to_Windows_8.1/x86_64/info/winusb.dll/symbols.html 78 // MSDN documentation has multiple errors (Jan 2017), annotated below 79 80 // As Isochochronous functions are provided by newer versions of ming64, we use a BTstack/BTSTACK prefix to prevent name collisions 81 82 typedef PVOID BTSTACK_WINUSB_ISOCH_BUFFER_HANDLE, *BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE; 83 84 typedef struct _BTSTACK_WINUSB_PIPE_INFORMATION_EX { 85 USBD_PIPE_TYPE PipeType; 86 UCHAR PipeId; 87 USHORT MaximumPacketSize; 88 UCHAR Interval; 89 ULONG MaximumBytesPerInterval; 90 } BTSTACK_WINUSB_PIPE_INFORMATION_EX, *BTSTACK_PWINUSB_PIPE_INFORMATION_EX; 91 92 typedef BOOL (WINAPI * BTstack_WinUsb_QueryPipeEx_t) ( 93 WINUSB_INTERFACE_HANDLE InterfaceHandle, 94 UCHAR AlternateInterfaceNumber, 95 UCHAR PipeIndex, 96 BTSTACK_PWINUSB_PIPE_INFORMATION_EX PipeInformationEx 97 ); 98 typedef BOOL (WINAPI * BTstack_WinUsb_RegisterIsochBuffer_t)( 99 WINUSB_INTERFACE_HANDLE InterfaceHandle, 100 UCHAR PipeID, 101 PVOID Buffer, 102 ULONG BufferLength, 103 BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle 104 ); 105 typedef BOOL (WINAPI * BTstack_WinUsb_ReadIsochPipe_t)( 106 BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle, 107 ULONG Offset, 108 ULONG Length, 109 PULONG FrameNumber, 110 ULONG NumberOfPackets, // MSDN lists PULONG 111 PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors, // MSDN lists PULONG 112 LPOVERLAPPED Overlapped 113 ); 114 typedef BOOL (WINAPI * BTstack_WinUsb_ReadIsochPipeAsap_t)( 115 BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle, 116 ULONG Offset, 117 ULONG Length, 118 BOOL ContinueStream, 119 ULONG NumberOfPackets, // MSDN lists PULONG 120 PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors, 121 LPOVERLAPPED Overlapped 122 ); 123 typedef BOOL (WINAPI * BTstack_WinUsb_WriteIsochPipe_t)( 124 BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle, 125 ULONG Offset, 126 ULONG Length, 127 PULONG FrameNumber, 128 LPOVERLAPPED Overlapped 129 ); 130 typedef BOOL (WINAPI * BTstack_WinUsb_WriteIsochPipeAsap_t)( 131 BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle, 132 ULONG Offset, 133 ULONG Length, 134 BOOL ContinueStream, 135 LPOVERLAPPED Overlapped 136 ); 137 typedef BOOL (WINAPI * BTstack_WinUsb_UnregisterIsochBuffer_t)( 138 BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle 139 ); 140 typedef BOOL (WINAPI * BTstack_WinUsb_GetCurrentFrameNumber_t)( 141 WINUSB_INTERFACE_HANDLE InterfaceHandle, // MSDN lists 'Device handle returned from CreateFile' 142 PULONG CurrentFrameNumber, 143 LARGE_INTEGER *TimeStamp 144 ); 145 146 static BTstack_WinUsb_QueryPipeEx_t BTstack_WinUsb_QueryPipeEx; 147 static BTstack_WinUsb_RegisterIsochBuffer_t BTstack_WinUsb_RegisterIsochBuffer; 148 static BTstack_WinUsb_ReadIsochPipe_t BTstack_WinUsb_ReadIsochPipe; 149 static BTstack_WinUsb_ReadIsochPipeAsap_t BTstack_WinUsb_ReadIsochPipeAsap; 150 static BTstack_WinUsb_WriteIsochPipe_t BTstack_WinUsb_WriteIsochPipe; 151 static BTstack_WinUsb_WriteIsochPipeAsap_t BTstack_WinUsb_WriteIsochPipeAsap; 152 static BTstack_WinUsb_UnregisterIsochBuffer_t BTstack_WinUsb_UnregisterIsochBuffer; 153 static BTstack_WinUsb_GetCurrentFrameNumber_t BTstack_WinUsb_GetCurrentFrameNumber; 154 #endif 155 156 // Doesn't work as expected 157 // #define SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 158 159 // Not tested yet 160 // #define SCHEDULE_SCO_OUT_TRANSFERS_MANUALLY 161 162 // 163 // Bluetooth USB Transport Alternate Settings: 164 // 165 // 0: No active voice channels (for USB compliance) 166 // 1: One 8 kHz voice channel with 8-bit encoding 167 // 2: Two 8 kHz voice channels with 8-bit encoding or one 8 kHz voice channel with 16-bit encoding 168 // 3: Three 8 kHz voice channels with 8-bit encoding 169 // 4: Two 8 kHz voice channels with 16-bit encoding or one 16 kHz voice channel with 16-bit encoding 170 // 5: Three 8 kHz voice channels with 16-bit encoding or one 8 kHz voice channel with 16-bit encoding and one 16 kHz voice channel with 16-bit encoding 171 // --> support only a single SCO connection 172 #define ALT_SETTING (1) 173 174 // alt setting for 1-3 connections and 8/16 bit 175 const int alt_setting_8_bit[] = {1,2,3}; 176 const int alt_setting_16_bit[] = {2,4,5}; 177 178 // for ALT_SETTING >= 1 and 8-bit channel, we need the following isochronous packets 179 // One complete SCO packet with 24 frames every 3 frames (== 3 ms) 180 #define NUM_ISO_PACKETS (3) 181 182 const uint16_t iso_packet_size_for_alt_setting[] = { 183 0, 184 9, 185 17, 186 25, 187 33, 188 49, 189 63, 190 }; 191 192 // 49 bytes is the max usb packet size for alternate setting 5 (Three 8 kHz 16-bit channels or one 8 kHz 16-bit channel and one 16 kHz 16-bit channel) 193 // note: alt setting 6 has max packet size of 63 every 7.5 ms = 472.5 bytes / HCI packet, while max SCO packet has 255 byte payload 194 #define SCO_PACKET_SIZE (49 * NUM_ISO_PACKETS) 195 196 #define ISOC_BUFFERS 8 197 198 // Outgoing SCO packet queue 199 // simplified ring buffer implementation 200 #define SCO_RING_BUFFER_COUNT (20) 201 #define SCO_RING_BUFFER_SIZE (SCO_RING_BUFFER_COUNT * SCO_PACKET_SIZE) 202 203 /** Request type bits of the "bmRequestType" field in control transfers. */ 204 enum usb_request_type { 205 USB_REQUEST_TYPE_STANDARD = (0x00 << 5), 206 USB_REQUEST_TYPE_CLASS = (0x01 << 5), 207 USB_REQUEST_TYPE_VENDOR = (0x02 << 5), 208 }; 209 210 /** Recipient bits of the "bmRequestType" field in control transfers. Values 4 through 31 are reserved. */ 211 enum usb_request_recipient { 212 USB_RECIPIENT_DEVICE = 0x00, 213 USB_RECIPIENT_INTERFACE = 0x01, 214 USB_RECIPIENT_ENDPOINT = 0x02, 215 USB_RECIPIENT_OTHER = 0x03, 216 }; 217 218 // This is the GUID for the USB device class 219 static GUID GUID_DEVINTERFACE_USB_DEVICE = 220 { 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }; 221 222 static void usb_dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size); 223 224 static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = &usb_dummy_handler; 225 226 // endpoint addresses 227 static int event_in_addr; 228 static int acl_in_addr; 229 static int acl_out_addr; 230 static int sco_in_addr; 231 static int sco_out_addr; 232 233 // 234 static HANDLE usb_device_handle; 235 static WINUSB_INTERFACE_HANDLE usb_interface_0_handle; 236 static WINUSB_INTERFACE_HANDLE usb_interface_1_handle; 237 static OVERLAPPED usb_overlapped_event_in; 238 static OVERLAPPED usb_overlapped_command_out; 239 static OVERLAPPED usb_overlapped_acl_in; 240 static OVERLAPPED usb_overlapped_acl_out; 241 static btstack_data_source_t usb_data_source_event_in; 242 static btstack_data_source_t usb_data_source_command_out; 243 static btstack_data_source_t usb_data_source_acl_in; 244 static btstack_data_source_t usb_data_source_acl_out; 245 246 // 247 static int usb_command_out_active; 248 static int usb_acl_out_active; 249 250 // buffer for HCI Events and ACL Packets 251 static uint8_t hci_event_in_buffer[2 + 255]; 252 static uint8_t hci_acl_in_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + HCI_ACL_BUFFER_SIZE]; 253 254 // transport interface state 255 static int usb_transport_open; 256 257 #ifdef ENABLE_SCO_OVER_HCI 258 259 typedef enum { 260 H2_W4_SCO_HEADER = 1, 261 H2_W4_PAYLOAD, 262 } H2_SCO_STATE; 263 264 // SCO Incoming Windows 265 static uint8_t hci_sco_in_buffer[ISOC_BUFFERS * SCO_PACKET_SIZE]; 266 static BTSTACK_WINUSB_ISOCH_BUFFER_HANDLE hci_sco_in_buffer_handle; 267 static USBD_ISO_PACKET_DESCRIPTOR hci_sco_packet_descriptors[ISOC_BUFFERS * NUM_ISO_PACKETS]; 268 static OVERLAPPED usb_overlapped_sco_in[ISOC_BUFFERS]; 269 static int usb_sco_in_expected_transfer; 270 271 // SCO Incoming Run Loop 272 static btstack_data_source_t usb_data_source_sco_in[ISOC_BUFFERS]; 273 274 // SCO Incoming HCI 275 static H2_SCO_STATE sco_state; 276 static uint8_t sco_buffer[SCO_PACKET_SIZE]; 277 static uint16_t sco_read_pos; 278 static uint16_t sco_bytes_to_read; 279 280 // SCO Outgoing Windows 281 static BTSTACK_WINUSB_ISOCH_BUFFER_HANDLE hci_sco_out_buffer_handle; 282 static OVERLAPPED usb_overlapped_sco_out[SCO_RING_BUFFER_COUNT]; 283 static int sco_ring_transfers_active; 284 static int usb_sco_out_expected_transfer; 285 286 #ifdef SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 287 // next tranfer 288 static ULONG sco_next_transfer_at_frame; 289 #endif 290 291 // SCO Outgoing Run Loop 292 static btstack_data_source_t usb_data_source_sco_out[SCO_RING_BUFFER_COUNT]; 293 294 // SCO Outgoing HCI 295 static uint8_t sco_ring_buffer[SCO_RING_BUFFER_SIZE]; 296 static int sco_ring_write; // packet idx 297 298 // SCO Reconfiguration - pause/resume 299 static uint16_t sco_voice_setting; 300 static int sco_num_connections; 301 static int sco_shutdown; 302 303 static uint16_t iso_packet_size; 304 #endif 305 306 // list of known devices, using VendorID/ProductID tuples 307 static const uint16_t known_bluetooth_devices[] = { 308 // BCM20702A0 - DeLOCK Bluetooth 4.0 309 0x0a5c, 0x21e8, 310 // BCM20702A0 - Asus BT400 311 0x0b05, 0x17cb, 312 // BCM20702B0 - Generic USB Detuned Class 1 @ 20 MHz 313 0x0a5c, 0x22be, 314 // nRF5x Zephyr USB HCI, e.g nRF52840-PCA10056 315 0x2fe3, 0x0100, 316 0x2fe3, 0x000b, 317 }; 318 319 static int num_known_devices = sizeof(known_bluetooth_devices) / sizeof(uint16_t) / 2; 320 321 // known devices 322 typedef struct { 323 btstack_linked_item_t next; 324 uint16_t vendor_id; 325 uint16_t product_id; 326 } usb_known_device_t; 327 328 static btstack_linked_list_t usb_knwon_devices; 329 330 void hci_transport_usb_add_device(uint16_t vendor_id, uint16_t product_id) { 331 usb_known_device_t * device = malloc(sizeof(usb_known_device_t)); 332 if (device != NULL) { 333 device->vendor_id = vendor_id; 334 device->product_id = product_id; 335 btstack_linked_list_add(&usb_knwon_devices, (btstack_linked_item_t *) device); 336 } 337 } 338 339 static bool usb_is_vmware_bluetooth_adapter(const char * device_path){ 340 // VMware Vendor ID 0e0f 341 const char * pos = strstr(device_path, "\\usb#vid_0e0f&pid"); 342 return (pos > 0); 343 } 344 345 static bool usb_device_path_match(const char * device_path, uint16_t vendor_id, uint16_t product_id){ 346 // construct pid/vid substring 347 char substring[20]; 348 sprintf_s(substring, sizeof(substring), "vid_%04x&pid_%04x", vendor_id, product_id); 349 const char * pos = strstr(device_path, substring); 350 log_info("check %s in %s -> %p", substring, device_path, pos); 351 return (pos > 0); 352 } 353 354 static bool usb_is_known_bluetooth_device(const char * device_path){ 355 int i; 356 for (i=0; i<num_known_devices; i++){ 357 if (usb_device_path_match( device_path, known_bluetooth_devices[i*2], known_bluetooth_devices[i*2+1])){ 358 return true; 359 } 360 } 361 btstack_linked_list_iterator_t it; 362 btstack_linked_list_iterator_init(&it, &usb_knwon_devices); 363 while (btstack_linked_list_iterator_has_next(&it)) { 364 usb_known_device_t * device = (usb_known_device_t *) btstack_linked_list_iterator_next(&it); 365 if (usb_device_path_match( device_path, device->vendor_id, device->product_id)){ 366 return true; 367 } 368 } 369 return false; 370 } 371 372 #ifdef ENABLE_SCO_OVER_HCI 373 static void sco_ring_init(void){ 374 sco_ring_write = 0; 375 sco_ring_transfers_active = 0; 376 } 377 static int sco_ring_have_space(void){ 378 return sco_ring_transfers_active < SCO_RING_BUFFER_COUNT; 379 } 380 static void usb_sco_register_buffers(void){ 381 BOOL result; 382 result = BTstack_WinUsb_RegisterIsochBuffer(usb_interface_1_handle, sco_in_addr, hci_sco_in_buffer, sizeof(hci_sco_in_buffer), &hci_sco_in_buffer_handle); 383 if (!result) { 384 log_error("usb_sco_register_buffers: register in buffer failed, error %lu", GetLastError()); 385 } 386 log_info("hci_sco_in_buffer_handle %p", hci_sco_in_buffer_handle); 387 388 result = BTstack_WinUsb_RegisterIsochBuffer(usb_interface_1_handle, sco_out_addr, sco_ring_buffer, sizeof(sco_ring_buffer), &hci_sco_out_buffer_handle); 389 if (!result) { 390 log_error("usb_sco_unregister_buffers: register out buffer failed, error %lu", GetLastError()); 391 } 392 log_info("hci_sco_out_buffer_handle %p", hci_sco_out_buffer_handle); 393 } 394 static void usb_sco_unregister_buffers(void){ 395 if (hci_sco_in_buffer_handle){ 396 BTstack_WinUsb_UnregisterIsochBuffer(hci_sco_in_buffer_handle); 397 hci_sco_in_buffer_handle = NULL; 398 } 399 if (hci_sco_out_buffer_handle){ 400 BTstack_WinUsb_UnregisterIsochBuffer(hci_sco_out_buffer_handle); 401 hci_sco_out_buffer_handle = NULL; 402 } 403 } 404 #endif 405 406 static void usb_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 407 log_info("registering packet handler"); 408 packet_handler = handler; 409 } 410 411 static void usb_dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ 412 } 413 414 static void usb_init(const void *transport_config){ 415 } 416 417 static void usb_free_resources(void){ 418 if (usb_interface_1_handle){ 419 WinUsb_Free(usb_interface_1_handle); 420 usb_interface_1_handle = NULL; 421 } 422 423 if (usb_interface_0_handle){ 424 WinUsb_Free(usb_interface_0_handle); 425 usb_interface_0_handle = NULL; 426 } 427 428 if (usb_device_handle) { 429 CloseHandle(usb_device_handle); 430 usb_device_handle = NULL; 431 } 432 433 #ifdef ENABLE_SCO_OVER_HCI 434 usb_sco_unregister_buffers(); 435 #endif 436 } 437 438 static void usb_submit_event_in_transfer(void){ 439 // submit transfer 440 BOOL result = WinUsb_ReadPipe(usb_interface_0_handle, event_in_addr, hci_event_in_buffer, sizeof(hci_event_in_buffer), NULL, &usb_overlapped_event_in); 441 if (!result) { 442 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 443 } 444 445 // IO_PENDING -> wait for completed 446 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_event_in, DATA_SOURCE_CALLBACK_READ); 447 return; 448 449 exit_on_error: 450 log_error("usb_submit_event_in_transfer: winusb last error %lu", GetLastError()); 451 } 452 453 static void usb_submit_acl_in_transfer(void){ 454 // submit transfer 455 BOOL result = WinUsb_ReadPipe(usb_interface_0_handle, acl_in_addr, hci_acl_in_buffer, sizeof(hci_acl_in_buffer), NULL, &usb_overlapped_acl_in); 456 if (!result) { 457 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 458 } 459 460 // IO_PENDING -> wait for completed 461 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_acl_in, DATA_SOURCE_CALLBACK_READ); 462 return; 463 464 exit_on_error: 465 log_error("usb_submit_acl_in_transfer: winusb last error %lu", GetLastError()); 466 } 467 468 #ifdef ENABLE_SCO_OVER_HCI 469 #ifdef SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 470 471 // frame number gets updated 472 static void usb_submit_sco_in_transfer_at_frame(int i, ULONG * frame_number){ 473 474 if (sco_shutdown){ 475 log_info("USB SCO Shutdown:: usb_submit_sco_in_transfer_at_frame called"); 476 return; 477 } 478 479 LARGE_INTEGER timestamp; 480 ULONG current_frame_number; 481 WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 482 483 ULONG frame_before = *frame_number; 484 485 BOOL result = BTstack_WinUsb_ReadIsochPipe(hci_sco_in_buffer_handle, i * SCO_PACKET_SIZE, iso_packet_size * NUM_ISO_PACKETS, 486 frame_number, NUM_ISO_PACKETS, &hci_sco_packet_descriptors[i * NUM_ISO_PACKETS], &usb_overlapped_sco_in[i]); 487 488 // log_info("BTstack_WinUsb_ReadIsochPipe #%02u: current %lu, planned %lu - buffer %lu", i, current_frame_number, frame_before, frame_before - current_frame_number); 489 490 if (!result) { 491 if (GetLastError() == ERROR_IO_PENDING) { 492 } else { 493 goto exit_on_error; 494 } 495 } 496 497 return; 498 499 exit_on_error: 500 log_error("usb_submit_sco_in_transfer: winusb last error %lu", GetLastError()); 501 } 502 503 #else 504 505 static void usb_submit_sco_in_transfer_asap(int i, int continue_stream){ 506 507 if (sco_shutdown){ 508 log_info("USB SCO Shutdown:: usb_submit_sco_in_transfer_at_frame called"); 509 return; 510 } 511 512 LARGE_INTEGER timestamp; 513 ULONG current_frame_number; 514 BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 515 516 // log_info("usb_submit_sco_in_transfer[%02u]: current frame %lu", i, current_frame_number); 517 518 BOOL result = BTstack_WinUsb_ReadIsochPipeAsap(hci_sco_in_buffer_handle, i * SCO_PACKET_SIZE, iso_packet_size * NUM_ISO_PACKETS, 519 continue_stream, NUM_ISO_PACKETS, &hci_sco_packet_descriptors[i * NUM_ISO_PACKETS], &usb_overlapped_sco_in[i]); 520 521 if (!result) { 522 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 523 } 524 525 return; 526 527 exit_on_error: 528 log_error("usb_submit_sco_in_transfer: winusb last error %lu", GetLastError()); 529 } 530 #endif 531 #endif 532 533 static void usb_process_event_in(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) { 534 535 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 536 537 DWORD bytes_read; 538 BOOL ok = WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_event_in, &bytes_read, FALSE); 539 if(!ok){ 540 DWORD err = GetLastError(); 541 if (err == ERROR_IO_INCOMPLETE){ 542 // IO_INCOMPLETE -> wait for completed 543 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 544 } else { 545 log_error("usb_process_event_in: error reading"); 546 } 547 return; 548 } 549 550 // notify uppper 551 packet_handler(HCI_EVENT_PACKET, hci_event_in_buffer, (uint16_t) bytes_read); 552 553 // re-submit transfer 554 usb_submit_event_in_transfer(); 555 } 556 557 static void usb_process_acl_in(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) { 558 559 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 560 561 DWORD bytes_read; 562 BOOL ok = WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_acl_in, &bytes_read, FALSE); 563 if(!ok){ 564 DWORD err = GetLastError(); 565 if (err == ERROR_IO_INCOMPLETE){ 566 // IO_INCOMPLETE -> wait for completed 567 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 568 } else { 569 log_error("usb_process_acl_in: error reading"); 570 571 // Reset Pipe 572 err = WinUsb_ResetPipe(usb_interface_0_handle, acl_in_addr); 573 log_info("WinUsb_ResetPipe: result %u", (int) err); 574 if (err){ 575 log_info("WinUsb_ResetPipe error %u", (int) GetLastError()); 576 } 577 578 // re-submit transfer 579 usb_submit_acl_in_transfer(); 580 } 581 return; 582 } 583 584 // notify uppper 585 packet_handler(HCI_ACL_DATA_PACKET, hci_acl_in_buffer, (uint16_t) bytes_read); 586 587 // re-submit transfer 588 usb_submit_acl_in_transfer(); 589 } 590 591 #ifdef ENABLE_SCO_OVER_HCI 592 static void sco_state_machine_init(void){ 593 sco_state = H2_W4_SCO_HEADER; 594 sco_read_pos = 0; 595 sco_bytes_to_read = 3; 596 } 597 598 static void sco_handle_data(uint8_t * buffer, uint16_t size){ 599 // printf("sco_handle_data: state %u, pos %u, to read %u, size %u", sco_state, sco_read_pos, sco_bytes_to_read, size); 600 while (size){ 601 if (size < sco_bytes_to_read){ 602 // just store incomplete data 603 memcpy(&sco_buffer[sco_read_pos], buffer, size); 604 sco_read_pos += size; 605 sco_bytes_to_read -= size; 606 return; 607 } 608 // copy requested data 609 memcpy(&sco_buffer[sco_read_pos], buffer, sco_bytes_to_read); 610 sco_read_pos += sco_bytes_to_read; 611 buffer += sco_bytes_to_read; 612 size -= sco_bytes_to_read; 613 614 // chunk read successfully, next action 615 switch (sco_state){ 616 case H2_W4_SCO_HEADER: 617 sco_state = H2_W4_PAYLOAD; 618 sco_bytes_to_read = sco_buffer[2]; 619 if (sco_bytes_to_read > (sizeof(sco_buffer)-3)){ 620 log_error("sco_handle_data: sco packet len > packet size"); 621 sco_state_machine_init(); 622 } 623 break; 624 case H2_W4_PAYLOAD: 625 // packet complete 626 packet_handler(HCI_SCO_DATA_PACKET, sco_buffer, sco_read_pos); 627 sco_state_machine_init(); 628 break; 629 default: 630 btstack_unreachable(); 631 break; 632 } 633 } 634 } 635 636 static void usb_process_sco_out(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 637 638 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE); 639 640 if (sco_shutdown){ 641 log_info("USB SCO Shutdown:: usb_process_sco_out called"); 642 return; 643 } 644 645 // get current frame number 646 ULONG current_frame_number; 647 LARGE_INTEGER timestamp; 648 BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 649 650 // find index 651 int transfer_index; 652 for (transfer_index=0;transfer_index<SCO_RING_BUFFER_COUNT;transfer_index++){ 653 if (ds == &usb_data_source_sco_out[transfer_index]) break; 654 } 655 656 // log_info("usb_process_sco_out[%02u] -- current frame %lu", transfer_index, current_frame_number); 657 658 DWORD bytes_transferred; 659 BOOL ok = WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_sco_out[transfer_index], &bytes_transferred, FALSE); 660 // log_info("usb_process_sco_out_done: #%u result %u, bytes %u, state %u", transfer_index, ok, (int) bytes_transferred, sco_state); 661 if(!ok){ 662 DWORD err = GetLastError(); 663 if (err == ERROR_IO_INCOMPLETE){ 664 // IO_INCOMPLETE -> wait for completed 665 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_out[transfer_index], DATA_SOURCE_CALLBACK_WRITE); 666 return; 667 } 668 log_error("usb_process_sco_out_done[%02u]: error writing %u, Internal %x", transfer_index, (int) err, (int) usb_overlapped_sco_out[transfer_index].Internal); 669 } 670 671 // decrease tab 672 sco_ring_transfers_active--; 673 674 // enable next data source callback 675 if (sco_ring_transfers_active){ 676 // update expected and wait for completion 677 usb_sco_out_expected_transfer = (transfer_index+ 1) % SCO_RING_BUFFER_COUNT; 678 // log_info("usb_process_sco_out_done[%02u]: wait for transfer %02u", transfer_index, usb_sco_out_expected_transfer); 679 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_out[usb_sco_out_expected_transfer], DATA_SOURCE_CALLBACK_WRITE); 680 } 681 682 // log_info("usb_process_sco_out_done: transfers active %u", sco_ring_transfers_active); 683 684 // mark free 685 if (sco_ring_have_space()) { 686 uint8_t event[] = { HCI_EVENT_SCO_CAN_SEND_NOW, 0}; 687 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 688 } 689 } 690 691 static void usb_process_sco_in(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 692 693 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 694 695 if (sco_shutdown){ 696 log_info("USB SCO Shutdown: usb_process_sco_out called"); 697 return; 698 } 699 700 // find index 701 int i; 702 for (i=0;i<ISOC_BUFFERS;i++){ 703 if (ds == &usb_data_source_sco_in[i]) break; 704 } 705 int transfer_index = i; 706 707 // ULONG current_frame_number; 708 // LARGE_INTEGER timestamp; 709 // BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 710 711 // log_info("usb_process_sco_in[%02u] -- current frame %lu", transfer_index, current_frame_number); 712 713 DWORD bytes_transferred; 714 BOOL ok = WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_sco_in[transfer_index], &bytes_transferred, FALSE); 715 716 if(!ok) { 717 DWORD err = GetLastError(); 718 if (err == ERROR_IO_INCOMPLETE) { 719 // IO_INCOMPLETE -> wait for completed 720 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 721 return; 722 } 723 log_error("usb_process_sco_in[%02u]: error reading %u, Internal %x", transfer_index, (int) err, (int) usb_overlapped_sco_out[i].Internal); 724 } 725 726 if (ok){ 727 for (i=0;i<NUM_ISO_PACKETS;i++){ 728 USBD_ISO_PACKET_DESCRIPTOR * packet_descriptor = &hci_sco_packet_descriptors[transfer_index * NUM_ISO_PACKETS + i]; 729 if (packet_descriptor->Length){ 730 uint8_t * iso_data = &hci_sco_in_buffer[transfer_index * SCO_PACKET_SIZE + packet_descriptor->Offset]; 731 uint16_t iso_len = (uint16_t) packet_descriptor->Length; 732 sco_handle_data(iso_data, iso_len); 733 } 734 } 735 } 736 737 #ifdef SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 738 usb_submit_sco_in_transfer_at_frame(i, &sco_next_transfer_at_frame); 739 #else 740 usb_submit_sco_in_transfer_asap(transfer_index, 1); 741 #endif 742 // update expected and wait for completion 743 usb_sco_in_expected_transfer = (transfer_index+ 1) % ISOC_BUFFERS; 744 745 // log_info("usb_process_sco_in[%02u]: enable data source %02u", transfer_index, usb_sco_in_expected_transfer); 746 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_in[usb_sco_in_expected_transfer], DATA_SOURCE_CALLBACK_READ); 747 } 748 #endif 749 750 static void usb_process_command_out(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 751 752 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE); 753 754 // update stata before submitting transfer 755 usb_command_out_active = 0; 756 757 // notify upper stack that provided buffer can be used again 758 uint8_t event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 759 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 760 } 761 762 static void usb_process_acl_out(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 763 764 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE); 765 766 // update stata before submitting transfer 767 usb_acl_out_active = 0; 768 769 // notify upper stack that provided buffer can be used again 770 uint8_t event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 771 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 772 } 773 774 static BOOL usb_scan_for_bluetooth_endpoints(void) { 775 int i; 776 USB_INTERFACE_DESCRIPTOR usb_interface_descriptor; 777 778 // reset 779 event_in_addr = 0; 780 acl_in_addr = 0; 781 acl_out_addr = 0; 782 783 log_info("Scanning USB Entpoints:"); 784 785 // look for Event and ACL pipes on Interface #0 786 BOOL result = WinUsb_QueryInterfaceSettings(usb_interface_0_handle, 0, &usb_interface_descriptor); 787 if (!result) goto exit_on_error; 788 for (i=0;i<usb_interface_descriptor.bNumEndpoints;i++){ 789 WINUSB_PIPE_INFORMATION pipe; 790 result = WinUsb_QueryPipe( 791 usb_interface_0_handle, 792 0, 793 (UCHAR) i, 794 &pipe); 795 if (!result) goto exit_on_error; 796 log_info("Interface #0, Alt #0, Pipe idx #%u: type %u, id 0x%02x, max packet size %u,", 797 i, pipe.PipeType, pipe.PipeId, pipe.MaximumPacketSize); 798 switch (pipe.PipeType){ 799 case USB_ENDPOINT_TYPE_INTERRUPT: 800 if (event_in_addr) continue; 801 event_in_addr = pipe.PipeId; 802 log_info("-> using 0x%2.2X for HCI Events", event_in_addr); 803 break; 804 case USB_ENDPOINT_TYPE_BULK: 805 if (pipe.PipeId & 0x80) { 806 if (acl_in_addr) continue; 807 acl_in_addr = pipe.PipeId; 808 log_info("-> using 0x%2.2X for ACL Data In", acl_in_addr); 809 } else { 810 if (acl_out_addr) continue; 811 acl_out_addr = pipe.PipeId; 812 log_info("-> using 0x%2.2X for ACL Data Out", acl_out_addr); 813 } 814 break; 815 default: 816 break; 817 } 818 } 819 820 #ifdef ENABLE_SCO_OVER_HCI 821 sco_out_addr = 0; 822 sco_in_addr = 0; 823 824 // look for SCO pipes on Interface #1, Alt Setting 1 825 int alt_setting = 1; 826 result = WinUsb_QueryInterfaceSettings(usb_interface_1_handle, alt_setting, &usb_interface_descriptor); 827 if (!result) goto exit_on_error; 828 for (i=0;i<usb_interface_descriptor.bNumEndpoints;i++){ 829 BTSTACK_WINUSB_PIPE_INFORMATION_EX pipe; 830 result = BTstack_WinUsb_QueryPipeEx( 831 usb_interface_1_handle, 832 alt_setting, 833 (UCHAR) i, 834 &pipe); 835 if (!result) goto exit_on_error; 836 log_info("Interface #1, Alt #%u, Pipe idx #%u: type %u, id 0x%02x, max packet size %u, interval %u, max bytes per interval %u", 837 alt_setting, i, pipe.PipeType, pipe.PipeId, pipe.MaximumPacketSize, pipe.Interval, (int) pipe.MaximumBytesPerInterval); 838 switch (pipe.PipeType){ 839 case USB_ENDPOINT_TYPE_ISOCHRONOUS: 840 if (pipe.PipeId & 0x80) { 841 if (sco_in_addr) continue; 842 sco_in_addr = pipe.PipeId; 843 log_info("-> using 0x%2.2X for SCO Data In", sco_in_addr); 844 } else { 845 if (sco_out_addr) continue; 846 sco_out_addr = pipe.PipeId; 847 log_info("-> using 0x%2.2X for SCO Data Out", sco_out_addr); 848 } 849 break; 850 default: 851 break; 852 } 853 } 854 if (!sco_in_addr){ 855 log_error("Couldn't find pipe for SCO IN!"); 856 return FALSE; 857 } 858 if (!sco_out_addr){ 859 log_error("Couldn't find pipe for SCO IN!"); 860 return FALSE; 861 } 862 #endif 863 864 // check if all found 865 if (!event_in_addr){ 866 log_error("Couldn't find pipe for Event IN!"); 867 return FALSE; 868 } 869 if (!acl_in_addr){ 870 log_error("Couldn't find pipe for ACL IN!"); 871 return FALSE; 872 } 873 if (!acl_out_addr){ 874 log_error("Couldn't find pipe for ACL OUT!"); 875 return FALSE; 876 } 877 878 // all clear 879 return TRUE; 880 881 exit_on_error: 882 log_error("usb_scan_for_bluetooth_endpoints: last error %lu", GetLastError()); 883 return FALSE; 884 } 885 886 #ifdef ENABLE_SCO_OVER_HCI 887 888 static int usb_sco_start(void){ 889 printf("usb_sco_start\n"); 890 log_info("usb_sco_start"); 891 892 sco_shutdown = 0; 893 894 sco_state_machine_init(); 895 sco_ring_init(); 896 897 // calc alt setting 898 int alt_setting; 899 if (sco_voice_setting & 0x0020){ 900 // 16-bit PCM 901 alt_setting = alt_setting_16_bit[sco_num_connections-1]; 902 } else { 903 // 8-bit PCM or mSBC 904 alt_setting = alt_setting_8_bit[sco_num_connections-1]; 905 } 906 907 log_info("Switching to setting %u on interface 1..", alt_setting); 908 // WinUsb_SetCurrentAlternateSetting returns TRUE if the operation succeeds. 909 BOOL result = WinUsb_SetCurrentAlternateSetting(usb_interface_1_handle, alt_setting); 910 if (!result) goto exit_on_error; 911 912 // derive iso packet size from alt setting 913 iso_packet_size = iso_packet_size_for_alt_setting[alt_setting]; 914 915 // register isochronous buffer after setting alternate setting 916 usb_sco_register_buffers(); 917 918 #ifdef SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 919 // get current frame number 920 ULONG current_frame_number; 921 LARGE_INTEGER timestamp; 922 BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 923 // plan for next tranfer 924 sco_next_transfer_at_frame = current_frame_number + ISOC_BUFFERS * NUM_ISO_PACKETS; 925 #endif 926 927 int i; 928 for (i=0;i<ISOC_BUFFERS;i++){ 929 #ifdef SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 930 usb_submit_sco_in_transfer_at_frame(i, &sco_next_transfer_at_frame); 931 #else 932 usb_submit_sco_in_transfer_asap(i, 0); 933 #endif 934 } 935 936 usb_sco_in_expected_transfer = 0; 937 938 // only await first transfer to return 939 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_in[usb_sco_in_expected_transfer], DATA_SOURCE_CALLBACK_READ); 940 return 1; 941 942 exit_on_error: 943 log_error("usb_sco_start: last error %lu", GetLastError()); 944 usb_free_resources(); 945 return 0; 946 } 947 948 static void usb_sco_stop(void){ 949 printf("usb_sco_stop\n"); 950 log_info("usb_sco_stop"); 951 952 sco_shutdown = 1; 953 954 // abort SCO transfers 955 WinUsb_AbortPipe(usb_interface_0_handle, sco_in_addr); 956 WinUsb_AbortPipe(usb_interface_0_handle, sco_out_addr); 957 958 // unlock/free SCO buffers 959 usb_sco_unregister_buffers(); 960 961 int alt_setting = 0; 962 log_info("Switching to setting %u on interface 1..", alt_setting); 963 // WinUsb_SetCurrentAlternateSetting returns TRUE if the operation succeeds. 964 WinUsb_SetCurrentAlternateSetting(usb_interface_1_handle, alt_setting); 965 } 966 #endif 967 968 // returns 0 if successful, -1 otherwise 969 static int usb_try_open_device(const char * device_path){ 970 971 // open file 972 usb_device_handle = CreateFile(device_path, 973 GENERIC_WRITE | GENERIC_READ, 974 FILE_SHARE_WRITE | FILE_SHARE_READ, 975 NULL, 976 OPEN_EXISTING, 977 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 978 NULL); 979 log_info("Opening USB device: %p", usb_device_handle); 980 if (!usb_device_handle) goto exit_on_error; 981 982 // WinUsb_Initialize returns TRUE if the operation succeed 983 BOOL result = WinUsb_Initialize(usb_device_handle, &usb_interface_0_handle); 984 if (!result) goto exit_on_error; 985 986 // Detect USB Dongle based Class, Subclass, and Protocol 987 // The class code (bDeviceClass) is 0xE0 – Wireless Controller. 988 // The SubClass code (bDeviceSubClass) is 0x01 – RF Controller. 989 // The Protocol code (bDeviceProtocol) is 0x01 – Bluetooth programming. 990 USB_INTERFACE_DESCRIPTOR usb_interface_descriptor; 991 result = WinUsb_QueryInterfaceSettings(usb_interface_0_handle, 0, &usb_interface_descriptor); 992 if (!result) goto exit_on_error; 993 994 // ignore virtual Bluetooth adapter of VMware 995 if (usb_is_vmware_bluetooth_adapter(device_path)) { 996 log_info("Ignoring simulated VMware Bluetooth adapter"); 997 usb_free_resources(); 998 return -1; 999 } 1000 1001 // 1002 if (usb_interface_descriptor.bInterfaceClass != 0xe0 || 1003 usb_interface_descriptor.bInterfaceSubClass != 0x01 || 1004 usb_interface_descriptor.bInterfaceProtocol != 0x01){ 1005 1006 // check whitelist 1007 if (!usb_is_known_bluetooth_device(device_path)){ 1008 log_info("Class, Subclass, Protocol does not match Bluetooth device"); 1009 usb_free_resources(); 1010 return 0; 1011 } 1012 } 1013 1014 #ifdef ENABLE_SCO_OVER_HCI 1015 log_info("Claiming interface 1..."); 1016 // WinUsb_GetAssociatedInterface returns TRUE if the operation succeeds. 1017 // We use index 1 - assuming it refers to interface #1 with libusb 1018 // A value of 0 indicates the first associated interface, a value of 1 indicates the second associated interface, and so on. 1019 result = WinUsb_GetAssociatedInterface(usb_interface_0_handle, 0, &usb_interface_1_handle); 1020 if (!result) goto exit_on_error; 1021 log_info("Claiming interface 1: success"); 1022 #endif 1023 1024 result = usb_scan_for_bluetooth_endpoints(); 1025 if (!result) { 1026 log_error("Could not find all Bluetooth Endpoints!"); 1027 usb_free_resources(); 1028 return 0; 1029 } 1030 1031 #ifdef ENABLE_SCO_OVER_HCI 1032 int i; 1033 1034 memset(hci_sco_packet_descriptors, 0, sizeof(hci_sco_packet_descriptors)); 1035 log_info("Size of packet descriptors for SCO IN%u", (int) sizeof(hci_sco_packet_descriptors)); 1036 1037 // setup async io && btstack handler 1038 memset(&usb_overlapped_sco_in, 0, sizeof(usb_overlapped_sco_in)); 1039 for (i=0;i<ISOC_BUFFERS;i++){ 1040 usb_overlapped_sco_in[i].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1041 // log_info_hexdump(&usb_overlapped_sco_in[i], sizeof(OVERLAPPED)); 1042 // log_info("data source SCO in %u, handle %p", i, usb_overlapped_sco_in[i].hEvent); 1043 usb_data_source_sco_in[i].source.handle = usb_overlapped_sco_in[i].hEvent; 1044 btstack_run_loop_set_data_source_handler(&usb_data_source_sco_in[i], &usb_process_sco_in); 1045 btstack_run_loop_add_data_source(&usb_data_source_sco_in[i]); 1046 } 1047 1048 memset(&usb_overlapped_sco_out, 0, sizeof(usb_overlapped_sco_out)); 1049 for (i=0;i<SCO_RING_BUFFER_COUNT;i++){ 1050 usb_overlapped_sco_out[i].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1051 // log_info("data source SCO out %u, handle %p", i, usb_overlapped_sco_out[i].hEvent); 1052 usb_data_source_sco_out[i].source.handle = usb_overlapped_sco_out[i].hEvent; 1053 btstack_run_loop_set_data_source_handler(&usb_data_source_sco_out[i], &usb_process_sco_out); 1054 btstack_run_loop_add_data_source(&usb_data_source_sco_out[i]); 1055 } 1056 #endif 1057 1058 // setup async io 1059 memset(&usb_overlapped_event_in, 0, sizeof(usb_overlapped_event_in)); 1060 memset(&usb_overlapped_command_out, 0, sizeof(usb_overlapped_command_out)); 1061 memset(&usb_overlapped_acl_out, 0, sizeof(usb_overlapped_acl_out)); 1062 memset(&usb_overlapped_acl_in, 0, sizeof(usb_overlapped_acl_in)); 1063 usb_overlapped_event_in.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1064 usb_overlapped_command_out.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1065 usb_overlapped_acl_in.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1066 usb_overlapped_acl_out.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1067 1068 // setup btstack data soures 1069 usb_data_source_event_in.source.handle = usb_overlapped_event_in.hEvent; 1070 btstack_run_loop_set_data_source_handler(&usb_data_source_event_in, &usb_process_event_in); 1071 btstack_run_loop_add_data_source(&usb_data_source_event_in); 1072 1073 usb_data_source_command_out.source.handle = usb_overlapped_command_out.hEvent; 1074 btstack_run_loop_set_data_source_handler(&usb_data_source_command_out, &usb_process_command_out); 1075 btstack_run_loop_add_data_source(&usb_data_source_command_out); 1076 1077 usb_data_source_acl_in.source.handle = usb_overlapped_acl_in.hEvent; 1078 btstack_run_loop_set_data_source_handler(&usb_data_source_acl_in, &usb_process_acl_in); 1079 btstack_run_loop_add_data_source(&usb_data_source_acl_in); 1080 1081 usb_data_source_acl_out.source.handle = usb_overlapped_acl_out.hEvent; 1082 btstack_run_loop_set_data_source_handler(&usb_data_source_acl_out, &usb_process_acl_out); 1083 btstack_run_loop_add_data_source(&usb_data_source_acl_out); 1084 1085 // submit all incoming transfers 1086 usb_submit_event_in_transfer(); 1087 usb_submit_acl_in_transfer(); 1088 return 1; 1089 1090 exit_on_error: 1091 log_error("usb_try_open_device: last error %lu", GetLastError()); 1092 usb_free_resources(); 1093 return 0; 1094 } 1095 1096 #ifdef ENABLE_SCO_OVER_HCI 1097 1098 #define WinUSB_Lookup(fn) do { BTstack_##fn = (BTstack_##fn##_t) GetProcAddress(h, #fn); log_info("%-30s %p", #fn, BTstack_##fn); if (!BTstack_##fn) return FALSE; } while(0) 1099 1100 static BOOL usb_lookup_symbols(void){ 1101 // lookup runtime symbols missing in current mingw64 distribution 1102 HMODULE h = GetModuleHandleA("WinUSB"); 1103 log_info("%-30s %p", "WinUSB", h); 1104 WinUSB_Lookup(WinUsb_QueryPipeEx); 1105 WinUSB_Lookup(WinUsb_RegisterIsochBuffer); 1106 WinUSB_Lookup(WinUsb_ReadIsochPipe); 1107 WinUSB_Lookup(WinUsb_ReadIsochPipeAsap); 1108 WinUSB_Lookup(WinUsb_WriteIsochPipe); 1109 WinUSB_Lookup(WinUsb_WriteIsochPipeAsap); 1110 WinUSB_Lookup(WinUsb_UnregisterIsochBuffer); 1111 WinUSB_Lookup(WinUsb_GetCurrentFrameNumber); 1112 return TRUE; 1113 } 1114 #endif 1115 1116 // returns 0 on success, -1 otherwise 1117 static int usb_open(void){ 1118 1119 if (usb_transport_open) return 0; 1120 1121 int r = -1; 1122 1123 #ifdef ENABLE_SCO_OVER_HCI 1124 BOOL ok = usb_lookup_symbols(); 1125 if (!ok){ 1126 log_error("usb_open: Failed to lookup WinSUB ISOCHRONOUS functions. Please disable ENABLE_SCO_OVER_HCI or use Windows 8.1 or higher"); 1127 return r; 1128 } 1129 sco_state_machine_init(); 1130 sco_ring_init(); 1131 #endif 1132 1133 HDEVINFO hDevInfo; 1134 SP_DEVICE_INTERFACE_DATA DevIntfData; 1135 PSP_DEVICE_INTERFACE_DETAIL_DATA DevIntfDetailData; 1136 SP_DEVINFO_DATA DevData; 1137 1138 DWORD dwSize; 1139 DWORD dwMemberIdx; 1140 1141 // default endpoint addresses 1142 event_in_addr = 0x81; // EP1, IN interrupt 1143 acl_in_addr = 0x82; // EP2, IN bulk 1144 acl_out_addr = 0x02; // EP2, OUT bulk 1145 sco_in_addr = 0x83; // EP3, IN isochronous 1146 sco_out_addr = 0x03; // EP3, OUT isochronous 1147 1148 // We will try to get device information set for all USB devices that have a 1149 // device interface and are currently present on the system (plugged in). 1150 hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); 1151 1152 log_info("usb_open: SetupDiGetClassDevs -> %p", hDevInfo); 1153 if (hDevInfo == INVALID_HANDLE_VALUE) return -1; 1154 1155 // Prepare to enumerate all device interfaces for the device information 1156 // set that we retrieved with SetupDiGetClassDevs(..) 1157 DevIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); 1158 dwMemberIdx = 0; 1159 1160 // Next, we will keep calling this SetupDiEnumDeviceInterfaces(..) until this 1161 // function causes GetLastError() to return ERROR_NO_MORE_ITEMS. With each 1162 // call the dwMemberIdx value needs to be incremented to retrieve the next 1163 // device interface information. 1164 1165 SetupDiEnumDeviceInterfaces(hDevInfo, NULL, (LPGUID) &GUID_DEVINTERFACE_USB_DEVICE, 1166 dwMemberIdx, &DevIntfData); 1167 1168 while(GetLastError() != ERROR_NO_MORE_ITEMS){ 1169 1170 // As a last step we will need to get some more details for each 1171 // of device interface information we are able to retrieve. This 1172 // device interface detail gives us the information we need to identify 1173 // the device (VID/PID), and decide if it's useful to us. It will also 1174 // provide a DEVINFO_DATA structure which we can use to know the serial 1175 // port name for a virtual com port. 1176 1177 DevData.cbSize = sizeof(DevData); 1178 1179 // Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with 1180 // a NULL DevIntfDetailData pointer, a DevIntfDetailDataSize 1181 // of zero, and a valid RequiredSize variable. In response to such a call, 1182 // this function returns the required buffer size at dwSize. 1183 1184 SetupDiGetDeviceInterfaceDetail( 1185 hDevInfo, &DevIntfData, NULL, 0, &dwSize, NULL); 1186 1187 // Allocate memory for the DeviceInterfaceDetail struct. Don't forget to 1188 // deallocate it later! 1189 DevIntfDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); 1190 DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); 1191 1192 if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData, 1193 DevIntfDetailData, dwSize, &dwSize, &DevData)) 1194 { 1195 // Finally we can start checking if we've found a useable device, 1196 // by inspecting the DevIntfDetailData->DevicePath variable. 1197 // The DevicePath looks something like this: 1198 // 1199 // \\?\usb#vid_04d8&pid_0033#5&19f2438f&0&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed} 1200 // 1201 1202 log_info("usb_open: Device Path: %s", DevIntfDetailData->DevicePath); 1203 1204 #if 0 1205 // check for hard-coded vendor/product ids 1206 char vid_pid_match[30]; 1207 uint16_t vid = 0x0a12; 1208 uint16_t pid = 0x0001; 1209 sprintf(vid_pid_match, "\\\\?\\usb#vid_%04x&pid_%04x", vid, pid); 1210 if (strncmp(DevIntfDetailData->DevicePath, &vid_pid_match[0], strlen(vid_pid_match)) == 0 ){ 1211 log_info("Matched search string %s", vid_pid_match); 1212 1213 BOOL result = usb_try_open_device(DevIntfDetailData->DevicePath); 1214 if (result){ 1215 log_info("usb_open: Device opened, stop scanning"); 1216 r = 0; 1217 } else { 1218 log_error("usb_open: Device open failed"); 1219 } 1220 } 1221 #endif 1222 1223 // try all devices 1224 BOOL result = usb_try_open_device(DevIntfDetailData->DevicePath); 1225 if (result){ 1226 log_info("usb_open: Device opened, stop scanning"); 1227 r = 0; 1228 } else { 1229 log_error("usb_open: Device open failed"); 1230 } 1231 } 1232 HeapFree(GetProcessHeap(), 0, DevIntfDetailData); 1233 1234 if (r == 0) break; 1235 1236 // Continue looping 1237 SetupDiEnumDeviceInterfaces( 1238 hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, ++dwMemberIdx, &DevIntfData); 1239 } 1240 1241 SetupDiDestroyDeviceInfoList(hDevInfo); 1242 1243 log_info("usb_open: done, r = %x", r); 1244 1245 if (r == 0){ 1246 // opened 1247 usb_transport_open = 1; 1248 } 1249 1250 return r; 1251 } 1252 1253 static int usb_close(void){ 1254 1255 if (!usb_transport_open) return 0; 1256 1257 // remove data sources 1258 btstack_run_loop_remove_data_source(&usb_data_source_command_out); 1259 btstack_run_loop_remove_data_source(&usb_data_source_event_in); 1260 btstack_run_loop_remove_data_source(&usb_data_source_acl_in); 1261 btstack_run_loop_remove_data_source(&usb_data_source_acl_out); 1262 1263 #ifdef ENABLE_SCO_OVER_HCI 1264 int i; 1265 for (i=0;i<ISOC_BUFFERS;i++){ 1266 btstack_run_loop_remove_data_source(&usb_data_source_sco_in[i]); 1267 } 1268 for (i=0;i<SCO_RING_BUFFER_COUNT;i++){ 1269 btstack_run_loop_remove_data_source(&usb_data_source_sco_out[i]); 1270 } 1271 #endif 1272 1273 log_info("usb_close abort event and acl pipes"); 1274 1275 // stop transfers 1276 WinUsb_AbortPipe(usb_interface_0_handle, event_in_addr); 1277 WinUsb_AbortPipe(usb_interface_0_handle, acl_in_addr); 1278 WinUsb_AbortPipe(usb_interface_0_handle, acl_out_addr); 1279 #ifdef ENABLE_SCO_OVER_HCI 1280 usb_sco_stop(); 1281 #endif 1282 usb_acl_out_active = 0; 1283 1284 // control transfer cannot be stopped, just wait for completion 1285 if (usb_command_out_active){ 1286 log_info("usb_close command out active, wait for complete"); 1287 DWORD bytes_transferred; 1288 WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_command_out, &bytes_transferred, TRUE); 1289 usb_command_out_active = 0; 1290 } 1291 1292 log_info("usb_close free resources"); 1293 1294 // free everything 1295 usb_free_resources(); 1296 1297 // transport closed 1298 usb_transport_open = 0; 1299 1300 return 0; 1301 } 1302 1303 static int usb_can_send_packet_now(uint8_t packet_type){ 1304 // return 0; 1305 switch (packet_type){ 1306 case HCI_COMMAND_DATA_PACKET: 1307 return !usb_command_out_active; 1308 case HCI_ACL_DATA_PACKET: 1309 return !usb_acl_out_active; 1310 #ifdef ENABLE_SCO_OVER_HCI 1311 case HCI_SCO_DATA_PACKET: 1312 // return 0; 1313 return sco_ring_have_space(); 1314 #endif 1315 default: 1316 return 0; 1317 } 1318 } 1319 1320 static int usb_send_cmd_packet(uint8_t *packet, int size){ 1321 1322 // update stata before submitting transfer 1323 usb_command_out_active = 1; 1324 1325 // Start trasnsfer 1326 WINUSB_SETUP_PACKET setup_packet; 1327 memset(&setup_packet, 0, sizeof(setup_packet)); 1328 setup_packet.RequestType = USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE; 1329 setup_packet.Length = sizeof(size); 1330 BOOL result = WinUsb_ControlTransfer(usb_interface_0_handle, setup_packet, packet, size, NULL, &usb_overlapped_command_out); 1331 if (!result) { 1332 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 1333 } 1334 1335 // IO_PENDING -> wait for completed 1336 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_command_out, DATA_SOURCE_CALLBACK_WRITE); 1337 1338 return 0; 1339 1340 exit_on_error: 1341 log_error("winusb: last error %lu", GetLastError()); 1342 return -1; 1343 } 1344 1345 static int usb_send_acl_packet(uint8_t *packet, int size){ 1346 1347 // update stata before submitting transfer 1348 usb_acl_out_active = 1; 1349 1350 // Start trasnsfer 1351 BOOL ok = WinUsb_WritePipe(usb_interface_0_handle, acl_out_addr, packet, size, NULL, &usb_overlapped_acl_out); 1352 if (!ok) { 1353 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 1354 } 1355 1356 // IO_PENDING -> wait for completed 1357 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_acl_out, DATA_SOURCE_CALLBACK_WRITE); 1358 return 0; 1359 1360 exit_on_error: 1361 log_error("winusb: last error %lu", GetLastError()); 1362 return -1; 1363 } 1364 1365 #ifdef ENABLE_SCO_OVER_HCI 1366 static int usb_send_sco_packet(uint8_t *packet, int size){ 1367 1368 if (size > SCO_PACKET_SIZE){ 1369 log_error("usb_send_sco_packet: size %u > SCO_PACKET_SIZE %u", size, SCO_PACKET_SIZE); 1370 return -1; 1371 } 1372 1373 // get current frame number 1374 ULONG current_frame_number; 1375 LARGE_INTEGER timestamp; 1376 BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 1377 1378 // store packet in free slot 1379 int transfer_index = sco_ring_write; 1380 uint8_t * data = &sco_ring_buffer[transfer_index * SCO_PACKET_SIZE]; 1381 memcpy(data, packet, size); 1382 1383 1384 // setup transfer 1385 int continue_stream = sco_ring_transfers_active > 0; 1386 BOOL ok = BTstack_WinUsb_WriteIsochPipeAsap(hci_sco_out_buffer_handle, transfer_index * SCO_PACKET_SIZE, size, continue_stream, &usb_overlapped_sco_out[transfer_index]); 1387 // log_info("usb_send_sco_packet: using slot #%02u, current frame %lu, continue stream %u, ok %u", transfer_index, current_frame_number, continue_stream, ok); 1388 if (!ok) { 1389 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 1390 } 1391 1392 // successful started transfer, enable data source callback if first active transfer 1393 if (sco_ring_transfers_active == 0){ 1394 usb_sco_out_expected_transfer = transfer_index; 1395 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_out[transfer_index], DATA_SOURCE_CALLBACK_WRITE); 1396 } 1397 1398 // mark slot as full 1399 sco_ring_write = (sco_ring_write + 1) % SCO_RING_BUFFER_COUNT; 1400 sco_ring_transfers_active++; 1401 1402 // notify upper stack that provided buffer can be used again 1403 uint8_t event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 1404 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 1405 1406 // log_info("usb_send_sco_packet: transfers active %u", sco_ring_transfers_active); 1407 1408 // and if we have more space for SCO packets 1409 if (sco_ring_have_space()) { 1410 uint8_t event_sco[] = { HCI_EVENT_SCO_CAN_SEND_NOW, 0}; 1411 packet_handler(HCI_EVENT_PACKET, &event_sco[0], sizeof(event_sco)); 1412 } 1413 return 0; 1414 1415 exit_on_error: 1416 log_error("usb_send_sco_packet: last error %lu", GetLastError()); 1417 return -1; 1418 } 1419 #endif 1420 1421 static int usb_send_packet(uint8_t packet_type, uint8_t * packet, int size){ 1422 switch (packet_type){ 1423 case HCI_COMMAND_DATA_PACKET: 1424 return usb_send_cmd_packet(packet, size); 1425 case HCI_ACL_DATA_PACKET: 1426 return usb_send_acl_packet(packet, size); 1427 #ifdef ENABLE_SCO_OVER_HCI 1428 case HCI_SCO_DATA_PACKET: 1429 return usb_send_sco_packet(packet, size); 1430 #endif 1431 default: 1432 return -1; 1433 } 1434 } 1435 1436 #ifdef ENABLE_SCO_OVER_HCI 1437 static void usb_set_sco_config(uint16_t voice_setting, int num_connections){ 1438 log_info("usb_set_sco_config: voice settings 0x%04x, num connections %u", voice_setting, num_connections); 1439 1440 if (num_connections != sco_num_connections){ 1441 sco_voice_setting = voice_setting; 1442 if (sco_num_connections){ 1443 usb_sco_stop(); 1444 } 1445 sco_num_connections = num_connections; 1446 if (num_connections){ 1447 usb_sco_start(); 1448 } 1449 } 1450 } 1451 #endif 1452 1453 // get usb singleton 1454 static const hci_transport_t hci_transport_usb = { 1455 /* const char * name; */ "H2_WINUSB", 1456 /* void (*init) (const void *transport_config); */ &usb_init, 1457 /* int (*open)(void); */ &usb_open, 1458 /* int (*close)(void); */ &usb_close, 1459 /* void (*register_packet_handler)(void (*handler)(...); */ &usb_register_packet_handler, 1460 /* int (*can_send_packet_now)(uint8_t packet_type); */ &usb_can_send_packet_now, 1461 /* int (*send_packet)(...); */ &usb_send_packet, 1462 /* int (*set_baudrate)(uint32_t baudrate); */ NULL, 1463 /* void (*reset_link)(void); */ NULL, 1464 #ifdef ENABLE_SCO_OVER_HCI 1465 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ usb_set_sco_config, 1466 #else 1467 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL, 1468 #endif 1469 }; 1470 1471 const hci_transport_t * hci_transport_usb_instance(void) { 1472 return &hci_transport_usb; 1473 } 1474