Andi
Andi

Reputation: 41

Problems receiving Notifications from IOKit (CoreFoundation) for plugged Devices

I'm currently developing an application on 10.6.7 which should receive notifications when a new usb device is plugged in. I found out that there is a IOKit function which handles such stuff 'IOServiceAddMatchingNotification'. Because the return value from this specific function is 0, I think that the problem perhaps is in my matching Dictionary, which is given into this function. I declare the Dictionary that way:

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);

Because I wan't to receive a notification for each device, I don't know if this is the right way to create this particular dictionary.

My complete code look like this:

ioKitNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
notificationRunLoopSource = IONotificationPortGetRunLoopSource(ioKitNotificationPort);

CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode);

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);


addMatchingNotificationResult = IOServiceAddMatchingNotification(ioKitNotificationPort,
                                                                 kIOPublishNotification,
                                                                 matchingDict,
                                                                 deviceAdded,
                                                                 NULL,

Does anyone has a idea why this won't work? (Note: The Callback function is a static void c function and the rest is wrapped ins ide a Obj-C class).

Thanks

Xcode 4, 10.6.7

Upvotes: 4

Views: 2114

Answers (4)

GTAE86
GTAE86

Reputation: 1846

Did you add the VID and PID of the device you wish to look for to your matching dictionary? For the dictionary you have, and VID= yourVid, PID= yourPid, it would be:

CFDictionaryAddValue(matchingDict, usbVendorId, yourVid);  
CFDictionaryAddValue(matchingDict, usbProductId, yourPid);  

Another thing - after the call to IOServiceAddMatchingNotification succeeds, you need to call your device-added handler with the iterator that was set in the call. That will arm the notification and check for existing devices.

Upvotes: 1

Mattie
Mattie

Reputation: 3028

Weirdly, you must empty the iterator returned by IOServiceAddMatchingNotification before the notification will be armed. I don't see that in the code provided, so that could be in the issue. That iterator is actually what you need to keep around to keep the notification running.

io_iterator_t ioNotification;

addMatchingNotificationResult = IOServiceAddMatchingNotification(ioKitNotificationPort,
                                                                 kIOPublishNotification,
                                                                 matchingDict,
                                                                 deviceAdded,
                                                                 NULL,
                                                                 &ioNotification);

while ((service = IOIteratorNext(ioNotification)))
{
    NSLog(@"Hey, I found a service!");

    IOObjectRelease(service); // yes, you have to release this
}

Upvotes: 5

Ivan
Ivan

Reputation: 179

In my opinion, u should download the source code form IOUSBFamily on opensource.apple.com, and then find the code for USB Prober, this application does exactly the same thing as u described, listening the USB Device attachment.(Further, USB Prober also get the general device and configuration descriptor, maybe it is also the things u need.)

Upvotes: 1

kent
kent

Reputation: 6566

the easiest way to do what i think you are describing is to hook into the DiskArbitration Framework. DA is relatively new to OSX and allows userland applications to examine devices as they get attached. it is what is used to open iTunes when an iPod is attached, launch iPhoto when a camera is attached, etc... if the USB device you are looking for is a storage device then this will work for you. otherwise you will need to go the matching dictionary route...

Upvotes: 0

Related Questions