30 #include <CoreFoundation/CoreFoundation.h> 
   31 #include <IOKit/IOKitLib.h> 
   32 #include <IOKit/IOKitKeys.h> 
   33 #include <IOKit/serial/IOSerialKeys.h> 
   47         int findSerialPorts(io_iterator_t *matchingServices) {
 
   49             CFMutableDictionaryRef classesToMatch =
 
   50                 IOServiceMatching(kIOSerialBSDServiceValue);
 
   51             if (classesToMatch == NULL) {
 
   55             CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey),
 
   56                                  CFSTR(kIOSerialBSDAllTypes));
 
   58             kern_return_t kernResult = IOServiceGetMatchingServices(
 
   59                 kIOMasterPortDefault, classesToMatch, matchingServices);
 
   60             if (KERN_SUCCESS != kernResult) {
 
   77         bool matches_ids(
const USBSerialDevice &device,
 
   78                          const boost::optional<uint16_t> &vendorID,
 
   79                          const boost::optional<uint16_t> &productID) {
 
   80             const bool vendor_matches =
 
   81                 (!vendorID || *vendorID == device.getVID());
 
   82             const bool product_matches =
 
   83                 (!productID || *productID == device.getPID());
 
   85             return (vendor_matches && product_matches);
 
   89     std::vector<USBSerialDevice>
 
   90     getSerialDeviceList(boost::optional<uint16_t> vendorID,
 
   91                         boost::optional<uint16_t> productID) {
 
   93         std::vector<USBSerialDevice> devices;
 
   95         io_iterator_t serialPortIterator;
 
   96         io_object_t serialPortService;
 
   98         if (findSerialPorts(&serialPortIterator) == 
true) {
 
  100             while ((serialPortService = IOIteratorNext(serialPortIterator)) !=
 
  102                 const CFNumberRef vidObj =
 
  103                     static_cast<CFNumberRef
>(IORegistryEntrySearchCFProperty(
 
  104                         serialPortService, kIOServicePlane, CFSTR(
"idVendor"),
 
  105                         NULL, kIORegistryIterateRecursively |
 
  106                                   kIORegistryIterateParents));
 
  107                 const CFNumberRef pidObj =
 
  108                     static_cast<CFNumberRef
>(IORegistryEntrySearchCFProperty(
 
  109                         serialPortService, kIOServicePlane, CFSTR(
"idProduct"),
 
  110                         NULL, kIORegistryIterateRecursively |
 
  111                                   kIORegistryIterateParents));
 
  112                 const CFStringRef bsdPathObj =
 
  113                     static_cast<CFStringRef
>(IORegistryEntryCreateCFProperty(
 
  114                         serialPortService, CFSTR(kIOCalloutDeviceKey),
 
  115                         kCFAllocatorDefault, 0));
 
  117                 if (!vidObj || !pidObj || !bsdPathObj) {
 
  122                 CFNumberGetValue(vidObj, kCFNumberSInt16Type, &vid);
 
  123                 CFNumberGetValue(pidObj, kCFNumberSInt16Type, &pid);
 
  126                 CFIndex bufferSize = CFStringGetMaximumSizeForEncoding(
 
  127                                          CFStringGetLength(bsdPathObj),
 
  128                                          kCFStringEncodingMacRoman) +
 
  130                 std::vector<char> bsdPathBuf(bufferSize);
 
  131                 CFStringGetCString(bsdPathObj, bsdPathBuf.data(), bufferSize,
 
  132                                    kCFStringEncodingMacRoman);
 
  134                 USBSerialDevice usb_serial_device(vid, pid, bsdPathBuf.data(),
 
  137                 if (matches_ids(usb_serial_device, vendorID, productID)) {
 
  138                     devices.push_back(usb_serial_device);