Skip to content

Commit 5e57387

Browse files
committed
macos: (try) get USB interface only if bus_type is USB
1 parent a10c772 commit 5e57387

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

mac/hid.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <IOKit/usb/USBSpec.h>
2929
#include <CoreFoundation/CoreFoundation.h>
3030
#include <mach/mach_error.h>
31+
#include <stdbool.h>
3132
#include <wchar.h>
3233
#include <locale.h>
3334
#include <pthread.h>
@@ -302,7 +303,7 @@ static CFArrayRef get_array_property(IOHIDDeviceRef device, CFStringRef key)
302303
static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key)
303304
{
304305
CFTypeRef ref;
305-
int32_t value;
306+
int32_t value = 0;
306307

307308
ref = IOHIDDeviceGetProperty(device, key);
308309
if (ref) {
@@ -314,6 +315,20 @@ static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key)
314315
return 0;
315316
}
316317

318+
static bool try_get_int_property(IOHIDDeviceRef device, CFStringRef key, int32_t *out_val)
319+
{
320+
bool result = false;
321+
CFTypeRef ref;
322+
323+
ref = IOHIDDeviceGetProperty(device, key);
324+
if (ref) {
325+
if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
326+
result = CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, out_val);
327+
}
328+
}
329+
return result;
330+
}
331+
317332
static CFArrayRef get_usage_pairs(IOHIDDeviceRef device)
318333
{
319334
return get_array_property(device, CFSTR(kIOHIDDeviceUsagePairsKey));
@@ -540,24 +555,25 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev,
540555
/* Release Number */
541556
cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey));
542557

543-
/* Interface Number */
544-
/* We can only retrieve the interface number for USB HID devices.
545-
* IOKit always seems to return 0 when querying a standard USB device
546-
* for its interface. */
547-
int is_usb_hid = get_int_property(dev, CFSTR(kUSBInterfaceClass)) == kUSBHIDClass;
548-
if (is_usb_hid) {
549-
/* Get the interface number */
550-
cur_dev->interface_number = get_int_property(dev, CFSTR(kUSBInterfaceNumber));
551-
} else {
552-
cur_dev->interface_number = -1;
553-
}
558+
/* Interface Number.
559+
* We can only retrieve the interface number for USB HID devices.
560+
* See below */
561+
cur_dev->interface_number = -1;
554562

555563
/* Bus Type */
556564
transport_prop = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDTransportKey));
557565

558566
if (transport_prop != NULL && CFGetTypeID(transport_prop) == CFStringGetTypeID()) {
559567
if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportUSBValue), 0) == kCFCompareEqualTo) {
568+
int32_t interface_number = -1;
560569
cur_dev->bus_type = HID_API_BUS_USB;
570+
if (try_get_int_property(dev, CFSTR(kUSBInterfaceNumber), &interface_number)) {
571+
cur_dev->interface_number = interface_number;
572+
}
573+
else {
574+
// TODO: use a different approach - this is a USB device after all
575+
}
576+
561577
/* Match "Bluetooth", "BluetoothLowEnergy" and "Bluetooth Low Energy" strings */
562578
} else if (CFStringHasPrefix((CFStringRef)transport_prop, CFSTR(kIOHIDTransportBluetoothValue))) {
563579
cur_dev->bus_type = HID_API_BUS_BLUETOOTH;

0 commit comments

Comments
 (0)