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