Skip to content

Getting Vendor ID and Product ID

Andrew Madsen edited this page Aug 13, 2015 · 2 revisions

Most serial port hardware these days consists of USB to serial adapters. USB devices include a vendor ID, product ID, and some other low level attributes. Sometimes it is useful to have this information for example to identify a specific piece of connected hardware. However, ORSSerialPort does not expose a built in API to get this information about the USB hardware for a given port.

ORSSerialPort does expose a property that returns the low level IOKit device object for a port:

/**
 *  The IOKit port object for the serial port device represented by the receiver. (read-only)
 */
@property (readonly) io_object_t IOKitDevice;

This can be used with the IOKit APIs to retrieve vendor ID, product ID, and other attributes. The category below can be used for this:

ORSSerialPort+Attributes.h:

#import <ORSSerial/ORSSerial.h>

@interface ORSSerialPort (Attributes)

@property (nonatomic, readonly) NSDictionary *ioDeviceAttributes;
@property (nonatomic, readonly) NSNumber *vendorID;
@property (nonatomic, readonly) NSNumber *productID;

@end

ORSSerialPort+Attributes.m:

#import "ORSSerialPort+Attributes.h"
#import <IOKit/usb/USBSpec.h>

@implementation ORSSerialPort (Attributes)

- (NSDictionary *)ioDeviceAttributes
{
  NSDictionary *result = nil;
    
    io_iterator_t iterator = 0;
    if (IORegistryEntryCreateIterator(self.IOKitDevice,
                                      kIOServicePlane,
                                      kIORegistryIterateRecursively + kIORegistryIterateParents,
                                      &iterator) != KERN_SUCCESS) return nil;
    
    io_object_t device = 0;
    while ((device = IOIteratorNext(iterator)) && result == nil)
    {
        CFMutableDictionaryRef usbProperties = 0;
        if (IORegistryEntryCreateCFProperties(device, &usbProperties, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS)
        {
            IOObjectRelease(device);
            continue;
        }
        NSDictionary *properties = CFBridgingRelease(usbProperties);
        
        NSNumber *vendorID = properties[(__bridge NSString *)CFSTR(kUSBVendorID)];
        NSNumber *productID = properties[(__bridge NSString *)CFSTR(kUSBProductID)];
        if (!vendorID || !productID) { IOObjectRelease(device); continue; } // not a USB device
        
        result = properties;
        
        IOObjectRelease(device);
    }
    
    IOObjectRelease(iterator);
    return result;
}

- (NSNumber *)vendorID;
{
	return [self ioDeviceAttributes][(__bridge NSString *)CFSTR(kUSBVendorID)];
}

- (NSNumber *)productID;
{
	return [self ioDeviceAttributes][(__bridge NSString *)CFSTR(kUSBProductID)];
}

@end
Clone this wiki locally