need to use IOServiceAddMatchingNotification routine for supporing multiple product identifications. To show the concept, I got part of this code from a site and revised it.Kept it short.
// Set up matching dictionary.
NSMutableDictionary* matchingDictionary;
for (int n = 0; n < numberOfDevices; n++)
{
matchingDictionary = (NSMutableDictionary*)IOServiceMatching(kIOUSBDeviceClassName);
[matchingDictionary setObject:[NSNumber numberWithLong:myVid[n]] forKey:[NSString stringWithUTF8String:kUSBVendorID]];
[matchingDictionary setObject:[NSNumber numberWithLong:myPid[n]] forKey:[NSString stringWithUTF8String:kUSBProductID]];
// Set up a notification callback for device addition on first match.
IOServiceAddMatchingNotification(g_notificationPort, kIOFirstMatchNotification, (CFMutableDictionaryRef)matchingDictionary, deviceAddedCallback, (void*)self, &g_iteratorAdded);
}
I am not sure if it really is correct?. I did not see complains from the xcode and it works.
This requires a nuanced answer - there are three things to note here:
io_iterator_t to be created and updated with each matching dictionary, as you only have a single variable to store it, g_iteratorAdded. This is not the case. The code shown suffers from a resource leak. Each successful call to IOServiceAddMatchingNotification will create a new iterator, so you will need to retain all of them in an array or so. And then, when you no longer need the notifications (at the latest, when self is dealloc'd, or you'll get callbacks on a freed object!), you need to release all of the iterators.kUSBProductID with a single NSNumber/CFNumber, provide a kUSBProductIdsArrayName (aka kUSBHostMatchingPropertyProductIDArray) and specify an array of numbers. (NSArray/CFArray containing a NSNumber/CFNumber for every product ID.)kUSBProductIDMask in conjunction with kUSBProductID: in this case, candidate devices' product IDs will be bitwise masked (&) with the number provided for kUSBProductIDMask before comparing to the kUSBProductID.kUSBProductIdsArrayName value for each.Some rough untested code for dealing with kUSBProductIdsArrayName, assuming your VIDs/PIDs are laid out like this:
static const uint16_t myVid[] = { 0x1234, 0x5555 };
static const size_t numberOfVids = sizeof(myVid) / sizeof(myVid[0]);
static const uint16_t myPid[] = {
// for VID 0x1234
0x1, 0x2, 0x3, 0x1001, 0x1002,
// for VID 0x555
0x100, 0x101,
};
static const unsigned pidsForVid[] = { 5, 2 };
Setting up the matching dictionaries would then look something like this:
unsigned next_pid_index = 0;
for (int n = 0; n < numberOfVids; n++)
{
NSMutableDictionary* matchingDictionary =
(__bridge_transfer NSMutableDictionary*)IOServiceMatching(kIOUSBDeviceClassName);
[matchingDictionary setObject:@(myVid[n]) forKey:@kUSBVendorID];
NSMutableArray* pid_array = [NSMutableArray arrayWithCapacity:pidsForVid[n]];
for (unsigned i = 0; i < pidsForVid[n]; ++i)
{
[pid_array addObject:@(myPid[next_pid_index])];
++next_pid_index;
}
[matchingDictionary setObject:pid_array forKey:@kUSBProductIdsArrayName];
// Set up a notification callback for device addition on first match.
IOReturn result = IOServiceAddMatchingNotification(
g_notificationPort,
kIOFirstMatchNotification,
(__bridge_retained CFMutableDictionaryRef)matchingDictionary,
deviceAddedCallback,
(__bridge void*)self,
&g_iteratorAdded[n]);
assert(result == kIOReturnSuccess);
}