mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-23 10:21:12 +00:00
windows-winusb: prefix isochronous functions and types with BTstack/BTSTACK to avoid name collisions, support device whitelist
This commit is contained in:
parent
beeed1f3ef
commit
ecf76c8d4f
@ -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, ¤t_frame_number, ×tamp);
|
||||
BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp);
|
||||
|
||||
// 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, ¤t_frame_number, ×tamp);
|
||||
BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp);
|
||||
|
||||
// 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, ¤t_frame_number, ×tamp);
|
||||
// BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp);
|
||||
|
||||
// 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, ¤t_frame_number, ×tamp);
|
||||
BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp);
|
||||
// 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, ¤t_frame_number, ×tamp);
|
||||
BTstack_WinUsb_GetCurrentFrameNumber(usb_interface_0_handle, ¤t_frame_number, ×tamp);
|
||||
|
||||
// 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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user