windows-winusb: prefix isochronous functions and types with BTstack/BTSTACK to avoid name collisions, support device whitelist

This commit is contained in:
Matthias Ringwald 2017-08-07 14:39:35 +02:00
parent beeed1f3ef
commit ecf76c8d4f

View File

@ -77,31 +77,33 @@
// Function signatures frome https://abi-laboratory.pro/compatibility/Windows_7.0_to_Windows_8.1/x86_64/info/winusb.dll/symbols.html // Function signatures frome https://abi-laboratory.pro/compatibility/Windows_7.0_to_Windows_8.1/x86_64/info/winusb.dll/symbols.html
// MSDN documentation has multiple errors (Jan 2017), annotated below // MSDN documentation has multiple errors (Jan 2017), annotated below
typedef PVOID WINUSB_ISOCH_BUFFER_HANDLE, *PWINUSB_ISOCH_BUFFER_HANDLE; // As Isochochronous functions are provided by newer versions of ming64, we use a BTstack/BTSTACK prefix to prevent name collisions
typedef struct _WINUSB_PIPE_INFORMATION_EX { typedef PVOID BTSTACK_WINUSB_ISOCH_BUFFER_HANDLE, *BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE;
typedef struct _BTSTACK_WINUSB_PIPE_INFORMATION_EX {
USBD_PIPE_TYPE PipeType; USBD_PIPE_TYPE PipeType;
UCHAR PipeId; UCHAR PipeId;
USHORT MaximumPacketSize; USHORT MaximumPacketSize;
UCHAR Interval; UCHAR Interval;
ULONG MaximumBytesPerInterval; ULONG MaximumBytesPerInterval;
} WINUSB_PIPE_INFORMATION_EX, *PWINUSB_PIPE_INFORMATION_EX; } BTSTACK_WINUSB_PIPE_INFORMATION_EX, *BTSTACK_PWINUSB_PIPE_INFORMATION_EX;
typedef WINBOOL (WINAPI * WinUsb_QueryPipeEx_t) ( typedef WINBOOL (WINAPI * BTstack_WinUsb_QueryPipeEx_t) (
WINUSB_INTERFACE_HANDLE InterfaceHandle, WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateInterfaceNumber, UCHAR AlternateInterfaceNumber,
UCHAR PipeIndex, UCHAR PipeIndex,
PWINUSB_PIPE_INFORMATION_EX PipeInformationEx BTSTACK_PWINUSB_PIPE_INFORMATION_EX PipeInformationEx
); );
typedef WINBOOL (WINAPI * WinUsb_RegisterIsochBuffer_t)( typedef WINBOOL (WINAPI * BTstack_WinUsb_RegisterIsochBuffer_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle, WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID, UCHAR PipeID,
PVOID Buffer, PVOID Buffer,
ULONG BufferLength, ULONG BufferLength,
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle
); );
typedef WINBOOL (WINAPI * WinUsb_ReadIsochPipe_t)( typedef WINBOOL (WINAPI * BTstack_WinUsb_ReadIsochPipe_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle, BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
ULONG Offset, ULONG Offset,
ULONG Length, ULONG Length,
PULONG FrameNumber, PULONG FrameNumber,
@ -109,8 +111,8 @@ typedef WINBOOL (WINAPI * WinUsb_ReadIsochPipe_t)(
PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors, // MSDN lists PULONG PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors, // MSDN lists PULONG
LPOVERLAPPED Overlapped LPOVERLAPPED Overlapped
); );
typedef WINBOOL (WINAPI * WinUsb_ReadIsochPipeAsap_t)( typedef WINBOOL (WINAPI * BTstack_WinUsb_ReadIsochPipeAsap_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle, BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
ULONG Offset, ULONG Offset,
ULONG Length, ULONG Length,
BOOL ContinueStream, BOOL ContinueStream,
@ -118,37 +120,37 @@ typedef WINBOOL (WINAPI * WinUsb_ReadIsochPipeAsap_t)(
PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors, PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors,
LPOVERLAPPED Overlapped LPOVERLAPPED Overlapped
); );
typedef WINBOOL (WINAPI * WinUsb_WriteIsochPipe_t)( typedef WINBOOL (WINAPI * BTstack_WinUsb_WriteIsochPipe_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle, BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
ULONG Offset, ULONG Offset,
ULONG Length, ULONG Length,
PULONG FrameNumber, PULONG FrameNumber,
LPOVERLAPPED Overlapped LPOVERLAPPED Overlapped
); );
typedef WINBOOL (WINAPI * WinUsb_WriteIsochPipeAsap_t)( typedef WINBOOL (WINAPI * BTstack_WinUsb_WriteIsochPipeAsap_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle, BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
ULONG Offset, ULONG Offset,
ULONG Length, ULONG Length,
BOOL ContinueStream, BOOL ContinueStream,
LPOVERLAPPED Overlapped LPOVERLAPPED Overlapped
); );
typedef WINBOOL (WINAPI * WinUsb_UnregisterIsochBuffer_t)( typedef WINBOOL (WINAPI * BTstack_WinUsb_UnregisterIsochBuffer_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle
); );
typedef WINBOOL (WINAPI * WinUsb_GetCurrentFrameNumber_t)( typedef WINBOOL (WINAPI * BTstack_WinUsb_GetCurrentFrameNumber_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle, // MSDN lists 'Device handle returned from CreateFile' WINUSB_INTERFACE_HANDLE InterfaceHandle, // MSDN lists 'Device handle returned from CreateFile'
PULONG CurrentFrameNumber, PULONG CurrentFrameNumber,
LARGE_INTEGER *TimeStamp LARGE_INTEGER *TimeStamp
); );
static WinUsb_QueryPipeEx_t WinUsb_QueryPipeEx; static BTstack_WinUsb_QueryPipeEx_t BTstack_WinUsb_QueryPipeEx;
static WinUsb_RegisterIsochBuffer_t WinUsb_RegisterIsochBuffer; static BTstack_WinUsb_RegisterIsochBuffer_t BTstack_WinUsb_RegisterIsochBuffer;
static WinUsb_ReadIsochPipe_t WinUsb_ReadIsochPipe; static BTstack_WinUsb_ReadIsochPipe_t BTstack_WinUsb_ReadIsochPipe;
static WinUsb_ReadIsochPipeAsap_t WinUsb_ReadIsochPipeAsap; static BTstack_WinUsb_ReadIsochPipeAsap_t BTstack_WinUsb_ReadIsochPipeAsap;
static WinUsb_WriteIsochPipe_t WinUsb_WriteIsochPipe; static BTstack_WinUsb_WriteIsochPipe_t BTstack_WinUsb_WriteIsochPipe;
static WinUsb_WriteIsochPipeAsap_t WinUsb_WriteIsochPipeAsap; static BTstack_WinUsb_WriteIsochPipeAsap_t BTstack_WinUsb_WriteIsochPipeAsap;
static WinUsb_UnregisterIsochBuffer_t WinUsb_UnregisterIsochBuffer; static BTstack_WinUsb_UnregisterIsochBuffer_t BTstack_WinUsb_UnregisterIsochBuffer;
static WinUsb_GetCurrentFrameNumber_t WinUsb_GetCurrentFrameNumber; static BTstack_WinUsb_GetCurrentFrameNumber_t BTstack_WinUsb_GetCurrentFrameNumber;
#endif #endif
// Doesn't work as expected // Doesn't work as expected
@ -259,7 +261,7 @@ typedef enum {
// SCO Incoming Windows // SCO Incoming Windows
static uint8_t hci_sco_in_buffer[ISOC_BUFFERS * SCO_PACKET_SIZE]; static uint8_t hci_sco_in_buffer[ISOC_BUFFERS * SCO_PACKET_SIZE];
static WINUSB_ISOCH_BUFFER_HANDLE hci_sco_in_buffer_handle; static BTSTACK_WINUSB_ISOCH_BUFFER_HANDLE hci_sco_in_buffer_handle;
static USBD_ISO_PACKET_DESCRIPTOR hci_sco_packet_descriptors[ISOC_BUFFERS * NUM_ISO_PACKETS]; static USBD_ISO_PACKET_DESCRIPTOR hci_sco_packet_descriptors[ISOC_BUFFERS * NUM_ISO_PACKETS];
static OVERLAPPED usb_overlapped_sco_in[ISOC_BUFFERS]; static OVERLAPPED usb_overlapped_sco_in[ISOC_BUFFERS];
static int usb_sco_in_expected_transfer; static int usb_sco_in_expected_transfer;
@ -274,7 +276,7 @@ static uint16_t sco_read_pos;
static uint16_t sco_bytes_to_read; static uint16_t sco_bytes_to_read;
// SCO Outgoing Windows // SCO Outgoing Windows
static WINUSB_ISOCH_BUFFER_HANDLE hci_sco_out_buffer_handle; static BTSTACK_WINUSB_ISOCH_BUFFER_HANDLE hci_sco_out_buffer_handle;
static OVERLAPPED usb_overlapped_sco_out[SCO_RING_BUFFER_COUNT]; static OVERLAPPED usb_overlapped_sco_out[SCO_RING_BUFFER_COUNT];
static int sco_ring_transfers_active; static int sco_ring_transfers_active;
static int usb_sco_out_expected_transfer; static int usb_sco_out_expected_transfer;
@ -299,7 +301,6 @@ static int sco_shutdown;
static uint16_t iso_packet_size; static uint16_t iso_packet_size;
#endif #endif
#if 0
// list of known devices, using VendorID/ProductID tuples // list of known devices, using VendorID/ProductID tuples
static const uint16_t known_bluetooth_devices[] = { static const uint16_t known_bluetooth_devices[] = {
// DeLOCK Bluetooth 4.0 // DeLOCK Bluetooth 4.0
@ -310,16 +311,20 @@ static const uint16_t known_bluetooth_devices[] = {
static int num_known_devices = sizeof(known_bluetooth_devices) / sizeof(uint16_t) / 2; static int num_known_devices = sizeof(known_bluetooth_devices) / sizeof(uint16_t) / 2;
static int usb_is_known_bluetooth_device(uint16_t vendor_id, uint16_t product_id){ static int usb_is_known_bluetooth_device(const char * device_path){
int i; int i;
for (i=0; i<num_known_devices; i++){ for (i=0; i<num_known_devices; i++){
if (known_bluetooth_devices[i*2] == vendor_id && known_bluetooth_devices[i*2+1] == product_id){ // construct pid/vid substring
char substring[20];
sprintf(substring, "vid_%04x&pid_%04x", known_bluetooth_devices[i*2], known_bluetooth_devices[i*2+1]);
const char * pos = strstr(device_path, substring);
log_info("check %s in %s -> %p", substring, device_path, pos);
if (pos){
return 1; return 1;
} }
} }
return 0; return 0;
} }
#endif
#ifdef ENABLE_SCO_OVER_HCI #ifdef ENABLE_SCO_OVER_HCI
static void sco_ring_init(void){ static void sco_ring_init(void){
@ -331,13 +336,13 @@ static int sco_ring_have_space(void){
} }
static void usb_sco_register_buffers(void){ static void usb_sco_register_buffers(void){
BOOL result; BOOL result;
result = WinUsb_RegisterIsochBuffer(usb_interface_1_handle, sco_in_addr, hci_sco_in_buffer, sizeof(hci_sco_in_buffer), &hci_sco_in_buffer_handle); 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);
if (!result) { if (!result) {
log_error("usb_sco_register_buffers: register in buffer failed, error %lu", GetLastError()); log_error("usb_sco_register_buffers: register in buffer failed, error %lu", GetLastError());
} }
log_info("hci_sco_in_buffer_handle %p", hci_sco_in_buffer_handle); log_info("hci_sco_in_buffer_handle %p", hci_sco_in_buffer_handle);
result = WinUsb_RegisterIsochBuffer(usb_interface_1_handle, sco_out_addr, sco_ring_buffer, sizeof(sco_ring_buffer), &hci_sco_out_buffer_handle); result = BTstack_WinUsb_RegisterIsochBuffer(usb_interface_1_handle, sco_out_addr, sco_ring_buffer, sizeof(sco_ring_buffer), &hci_sco_out_buffer_handle);
if (!result) { if (!result) {
log_error("usb_sco_unregister_buffers: register out buffer failed, error %lu", GetLastError()); log_error("usb_sco_unregister_buffers: register out buffer failed, error %lu", GetLastError());
} }
@ -345,11 +350,11 @@ static void usb_sco_register_buffers(void){
} }
static void usb_sco_unregister_buffers(void){ static void usb_sco_unregister_buffers(void){
if (hci_sco_in_buffer_handle){ if (hci_sco_in_buffer_handle){
WinUsb_UnregisterIsochBuffer(hci_sco_in_buffer_handle); BTstack_WinUsb_UnregisterIsochBuffer(hci_sco_in_buffer_handle);
hci_sco_in_buffer_handle = NULL; hci_sco_in_buffer_handle = NULL;
} }
if (hci_sco_out_buffer_handle){ if (hci_sco_out_buffer_handle){
WinUsb_UnregisterIsochBuffer(hci_sco_out_buffer_handle); BTstack_WinUsb_UnregisterIsochBuffer(hci_sco_out_buffer_handle);
hci_sco_out_buffer_handle = NULL; hci_sco_out_buffer_handle = NULL;
} }
} }
@ -434,10 +439,10 @@ static void usb_submit_sco_in_transfer_at_frame(int i, ULONG * frame_number){
ULONG frame_before = *frame_number; ULONG frame_before = *frame_number;
BOOL result = WinUsb_ReadIsochPipe(hci_sco_in_buffer_handle, i * SCO_PACKET_SIZE, iso_packet_size * NUM_ISO_PACKETS, BOOL result = BTstack_WinUsb_ReadIsochPipe(hci_sco_in_buffer_handle, i * SCO_PACKET_SIZE, iso_packet_size * NUM_ISO_PACKETS,
frame_number, NUM_ISO_PACKETS, &hci_sco_packet_descriptors[i * NUM_ISO_PACKETS], &usb_overlapped_sco_in[i]); frame_number, NUM_ISO_PACKETS, &hci_sco_packet_descriptors[i * NUM_ISO_PACKETS], &usb_overlapped_sco_in[i]);
// log_info("WinUsb_ReadIsochPipe #%02u: current %lu, planned %lu - buffer %lu", i, current_frame_number, frame_before, frame_before - current_frame_number); // log_info("BTstack_WinUsb_ReadIsochPipe #%02u: current %lu, planned %lu - buffer %lu", i, current_frame_number, frame_before, frame_before - current_frame_number);
if (!result) { if (!result) {
if (GetLastError() == ERROR_IO_PENDING) { if (GetLastError() == ERROR_IO_PENDING) {
@ -463,11 +468,11 @@ static void usb_submit_sco_in_transfer_asap(int i, int continue_stream){
LARGE_INTEGER timestamp; LARGE_INTEGER timestamp;
ULONG current_frame_number; ULONG current_frame_number;
WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp); BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp);
// log_info("usb_submit_sco_in_transfer[%02u]: current frame %lu", i, current_frame_number); // log_info("usb_submit_sco_in_transfer[%02u]: current frame %lu", i, current_frame_number);
BOOL result = WinUsb_ReadIsochPipeAsap(hci_sco_in_buffer_handle, i * SCO_PACKET_SIZE, iso_packet_size * NUM_ISO_PACKETS, BOOL result = BTstack_WinUsb_ReadIsochPipeAsap(hci_sco_in_buffer_handle, i * SCO_PACKET_SIZE, iso_packet_size * NUM_ISO_PACKETS,
continue_stream, NUM_ISO_PACKETS, &hci_sco_packet_descriptors[i * NUM_ISO_PACKETS], &usb_overlapped_sco_in[i]); continue_stream, NUM_ISO_PACKETS, &hci_sco_packet_descriptors[i * NUM_ISO_PACKETS], &usb_overlapped_sco_in[i]);
if (!result) { if (!result) {
@ -584,7 +589,7 @@ static void usb_process_sco_out(btstack_data_source_t *ds, btstack_data_source_
// get current frame number // get current frame number
ULONG current_frame_number; ULONG current_frame_number;
LARGE_INTEGER timestamp; LARGE_INTEGER timestamp;
WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp); BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp);
// find index // find index
int transfer_index; int transfer_index;
@ -645,7 +650,7 @@ static void usb_process_sco_in(btstack_data_source_t *ds, btstack_data_source_c
// ULONG current_frame_number; // ULONG current_frame_number;
// LARGE_INTEGER timestamp; // LARGE_INTEGER timestamp;
// WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp); // BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp);
// log_info("usb_process_sco_in[%02u] -- current frame %lu", transfer_index, current_frame_number); // log_info("usb_process_sco_in[%02u] -- current frame %lu", transfer_index, current_frame_number);
@ -765,8 +770,8 @@ static BOOL usb_scan_for_bluetooth_endpoints(void) {
result = WinUsb_QueryInterfaceSettings(usb_interface_1_handle, alt_setting, &usb_interface_descriptor); result = WinUsb_QueryInterfaceSettings(usb_interface_1_handle, alt_setting, &usb_interface_descriptor);
if (!result) goto exit_on_error; if (!result) goto exit_on_error;
for (i=0;i<usb_interface_descriptor.bNumEndpoints;i++){ for (i=0;i<usb_interface_descriptor.bNumEndpoints;i++){
WINUSB_PIPE_INFORMATION_EX pipe; BTSTACK_WINUSB_PIPE_INFORMATION_EX pipe;
result = WinUsb_QueryPipeEx( result = BTstack_WinUsb_QueryPipeEx(
usb_interface_1_handle, usb_interface_1_handle,
alt_setting, alt_setting,
(UCHAR) i, (UCHAR) i,
@ -858,7 +863,7 @@ static int usb_sco_start(void){
// get current frame number // get current frame number
ULONG current_frame_number; ULONG current_frame_number;
LARGE_INTEGER timestamp; LARGE_INTEGER timestamp;
WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp); BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp);
// plan for next tranfer // plan for next tranfer
sco_next_transfer_at_frame = current_frame_number + ISOC_BUFFERS * NUM_ISO_PACKETS; sco_next_transfer_at_frame = current_frame_number + ISOC_BUFFERS * NUM_ISO_PACKETS;
#endif #endif
@ -934,11 +939,13 @@ static int usb_try_open_device(const char * device_path){
usb_interface_descriptor.bInterfaceSubClass != 0x01 || usb_interface_descriptor.bInterfaceSubClass != 0x01 ||
usb_interface_descriptor.bInterfaceProtocol != 0x01){ usb_interface_descriptor.bInterfaceProtocol != 0x01){
// TODO: fallback to whitelist // check whitelist
if (!usb_is_known_bluetooth_device(device_path)){
log_info("Class, Subclass, Protocol does not match Bluetooth device"); log_info("Class, Subclass, Protocol does not match Bluetooth device");
usb_free_resources(); usb_free_resources();
return 0; return 0;
} }
}
#ifdef ENABLE_SCO_OVER_HCI #ifdef ENABLE_SCO_OVER_HCI
log_info("Claiming interface 1..."); log_info("Claiming interface 1...");
@ -1024,7 +1031,7 @@ exit_on_error:
#ifdef ENABLE_SCO_OVER_HCI #ifdef ENABLE_SCO_OVER_HCI
#define WinUSB_Lookup(fn) do { fn = (fn##_t) GetProcAddress(h, #fn); log_info("%-30s %p", #fn, fn); if (!fn) return FALSE; } while(0) #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)
static BOOL usb_lookup_symbols(void){ static BOOL usb_lookup_symbols(void){
// lookup runtime symbols missing in current mingw64 distribution // lookup runtime symbols missing in current mingw64 distribution
@ -1284,7 +1291,7 @@ static int usb_send_sco_packet(uint8_t *packet, int size){
// get current frame number // get current frame number
ULONG current_frame_number; ULONG current_frame_number;
LARGE_INTEGER timestamp; LARGE_INTEGER timestamp;
WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp); BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, &current_frame_number, &timestamp);
// store packet in free slot // store packet in free slot
int transfer_index = sco_ring_write; int transfer_index = sco_ring_write;
@ -1294,7 +1301,7 @@ static int usb_send_sco_packet(uint8_t *packet, int size){
// setup transfer // setup transfer
int continue_stream = sco_ring_transfers_active > 0; int continue_stream = sco_ring_transfers_active > 0;
BOOL ok = WinUsb_WriteIsochPipeAsap(hci_sco_out_buffer_handle, transfer_index * SCO_PACKET_SIZE, size, continue_stream, &usb_overlapped_sco_out[transfer_index]); BOOL ok = BTstack_WinUsb_WriteIsochPipeAsap(hci_sco_out_buffer_handle, transfer_index * SCO_PACKET_SIZE, size, continue_stream, &usb_overlapped_sco_out[transfer_index]);
// 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); // 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);
if (!ok) { if (!ok) {
if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error; if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error;