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

@ -34,8 +34,8 @@
* contact@bluekitchen-gmbh.com
*
*/
#define __BTSTACK_FILE__ "hci_transport_h2_winusb.c"
#define __BTSTACK_FILE__ "hci_transport_h2_winusb.c"
/*
* hci_transport_usb.c
@ -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
// 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;
UCHAR PipeId;
USHORT MaximumPacketSize;
UCHAR Interval;
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,
UCHAR AlternateInterfaceNumber,
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,
UCHAR PipeID,
PVOID Buffer,
ULONG BufferLength,
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle
BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle
);
typedef WINBOOL (WINAPI * WinUsb_ReadIsochPipe_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
typedef WINBOOL (WINAPI * BTstack_WinUsb_ReadIsochPipe_t)(
BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
ULONG Offset,
ULONG Length,
PULONG FrameNumber,
@ -109,8 +111,8 @@ typedef WINBOOL (WINAPI * WinUsb_ReadIsochPipe_t)(
PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors, // MSDN lists PULONG
LPOVERLAPPED Overlapped
);
typedef WINBOOL (WINAPI * WinUsb_ReadIsochPipeAsap_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
typedef WINBOOL (WINAPI * BTstack_WinUsb_ReadIsochPipeAsap_t)(
BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
ULONG Offset,
ULONG Length,
BOOL ContinueStream,
@ -118,37 +120,37 @@ typedef WINBOOL (WINAPI * WinUsb_ReadIsochPipeAsap_t)(
PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors,
LPOVERLAPPED Overlapped
);
typedef WINBOOL (WINAPI * WinUsb_WriteIsochPipe_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
typedef WINBOOL (WINAPI * BTstack_WinUsb_WriteIsochPipe_t)(
BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
ULONG Offset,
ULONG Length,
PULONG FrameNumber,
LPOVERLAPPED Overlapped
);
typedef WINBOOL (WINAPI * WinUsb_WriteIsochPipeAsap_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
typedef WINBOOL (WINAPI * BTstack_WinUsb_WriteIsochPipeAsap_t)(
BTSTACK_PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
ULONG Offset,
ULONG Length,
BOOL ContinueStream,
LPOVERLAPPED Overlapped
);
typedef WINBOOL (WINAPI * WinUsb_UnregisterIsochBuffer_t)(
PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle
typedef WINBOOL (WINAPI * BTstack_WinUsb_UnregisterIsochBuffer_t)(
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'
PULONG CurrentFrameNumber,
LARGE_INTEGER *TimeStamp
);
static WinUsb_QueryPipeEx_t WinUsb_QueryPipeEx;
static WinUsb_RegisterIsochBuffer_t WinUsb_RegisterIsochBuffer;
static WinUsb_ReadIsochPipe_t WinUsb_ReadIsochPipe;
static WinUsb_ReadIsochPipeAsap_t WinUsb_ReadIsochPipeAsap;
static WinUsb_WriteIsochPipe_t WinUsb_WriteIsochPipe;
static WinUsb_WriteIsochPipeAsap_t WinUsb_WriteIsochPipeAsap;
static WinUsb_UnregisterIsochBuffer_t WinUsb_UnregisterIsochBuffer;
static WinUsb_GetCurrentFrameNumber_t WinUsb_GetCurrentFrameNumber;
static BTstack_WinUsb_QueryPipeEx_t BTstack_WinUsb_QueryPipeEx;
static BTstack_WinUsb_RegisterIsochBuffer_t BTstack_WinUsb_RegisterIsochBuffer;
static BTstack_WinUsb_ReadIsochPipe_t BTstack_WinUsb_ReadIsochPipe;
static BTstack_WinUsb_ReadIsochPipeAsap_t BTstack_WinUsb_ReadIsochPipeAsap;
static BTstack_WinUsb_WriteIsochPipe_t BTstack_WinUsb_WriteIsochPipe;
static BTstack_WinUsb_WriteIsochPipeAsap_t BTstack_WinUsb_WriteIsochPipeAsap;
static BTstack_WinUsb_UnregisterIsochBuffer_t BTstack_WinUsb_UnregisterIsochBuffer;
static BTstack_WinUsb_GetCurrentFrameNumber_t BTstack_WinUsb_GetCurrentFrameNumber;
#endif
// Doesn't work as expected
@ -259,7 +261,7 @@ typedef enum {
// SCO Incoming Windows
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 OVERLAPPED usb_overlapped_sco_in[ISOC_BUFFERS];
static int usb_sco_in_expected_transfer;
@ -274,7 +276,7 @@ static uint16_t sco_read_pos;
static uint16_t sco_bytes_to_read;
// 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 int sco_ring_transfers_active;
static int usb_sco_out_expected_transfer;
@ -299,7 +301,6 @@ static int sco_shutdown;
static uint16_t iso_packet_size;
#endif
#if 0
// list of known devices, using VendorID/ProductID tuples
static const uint16_t known_bluetooth_devices[] = {
// 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 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;
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 0;
}
#endif
#ifdef ENABLE_SCO_OVER_HCI
static void sco_ring_init(void){
@ -331,13 +336,13 @@ static int sco_ring_have_space(void){
}
static void usb_sco_register_buffers(void){
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) {
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);
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) {
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){
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;
}
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;
}
}
@ -434,10 +439,10 @@ static void usb_submit_sco_in_transfer_at_frame(int i, ULONG * 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]);
// 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 (GetLastError() == ERROR_IO_PENDING) {
@ -463,11 +468,11 @@ static void usb_submit_sco_in_transfer_asap(int i, int continue_stream){
LARGE_INTEGER timestamp;
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);
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]);
if (!result) {
@ -584,7 +589,7 @@ static void usb_process_sco_out(btstack_data_source_t *ds, btstack_data_source_
// get current frame number
ULONG current_frame_number;
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
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;
// 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);
@ -765,8 +770,8 @@ static BOOL usb_scan_for_bluetooth_endpoints(void) {
result = WinUsb_QueryInterfaceSettings(usb_interface_1_handle, alt_setting, &usb_interface_descriptor);
if (!result) goto exit_on_error;
for (i=0;i<usb_interface_descriptor.bNumEndpoints;i++){
WINUSB_PIPE_INFORMATION_EX pipe;
result = WinUsb_QueryPipeEx(
BTSTACK_WINUSB_PIPE_INFORMATION_EX pipe;
result = BTstack_WinUsb_QueryPipeEx(
usb_interface_1_handle,
alt_setting,
(UCHAR) i,
@ -858,7 +863,7 @@ static int usb_sco_start(void){
// get current frame number
ULONG current_frame_number;
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
sco_next_transfer_at_frame = current_frame_number + ISOC_BUFFERS * NUM_ISO_PACKETS;
#endif
@ -934,10 +939,12 @@ static int usb_try_open_device(const char * device_path){
usb_interface_descriptor.bInterfaceSubClass != 0x01 ||
usb_interface_descriptor.bInterfaceProtocol != 0x01){
// TODO: fallback to whitelist
log_info("Class, Subclass, Protocol does not match Bluetooth device");
usb_free_resources();
return 0;
// check whitelist
if (!usb_is_known_bluetooth_device(device_path)){
log_info("Class, Subclass, Protocol does not match Bluetooth device");
usb_free_resources();
return 0;
}
}
#ifdef ENABLE_SCO_OVER_HCI
@ -1024,7 +1031,7 @@ exit_on_error:
#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){
// 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
ULONG current_frame_number;
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
int transfer_index = sco_ring_write;
@ -1294,7 +1301,7 @@ static int usb_send_sco_packet(uint8_t *packet, int size){
// setup transfer
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);
if (!ok) {
if (GetLastError() != ERROR_IO_PENDING) goto exit_on_error;