From 8d5810a1038347b9e56d41334d3f83641c913b3d Mon Sep 17 00:00:00 2001 From: Vincent Duvert Date: Sun, 7 Jan 2018 11:00:01 +0100 Subject: [PATCH 1/3] macOS: Use unique IDs for HID paths If available, use the system-generated unique ID for HID device paths instead of a transport/vid/pid/location tuple. The Mayflash Dolphinbar registers four HID devices (regardless of the number of connected Wiimotes) which had the same path with the previous path building method, causing a bit of confusion when detecting and connecting to Wiimotes. The unique IDs do not change if the computer is suspended and resumed, but do change if the HID device is unplugged/replugged. --- Externals/hidapi/mac/hid.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Externals/hidapi/mac/hid.c b/Externals/hidapi/mac/hid.c index 38bb635af2..46a97886d7 100644 --- a/Externals/hidapi/mac/hid.c +++ b/Externals/hidapi/mac/hid.c @@ -217,6 +217,11 @@ static int32_t get_location_id(IOHIDDeviceRef device) return get_int_property(device, CFSTR(kIOHIDLocationIDKey)); } +static int32_t get_unique_id(IOHIDDeviceRef device) +{ + return get_int_property(device, CFSTR(kIOHIDUniqueIDKey)); +} + static int32_t get_max_report_length(IOHIDDeviceRef device) { return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey)); @@ -337,6 +342,7 @@ static int make_path(IOHIDDeviceRef device, char *buf, size_t len) unsigned short vid, pid; char transport[32]; int32_t location; + int32_t unique_id; buf[0] = '\0'; @@ -347,12 +353,17 @@ static int make_path(IOHIDDeviceRef device, char *buf, size_t len) if (!res) return -1; - location = get_location_id(device); - vid = get_vendor_id(device); - pid = get_product_id(device); + unique_id = get_unique_id(device); + if (unique_id != 0) { + res = snprintf(buf, len, "id_%x", unique_id); + } else { + location = get_location_id(device); + vid = get_vendor_id(device); + pid = get_product_id(device); - res = snprintf(buf, len, "%s_%04hx_%04hx_%x", - transport, vid, pid, location); + res = snprintf(buf, len, "%s_%04hx_%04hx_%x", + transport, vid, pid, location); + } buf[len-1] = '\0'; From 3abc288e02089b3143547177e027d3820e5d7e59 Mon Sep 17 00:00:00 2001 From: Vincent Duvert Date: Sun, 7 Jan 2018 11:14:51 +0100 Subject: [PATCH 2/3] macOS: Add errno setting in set_report (HID) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IsDeviceUsable in IOhidapi.cpp uses errno to detect if hid_write failed because of an unconnected Wiimote on a Dolphinbar (it expects errno == EPIPE in this case). macOS’s implementation of hid_write detected this specific error (IOHIDDeviceSetReport returns kUSBHostReturnPipeStalled) but didn’t set errno so the check failed. This add errno assignment to failure cases of macOS’s hid_write. --- Externals/hidapi/mac/hid.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Externals/hidapi/mac/hid.c b/Externals/hidapi/mac/hid.c index 46a97886d7..70b615d40d 100644 --- a/Externals/hidapi/mac/hid.c +++ b/Externals/hidapi/mac/hid.c @@ -773,8 +773,10 @@ static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char IOReturn res; /* Return if the device has been disconnected. */ - if (dev->disconnected) + if (dev->disconnected) { + errno = ENODEV; return -1; + } if (data[0] == 0x0) { /* Not using numbered Reports. @@ -797,9 +799,14 @@ static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char if (res == kIOReturnSuccess) { return length; - } - else + } else if (res == (IOReturn)0xe0005000) { + /* Kernel.framework's IOUSBHostFamily.h defines this error as kUSBHostReturnPipeStalled */ + errno = EPIPE; return -1; + } else { + errno = EBUSY; + return -1; + } } return -1; From bb5e5d964a172d92596aa403dec3f83f369554d8 Mon Sep 17 00:00:00 2001 From: Vincent Duvert Date: Sat, 13 Jan 2018 21:20:54 +0100 Subject: [PATCH 3/3] Added patches for hidapi modifications This allows tracking what modifications were made to the upstream code. --- ...1-macOS-Use-unique-IDs-for-HID-paths.patch | 62 +++++++++++++++++++ ...-Add-errno-setting-in-set_report-HID.patch | 51 +++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 Externals/hidapi/applied_patches/0001-macOS-Use-unique-IDs-for-HID-paths.patch create mode 100644 Externals/hidapi/applied_patches/0002-macOS-Add-errno-setting-in-set_report-HID.patch diff --git a/Externals/hidapi/applied_patches/0001-macOS-Use-unique-IDs-for-HID-paths.patch b/Externals/hidapi/applied_patches/0001-macOS-Use-unique-IDs-for-HID-paths.patch new file mode 100644 index 0000000000..a7cbac9866 --- /dev/null +++ b/Externals/hidapi/applied_patches/0001-macOS-Use-unique-IDs-for-HID-paths.patch @@ -0,0 +1,62 @@ +From 8d5810a1038347b9e56d41334d3f83641c913b3d Mon Sep 17 00:00:00 2001 +From: Vincent Duvert +Date: Sun, 7 Jan 2018 11:00:01 +0100 +Subject: [PATCH 1/2] macOS: Use unique IDs for HID paths + +If available, use the system-generated unique ID for HID device paths instead of a transport/vid/pid/location tuple. +The Mayflash Dolphinbar registers four HID devices (regardless of the number of connected Wiimotes) which had the same path with the previous path building method, causing a bit of confusion when detecting and connecting to Wiimotes. +The unique IDs do not change if the computer is suspended and resumed, but do change if the HID device is unplugged/replugged. +--- + Externals/hidapi/mac/hid.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +diff --git a/Externals/hidapi/mac/hid.c b/Externals/hidapi/mac/hid.c +index 38bb635af2..46a97886d7 100644 +--- a/Externals/hidapi/mac/hid.c ++++ b/Externals/hidapi/mac/hid.c +@@ -217,6 +217,11 @@ static int32_t get_location_id(IOHIDDeviceRef device) + return get_int_property(device, CFSTR(kIOHIDLocationIDKey)); + } + ++static int32_t get_unique_id(IOHIDDeviceRef device) ++{ ++ return get_int_property(device, CFSTR(kIOHIDUniqueIDKey)); ++} ++ + static int32_t get_max_report_length(IOHIDDeviceRef device) + { + return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey)); +@@ -337,6 +342,7 @@ static int make_path(IOHIDDeviceRef device, char *buf, size_t len) + unsigned short vid, pid; + char transport[32]; + int32_t location; ++ int32_t unique_id; + + buf[0] = '\0'; + +@@ -347,12 +353,17 @@ static int make_path(IOHIDDeviceRef device, char *buf, size_t len) + if (!res) + return -1; + +- location = get_location_id(device); +- vid = get_vendor_id(device); +- pid = get_product_id(device); ++ unique_id = get_unique_id(device); ++ if (unique_id != 0) { ++ res = snprintf(buf, len, "id_%x", unique_id); ++ } else { ++ location = get_location_id(device); ++ vid = get_vendor_id(device); ++ pid = get_product_id(device); + +- res = snprintf(buf, len, "%s_%04hx_%04hx_%x", +- transport, vid, pid, location); ++ res = snprintf(buf, len, "%s_%04hx_%04hx_%x", ++ transport, vid, pid, location); ++ } + + + buf[len-1] = '\0'; +-- +2.14.3 (Apple Git-98) + diff --git a/Externals/hidapi/applied_patches/0002-macOS-Add-errno-setting-in-set_report-HID.patch b/Externals/hidapi/applied_patches/0002-macOS-Add-errno-setting-in-set_report-HID.patch new file mode 100644 index 0000000000..87a928f203 --- /dev/null +++ b/Externals/hidapi/applied_patches/0002-macOS-Add-errno-setting-in-set_report-HID.patch @@ -0,0 +1,51 @@ +From 3abc288e02089b3143547177e027d3820e5d7e59 Mon Sep 17 00:00:00 2001 +From: Vincent Duvert +Date: Sun, 7 Jan 2018 11:14:51 +0100 +Subject: [PATCH 2/2] macOS: Add errno setting in set_report (HID) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +IsDeviceUsable in IOhidapi.cpp uses errno to detect if hid_write failed because of an unconnected Wiimote on a Dolphinbar (it expects errno == EPIPE in this case). +macOS’s implementation of hid_write detected this specific error (IOHIDDeviceSetReport returns kUSBHostReturnPipeStalled) but didn’t set errno so the check failed. +This add errno assignment to failure cases of macOS’s hid_write. +--- + Externals/hidapi/mac/hid.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/Externals/hidapi/mac/hid.c b/Externals/hidapi/mac/hid.c +index 46a97886d7..70b615d40d 100644 +--- a/Externals/hidapi/mac/hid.c ++++ b/Externals/hidapi/mac/hid.c +@@ -773,8 +773,10 @@ static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char + IOReturn res; + + /* Return if the device has been disconnected. */ +- if (dev->disconnected) ++ if (dev->disconnected) { ++ errno = ENODEV; + return -1; ++ } + + if (data[0] == 0x0) { + /* Not using numbered Reports. +@@ -797,9 +799,14 @@ static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char + + if (res == kIOReturnSuccess) { + return length; +- } +- else ++ } else if (res == (IOReturn)0xe0005000) { ++ /* Kernel.framework's IOUSBHostFamily.h defines this error as kUSBHostReturnPipeStalled */ ++ errno = EPIPE; ++ return -1; ++ } else { ++ errno = EBUSY; + return -1; ++ } + } + + return -1; +-- +2.14.3 (Apple Git-98) +