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