5

I'm maintaining a library for accessing a USB device, which registers itself as an HID device, and enables Mac apps to perform all kinds of nifty stuff (GPIO, I2C, etc). This library can be found here:

https://github.com/codemercs-com/io-warrior-mac

Since I upgraded the project to MacOS 10.13 SDK, IOServiceGetMatchingServices() returns a nil iterator object when called from the DeviceAdded callback, but does not return an error code.

My assumption is that something in IOKit has fundamentally changed since I initially wrote this library around 2002.

I'm registering my 'device-plugged-in' callback like this:

 result = IOServiceAddMatchingNotification(gNotifyPort,
                                          kIOFirstMatchNotification, matchingDict,
                                          IOWarriorAdded, NULL, &gIOWarriorAddedIter);

Source

This callback is indeed called when a supported device is plugged-in, but when I subsequently call IOServiceGetMatchingServices, the iterator is nil, -- or, when other devices were already connected, contains only these devices, but not the ones newly plugged-in.

io_iterator_t IOWarriorFindHIDDevices ()
{
    CFMutableDictionaryRef hidMatchDictionary = IOWarriorSetUpHIDMatchingDictionary ();

    // Set up matching dictionary to search the I/O Registry for HID devices we are interested in. Dictionary reference is NULL if error.
    if (NULL == hidMatchDictionary) {
        PrintErrMsg ("Couldn't create a matching dictionary.");
        return 0;
    }

    io_iterator_t hidObjectIterator;

    // Now search I/O Registry for matching devices.
    IOReturn ioReturnValue = IOServiceGetMatchingServices (kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator);
    if (ioReturnValue != kIOReturnSuccess) {
        PrintErrMsgIfIOErr(ioReturnValue, "IOServiceGetMatchingServices returned error");
        return 0;
    }
    if (hidObjectIterator == 0) {
        PrintErrMsg("IOServiceGetMatchingServices returned nil hidObjectIterator");
        return 0;
    }

    return hidObjectIterator;
}

Source

When iterating through the available devices upon application start-up, all devices are discovered just fine.

Any ideas what I might be doing wrong, here?

iljawascoding
  • 1,090
  • 9
  • 20
  • I'm not aware of any changes to these IOKit APIs. The only thing I can imagine is that you've got an object retain/release bug in your code, especially on the matching dictionary, as e.g. `IOServiceGetMatchingServices` consumes a reference. Have you run a clang Static Analyser pass on the code? If this doesn't find anything, I'd try running with memory diagnostics, e.g. zombie objects and see if that finds anything. – pmdj Jun 16 '19 at 08:22
  • Also note that the iterator returned by `IOServiceAddMatchingNotification` will give you the ioservice objects for any hot-plugged devices in the callback, no need to call `IOServiceGetMatchingServices` every time. – pmdj Jun 16 '19 at 08:23
  • If your matching dictionaries for `IOServiceGetMatchingServices()` and `IOServiceAddMatchingNotification` are different though, I'd also look for the problem there. In recent versions of macOS, the USB and HID classes have changed a bit, and Apple is gradually removing the backward compatibility layers. – pmdj Jun 16 '19 at 08:25

0 Answers0