28
28
#include <IOKit/usb/USBSpec.h>
29
29
#include <CoreFoundation/CoreFoundation.h>
30
30
#include <mach/mach_error.h>
31
+ #include <stdbool.h>
31
32
#include <wchar.h>
32
33
#include <locale.h>
33
34
#include <pthread.h>
@@ -302,7 +303,7 @@ static CFArrayRef get_array_property(IOHIDDeviceRef device, CFStringRef key)
302
303
static int32_t get_int_property (IOHIDDeviceRef device , CFStringRef key )
303
304
{
304
305
CFTypeRef ref ;
305
- int32_t value ;
306
+ int32_t value = 0 ;
306
307
307
308
ref = IOHIDDeviceGetProperty (device , key );
308
309
if (ref ) {
@@ -314,6 +315,20 @@ static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key)
314
315
return 0 ;
315
316
}
316
317
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
+
317
332
static CFArrayRef get_usage_pairs (IOHIDDeviceRef device )
318
333
{
319
334
return get_array_property (device , CFSTR (kIOHIDDeviceUsagePairsKey ));
@@ -540,24 +555,25 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev,
540
555
/* Release Number */
541
556
cur_dev -> release_number = get_int_property (dev , CFSTR (kIOHIDVersionNumberKey ));
542
557
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 ;
554
562
555
563
/* Bus Type */
556
564
transport_prop = IOHIDDeviceGetProperty (dev , CFSTR (kIOHIDTransportKey ));
557
565
558
566
if (transport_prop != NULL && CFGetTypeID (transport_prop ) == CFStringGetTypeID ()) {
559
567
if (CFStringCompare ((CFStringRef )transport_prop , CFSTR (kIOHIDTransportUSBValue ), 0 ) == kCFCompareEqualTo ) {
568
+ int32_t interface_number = -1 ;
560
569
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
+
561
577
/* Match "Bluetooth", "BluetoothLowEnergy" and "Bluetooth Low Energy" strings */
562
578
} else if (CFStringHasPrefix ((CFStringRef )transport_prop , CFSTR (kIOHIDTransportBluetoothValue ))) {
563
579
cur_dev -> bus_type = HID_API_BUS_BLUETOOTH ;
0 commit comments