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 MATTHIAS 24 * RINGWALD 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 <strings.h> 58 #include <string.h> 59 #include <unistd.h> /* UNIX standard function definitions */ 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 69 #include <Windows.h> 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 WINBOOL (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 WINBOOL (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 WINBOOL (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 WINBOOL (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 WINBOOL (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 WINBOOL (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 WINBOOL (WINAPI * BTstack_WinUsb_UnregisterIsochBuffer_t)( 138 BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle 139 ); 140 typedef WINBOOL (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 // DeLOCK Bluetooth 4.0 309 0x0a5c, 0x21e8, 310 // Asus BT400 311 0x0b05, 0x17cb, 312 // BCM20702B0 (Generic USB Detuned Class 1 @ 20 MHz) 313 0x0a5c, 0x22be, 314 }; 315 316 static int num_known_devices = sizeof(known_bluetooth_devices) / sizeof(uint16_t) / 2; 317 318 static int usb_is_known_bluetooth_device(const char * device_path){ 319 int i; 320 for (i=0; i<num_known_devices; i++){ 321 // construct pid/vid substring 322 char substring[20]; 323 sprintf(substring, "vid_%04x&pid_%04x", known_bluetooth_devices[i*2], known_bluetooth_devices[i*2+1]); 324 const char * pos = strstr(device_path, substring); 325 log_info("check %s in %s -> %p", substring, device_path, pos); 326 if (pos){ 327 return 1; 328 } 329 } 330 return 0; 331 } 332 333 static int usb_is_vmware_bluetooth_adapter(const char * device_path){ 334 // VMware Vendor ID 0e0f 335 const char * pos = strstr(device_path, "\\usb#vid_0e0f&pid"); 336 return pos ? 1 : 0; 337 } 338 339 #ifdef ENABLE_SCO_OVER_HCI 340 static void sco_ring_init(void){ 341 sco_ring_write = 0; 342 sco_ring_transfers_active = 0; 343 } 344 static int sco_ring_have_space(void){ 345 return sco_ring_transfers_active < SCO_RING_BUFFER_COUNT; 346 } 347 static void usb_sco_register_buffers(void){ 348 BOOL result; 349 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); 350 if (!result) { 351 log_error("usb_sco_register_buffers: register in buffer failed, error %lu", GetLastError()); 352 } 353 log_info("hci_sco_in_buffer_handle %p", hci_sco_in_buffer_handle); 354 355 result = BTstack_WinUsb_RegisterIsochBuffer(usb_interface_1_handle, sco_out_addr, sco_ring_buffer, sizeof(sco_ring_buffer), &hci_sco_out_buffer_handle); 356 if (!result) { 357 log_error("usb_sco_unregister_buffers: register out buffer failed, error %lu", GetLastError()); 358 } 359 log_info("hci_sco_out_buffer_handle %p", hci_sco_out_buffer_handle); 360 } 361 static void usb_sco_unregister_buffers(void){ 362 if (hci_sco_in_buffer_handle){ 363 BTstack_WinUsb_UnregisterIsochBuffer(hci_sco_in_buffer_handle); 364 hci_sco_in_buffer_handle = NULL; 365 } 366 if (hci_sco_out_buffer_handle){ 367 BTstack_WinUsb_UnregisterIsochBuffer(hci_sco_out_buffer_handle); 368 hci_sco_out_buffer_handle = NULL; 369 } 370 } 371 #endif 372 373 static void usb_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 374 log_info("registering packet handler"); 375 packet_handler = handler; 376 } 377 378 static void usb_dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ 379 } 380 381 static void usb_init(const void *transport_config){ 382 } 383 384 static void usb_free_resources(void){ 385 if (usb_interface_1_handle){ 386 WinUsb_Free(usb_interface_1_handle); 387 usb_interface_1_handle = NULL; 388 } 389 390 if (usb_interface_0_handle){ 391 WinUsb_Free(usb_interface_0_handle); 392 usb_interface_0_handle = NULL; 393 } 394 395 if (usb_device_handle) { 396 CloseHandle(usb_device_handle); 397 usb_device_handle = NULL; 398 } 399 400 #ifdef ENABLE_SCO_OVER_HCI 401 usb_sco_unregister_buffers(); 402 #endif 403 } 404 405 static void usb_submit_event_in_transfer(void){ 406 // submit transfer 407 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); 408 if (!result) { 409 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 410 } 411 412 // IO_PENDING -> wait for completed 413 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_event_in, DATA_SOURCE_CALLBACK_READ); 414 return; 415 416 exit_on_error: 417 log_error("usb_submit_event_in_transfer: winusb last error %lu", GetLastError()); 418 } 419 420 static void usb_submit_acl_in_transfer(void){ 421 // submit transfer 422 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); 423 if (!result) { 424 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 425 } 426 427 // IO_PENDING -> wait for completed 428 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_acl_in, DATA_SOURCE_CALLBACK_READ); 429 return; 430 431 exit_on_error: 432 log_error("usb_submit_acl_in_transfer: winusb last error %lu", GetLastError()); 433 } 434 435 #ifdef ENABLE_SCO_OVER_HCI 436 #ifdef SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 437 438 // frame number gets updated 439 static void usb_submit_sco_in_transfer_at_frame(int i, ULONG * frame_number){ 440 441 if (sco_shutdown){ 442 log_info("USB SCO Shutdown:: usb_submit_sco_in_transfer_at_frame called"); 443 return; 444 } 445 446 LARGE_INTEGER timestamp; 447 ULONG current_frame_number; 448 WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 449 450 ULONG frame_before = *frame_number; 451 452 BOOL result = BTstack_WinUsb_ReadIsochPipe(hci_sco_in_buffer_handle, i * SCO_PACKET_SIZE, iso_packet_size * NUM_ISO_PACKETS, 453 frame_number, NUM_ISO_PACKETS, &hci_sco_packet_descriptors[i * NUM_ISO_PACKETS], &usb_overlapped_sco_in[i]); 454 455 // log_info("BTstack_WinUsb_ReadIsochPipe #%02u: current %lu, planned %lu - buffer %lu", i, current_frame_number, frame_before, frame_before - current_frame_number); 456 457 if (!result) { 458 if (GetLastError() == ERROR_IO_PENDING) { 459 } else { 460 goto exit_on_error; 461 } 462 } 463 464 return; 465 466 exit_on_error: 467 log_error("usb_submit_sco_in_transfer: winusb last error %lu", GetLastError()); 468 } 469 470 #else 471 472 static void usb_submit_sco_in_transfer_asap(int i, int continue_stream){ 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 BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 482 483 // log_info("usb_submit_sco_in_transfer[%02u]: current frame %lu", i, current_frame_number); 484 485 BOOL result = BTstack_WinUsb_ReadIsochPipeAsap(hci_sco_in_buffer_handle, i * SCO_PACKET_SIZE, iso_packet_size * NUM_ISO_PACKETS, 486 continue_stream, NUM_ISO_PACKETS, &hci_sco_packet_descriptors[i * NUM_ISO_PACKETS], &usb_overlapped_sco_in[i]); 487 488 if (!result) { 489 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 490 } 491 492 return; 493 494 exit_on_error: 495 log_error("usb_submit_sco_in_transfer: winusb last error %lu", GetLastError()); 496 } 497 #endif 498 #endif 499 500 static void usb_process_event_in(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) { 501 502 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 503 504 DWORD bytes_read; 505 BOOL ok = WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_event_in, &bytes_read, FALSE); 506 if(!ok){ 507 DWORD err = GetLastError(); 508 if (err == ERROR_IO_INCOMPLETE){ 509 // IO_INCOMPLETE -> wait for completed 510 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 511 } else { 512 log_error("usb_process_event_in: error reading"); 513 } 514 return; 515 } 516 517 // notify uppper 518 packet_handler(HCI_EVENT_PACKET, hci_event_in_buffer, bytes_read); 519 520 // re-submit transfer 521 usb_submit_event_in_transfer(); 522 } 523 524 static void usb_process_acl_in(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) { 525 526 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 527 528 DWORD bytes_read; 529 BOOL ok = WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_acl_in, &bytes_read, FALSE); 530 if(!ok){ 531 DWORD err = GetLastError(); 532 if (err == ERROR_IO_INCOMPLETE){ 533 // IO_INCOMPLETE -> wait for completed 534 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 535 } else { 536 log_error("usb_process_acl_in: error reading"); 537 538 // Reset Pipe 539 err = WinUsb_ResetPipe(usb_interface_0_handle, acl_in_addr); 540 log_info("WinUsb_ResetPipe: result %u", (int) err); 541 if (err){ 542 log_info("WinUsb_ResetPipe error %u", (int) GetLastError()); 543 } 544 545 // re-submit transfer 546 usb_submit_acl_in_transfer(); 547 } 548 return; 549 } 550 551 // notify uppper 552 packet_handler(HCI_ACL_DATA_PACKET, hci_acl_in_buffer, bytes_read); 553 554 // re-submit transfer 555 usb_submit_acl_in_transfer(); 556 } 557 558 #ifdef ENABLE_SCO_OVER_HCI 559 static void sco_state_machine_init(void){ 560 sco_state = H2_W4_SCO_HEADER; 561 sco_read_pos = 0; 562 sco_bytes_to_read = 3; 563 } 564 565 static void sco_handle_data(uint8_t * buffer, uint16_t size){ 566 // printf("sco_handle_data: state %u, pos %u, to read %u, size %u", sco_state, sco_read_pos, sco_bytes_to_read, size); 567 while (size){ 568 if (size < sco_bytes_to_read){ 569 // just store incomplete data 570 memcpy(&sco_buffer[sco_read_pos], buffer, size); 571 sco_read_pos += size; 572 sco_bytes_to_read -= size; 573 return; 574 } 575 // copy requested data 576 memcpy(&sco_buffer[sco_read_pos], buffer, sco_bytes_to_read); 577 sco_read_pos += sco_bytes_to_read; 578 buffer += sco_bytes_to_read; 579 size -= sco_bytes_to_read; 580 581 // chunk read successfully, next action 582 switch (sco_state){ 583 case H2_W4_SCO_HEADER: 584 sco_state = H2_W4_PAYLOAD; 585 sco_bytes_to_read = sco_buffer[2]; 586 if (sco_bytes_to_read > (sizeof(sco_buffer)-3)){ 587 log_error("sco_handle_data: sco packet len > packet size"); 588 sco_state_machine_init(); 589 } 590 break; 591 case H2_W4_PAYLOAD: 592 // packet complete 593 packet_handler(HCI_SCO_DATA_PACKET, sco_buffer, sco_read_pos); 594 sco_state_machine_init(); 595 break; 596 } 597 } 598 } 599 600 static void usb_process_sco_out(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 601 602 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE); 603 604 if (sco_shutdown){ 605 log_info("USB SCO Shutdown:: usb_process_sco_out called"); 606 return; 607 } 608 609 // get current frame number 610 ULONG current_frame_number; 611 LARGE_INTEGER timestamp; 612 BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 613 614 // find index 615 int transfer_index; 616 for (transfer_index=0;transfer_index<SCO_RING_BUFFER_COUNT;transfer_index++){ 617 if (ds == &usb_data_source_sco_out[transfer_index]) break; 618 } 619 620 // log_info("usb_process_sco_out[%02u] -- current frame %lu", transfer_index, current_frame_number); 621 622 DWORD bytes_transferred; 623 BOOL ok = WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_sco_out[transfer_index], &bytes_transferred, FALSE); 624 // log_info("usb_process_sco_out_done: #%u result %u, bytes %u, state %u", transfer_index, ok, (int) bytes_transferred, sco_state); 625 if(!ok){ 626 DWORD err = GetLastError(); 627 if (err == ERROR_IO_INCOMPLETE){ 628 // IO_INCOMPLETE -> wait for completed 629 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_out[transfer_index], DATA_SOURCE_CALLBACK_WRITE); 630 return; 631 } 632 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); 633 } 634 635 // decrease tab 636 sco_ring_transfers_active--; 637 638 // enable next data source callback 639 if (sco_ring_transfers_active){ 640 // update expected and wait for completion 641 usb_sco_out_expected_transfer = (transfer_index+ 1) % SCO_RING_BUFFER_COUNT; 642 // log_info("usb_process_sco_out_done[%02u]: wait for transfer %02u", transfer_index, usb_sco_out_expected_transfer); 643 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_out[usb_sco_out_expected_transfer], DATA_SOURCE_CALLBACK_WRITE); 644 } 645 646 // log_info("usb_process_sco_out_done: transfers active %u", sco_ring_transfers_active); 647 648 // mark free 649 if (sco_ring_have_space()) { 650 uint8_t event[] = { HCI_EVENT_SCO_CAN_SEND_NOW, 0}; 651 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 652 } 653 } 654 655 static void usb_process_sco_in(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 656 657 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 658 659 if (sco_shutdown){ 660 log_info("USB SCO Shutdown: usb_process_sco_out called"); 661 return; 662 } 663 664 // find index 665 int i; 666 for (i=0;i<ISOC_BUFFERS;i++){ 667 if (ds == &usb_data_source_sco_in[i]) break; 668 } 669 int transfer_index = i; 670 671 // ULONG current_frame_number; 672 // LARGE_INTEGER timestamp; 673 // BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 674 675 // log_info("usb_process_sco_in[%02u] -- current frame %lu", transfer_index, current_frame_number); 676 677 DWORD bytes_transferred; 678 BOOL ok = WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_sco_in[transfer_index], &bytes_transferred, FALSE); 679 680 if(!ok) { 681 DWORD err = GetLastError(); 682 if (err == ERROR_IO_INCOMPLETE) { 683 // IO_INCOMPLETE -> wait for completed 684 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 685 return; 686 } 687 log_error("usb_process_sco_in[%02u]: error reading %u, Internal %x", transfer_index, (int) err, (int) usb_overlapped_sco_out[i].Internal); 688 } 689 690 if (ok){ 691 for (i=0;i<NUM_ISO_PACKETS;i++){ 692 USBD_ISO_PACKET_DESCRIPTOR * packet_descriptor = &hci_sco_packet_descriptors[transfer_index * NUM_ISO_PACKETS + i]; 693 if (packet_descriptor->Length){ 694 uint8_t * iso_data = &hci_sco_in_buffer[transfer_index * SCO_PACKET_SIZE + packet_descriptor->Offset]; 695 uint16_t iso_len = packet_descriptor->Length; 696 sco_handle_data(iso_data, iso_len); 697 } 698 } 699 } 700 701 #ifdef SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 702 usb_submit_sco_in_transfer_at_frame(i, &sco_next_transfer_at_frame); 703 #else 704 usb_submit_sco_in_transfer_asap(transfer_index, 1); 705 #endif 706 // update expected and wait for completion 707 usb_sco_in_expected_transfer = (transfer_index+ 1) % ISOC_BUFFERS; 708 709 // log_info("usb_process_sco_in[%02u]: enable data source %02u", transfer_index, usb_sco_in_expected_transfer); 710 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_in[usb_sco_in_expected_transfer], DATA_SOURCE_CALLBACK_READ); 711 } 712 #endif 713 714 static void usb_process_command_out(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 715 716 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE); 717 718 // update stata before submitting transfer 719 usb_command_out_active = 0; 720 721 // notify upper stack that provided buffer can be used again 722 uint8_t event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 723 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 724 } 725 726 static void usb_process_acl_out(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 727 728 btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE); 729 730 // update stata before submitting transfer 731 usb_acl_out_active = 0; 732 733 // notify upper stack that provided buffer can be used again 734 uint8_t event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 735 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 736 } 737 738 static BOOL usb_scan_for_bluetooth_endpoints(void) { 739 int i; 740 USB_INTERFACE_DESCRIPTOR usb_interface_descriptor; 741 742 // reset 743 event_in_addr = 0; 744 acl_in_addr = 0; 745 acl_out_addr = 0; 746 747 log_info("Scanning USB Entpoints:"); 748 749 // look for Event and ACL pipes on Interface #0 750 BOOL result = WinUsb_QueryInterfaceSettings(usb_interface_0_handle, 0, &usb_interface_descriptor); 751 if (!result) goto exit_on_error; 752 for (i=0;i<usb_interface_descriptor.bNumEndpoints;i++){ 753 WINUSB_PIPE_INFORMATION pipe; 754 result = WinUsb_QueryPipe( 755 usb_interface_0_handle, 756 0, 757 (UCHAR) i, 758 &pipe); 759 if (!result) goto exit_on_error; 760 log_info("Interface #0, Alt #0, Pipe idx #%u: type %u, id 0x%02x, max packet size %u,", 761 i, pipe.PipeType, pipe.PipeId, pipe.MaximumPacketSize); 762 switch (pipe.PipeType){ 763 case USB_ENDPOINT_TYPE_INTERRUPT: 764 if (event_in_addr) continue; 765 event_in_addr = pipe.PipeId; 766 log_info("-> using 0x%2.2X for HCI Events", event_in_addr); 767 break; 768 case USB_ENDPOINT_TYPE_BULK: 769 if (pipe.PipeId & 0x80) { 770 if (acl_in_addr) continue; 771 acl_in_addr = pipe.PipeId; 772 log_info("-> using 0x%2.2X for ACL Data In", acl_in_addr); 773 } else { 774 if (acl_out_addr) continue; 775 acl_out_addr = pipe.PipeId; 776 log_info("-> using 0x%2.2X for ACL Data Out", acl_out_addr); 777 } 778 break; 779 default: 780 break; 781 } 782 } 783 784 #ifdef ENABLE_SCO_OVER_HCI 785 sco_out_addr = 0; 786 sco_in_addr = 0; 787 788 // look for SCO pipes on Interface #1, Alt Setting 1 789 int alt_setting = 1; 790 result = WinUsb_QueryInterfaceSettings(usb_interface_1_handle, alt_setting, &usb_interface_descriptor); 791 if (!result) goto exit_on_error; 792 for (i=0;i<usb_interface_descriptor.bNumEndpoints;i++){ 793 BTSTACK_WINUSB_PIPE_INFORMATION_EX pipe; 794 result = BTstack_WinUsb_QueryPipeEx( 795 usb_interface_1_handle, 796 alt_setting, 797 (UCHAR) i, 798 &pipe); 799 if (!result) goto exit_on_error; 800 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", 801 alt_setting, i, pipe.PipeType, pipe.PipeId, pipe.MaximumPacketSize, pipe.Interval, (int) pipe.MaximumBytesPerInterval); 802 switch (pipe.PipeType){ 803 case USB_ENDPOINT_TYPE_ISOCHRONOUS: 804 if (pipe.PipeId & 0x80) { 805 if (sco_in_addr) continue; 806 sco_in_addr = pipe.PipeId; 807 log_info("-> using 0x%2.2X for SCO Data In", sco_in_addr); 808 } else { 809 if (sco_out_addr) continue; 810 sco_out_addr = pipe.PipeId; 811 log_info("-> using 0x%2.2X for SCO Data Out", sco_out_addr); 812 } 813 break; 814 default: 815 break; 816 } 817 } 818 if (!sco_in_addr){ 819 log_error("Couldn't find pipe for SCO IN!"); 820 return FALSE; 821 } 822 if (!sco_out_addr){ 823 log_error("Couldn't find pipe for SCO IN!"); 824 return FALSE; 825 } 826 #endif 827 828 // check if all found 829 if (!event_in_addr){ 830 log_error("Couldn't find pipe for Event IN!"); 831 return FALSE; 832 } 833 if (!acl_in_addr){ 834 log_error("Couldn't find pipe for ACL IN!"); 835 return FALSE; 836 } 837 if (!acl_out_addr){ 838 log_error("Couldn't find pipe for ACL OUT!"); 839 return FALSE; 840 } 841 842 // all clear 843 return TRUE; 844 845 exit_on_error: 846 log_error("usb_scan_for_bluetooth_endpoints: last error %lu", GetLastError()); 847 return FALSE; 848 } 849 850 #ifdef ENABLE_SCO_OVER_HCI 851 852 static int usb_sco_start(void){ 853 printf("usb_sco_start\n"); 854 log_info("usb_sco_start"); 855 856 sco_shutdown = 0; 857 858 sco_state_machine_init(); 859 sco_ring_init(); 860 861 // calc alt setting 862 int alt_setting; 863 if (sco_voice_setting & 0x0020){ 864 // 16-bit PCM 865 alt_setting = alt_setting_16_bit[sco_num_connections-1]; 866 } else { 867 // 8-bit PCM or mSBC 868 alt_setting = alt_setting_8_bit[sco_num_connections-1]; 869 } 870 871 log_info("Switching to setting %u on interface 1..", alt_setting); 872 // WinUsb_SetCurrentAlternateSetting returns TRUE if the operation succeeds. 873 BOOL result = WinUsb_SetCurrentAlternateSetting(usb_interface_1_handle, alt_setting); 874 if (!result) goto exit_on_error; 875 876 // derive iso packet size from alt setting 877 iso_packet_size = iso_packet_size_for_alt_setting[alt_setting]; 878 879 // register isochronous buffer after setting alternate setting 880 usb_sco_register_buffers(); 881 882 #ifdef SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 883 // get current frame number 884 ULONG current_frame_number; 885 LARGE_INTEGER timestamp; 886 BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 887 // plan for next tranfer 888 sco_next_transfer_at_frame = current_frame_number + ISOC_BUFFERS * NUM_ISO_PACKETS; 889 #endif 890 891 int i; 892 for (i=0;i<ISOC_BUFFERS;i++){ 893 #ifdef SCHEDULE_SCO_IN_TRANSFERS_MANUALLY 894 usb_submit_sco_in_transfer_at_frame(i, &sco_next_transfer_at_frame); 895 #else 896 usb_submit_sco_in_transfer_asap(i, 0); 897 #endif 898 } 899 900 usb_sco_in_expected_transfer = 0; 901 902 // only await first transfer to return 903 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_in[usb_sco_in_expected_transfer], DATA_SOURCE_CALLBACK_READ); 904 return 1; 905 906 exit_on_error: 907 log_error("usb_sco_start: last error %lu", GetLastError()); 908 usb_free_resources(); 909 return 0; 910 } 911 912 static void usb_sco_stop(void){ 913 printf("usb_sco_stop\n"); 914 log_info("usb_sco_stop"); 915 916 sco_shutdown = 1; 917 918 // abort SCO transfers 919 WinUsb_AbortPipe(usb_interface_0_handle, sco_in_addr); 920 WinUsb_AbortPipe(usb_interface_0_handle, sco_out_addr); 921 922 // unlock/free SCO buffers 923 usb_sco_unregister_buffers(); 924 925 int alt_setting = 0; 926 log_info("Switching to setting %u on interface 1..", alt_setting); 927 // WinUsb_SetCurrentAlternateSetting returns TRUE if the operation succeeds. 928 WinUsb_SetCurrentAlternateSetting(usb_interface_1_handle, alt_setting); 929 } 930 #endif 931 932 // returns 0 if successful, -1 otherwise 933 static int usb_try_open_device(const char * device_path){ 934 935 // open file 936 usb_device_handle = CreateFile(device_path, 937 GENERIC_WRITE | GENERIC_READ, 938 FILE_SHARE_WRITE | FILE_SHARE_READ, 939 NULL, 940 OPEN_EXISTING, 941 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 942 NULL); 943 log_info("Opening USB device: %p", usb_device_handle); 944 if (!usb_device_handle) goto exit_on_error; 945 946 // WinUsb_Initialize returns TRUE if the operation succeed 947 BOOL result = WinUsb_Initialize(usb_device_handle, &usb_interface_0_handle); 948 if (!result) goto exit_on_error; 949 950 // Detect USB Dongle based Class, Subclass, and Protocol 951 // The class code (bDeviceClass) is 0xE0 – Wireless Controller. 952 // The SubClass code (bDeviceSubClass) is 0x01 – RF Controller. 953 // The Protocol code (bDeviceProtocol) is 0x01 – Bluetooth programming. 954 USB_INTERFACE_DESCRIPTOR usb_interface_descriptor; 955 result = WinUsb_QueryInterfaceSettings(usb_interface_0_handle, 0, &usb_interface_descriptor); 956 if (!result) goto exit_on_error; 957 958 // ignore virtual Bluetooth adapter of VMware 959 if (usb_is_vmware_bluetooth_adapter(device_path)) { 960 log_info("Ignoring simulated VMware Bluetooth adapter"); 961 usb_free_resources(); 962 return -1; 963 } 964 965 // 966 if (usb_interface_descriptor.bInterfaceClass != 0xe0 || 967 usb_interface_descriptor.bInterfaceSubClass != 0x01 || 968 usb_interface_descriptor.bInterfaceProtocol != 0x01){ 969 970 // check whitelist 971 if (!usb_is_known_bluetooth_device(device_path)){ 972 log_info("Class, Subclass, Protocol does not match Bluetooth device"); 973 usb_free_resources(); 974 return 0; 975 } 976 } 977 978 #ifdef ENABLE_SCO_OVER_HCI 979 log_info("Claiming interface 1..."); 980 // WinUsb_GetAssociatedInterface returns TRUE if the operation succeeds. 981 // We use index 1 - assuming it refers to interface #1 with libusb 982 // A value of 0 indicates the first associated interface, a value of 1 indicates the second associated interface, and so on. 983 result = WinUsb_GetAssociatedInterface(usb_interface_0_handle, 0, &usb_interface_1_handle); 984 if (!result) goto exit_on_error; 985 log_info("Claiming interface 1: success"); 986 #endif 987 988 result = usb_scan_for_bluetooth_endpoints(); 989 if (!result) { 990 log_error("Could not find all Bluetooth Endpoints!"); 991 usb_free_resources(); 992 return 0; 993 } 994 995 #ifdef ENABLE_SCO_OVER_HCI 996 int i; 997 998 memset(hci_sco_packet_descriptors, 0, sizeof(hci_sco_packet_descriptors)); 999 log_info("Size of packet descriptors for SCO IN%u", (int) sizeof(hci_sco_packet_descriptors)); 1000 1001 // setup async io && btstack handler 1002 memset(&usb_overlapped_sco_in, 0, sizeof(usb_overlapped_sco_in)); 1003 for (i=0;i<ISOC_BUFFERS;i++){ 1004 usb_overlapped_sco_in[i].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1005 // log_info_hexdump(&usb_overlapped_sco_in[i], sizeof(OVERLAPPED)); 1006 // log_info("data source SCO in %u, handle %p", i, usb_overlapped_sco_in[i].hEvent); 1007 usb_data_source_sco_in[i].source.handle = usb_overlapped_sco_in[i].hEvent; 1008 btstack_run_loop_set_data_source_handler(&usb_data_source_sco_in[i], &usb_process_sco_in); 1009 btstack_run_loop_add_data_source(&usb_data_source_sco_in[i]); 1010 } 1011 1012 memset(&usb_overlapped_sco_out, 0, sizeof(usb_overlapped_sco_out)); 1013 for (i=0;i<SCO_RING_BUFFER_COUNT;i++){ 1014 usb_overlapped_sco_out[i].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1015 // log_info("data source SCO out %u, handle %p", i, usb_overlapped_sco_out[i].hEvent); 1016 usb_data_source_sco_out[i].source.handle = usb_overlapped_sco_out[i].hEvent; 1017 btstack_run_loop_set_data_source_handler(&usb_data_source_sco_out[i], &usb_process_sco_out); 1018 btstack_run_loop_add_data_source(&usb_data_source_sco_out[i]); 1019 } 1020 #endif 1021 1022 // setup async io 1023 memset(&usb_overlapped_event_in, 0, sizeof(usb_overlapped_event_in)); 1024 memset(&usb_overlapped_command_out, 0, sizeof(usb_overlapped_command_out)); 1025 memset(&usb_overlapped_acl_out, 0, sizeof(usb_overlapped_acl_out)); 1026 memset(&usb_overlapped_acl_in, 0, sizeof(usb_overlapped_acl_in)); 1027 usb_overlapped_event_in.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1028 usb_overlapped_command_out.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1029 usb_overlapped_acl_in.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1030 usb_overlapped_acl_out.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1031 1032 // setup btstack data soures 1033 usb_data_source_event_in.source.handle = usb_overlapped_event_in.hEvent; 1034 btstack_run_loop_set_data_source_handler(&usb_data_source_event_in, &usb_process_event_in); 1035 btstack_run_loop_add_data_source(&usb_data_source_event_in); 1036 1037 usb_data_source_command_out.source.handle = usb_overlapped_command_out.hEvent; 1038 btstack_run_loop_set_data_source_handler(&usb_data_source_command_out, &usb_process_command_out); 1039 btstack_run_loop_add_data_source(&usb_data_source_command_out); 1040 1041 usb_data_source_acl_in.source.handle = usb_overlapped_acl_in.hEvent; 1042 btstack_run_loop_set_data_source_handler(&usb_data_source_acl_in, &usb_process_acl_in); 1043 btstack_run_loop_add_data_source(&usb_data_source_acl_in); 1044 1045 usb_data_source_acl_out.source.handle = usb_overlapped_acl_out.hEvent; 1046 btstack_run_loop_set_data_source_handler(&usb_data_source_acl_out, &usb_process_acl_out); 1047 btstack_run_loop_add_data_source(&usb_data_source_acl_out); 1048 1049 // submit all incoming transfers 1050 usb_submit_event_in_transfer(); 1051 usb_submit_acl_in_transfer(); 1052 return 1; 1053 1054 exit_on_error: 1055 log_error("usb_try_open_device: last error %lu", GetLastError()); 1056 usb_free_resources(); 1057 return 0; 1058 } 1059 1060 #ifdef ENABLE_SCO_OVER_HCI 1061 1062 #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) 1063 1064 static BOOL usb_lookup_symbols(void){ 1065 // lookup runtime symbols missing in current mingw64 distribution 1066 HMODULE h = GetModuleHandleA("WinUSB"); 1067 log_info("%-30s %p", "WinUSB", h); 1068 WinUSB_Lookup(WinUsb_QueryPipeEx); 1069 WinUSB_Lookup(WinUsb_RegisterIsochBuffer); 1070 WinUSB_Lookup(WinUsb_ReadIsochPipe); 1071 WinUSB_Lookup(WinUsb_ReadIsochPipeAsap); 1072 WinUSB_Lookup(WinUsb_WriteIsochPipe); 1073 WinUSB_Lookup(WinUsb_WriteIsochPipeAsap); 1074 WinUSB_Lookup(WinUsb_UnregisterIsochBuffer); 1075 WinUSB_Lookup(WinUsb_GetCurrentFrameNumber); 1076 return TRUE; 1077 } 1078 #endif 1079 1080 // returns 0 on success, -1 otherwise 1081 static int usb_open(void){ 1082 1083 if (usb_transport_open) return 0; 1084 1085 int r = -1; 1086 1087 #ifdef ENABLE_SCO_OVER_HCI 1088 BOOL ok = usb_lookup_symbols(); 1089 if (!ok){ 1090 log_error("usb_open: Failed to lookup WinSUB ISOCHRONOUS functions. Please disable ENABLE_SCO_OVER_HCI or use Windows 8.1 or higher"); 1091 return r; 1092 } 1093 sco_state_machine_init(); 1094 sco_ring_init(); 1095 #endif 1096 1097 HDEVINFO hDevInfo; 1098 SP_DEVICE_INTERFACE_DATA DevIntfData; 1099 PSP_DEVICE_INTERFACE_DETAIL_DATA DevIntfDetailData; 1100 SP_DEVINFO_DATA DevData; 1101 1102 DWORD dwSize; 1103 DWORD dwMemberIdx; 1104 1105 // default endpoint addresses 1106 event_in_addr = 0x81; // EP1, IN interrupt 1107 acl_in_addr = 0x82; // EP2, IN bulk 1108 acl_out_addr = 0x02; // EP2, OUT bulk 1109 sco_in_addr = 0x83; // EP3, IN isochronous 1110 sco_out_addr = 0x03; // EP3, OUT isochronous 1111 1112 // We will try to get device information set for all USB devices that have a 1113 // device interface and are currently present on the system (plugged in). 1114 hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); 1115 1116 log_info("usb_open: SetupDiGetClassDevs -> %p", hDevInfo); 1117 if (hDevInfo == INVALID_HANDLE_VALUE) return -1; 1118 1119 // Prepare to enumerate all device interfaces for the device information 1120 // set that we retrieved with SetupDiGetClassDevs(..) 1121 DevIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); 1122 dwMemberIdx = 0; 1123 1124 // Next, we will keep calling this SetupDiEnumDeviceInterfaces(..) until this 1125 // function causes GetLastError() to return ERROR_NO_MORE_ITEMS. With each 1126 // call the dwMemberIdx value needs to be incremented to retrieve the next 1127 // device interface information. 1128 1129 SetupDiEnumDeviceInterfaces(hDevInfo, NULL, (LPGUID) &GUID_DEVINTERFACE_USB_DEVICE, 1130 dwMemberIdx, &DevIntfData); 1131 1132 while(GetLastError() != ERROR_NO_MORE_ITEMS){ 1133 1134 // As a last step we will need to get some more details for each 1135 // of device interface information we are able to retrieve. This 1136 // device interface detail gives us the information we need to identify 1137 // the device (VID/PID), and decide if it's useful to us. It will also 1138 // provide a DEVINFO_DATA structure which we can use to know the serial 1139 // port name for a virtual com port. 1140 1141 DevData.cbSize = sizeof(DevData); 1142 1143 // Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with 1144 // a NULL DevIntfDetailData pointer, a DevIntfDetailDataSize 1145 // of zero, and a valid RequiredSize variable. In response to such a call, 1146 // this function returns the required buffer size at dwSize. 1147 1148 SetupDiGetDeviceInterfaceDetail( 1149 hDevInfo, &DevIntfData, NULL, 0, &dwSize, NULL); 1150 1151 // Allocate memory for the DeviceInterfaceDetail struct. Don't forget to 1152 // deallocate it later! 1153 DevIntfDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); 1154 DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); 1155 1156 if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData, 1157 DevIntfDetailData, dwSize, &dwSize, &DevData)) 1158 { 1159 // Finally we can start checking if we've found a useable device, 1160 // by inspecting the DevIntfDetailData->DevicePath variable. 1161 // The DevicePath looks something like this: 1162 // 1163 // \\?\usb#vid_04d8&pid_0033#5&19f2438f&0&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed} 1164 // 1165 1166 log_info("usb_open: Device Path: %s", DevIntfDetailData->DevicePath); 1167 1168 #if 0 1169 // check for hard-coded vendor/product ids 1170 char vid_pid_match[30]; 1171 uint16_t vid = 0x0a12; 1172 uint16_t pid = 0x0001; 1173 sprintf(vid_pid_match, "\\\\?\\usb#vid_%04x&pid_%04x", vid, pid); 1174 if (strncmp(DevIntfDetailData->DevicePath, &vid_pid_match[0], strlen(vid_pid_match)) == 0 ){ 1175 log_info("Matched search string %s", vid_pid_match); 1176 1177 BOOL result = usb_try_open_device(DevIntfDetailData->DevicePath); 1178 if (result){ 1179 log_info("usb_open: Device opened, stop scanning"); 1180 r = 0; 1181 } else { 1182 log_error("usb_open: Device open failed"); 1183 } 1184 } 1185 #endif 1186 1187 // try all devices 1188 BOOL result = usb_try_open_device(DevIntfDetailData->DevicePath); 1189 if (result){ 1190 log_info("usb_open: Device opened, stop scanning"); 1191 r = 0; 1192 } else { 1193 log_error("usb_open: Device open failed"); 1194 } 1195 } 1196 HeapFree(GetProcessHeap(), 0, DevIntfDetailData); 1197 1198 if (r == 0) break; 1199 1200 // Continue looping 1201 SetupDiEnumDeviceInterfaces( 1202 hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, ++dwMemberIdx, &DevIntfData); 1203 } 1204 1205 SetupDiDestroyDeviceInfoList(hDevInfo); 1206 1207 log_info("usb_open: done, r = %x", r); 1208 1209 if (r == 0){ 1210 // opened 1211 usb_transport_open = 1; 1212 } 1213 1214 return r; 1215 } 1216 1217 static int usb_close(void){ 1218 1219 if (!usb_transport_open == 0) return 0; 1220 1221 // remove data sources 1222 btstack_run_loop_remove_data_source(&usb_data_source_command_out); 1223 btstack_run_loop_remove_data_source(&usb_data_source_event_in); 1224 btstack_run_loop_remove_data_source(&usb_data_source_acl_in); 1225 btstack_run_loop_remove_data_source(&usb_data_source_acl_out); 1226 1227 #ifdef ENABLE_SCO_OVER_HCI 1228 int i; 1229 for (i=0;i<ISOC_BUFFERS;i++){ 1230 btstack_run_loop_remove_data_source(&usb_data_source_sco_in[i]); 1231 } 1232 for (i=0;i<SCO_RING_BUFFER_COUNT;i++){ 1233 btstack_run_loop_remove_data_source(&usb_data_source_sco_out[i]); 1234 } 1235 #endif 1236 1237 log_info("usb_close abort event and acl pipes"); 1238 1239 // stop transfers 1240 WinUsb_AbortPipe(usb_interface_0_handle, event_in_addr); 1241 WinUsb_AbortPipe(usb_interface_0_handle, acl_in_addr); 1242 WinUsb_AbortPipe(usb_interface_0_handle, acl_out_addr); 1243 #ifdef ENABLE_SCO_OVER_HCI 1244 usb_sco_stop(); 1245 #endif 1246 usb_acl_out_active = 0; 1247 1248 // control transfer cannot be stopped, just wait for completion 1249 if (usb_command_out_active){ 1250 log_info("usb_close command out active, wait for complete"); 1251 DWORD bytes_transferred; 1252 WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_command_out, &bytes_transferred, TRUE); 1253 usb_command_out_active = 0; 1254 } 1255 1256 log_info("usb_close free resources"); 1257 1258 // free everything 1259 usb_free_resources(); 1260 1261 // transport closed 1262 usb_transport_open = 0; 1263 1264 return 0; 1265 } 1266 1267 static int usb_can_send_packet_now(uint8_t packet_type){ 1268 // return 0; 1269 switch (packet_type){ 1270 case HCI_COMMAND_DATA_PACKET: 1271 return !usb_command_out_active; 1272 case HCI_ACL_DATA_PACKET: 1273 return !usb_acl_out_active; 1274 #ifdef ENABLE_SCO_OVER_HCI 1275 case HCI_SCO_DATA_PACKET: 1276 // return 0; 1277 return sco_ring_have_space(); 1278 #endif 1279 default: 1280 return 0; 1281 } 1282 } 1283 1284 static int usb_send_cmd_packet(uint8_t *packet, int size){ 1285 1286 // update stata before submitting transfer 1287 usb_command_out_active = 1; 1288 1289 // Start trasnsfer 1290 WINUSB_SETUP_PACKET setup_packet; 1291 memset(&setup_packet, 0, sizeof(setup_packet)); 1292 setup_packet.RequestType = USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE; 1293 setup_packet.Length = sizeof(size); 1294 BOOL result = WinUsb_ControlTransfer(usb_interface_0_handle, setup_packet, packet, size, NULL, &usb_overlapped_command_out); 1295 if (!result) { 1296 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 1297 } 1298 1299 // IO_PENDING -> wait for completed 1300 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_command_out, DATA_SOURCE_CALLBACK_WRITE); 1301 1302 return 0; 1303 1304 exit_on_error: 1305 log_error("winusb: last error %lu", GetLastError()); 1306 return -1; 1307 } 1308 1309 static int usb_send_acl_packet(uint8_t *packet, int size){ 1310 1311 // update stata before submitting transfer 1312 usb_acl_out_active = 1; 1313 1314 // Start trasnsfer 1315 BOOL ok = WinUsb_WritePipe(usb_interface_0_handle, acl_out_addr, packet, size, NULL, &usb_overlapped_acl_out); 1316 if (!ok) { 1317 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 1318 } 1319 1320 // IO_PENDING -> wait for completed 1321 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_acl_out, DATA_SOURCE_CALLBACK_WRITE); 1322 return 0; 1323 1324 exit_on_error: 1325 log_error("winusb: last error %lu", GetLastError()); 1326 return -1; 1327 } 1328 1329 #ifdef ENABLE_SCO_OVER_HCI 1330 static int usb_send_sco_packet(uint8_t *packet, int size){ 1331 1332 if (size > SCO_PACKET_SIZE){ 1333 log_error("usb_send_sco_packet: size %u > SCO_PACKET_SIZE %u", size, SCO_PACKET_SIZE); 1334 return -1; 1335 } 1336 1337 // get current frame number 1338 ULONG current_frame_number; 1339 LARGE_INTEGER timestamp; 1340 BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp); 1341 1342 // store packet in free slot 1343 int transfer_index = sco_ring_write; 1344 uint8_t * data = &sco_ring_buffer[transfer_index * SCO_PACKET_SIZE]; 1345 memcpy(data, packet, size); 1346 1347 1348 // setup transfer 1349 int continue_stream = sco_ring_transfers_active > 0; 1350 BOOL ok = BTstack_WinUsb_WriteIsochPipeAsap(hci_sco_out_buffer_handle, transfer_index * SCO_PACKET_SIZE, size, continue_stream, &usb_overlapped_sco_out[transfer_index]); 1351 // 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); 1352 if (!ok) { 1353 if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; 1354 } 1355 1356 // successful started transfer, enable data source callback if first active transfer 1357 if (sco_ring_transfers_active == 0){ 1358 usb_sco_out_expected_transfer = transfer_index; 1359 btstack_run_loop_enable_data_source_callbacks(&usb_data_source_sco_out[transfer_index], DATA_SOURCE_CALLBACK_WRITE); 1360 } 1361 1362 // mark slot as full 1363 sco_ring_write = (sco_ring_write + 1) % SCO_RING_BUFFER_COUNT; 1364 sco_ring_transfers_active++; 1365 1366 // notify upper stack that provided buffer can be used again 1367 uint8_t event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 1368 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 1369 1370 // log_info("usb_send_sco_packet: transfers active %u", sco_ring_transfers_active); 1371 1372 // and if we have more space for SCO packets 1373 if (sco_ring_have_space()) { 1374 uint8_t event_sco[] = { HCI_EVENT_SCO_CAN_SEND_NOW, 0}; 1375 packet_handler(HCI_EVENT_PACKET, &event_sco[0], sizeof(event_sco)); 1376 } 1377 return 0; 1378 1379 exit_on_error: 1380 log_error("usb_send_sco_packet: last error %lu", GetLastError()); 1381 return -1; 1382 } 1383 #endif 1384 1385 static int usb_send_packet(uint8_t packet_type, uint8_t * packet, int size){ 1386 switch (packet_type){ 1387 case HCI_COMMAND_DATA_PACKET: 1388 return usb_send_cmd_packet(packet, size); 1389 case HCI_ACL_DATA_PACKET: 1390 return usb_send_acl_packet(packet, size); 1391 #ifdef ENABLE_SCO_OVER_HCI 1392 case HCI_SCO_DATA_PACKET: 1393 return usb_send_sco_packet(packet, size); 1394 #endif 1395 default: 1396 return -1; 1397 } 1398 } 1399 1400 #ifdef ENABLE_SCO_OVER_HCI 1401 static void usb_set_sco_config(uint16_t voice_setting, int num_connections){ 1402 log_info("usb_set_sco_config: voice settings 0x%04x, num connections %u", voice_setting, num_connections); 1403 1404 if (num_connections != sco_num_connections){ 1405 sco_voice_setting = voice_setting; 1406 if (sco_num_connections){ 1407 usb_sco_stop(); 1408 } 1409 sco_num_connections = num_connections; 1410 if (num_connections){ 1411 usb_sco_start(); 1412 } 1413 } 1414 } 1415 #endif 1416 1417 // get usb singleton 1418 static const hci_transport_t hci_transport_usb = { 1419 /* const char * name; */ "H2_WINUSB", 1420 /* void (*init) (const void *transport_config); */ &usb_init, 1421 /* int (*open)(void); */ &usb_open, 1422 /* int (*close)(void); */ &usb_close, 1423 /* void (*register_packet_handler)(void (*handler)(...); */ &usb_register_packet_handler, 1424 /* int (*can_send_packet_now)(uint8_t packet_type); */ &usb_can_send_packet_now, 1425 /* int (*send_packet)(...); */ &usb_send_packet, 1426 /* int (*set_baudrate)(uint32_t baudrate); */ NULL, 1427 /* void (*reset_link)(void); */ NULL, 1428 #ifdef ENABLE_SCO_OVER_HCI 1429 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ usb_set_sco_config, 1430 #else 1431 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL, 1432 #endif 1433 }; 1434 1435 const hci_transport_t * hci_transport_usb_instance(void) { 1436 return &hci_transport_usb; 1437 } 1438