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