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);
}