From 9bf67d4bb1db516a83f8e5c53bf6efee32131579 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Wed, 28 Mar 2012 21:52:17 +1300 Subject: [PATCH] Implemented /dev/usb/hid as libusb, but this will not work on mac. Code started for using hidapi instead. --- Externals/libusb/include/hidapi.h | 384 ++++++++++++++++ Externals/libusb/include/lusb0_usb.h | 427 ++++++++++++++++++ Externals/libusb/win32/hidapi.h | 384 ++++++++++++++++ Externals/libusb/win32/lusb0_usb.h | 427 ++++++++++++++++++ Externals/libusb/x64/hidapi.dll | Bin 0 -> 37888 bytes Externals/libusb/x64/hidapi.h | 384 ++++++++++++++++ Externals/libusb/x64/lusb0_usb.h | 427 ++++++++++++++++++ Source/Core/Common/Src/Log.h | 1 + Source/Core/Common/Src/LogManager.cpp | 1 + Source/Core/Core/Core.vcxproj | 14 +- Source/Core/Core/Core.vcxproj.filters | 9 + Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 3 +- .../Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 416 +++++++++++++++++ .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 126 ++++++ Source/VSProps/Dolphin.Win32.props | 4 +- Source/VSProps/Dolphin.x64.props | 4 +- 16 files changed, 3000 insertions(+), 11 deletions(-) create mode 100644 Externals/libusb/include/hidapi.h create mode 100644 Externals/libusb/include/lusb0_usb.h create mode 100644 Externals/libusb/win32/hidapi.h create mode 100644 Externals/libusb/win32/lusb0_usb.h create mode 100644 Externals/libusb/x64/hidapi.dll create mode 100644 Externals/libusb/x64/hidapi.h create mode 100644 Externals/libusb/x64/lusb0_usb.h create mode 100644 Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp create mode 100644 Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h diff --git a/Externals/libusb/include/hidapi.h b/Externals/libusb/include/hidapi.h new file mode 100644 index 0000000000..bd912acd7f --- /dev/null +++ b/Externals/libusb/include/hidapi.h @@ -0,0 +1,384 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/** @file + * @defgroup API hidapi API + */ + +#ifndef HIDAPI_H__ +#define HIDAPI_H__ + +#include + +#ifdef _WIN32 + #define HID_API_EXPORT __declspec(dllexport) + #define HID_API_CALL +#else + #define HID_API_EXPORT /**< API export macro */ + #define HID_API_CALL /**< API call macro */ +#endif + +#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ + +#ifdef __cplusplus +extern "C" { +#endif + struct hid_device_; + typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ + + /** hidapi info structure */ + struct hid_device_info { + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. Valid on both Linux implementations + in all cases, and valid on the Windows implementation + only if the device contains more than one interface. */ + int interface_number; + + /** Pointer to the next device */ + struct hid_device_info *next; + }; + + + /** @brief Initialize the HIDAPI library. + + This function initializes the HIDAPI library. Calling it is not + strictly necessary, as it will be called automatically by + hid_enumerate() and any of the hid_open_*() functions if it is + needed. This function should be called at the beginning of + execution however, if there is a chance of HIDAPI handles + being opened by different threads simultaneously. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_init(void); + + /** @brief Finalize the HIDAPI library. + + This function frees all of the static data associated with + HIDAPI. It should be called at the end of execution to avoid + memory leaks. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_exit(void); + + /** @brief Enumerate the HID Devices. + + This function returns a linked list of all the HID devices + attached to the system which match vendor_id and product_id. + If @p vendor_id and @p product_id are both set to 0, then + all HID devices will be returned. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the types of device + to open. + @param product_id The Product ID (PID) of the types of + device to open. + + @returns + This function returns a pointer to a linked list of type + struct #hid_device, containing information about the HID devices + attached to the system, or NULL in the case of failure. Free + this linked list by calling hid_free_enumeration(). + */ + struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); + + /** @brief Free an enumeration Linked List + + This function frees a linked list created by hid_enumerate(). + + @ingroup API + @param devs Pointer to a list of struct_device returned from + hid_enumerate(). + */ + void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); + + /** @brief Open a HID device using a Vendor ID (VID), Product ID + (PID) and optionally a serial number. + + If @p serial_number is NULL, the first device with the + specified VID and PID is opened. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the device to open. + @param product_id The Product ID (PID) of the device to open. + @param serial_number The Serial Number of the device to open + (Optionally NULL). + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number); + + /** @brief Open a HID device by its path name. + + The path name be determined by calling hid_enumerate(), or a + platform-specific path name can be used (eg: /dev/hidraw0 on + Linux). + + @ingroup API + @param path The path name of the device to open + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); + + /** @brief Write an Output report to a HID device. + + The first byte of @p data[] must contain the Report ID. For + devices which only support a single report, this must be set + to 0x0. The remaining bytes contain the report data. Since + the Report ID is mandatory, calls to hid_write() will always + contain one more byte than the report contains. For example, + if a hid report is 16 bytes long, 17 bytes must be passed to + hid_write(), the Report ID (or 0x0, for devices with a + single report), followed by the report data (16 bytes). In + this example, the length passed in would be 17. + + hid_write() will send the data on the first OUT endpoint, if + one exists. If it does not, it will send the data through + the Control Endpoint (Endpoint 0). + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); + + int HID_API_EXPORT HID_API_CALL hid_set_output_report(hid_device *dev, const unsigned char *data, size_t length); + /** @brief Read an Input report from a HID device with timeout. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + @param milliseconds timeout in milliseconds or -1 for blocking wait. + + @returns + This function returns the actual number of bytes read and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); + + /** @brief Read an Input report from a HID device. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + + @returns + This function returns the actual number of bytes read and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); + + /** @brief Set the device handle to be non-blocking. + + In non-blocking mode calls to hid_read() will return + immediately with a value of 0 if there is no data to be + read. In blocking mode, hid_read() will wait (block) until + there is data to read before returning. + + Nonblocking can be turned on and off at any time. + + @ingroup API + @param device A device handle returned from hid_open(). + @param nonblock enable or not the nonblocking reads + - 1 to enable nonblocking + - 0 to disable nonblocking. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); + + /** @brief Send a Feature report to the device. + + Feature reports are sent over the Control endpoint as a + Set_Report transfer. The first byte of @p data[] must + contain the Report ID. For devices which only support a + single report, this must be set to 0x0. The remaining bytes + contain the report data. Since the Report ID is mandatory, + calls to hid_send_feature_report() will always contain one + more byte than the report contains. For example, if a hid + report is 16 bytes long, 17 bytes must be passed to + hid_send_feature_report(): the Report ID (or 0x0, for + devices which do not use numbered reports), followed by the + report data (16 bytes). In this example, the length passed + in would be 17. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send, including + the report number. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); + + /** @brief Get a feature report from a HID device. + + Make sure to set the first byte of @p data[] to the Report + ID of the report to be read. Make sure to allow space for + this extra byte in @p data[]. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into, including + the Report ID. Set the first byte of @p data[] to the + Report ID of the report to be read. + @param length The number of bytes to read, including an + extra byte for the report ID. The buffer can be longer + than the actual report. + + @returns + This function returns the number of bytes read and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); + + /** @brief Close a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + */ + void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); + + /** @brief Get The Manufacturer String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Product String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Serial Number String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get a string from a HID device, based on its string index. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string_index The index of the string to get. + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); + + /** @brief Get a string describing the last error which occurred. + + @ingroup API + @param device A device handle returned from hid_open(). + + @returns + This function returns a string containing the last error + which occurred or NULL if none has occurred. + */ + HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Externals/libusb/include/lusb0_usb.h b/Externals/libusb/include/lusb0_usb.h new file mode 100644 index 0000000000..b95fbf0a6d --- /dev/null +++ b/Externals/libusb/include/lusb0_usb.h @@ -0,0 +1,427 @@ +#ifndef __USB_H__ +#define __USB_H__ + +#include +#include + +/* + * 'interface' is defined somewhere in the Windows header files. This macro + * is deleted here to avoid conflicts and compile errors. + */ + +#ifdef interface +#undef interface +#endif + +/* + * PATH_MAX from limits.h can't be used on Windows if the dll and + * import libraries are build/used by different compilers + */ + +#define LIBUSB_PATH_MAX 512 + + +/* + * USB spec information + * + * This is all stuff grabbed from various USB specs and is pretty much + * not subject to change + */ + +/* + * Device and/or Interface Class codes + */ +#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_DATA 10 +#define USB_CLASS_VENDOR_SPEC 0xff + +/* + * Descriptor types + */ +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 + +#define USB_DT_HID 0x21 +#define USB_DT_REPORT 0x22 +#define USB_DT_PHYSICAL 0x23 +#define USB_DT_HUB 0x29 + +/* + * Descriptor sizes per descriptor type + */ +#define USB_DT_DEVICE_SIZE 18 +#define USB_DT_CONFIG_SIZE 9 +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define USB_DT_HUB_NONVAR_SIZE 7 + + +/* ensure byte-packed structures */ +#include + + +/* All standard descriptors have these 2 fields in common */ +struct usb_descriptor_header +{ + unsigned char bLength; + unsigned char bDescriptorType; +}; + +/* String descriptor */ +struct usb_string_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wData[1]; +}; + +/* HID descriptor */ +struct usb_hid_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdHID; + unsigned char bCountryCode; + unsigned char bNumDescriptors; +}; + +/* Endpoint descriptor */ +#define USB_MAXENDPOINTS 32 +struct usb_endpoint_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bEndpointAddress; + unsigned char bmAttributes; + unsigned short wMaxPacketSize; + unsigned char bInterval; + unsigned char bRefresh; + unsigned char bSynchAddress; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */ +#define USB_ENDPOINT_TYPE_CONTROL 0 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1 +#define USB_ENDPOINT_TYPE_BULK 2 +#define USB_ENDPOINT_TYPE_INTERRUPT 3 + +/* Interface descriptor */ +#define USB_MAXINTERFACES 32 +struct usb_interface_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bInterfaceNumber; + unsigned char bAlternateSetting; + unsigned char bNumEndpoints; + unsigned char bInterfaceClass; + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char iInterface; + + struct usb_endpoint_descriptor *endpoint; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +#define USB_MAXALTSETTING 128 /* Hard limit */ + +struct usb_interface +{ + struct usb_interface_descriptor *altsetting; + + int num_altsetting; +}; + +/* Configuration descriptor information.. */ +#define USB_MAXCONFIG 8 +struct usb_config_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wTotalLength; + unsigned char bNumInterfaces; + unsigned char bConfigurationValue; + unsigned char iConfiguration; + unsigned char bmAttributes; + unsigned char MaxPower; + + struct usb_interface *interface; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +/* Device descriptor */ +struct usb_device_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdUSB; + unsigned char bDeviceClass; + unsigned char bDeviceSubClass; + unsigned char bDeviceProtocol; + unsigned char bMaxPacketSize0; + unsigned short idVendor; + unsigned short idProduct; + unsigned short bcdDevice; + unsigned char iManufacturer; + unsigned char iProduct; + unsigned char iSerialNumber; + unsigned char bNumConfigurations; +}; + +struct usb_ctrl_setup +{ + unsigned char bRequestType; + unsigned char bRequest; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; +}; + +/* + * Standard requests + */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +/* 0x02 is reserved */ +#define USB_REQ_SET_FEATURE 0x03 +/* 0x04 is reserved */ +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 + +/* + * Various libusb API related stuff + */ + +#define USB_ENDPOINT_IN 0x80 +#define USB_ENDPOINT_OUT 0x00 + +/* Error codes */ +#define USB_ERROR_BEGIN 500000 + +/* + * This is supposed to look weird. This file is generated from autoconf + * and I didn't want to make this too complicated. + */ +#define USB_LE16_TO_CPU(x) + +/* + * Device reset types for usb_reset_ex. + * http://msdn.microsoft.com/en-us/library/ff537269%28VS.85%29.aspx + * http://msdn.microsoft.com/en-us/library/ff537243%28v=vs.85%29.aspx + */ +#define USB_RESET_TYPE_RESET_PORT (1 << 0) +#define USB_RESET_TYPE_CYCLE_PORT (1 << 1) +#define USB_RESET_TYPE_FULL_RESET (USB_RESET_TYPE_CYCLE_PORT | USB_RESET_TYPE_RESET_PORT) + + +/* Data types */ +/* struct usb_device; */ +/* struct usb_bus; */ + +struct usb_device +{ + struct usb_device *next, *prev; + + char filename[LIBUSB_PATH_MAX]; + + struct usb_bus *bus; + + struct usb_device_descriptor descriptor; + struct usb_config_descriptor *config; + + void *dev; /* Darwin support */ + + unsigned char devnum; + + unsigned char num_children; + struct usb_device **children; +}; + +struct usb_bus +{ + struct usb_bus *next, *prev; + + char dirname[LIBUSB_PATH_MAX]; + + struct usb_device *devices; + unsigned long location; + + struct usb_device *root_dev; +}; + +/* Version information, Windows specific */ +struct usb_version +{ + struct + { + int major; + int minor; + int micro; + int nano; + } dll; + struct + { + int major; + int minor; + int micro; + int nano; + } driver; +}; + + +struct usb_dev_handle; +typedef struct usb_dev_handle usb_dev_handle; + +/* Variables */ +#ifndef __USB_C__ +#define usb_busses usb_get_busses() +#endif + + + +#include + + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Function prototypes */ + + /* usb.c */ + usb_dev_handle *usb_open(struct usb_device *dev); + int usb_close(usb_dev_handle *dev); + int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, + size_t buflen); + int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, + size_t buflen); + + /* descriptors.c */ + int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, + unsigned char type, unsigned char index, + void *buf, int size); + int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, + unsigned char index, void *buf, int size); + + /* .c */ + int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, + int value, int index, char *bytes, int size, + int timeout); + int usb_set_configuration(usb_dev_handle *dev, int configuration); + int usb_claim_interface(usb_dev_handle *dev, int interface); + int usb_release_interface(usb_dev_handle *dev, int interface); + int usb_set_altinterface(usb_dev_handle *dev, int alternate); + int usb_resetep(usb_dev_handle *dev, unsigned int ep); + int usb_clear_halt(usb_dev_handle *dev, unsigned int ep); + int usb_reset(usb_dev_handle *dev); + int usb_reset_ex(usb_dev_handle *dev, unsigned int reset_type); + + char *usb_strerror(void); + + void usb_init(void); + void usb_set_debug(int level); + int usb_find_busses(void); + int usb_find_devices(void); + struct usb_device *usb_device(usb_dev_handle *dev); + struct usb_bus *usb_get_busses(void); + + + /* Windows specific functions */ + +#define LIBUSB_HAS_INSTALL_SERVICE_NP 1 + int usb_install_service_np(void); + void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1 + int usb_uninstall_service_np(void); + void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_INSTALL_DRIVER_NP 1 + int usb_install_driver_np(const char *inf_file); + void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1 + int usb_touch_inf_file_np(const char *inf_file); + void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1 + int usb_install_needs_restart_np(void); + +#define LIBUSB_HAS_INSTALL_NP 1 + int usb_install_npW(HWND hwnd, HINSTANCE instance, LPCWSTR cmd_line, int starg_arg); + int usb_install_npA(HWND hwnd, HINSTANCE instance, LPCSTR cmd_line, int starg_arg); + #define usb_install_np usb_install_npA + void CALLBACK usb_install_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + + const struct usb_version *usb_get_version(void); + + int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep, int pktsize); + int usb_bulk_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); + int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); + + int usb_submit_async(void *context, char *bytes, int size); + int usb_reap_async(void *context, int timeout); + int usb_reap_async_nocancel(void *context, int timeout); + int usb_cancel_async(void *context); + int usb_free_async(void **context); + + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_H__ */ + diff --git a/Externals/libusb/win32/hidapi.h b/Externals/libusb/win32/hidapi.h new file mode 100644 index 0000000000..bd912acd7f --- /dev/null +++ b/Externals/libusb/win32/hidapi.h @@ -0,0 +1,384 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/** @file + * @defgroup API hidapi API + */ + +#ifndef HIDAPI_H__ +#define HIDAPI_H__ + +#include + +#ifdef _WIN32 + #define HID_API_EXPORT __declspec(dllexport) + #define HID_API_CALL +#else + #define HID_API_EXPORT /**< API export macro */ + #define HID_API_CALL /**< API call macro */ +#endif + +#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ + +#ifdef __cplusplus +extern "C" { +#endif + struct hid_device_; + typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ + + /** hidapi info structure */ + struct hid_device_info { + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. Valid on both Linux implementations + in all cases, and valid on the Windows implementation + only if the device contains more than one interface. */ + int interface_number; + + /** Pointer to the next device */ + struct hid_device_info *next; + }; + + + /** @brief Initialize the HIDAPI library. + + This function initializes the HIDAPI library. Calling it is not + strictly necessary, as it will be called automatically by + hid_enumerate() and any of the hid_open_*() functions if it is + needed. This function should be called at the beginning of + execution however, if there is a chance of HIDAPI handles + being opened by different threads simultaneously. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_init(void); + + /** @brief Finalize the HIDAPI library. + + This function frees all of the static data associated with + HIDAPI. It should be called at the end of execution to avoid + memory leaks. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_exit(void); + + /** @brief Enumerate the HID Devices. + + This function returns a linked list of all the HID devices + attached to the system which match vendor_id and product_id. + If @p vendor_id and @p product_id are both set to 0, then + all HID devices will be returned. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the types of device + to open. + @param product_id The Product ID (PID) of the types of + device to open. + + @returns + This function returns a pointer to a linked list of type + struct #hid_device, containing information about the HID devices + attached to the system, or NULL in the case of failure. Free + this linked list by calling hid_free_enumeration(). + */ + struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); + + /** @brief Free an enumeration Linked List + + This function frees a linked list created by hid_enumerate(). + + @ingroup API + @param devs Pointer to a list of struct_device returned from + hid_enumerate(). + */ + void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); + + /** @brief Open a HID device using a Vendor ID (VID), Product ID + (PID) and optionally a serial number. + + If @p serial_number is NULL, the first device with the + specified VID and PID is opened. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the device to open. + @param product_id The Product ID (PID) of the device to open. + @param serial_number The Serial Number of the device to open + (Optionally NULL). + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number); + + /** @brief Open a HID device by its path name. + + The path name be determined by calling hid_enumerate(), or a + platform-specific path name can be used (eg: /dev/hidraw0 on + Linux). + + @ingroup API + @param path The path name of the device to open + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); + + /** @brief Write an Output report to a HID device. + + The first byte of @p data[] must contain the Report ID. For + devices which only support a single report, this must be set + to 0x0. The remaining bytes contain the report data. Since + the Report ID is mandatory, calls to hid_write() will always + contain one more byte than the report contains. For example, + if a hid report is 16 bytes long, 17 bytes must be passed to + hid_write(), the Report ID (or 0x0, for devices with a + single report), followed by the report data (16 bytes). In + this example, the length passed in would be 17. + + hid_write() will send the data on the first OUT endpoint, if + one exists. If it does not, it will send the data through + the Control Endpoint (Endpoint 0). + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); + + int HID_API_EXPORT HID_API_CALL hid_set_output_report(hid_device *dev, const unsigned char *data, size_t length); + /** @brief Read an Input report from a HID device with timeout. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + @param milliseconds timeout in milliseconds or -1 for blocking wait. + + @returns + This function returns the actual number of bytes read and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); + + /** @brief Read an Input report from a HID device. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + + @returns + This function returns the actual number of bytes read and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); + + /** @brief Set the device handle to be non-blocking. + + In non-blocking mode calls to hid_read() will return + immediately with a value of 0 if there is no data to be + read. In blocking mode, hid_read() will wait (block) until + there is data to read before returning. + + Nonblocking can be turned on and off at any time. + + @ingroup API + @param device A device handle returned from hid_open(). + @param nonblock enable or not the nonblocking reads + - 1 to enable nonblocking + - 0 to disable nonblocking. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); + + /** @brief Send a Feature report to the device. + + Feature reports are sent over the Control endpoint as a + Set_Report transfer. The first byte of @p data[] must + contain the Report ID. For devices which only support a + single report, this must be set to 0x0. The remaining bytes + contain the report data. Since the Report ID is mandatory, + calls to hid_send_feature_report() will always contain one + more byte than the report contains. For example, if a hid + report is 16 bytes long, 17 bytes must be passed to + hid_send_feature_report(): the Report ID (or 0x0, for + devices which do not use numbered reports), followed by the + report data (16 bytes). In this example, the length passed + in would be 17. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send, including + the report number. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); + + /** @brief Get a feature report from a HID device. + + Make sure to set the first byte of @p data[] to the Report + ID of the report to be read. Make sure to allow space for + this extra byte in @p data[]. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into, including + the Report ID. Set the first byte of @p data[] to the + Report ID of the report to be read. + @param length The number of bytes to read, including an + extra byte for the report ID. The buffer can be longer + than the actual report. + + @returns + This function returns the number of bytes read and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); + + /** @brief Close a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + */ + void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); + + /** @brief Get The Manufacturer String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Product String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Serial Number String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get a string from a HID device, based on its string index. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string_index The index of the string to get. + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); + + /** @brief Get a string describing the last error which occurred. + + @ingroup API + @param device A device handle returned from hid_open(). + + @returns + This function returns a string containing the last error + which occurred or NULL if none has occurred. + */ + HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Externals/libusb/win32/lusb0_usb.h b/Externals/libusb/win32/lusb0_usb.h new file mode 100644 index 0000000000..b95fbf0a6d --- /dev/null +++ b/Externals/libusb/win32/lusb0_usb.h @@ -0,0 +1,427 @@ +#ifndef __USB_H__ +#define __USB_H__ + +#include +#include + +/* + * 'interface' is defined somewhere in the Windows header files. This macro + * is deleted here to avoid conflicts and compile errors. + */ + +#ifdef interface +#undef interface +#endif + +/* + * PATH_MAX from limits.h can't be used on Windows if the dll and + * import libraries are build/used by different compilers + */ + +#define LIBUSB_PATH_MAX 512 + + +/* + * USB spec information + * + * This is all stuff grabbed from various USB specs and is pretty much + * not subject to change + */ + +/* + * Device and/or Interface Class codes + */ +#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_DATA 10 +#define USB_CLASS_VENDOR_SPEC 0xff + +/* + * Descriptor types + */ +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 + +#define USB_DT_HID 0x21 +#define USB_DT_REPORT 0x22 +#define USB_DT_PHYSICAL 0x23 +#define USB_DT_HUB 0x29 + +/* + * Descriptor sizes per descriptor type + */ +#define USB_DT_DEVICE_SIZE 18 +#define USB_DT_CONFIG_SIZE 9 +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define USB_DT_HUB_NONVAR_SIZE 7 + + +/* ensure byte-packed structures */ +#include + + +/* All standard descriptors have these 2 fields in common */ +struct usb_descriptor_header +{ + unsigned char bLength; + unsigned char bDescriptorType; +}; + +/* String descriptor */ +struct usb_string_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wData[1]; +}; + +/* HID descriptor */ +struct usb_hid_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdHID; + unsigned char bCountryCode; + unsigned char bNumDescriptors; +}; + +/* Endpoint descriptor */ +#define USB_MAXENDPOINTS 32 +struct usb_endpoint_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bEndpointAddress; + unsigned char bmAttributes; + unsigned short wMaxPacketSize; + unsigned char bInterval; + unsigned char bRefresh; + unsigned char bSynchAddress; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */ +#define USB_ENDPOINT_TYPE_CONTROL 0 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1 +#define USB_ENDPOINT_TYPE_BULK 2 +#define USB_ENDPOINT_TYPE_INTERRUPT 3 + +/* Interface descriptor */ +#define USB_MAXINTERFACES 32 +struct usb_interface_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bInterfaceNumber; + unsigned char bAlternateSetting; + unsigned char bNumEndpoints; + unsigned char bInterfaceClass; + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char iInterface; + + struct usb_endpoint_descriptor *endpoint; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +#define USB_MAXALTSETTING 128 /* Hard limit */ + +struct usb_interface +{ + struct usb_interface_descriptor *altsetting; + + int num_altsetting; +}; + +/* Configuration descriptor information.. */ +#define USB_MAXCONFIG 8 +struct usb_config_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wTotalLength; + unsigned char bNumInterfaces; + unsigned char bConfigurationValue; + unsigned char iConfiguration; + unsigned char bmAttributes; + unsigned char MaxPower; + + struct usb_interface *interface; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +/* Device descriptor */ +struct usb_device_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdUSB; + unsigned char bDeviceClass; + unsigned char bDeviceSubClass; + unsigned char bDeviceProtocol; + unsigned char bMaxPacketSize0; + unsigned short idVendor; + unsigned short idProduct; + unsigned short bcdDevice; + unsigned char iManufacturer; + unsigned char iProduct; + unsigned char iSerialNumber; + unsigned char bNumConfigurations; +}; + +struct usb_ctrl_setup +{ + unsigned char bRequestType; + unsigned char bRequest; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; +}; + +/* + * Standard requests + */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +/* 0x02 is reserved */ +#define USB_REQ_SET_FEATURE 0x03 +/* 0x04 is reserved */ +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 + +/* + * Various libusb API related stuff + */ + +#define USB_ENDPOINT_IN 0x80 +#define USB_ENDPOINT_OUT 0x00 + +/* Error codes */ +#define USB_ERROR_BEGIN 500000 + +/* + * This is supposed to look weird. This file is generated from autoconf + * and I didn't want to make this too complicated. + */ +#define USB_LE16_TO_CPU(x) + +/* + * Device reset types for usb_reset_ex. + * http://msdn.microsoft.com/en-us/library/ff537269%28VS.85%29.aspx + * http://msdn.microsoft.com/en-us/library/ff537243%28v=vs.85%29.aspx + */ +#define USB_RESET_TYPE_RESET_PORT (1 << 0) +#define USB_RESET_TYPE_CYCLE_PORT (1 << 1) +#define USB_RESET_TYPE_FULL_RESET (USB_RESET_TYPE_CYCLE_PORT | USB_RESET_TYPE_RESET_PORT) + + +/* Data types */ +/* struct usb_device; */ +/* struct usb_bus; */ + +struct usb_device +{ + struct usb_device *next, *prev; + + char filename[LIBUSB_PATH_MAX]; + + struct usb_bus *bus; + + struct usb_device_descriptor descriptor; + struct usb_config_descriptor *config; + + void *dev; /* Darwin support */ + + unsigned char devnum; + + unsigned char num_children; + struct usb_device **children; +}; + +struct usb_bus +{ + struct usb_bus *next, *prev; + + char dirname[LIBUSB_PATH_MAX]; + + struct usb_device *devices; + unsigned long location; + + struct usb_device *root_dev; +}; + +/* Version information, Windows specific */ +struct usb_version +{ + struct + { + int major; + int minor; + int micro; + int nano; + } dll; + struct + { + int major; + int minor; + int micro; + int nano; + } driver; +}; + + +struct usb_dev_handle; +typedef struct usb_dev_handle usb_dev_handle; + +/* Variables */ +#ifndef __USB_C__ +#define usb_busses usb_get_busses() +#endif + + + +#include + + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Function prototypes */ + + /* usb.c */ + usb_dev_handle *usb_open(struct usb_device *dev); + int usb_close(usb_dev_handle *dev); + int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, + size_t buflen); + int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, + size_t buflen); + + /* descriptors.c */ + int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, + unsigned char type, unsigned char index, + void *buf, int size); + int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, + unsigned char index, void *buf, int size); + + /* .c */ + int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, + int value, int index, char *bytes, int size, + int timeout); + int usb_set_configuration(usb_dev_handle *dev, int configuration); + int usb_claim_interface(usb_dev_handle *dev, int interface); + int usb_release_interface(usb_dev_handle *dev, int interface); + int usb_set_altinterface(usb_dev_handle *dev, int alternate); + int usb_resetep(usb_dev_handle *dev, unsigned int ep); + int usb_clear_halt(usb_dev_handle *dev, unsigned int ep); + int usb_reset(usb_dev_handle *dev); + int usb_reset_ex(usb_dev_handle *dev, unsigned int reset_type); + + char *usb_strerror(void); + + void usb_init(void); + void usb_set_debug(int level); + int usb_find_busses(void); + int usb_find_devices(void); + struct usb_device *usb_device(usb_dev_handle *dev); + struct usb_bus *usb_get_busses(void); + + + /* Windows specific functions */ + +#define LIBUSB_HAS_INSTALL_SERVICE_NP 1 + int usb_install_service_np(void); + void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1 + int usb_uninstall_service_np(void); + void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_INSTALL_DRIVER_NP 1 + int usb_install_driver_np(const char *inf_file); + void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1 + int usb_touch_inf_file_np(const char *inf_file); + void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1 + int usb_install_needs_restart_np(void); + +#define LIBUSB_HAS_INSTALL_NP 1 + int usb_install_npW(HWND hwnd, HINSTANCE instance, LPCWSTR cmd_line, int starg_arg); + int usb_install_npA(HWND hwnd, HINSTANCE instance, LPCSTR cmd_line, int starg_arg); + #define usb_install_np usb_install_npA + void CALLBACK usb_install_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + + const struct usb_version *usb_get_version(void); + + int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep, int pktsize); + int usb_bulk_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); + int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); + + int usb_submit_async(void *context, char *bytes, int size); + int usb_reap_async(void *context, int timeout); + int usb_reap_async_nocancel(void *context, int timeout); + int usb_cancel_async(void *context); + int usb_free_async(void **context); + + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_H__ */ + diff --git a/Externals/libusb/x64/hidapi.dll b/Externals/libusb/x64/hidapi.dll new file mode 100644 index 0000000000000000000000000000000000000000..1461560e500765127d643e677dee6cd415a2c708 GIT binary patch literal 37888 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 literal 0 HcmV?d00001 diff --git a/Externals/libusb/x64/hidapi.h b/Externals/libusb/x64/hidapi.h new file mode 100644 index 0000000000..bd912acd7f --- /dev/null +++ b/Externals/libusb/x64/hidapi.h @@ -0,0 +1,384 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/** @file + * @defgroup API hidapi API + */ + +#ifndef HIDAPI_H__ +#define HIDAPI_H__ + +#include + +#ifdef _WIN32 + #define HID_API_EXPORT __declspec(dllexport) + #define HID_API_CALL +#else + #define HID_API_EXPORT /**< API export macro */ + #define HID_API_CALL /**< API call macro */ +#endif + +#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ + +#ifdef __cplusplus +extern "C" { +#endif + struct hid_device_; + typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ + + /** hidapi info structure */ + struct hid_device_info { + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. Valid on both Linux implementations + in all cases, and valid on the Windows implementation + only if the device contains more than one interface. */ + int interface_number; + + /** Pointer to the next device */ + struct hid_device_info *next; + }; + + + /** @brief Initialize the HIDAPI library. + + This function initializes the HIDAPI library. Calling it is not + strictly necessary, as it will be called automatically by + hid_enumerate() and any of the hid_open_*() functions if it is + needed. This function should be called at the beginning of + execution however, if there is a chance of HIDAPI handles + being opened by different threads simultaneously. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_init(void); + + /** @brief Finalize the HIDAPI library. + + This function frees all of the static data associated with + HIDAPI. It should be called at the end of execution to avoid + memory leaks. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_exit(void); + + /** @brief Enumerate the HID Devices. + + This function returns a linked list of all the HID devices + attached to the system which match vendor_id and product_id. + If @p vendor_id and @p product_id are both set to 0, then + all HID devices will be returned. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the types of device + to open. + @param product_id The Product ID (PID) of the types of + device to open. + + @returns + This function returns a pointer to a linked list of type + struct #hid_device, containing information about the HID devices + attached to the system, or NULL in the case of failure. Free + this linked list by calling hid_free_enumeration(). + */ + struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); + + /** @brief Free an enumeration Linked List + + This function frees a linked list created by hid_enumerate(). + + @ingroup API + @param devs Pointer to a list of struct_device returned from + hid_enumerate(). + */ + void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); + + /** @brief Open a HID device using a Vendor ID (VID), Product ID + (PID) and optionally a serial number. + + If @p serial_number is NULL, the first device with the + specified VID and PID is opened. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the device to open. + @param product_id The Product ID (PID) of the device to open. + @param serial_number The Serial Number of the device to open + (Optionally NULL). + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number); + + /** @brief Open a HID device by its path name. + + The path name be determined by calling hid_enumerate(), or a + platform-specific path name can be used (eg: /dev/hidraw0 on + Linux). + + @ingroup API + @param path The path name of the device to open + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); + + /** @brief Write an Output report to a HID device. + + The first byte of @p data[] must contain the Report ID. For + devices which only support a single report, this must be set + to 0x0. The remaining bytes contain the report data. Since + the Report ID is mandatory, calls to hid_write() will always + contain one more byte than the report contains. For example, + if a hid report is 16 bytes long, 17 bytes must be passed to + hid_write(), the Report ID (or 0x0, for devices with a + single report), followed by the report data (16 bytes). In + this example, the length passed in would be 17. + + hid_write() will send the data on the first OUT endpoint, if + one exists. If it does not, it will send the data through + the Control Endpoint (Endpoint 0). + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); + + int HID_API_EXPORT HID_API_CALL hid_set_output_report(hid_device *dev, const unsigned char *data, size_t length); + /** @brief Read an Input report from a HID device with timeout. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + @param milliseconds timeout in milliseconds or -1 for blocking wait. + + @returns + This function returns the actual number of bytes read and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); + + /** @brief Read an Input report from a HID device. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + + @returns + This function returns the actual number of bytes read and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); + + /** @brief Set the device handle to be non-blocking. + + In non-blocking mode calls to hid_read() will return + immediately with a value of 0 if there is no data to be + read. In blocking mode, hid_read() will wait (block) until + there is data to read before returning. + + Nonblocking can be turned on and off at any time. + + @ingroup API + @param device A device handle returned from hid_open(). + @param nonblock enable or not the nonblocking reads + - 1 to enable nonblocking + - 0 to disable nonblocking. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); + + /** @brief Send a Feature report to the device. + + Feature reports are sent over the Control endpoint as a + Set_Report transfer. The first byte of @p data[] must + contain the Report ID. For devices which only support a + single report, this must be set to 0x0. The remaining bytes + contain the report data. Since the Report ID is mandatory, + calls to hid_send_feature_report() will always contain one + more byte than the report contains. For example, if a hid + report is 16 bytes long, 17 bytes must be passed to + hid_send_feature_report(): the Report ID (or 0x0, for + devices which do not use numbered reports), followed by the + report data (16 bytes). In this example, the length passed + in would be 17. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send, including + the report number. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); + + /** @brief Get a feature report from a HID device. + + Make sure to set the first byte of @p data[] to the Report + ID of the report to be read. Make sure to allow space for + this extra byte in @p data[]. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into, including + the Report ID. Set the first byte of @p data[] to the + Report ID of the report to be read. + @param length The number of bytes to read, including an + extra byte for the report ID. The buffer can be longer + than the actual report. + + @returns + This function returns the number of bytes read and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); + + /** @brief Close a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + */ + void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); + + /** @brief Get The Manufacturer String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Product String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Serial Number String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get a string from a HID device, based on its string index. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string_index The index of the string to get. + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); + + /** @brief Get a string describing the last error which occurred. + + @ingroup API + @param device A device handle returned from hid_open(). + + @returns + This function returns a string containing the last error + which occurred or NULL if none has occurred. + */ + HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Externals/libusb/x64/lusb0_usb.h b/Externals/libusb/x64/lusb0_usb.h new file mode 100644 index 0000000000..b95fbf0a6d --- /dev/null +++ b/Externals/libusb/x64/lusb0_usb.h @@ -0,0 +1,427 @@ +#ifndef __USB_H__ +#define __USB_H__ + +#include +#include + +/* + * 'interface' is defined somewhere in the Windows header files. This macro + * is deleted here to avoid conflicts and compile errors. + */ + +#ifdef interface +#undef interface +#endif + +/* + * PATH_MAX from limits.h can't be used on Windows if the dll and + * import libraries are build/used by different compilers + */ + +#define LIBUSB_PATH_MAX 512 + + +/* + * USB spec information + * + * This is all stuff grabbed from various USB specs and is pretty much + * not subject to change + */ + +/* + * Device and/or Interface Class codes + */ +#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_DATA 10 +#define USB_CLASS_VENDOR_SPEC 0xff + +/* + * Descriptor types + */ +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 + +#define USB_DT_HID 0x21 +#define USB_DT_REPORT 0x22 +#define USB_DT_PHYSICAL 0x23 +#define USB_DT_HUB 0x29 + +/* + * Descriptor sizes per descriptor type + */ +#define USB_DT_DEVICE_SIZE 18 +#define USB_DT_CONFIG_SIZE 9 +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define USB_DT_HUB_NONVAR_SIZE 7 + + +/* ensure byte-packed structures */ +#include + + +/* All standard descriptors have these 2 fields in common */ +struct usb_descriptor_header +{ + unsigned char bLength; + unsigned char bDescriptorType; +}; + +/* String descriptor */ +struct usb_string_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wData[1]; +}; + +/* HID descriptor */ +struct usb_hid_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdHID; + unsigned char bCountryCode; + unsigned char bNumDescriptors; +}; + +/* Endpoint descriptor */ +#define USB_MAXENDPOINTS 32 +struct usb_endpoint_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bEndpointAddress; + unsigned char bmAttributes; + unsigned short wMaxPacketSize; + unsigned char bInterval; + unsigned char bRefresh; + unsigned char bSynchAddress; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */ +#define USB_ENDPOINT_TYPE_CONTROL 0 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1 +#define USB_ENDPOINT_TYPE_BULK 2 +#define USB_ENDPOINT_TYPE_INTERRUPT 3 + +/* Interface descriptor */ +#define USB_MAXINTERFACES 32 +struct usb_interface_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bInterfaceNumber; + unsigned char bAlternateSetting; + unsigned char bNumEndpoints; + unsigned char bInterfaceClass; + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char iInterface; + + struct usb_endpoint_descriptor *endpoint; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +#define USB_MAXALTSETTING 128 /* Hard limit */ + +struct usb_interface +{ + struct usb_interface_descriptor *altsetting; + + int num_altsetting; +}; + +/* Configuration descriptor information.. */ +#define USB_MAXCONFIG 8 +struct usb_config_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wTotalLength; + unsigned char bNumInterfaces; + unsigned char bConfigurationValue; + unsigned char iConfiguration; + unsigned char bmAttributes; + unsigned char MaxPower; + + struct usb_interface *interface; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +/* Device descriptor */ +struct usb_device_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdUSB; + unsigned char bDeviceClass; + unsigned char bDeviceSubClass; + unsigned char bDeviceProtocol; + unsigned char bMaxPacketSize0; + unsigned short idVendor; + unsigned short idProduct; + unsigned short bcdDevice; + unsigned char iManufacturer; + unsigned char iProduct; + unsigned char iSerialNumber; + unsigned char bNumConfigurations; +}; + +struct usb_ctrl_setup +{ + unsigned char bRequestType; + unsigned char bRequest; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; +}; + +/* + * Standard requests + */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +/* 0x02 is reserved */ +#define USB_REQ_SET_FEATURE 0x03 +/* 0x04 is reserved */ +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 + +/* + * Various libusb API related stuff + */ + +#define USB_ENDPOINT_IN 0x80 +#define USB_ENDPOINT_OUT 0x00 + +/* Error codes */ +#define USB_ERROR_BEGIN 500000 + +/* + * This is supposed to look weird. This file is generated from autoconf + * and I didn't want to make this too complicated. + */ +#define USB_LE16_TO_CPU(x) + +/* + * Device reset types for usb_reset_ex. + * http://msdn.microsoft.com/en-us/library/ff537269%28VS.85%29.aspx + * http://msdn.microsoft.com/en-us/library/ff537243%28v=vs.85%29.aspx + */ +#define USB_RESET_TYPE_RESET_PORT (1 << 0) +#define USB_RESET_TYPE_CYCLE_PORT (1 << 1) +#define USB_RESET_TYPE_FULL_RESET (USB_RESET_TYPE_CYCLE_PORT | USB_RESET_TYPE_RESET_PORT) + + +/* Data types */ +/* struct usb_device; */ +/* struct usb_bus; */ + +struct usb_device +{ + struct usb_device *next, *prev; + + char filename[LIBUSB_PATH_MAX]; + + struct usb_bus *bus; + + struct usb_device_descriptor descriptor; + struct usb_config_descriptor *config; + + void *dev; /* Darwin support */ + + unsigned char devnum; + + unsigned char num_children; + struct usb_device **children; +}; + +struct usb_bus +{ + struct usb_bus *next, *prev; + + char dirname[LIBUSB_PATH_MAX]; + + struct usb_device *devices; + unsigned long location; + + struct usb_device *root_dev; +}; + +/* Version information, Windows specific */ +struct usb_version +{ + struct + { + int major; + int minor; + int micro; + int nano; + } dll; + struct + { + int major; + int minor; + int micro; + int nano; + } driver; +}; + + +struct usb_dev_handle; +typedef struct usb_dev_handle usb_dev_handle; + +/* Variables */ +#ifndef __USB_C__ +#define usb_busses usb_get_busses() +#endif + + + +#include + + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Function prototypes */ + + /* usb.c */ + usb_dev_handle *usb_open(struct usb_device *dev); + int usb_close(usb_dev_handle *dev); + int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, + size_t buflen); + int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, + size_t buflen); + + /* descriptors.c */ + int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, + unsigned char type, unsigned char index, + void *buf, int size); + int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, + unsigned char index, void *buf, int size); + + /* .c */ + int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); + int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, + int value, int index, char *bytes, int size, + int timeout); + int usb_set_configuration(usb_dev_handle *dev, int configuration); + int usb_claim_interface(usb_dev_handle *dev, int interface); + int usb_release_interface(usb_dev_handle *dev, int interface); + int usb_set_altinterface(usb_dev_handle *dev, int alternate); + int usb_resetep(usb_dev_handle *dev, unsigned int ep); + int usb_clear_halt(usb_dev_handle *dev, unsigned int ep); + int usb_reset(usb_dev_handle *dev); + int usb_reset_ex(usb_dev_handle *dev, unsigned int reset_type); + + char *usb_strerror(void); + + void usb_init(void); + void usb_set_debug(int level); + int usb_find_busses(void); + int usb_find_devices(void); + struct usb_device *usb_device(usb_dev_handle *dev); + struct usb_bus *usb_get_busses(void); + + + /* Windows specific functions */ + +#define LIBUSB_HAS_INSTALL_SERVICE_NP 1 + int usb_install_service_np(void); + void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1 + int usb_uninstall_service_np(void); + void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_INSTALL_DRIVER_NP 1 + int usb_install_driver_np(const char *inf_file); + void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1 + int usb_touch_inf_file_np(const char *inf_file); + void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1 + int usb_install_needs_restart_np(void); + +#define LIBUSB_HAS_INSTALL_NP 1 + int usb_install_npW(HWND hwnd, HINSTANCE instance, LPCWSTR cmd_line, int starg_arg); + int usb_install_npA(HWND hwnd, HINSTANCE instance, LPCSTR cmd_line, int starg_arg); + #define usb_install_np usb_install_npA + void CALLBACK usb_install_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + + const struct usb_version *usb_get_version(void); + + int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep, int pktsize); + int usb_bulk_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); + int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); + + int usb_submit_async(void *context, char *bytes, int size); + int usb_reap_async(void *context, int timeout); + int usb_reap_async_nocancel(void *context, int timeout); + int usb_cancel_async(void *context); + int usb_free_async(void **context); + + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_H__ */ + diff --git a/Source/Core/Common/Src/Log.h b/Source/Core/Common/Src/Log.h index 3be97d54d4..4892886693 100644 --- a/Source/Core/Common/Src/Log.h +++ b/Source/Core/Common/Src/Log.h @@ -64,6 +64,7 @@ enum LOG_TYPE { WII_IPC_DVD, WII_IPC_ES, WII_IPC_FILEIO, + WII_IPC_HID, WII_IPC_HLE, WII_IPC_NET, WII_IPC_SD, diff --git a/Source/Core/Common/Src/LogManager.cpp b/Source/Core/Common/Src/LogManager.cpp index a79c413cf8..df55f018c6 100644 --- a/Source/Core/Common/Src/LogManager.cpp +++ b/Source/Core/Common/Src/LogManager.cpp @@ -71,6 +71,7 @@ LogManager::LogManager() m_Log[LogTypes::WIIMOTE] = new LogContainer("Wiimote", "Wiimote"); m_Log[LogTypes::WII_IOB] = new LogContainer("WII_IOB", "WII IO Bridge"); m_Log[LogTypes::WII_IPC] = new LogContainer("WII_IPC", "WII IPC"); + m_Log[LogTypes::WII_IPC_HID] = new LogContainer("WII_IPC_HID", "WII IPC HID"); m_Log[LogTypes::WII_IPC_HLE] = new LogContainer("WII_IPC_HLE", "WII IPC HLE"); m_Log[LogTypes::WII_IPC_DVD] = new LogContainer("WII_IPC_DVD", "WII IPC DVD"); m_Log[LogTypes::WII_IPC_ES] = new LogContainer("WII_IPC_ES", "WII IPC ES"); diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index e03d40e43a..25ede66e60 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -115,7 +115,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include true @@ -127,7 +127,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include true @@ -139,7 +139,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories) true @@ -153,7 +153,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include true @@ -167,7 +167,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories) true @@ -181,7 +181,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include true @@ -326,6 +326,7 @@ + @@ -526,6 +527,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 020cf76ad0..475861b64a 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -556,6 +556,9 @@ HW %28Flipper/Hollywood%29\GCMemcard + + IPC HLE %28IOS/Starlet%29\USB + @@ -1033,6 +1036,9 @@ HW %28Flipper/Hollywood%29\GCMemcard + + IPC HLE %28IOS/Starlet%29\USB + @@ -1173,5 +1179,8 @@ {3e9e6e83-c1bf-45f9-aeff-231f98f60d29} + + {321a9af5-9b3d-4620-888c-fe9d02e9559e} + \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index cd4f679db9..40c31c9e2b 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -50,6 +50,7 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC #include "WII_IPC_HLE_Device_usb.h" #include "WII_IPC_HLE_Device_usb_kbd.h" #include "WII_IPC_HLE_Device_sdio_slot0.h" +#include "WII_IPC_HLE_Device_hid.h" #include "FileUtil.h" // For Copy #include "../ConfigManager.h" @@ -113,7 +114,7 @@ void Init() g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_kbd(i, std::string("/dev/usb/kbd")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_sdio_slot0(i, std::string("/dev/sdio/slot0")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++; - g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/hid")); i++; + g_DeviceMap[i] = new CWII_IPC_HLE_Device_hid(i, std::string("/dev/usb/hid")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++; g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++; } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp new file mode 100644 index 0000000000..0103a534c3 --- /dev/null +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -0,0 +1,416 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "../Core.h" +#include "../Debugger/Debugger_SymbolMap.h" +#include "../HW/WII_IPC.h" +#include "WII_IPC_HLE.h" +#include "WII_IPC_HLE_Device_hid.h" +#include "lusb0_usb.h" +#include "hidapi.h" + +CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) + : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) +{ + + usb_init(); /* initialize the library */ + +} + +CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() +{ + +} + +bool CWII_IPC_HLE_Device_hid::Open(u32 _CommandAddress, u32 _Mode) +{ + Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING); + DEBUG_LOG(WII_IPC_HID, "HID::Open"); + Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); + return true; +} + +bool CWII_IPC_HLE_Device_hid::Close(u32 _CommandAddress, bool _bForce) +{ + DEBUG_LOG(WII_IPC_HID, "HID::Close"); + if (!_bForce) + Memory::Write_U32(0, _CommandAddress + 4); + return true; +} + +bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) +{ + static u32 replyAddress = 0; + static bool hasRun = false; + u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); + u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); + u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); + u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); + u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); + + u32 ReturnValue = 0; + switch (Parameter) + { + case IOCTL_HID_GET_ATTACHED: + { + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + BufferIn, BufferInSize, BufferOut, BufferOutSize); + if(!hasRun) + { + FillOutDevices(BufferOut, BufferOutSize); + hasRun = true; + } + else + { + replyAddress = _CommandAddress; + return false; + } + break; + } + case IOCTL_HID_OPEN: + { + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Open) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + BufferIn, BufferInSize, BufferOut, BufferOutSize); + + //hid version, apparently + ReturnValue = 0x40001; + break; + } + case IOCTL_HID_SET_SUSPEND: + { + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Set Suspend) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + BufferIn, BufferInSize, BufferOut, BufferOutSize); + // not actually implemented in IOS + ReturnValue = 0; + + if (replyAddress != 0){ + FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); + WII_IPC_HLE_Interface::EnqReply(replyAddress); + replyAddress = 0; + hasRun = false; + } + + break; + } + case IOCTL_HID_CANCEL_INTERRUPT: + { + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + BufferIn, BufferInSize, BufferOut, BufferOutSize); + + if (replyAddress != 0){ + FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); + WII_IPC_HLE_Interface::EnqReply(replyAddress); + replyAddress = 0; + hasRun = false; + } + + ReturnValue = 0; + break; + } + case IOCTL_HID_CONTROL: + { + /* + ERROR CODES: + -4 Cant find device specified + */ + u32 dev_num = Memory::Read_U32(BufferIn+0x10); + u8 requesttype = Memory::Read_U8(BufferIn+0x14); + u8 request = Memory::Read_U8(BufferIn+0x15); + u16 value = Memory::Read_U16(BufferIn+0x16); + u16 index = Memory::Read_U16(BufferIn+0x18); + u16 size = Memory::Read_U16(BufferIn+0x1A); + u32 data = Memory::Read_U32(BufferIn+0x1C); + + static int upto = 0; + int i; + usb_find_busses(); /* find all busses */ + usb_find_devices(); /* find all connected devices */ + + struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + + if (dev_handle == NULL) + { + ReturnValue = -4; + break; + } + + ReturnValue = usb_control_msg(dev_handle, requesttype, request, + value, index, (char*)Memory::GetPointer(data), size, + 0); + + if(ReturnValue>=0) + { + ReturnValue += sizeof(usb_ctrl_setup); + } + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d", + requesttype, request, ReturnValue); + + usb_close(dev_handle); + + u8 test_out[0x20]; + Memory::ReadBigEData(test_out, BufferIn, BufferInSize); + char file[0x50]; + snprintf(file, 0x50, "ctrl_ctrlprotocol_%d.bin", upto); + FILE* test = fopen (file, "wb"); + for(i=0;i<0x20;i++) + fwrite(&test_out[i], 1, 1, test); + if (size > 0) + fwrite((char*)Memory::GetPointer(data), 1, size, test); + fclose(test); + upto++; + break; + } + case IOCTL_HID_INTERRUPT_IN: + { + + + u32 dev_num = Memory::Read_U32(BufferIn+0x10); + u32 end_point = Memory::Read_U32(BufferIn+0x14); + u32 length = Memory::Read_U32(BufferIn+0x18); + + u32 data = Memory::Read_U32(BufferIn+0x1C); + + struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + + if (dev_handle == NULL) + { + ReturnValue = -4; + break; + } + + usb_claim_interface(dev_handle,0); + ReturnValue = usb_interrupt_read(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 1000); + + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt In)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + end_point, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + + usb_close(dev_handle); + break; + } + case IOCTL_HID_INTERRUPT_OUT: + { + + + u32 dev_num = Memory::Read_U32(BufferIn+0x10); + u32 end_point = Memory::Read_U32(BufferIn+0x14); + u32 length = Memory::Read_U32(BufferIn+0x18); + + u32 data = Memory::Read_U32(BufferIn+0x1C); + + struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + + if (dev_handle == NULL) + { + ReturnValue = -4; + break; + } + + usb_claim_interface(dev_handle,0); + ReturnValue = usb_interrupt_write(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 0); + + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt Out) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + + usb_close(dev_handle); + break; + } + default: + { + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(0x%x) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); + break; + } + } + + Memory::Write_U32(ReturnValue, _CommandAddress + 4); + + return true; +} + +bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) +{ + + Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING); + u32 ReturnValue = 0; + SIOCtlVBuffer CommandBuffer(_CommandAddress); + + switch (CommandBuffer.Parameter) + { + + default: + { + DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); + DEBUG_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); + DEBUG_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); + DEBUG_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); + DEBUG_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); + DEBUG_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); + DEBUG_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); + #if defined(_DEBUG) || defined(DEBUGFAST) + DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); + #endif + } + break; + } + + Memory::Write_U32(ReturnValue, _CommandAddress + 4); + return true; +} + + + +void CWII_IPC_HLE_Device_hid::ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src) +{ + memcpy(dest,src,sizeof(WiiHIDDeviceDescriptor)); + dest->bcdUSB = Common::swap16(dest->bcdUSB); + dest->idVendor = Common::swap16(dest->idVendor); + dest->idProduct = Common::swap16(dest->idProduct); + dest->bcdDevice = Common::swap16(dest->bcdDevice); +} + +void CWII_IPC_HLE_Device_hid::ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src) +{ + memcpy(dest,src,sizeof(WiiHIDConfigDescriptor)); + dest->wTotalLength = Common::swap16(dest->wTotalLength); +} + +void CWII_IPC_HLE_Device_hid::ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, struct usb_interface_descriptor *src) +{ + memcpy(dest,src,sizeof(WiiHIDInterfaceDescriptor)); +} + +void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src) +{ + memcpy(dest,src,sizeof(WiiHIDEndpointDescriptor)); + dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize); +} +/* +// hidapi version +void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) +{ + // Enumerate and print the HID devices on the system + struct hid_device_info *devs, *cur_dev; + + devs = hid_enumerate(0x0, 0x0); + cur_dev = devs; + while (cur_dev) { + printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", + cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); + printf("\n"); + printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string); + printf(" Product: %ls\n", cur_dev->product_string); + printf("\n"); + cur_dev = cur_dev->next; + } + hid_free_enumeration(devs); +} +*/ + +// libusb version +void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) +{ + usb_find_busses(); // find all busses + usb_find_devices(); // find all connected devices + struct usb_bus *bus; + struct usb_device *dev; + int OffsetBuffer = BufferOut; + int OffsetStart = 0; + int c,ic,i,e; // config, interface container, interface, endpoint + for (bus = usb_get_busses(); bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { + struct usb_device_descriptor *device = &dev->descriptor; + DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d",device->idVendor, device->idProduct, dev->devnum); + + OffsetStart = OffsetBuffer; + OffsetBuffer += 4; // skip length for now, fill at end + + Memory::Write_U32(dev->devnum, OffsetBuffer); //write device num + OffsetBuffer += 4; + + WiiHIDDeviceDescriptor wii_device; + ConvertDeviceToWii(&wii_device, device); + Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4)); + OffsetBuffer += Align(wii_device.bLength, 4); + + for (c = 0; c < device->bNumConfigurations; c++) + { + struct usb_config_descriptor *config = &dev->config[c]; + + WiiHIDConfigDescriptor wii_config; + ConvertConfigToWii(&wii_config, config); + Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(wii_config.bLength, 4)); + OffsetBuffer += Align(wii_config.bLength, 4); + + for (ic = 0; ic < config->bNumInterfaces; ic++) + { + struct usb_interface *interfaceContainer = &config->interface[ic]; + for (i = 0; i < interfaceContainer->num_altsetting; i++) + { + struct usb_interface_descriptor *interface = &interfaceContainer->altsetting[i]; + + WiiHIDInterfaceDescriptor wii_interface; + ConvertInterfaceToWii(&wii_interface, interface); + Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(wii_interface.bLength, 4)); + OffsetBuffer += Align(wii_interface.bLength, 4); + + for (e = 0; e < interface->bNumEndpoints; e++) + { + struct usb_endpoint_descriptor *endpoint = &interface->endpoint[e]; + + WiiHIDEndpointDescriptor wii_endpoint; + ConvertEndpointToWii(&wii_endpoint, endpoint); + Memory::WriteBigEData((const u8*)&wii_endpoint, OffsetBuffer, Align(wii_endpoint.bLength, 4)); + OffsetBuffer += Align(wii_endpoint.bLength, 4); + + } //endpoints + } // interfaces + } // interface containters + } // configs + + Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length + + } // devices + } // buses + + Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices + + +} + + + +int CWII_IPC_HLE_Device_hid::Align(int num, int alignment) +{ + return (num + (alignment-1)) & ~(alignment-1); +} + + +struct usb_dev_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) +{ + for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) + { + for (struct usb_device *dev = bus->devices; dev; dev = dev->next) + { + if(dev->devnum == devNum){ + return usb_open(dev); + } + } + } + return NULL; +} \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h new file mode 100644 index 0000000000..2bb7f47a59 --- /dev/null +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -0,0 +1,126 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +#include "WII_IPC_HLE.h" +#include "WII_IPC_HLE_Device.h" + +class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device +{ +public: + CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName); + + virtual ~CWII_IPC_HLE_Device_hid(); + + virtual bool Open(u32 _CommandAddress, u32 _Mode); + virtual bool Close(u32 _CommandAddress, bool _bForce); + + virtual bool IOCtlV(u32 _CommandAddress); + virtual bool IOCtl(u32 _CommandAddress); +private: + + + std::map deviceList; + + enum + { + IOCTL_HID_GET_ATTACHED = 0x00, + IOCTL_HID_SET_SUSPEND = 0x01, + IOCTL_HID_CONTROL = 0x02, + IOCTL_HID_INTERRUPT_IN = 0x03, + IOCTL_HID_INTERRUPT_OUT = 0x04, + IOCTL_HID_GET_US_STRING = 0x05, + IOCTL_HID_OPEN = 0x06, + IOCTL_HID_SHUTDOWN = 0x07, + IOCTL_HID_CANCEL_INTERRUPT = 0x08, + }; + + /* Device descriptor */ + typedef struct + { + u8 bLength; + u8 bDescriptorType; + u16 bcdUSB; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u16 idVendor; + u16 idProduct; + u16 bcdDevice; + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; + u8 pad[2]; + } WiiHIDDeviceDescriptor; + + typedef struct + { + u8 bLength; + u8 bDescriptorType; + u16 wTotalLength; + u8 bNumInterfaces; + u8 bConfigurationValue; + u8 iConfiguration; + u8 bmAttributes; + u8 MaxPower; + u8 pad[3]; + } WiiHIDConfigDescriptor; + + typedef struct + { + u8 bLength; + u8 bDescriptorType; + u8 bInterfaceNumber; + u8 bAlternateSetting; + u8 bNumEndpoints; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + u8 iInterface; + u8 pad[3]; + } WiiHIDInterfaceDescriptor; + + typedef struct + { + u8 bLength; + u8 bDescriptorType; + u8 bEndpointAddress; + u8 bmAttributes; + u16 wMaxPacketSize; + u8 bInterval; + u8 bRefresh; + u8 bSynchAddress; + u8 pad[1]; + } WiiHIDEndpointDescriptor; + + + void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize); + + void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src); + void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src); + void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, struct usb_interface_descriptor *src); + void ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src); + + int Align(int num, int alignment); + + struct usb_dev_handle * GetDeviceByDevNum(u32 devNum); + + +}; diff --git a/Source/VSProps/Dolphin.Win32.props b/Source/VSProps/Dolphin.Win32.props index 5adc4159e0..a78f75c4ac 100644 --- a/Source/VSProps/Dolphin.Win32.props +++ b/Source/VSProps/Dolphin.Win32.props @@ -7,8 +7,8 @@ - ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName) - portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew32s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;%(AdditionalDependencies) + ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName);..\..\..\Externals\libusb\$(PlatformName) + portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew32s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;hidapi.lib;%(AdditionalDependencies) diff --git a/Source/VSProps/Dolphin.x64.props b/Source/VSProps/Dolphin.x64.props index 557e6350e7..c9cc2eb7ff 100644 --- a/Source/VSProps/Dolphin.x64.props +++ b/Source/VSProps/Dolphin.x64.props @@ -8,8 +8,8 @@ - ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg64;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName) - portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;%(AdditionalDependencies) + ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg64;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName);..\..\..\Externals\libusb\$(PlatformName) + portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;hidapi.lib;%(AdditionalDependencies)