X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2FAdapterDetection.cpp;h=98c3a0e60a09a083daf38fc9e8cbc80d03b2a500;hb=802b7a0f90e3668f7c4eac90f8692bc9b39a4833;hp=5d957a7a0150300bcd582a49616077e79f81e6b2;hpb=2b32d0ab4a65fd7ac86072285e87972e1131b98a;p=deb_libcec.git diff --git a/src/lib/AdapterDetection.cpp b/src/lib/AdapterDetection.cpp index 5d957a7..98c3a0e 100644 --- a/src/lib/AdapterDetection.cpp +++ b/src/lib/AdapterDetection.cpp @@ -34,7 +34,17 @@ #include "platform/os-dependent.h" #include "util/StdString.h" -#if !defined(__WINDOWS__) +#if defined(__APPLE__) +#include +#include +#include +#include +#include +#include +#include +#include + +#elif !defined(__WINDOWS__) #include #include #include @@ -104,7 +114,74 @@ uint8_t CAdapterDetection::FindAdapters(cec_adapter *deviceList, uint8_t iBufSiz { uint8_t iFound(0); -#if !defined(__WINDOWS__) +#if defined(__APPLE__) + kern_return_t kresult; + char bsdPath[MAXPATHLEN] = {0}; + io_iterator_t serialPortIterator; + + CFMutableDictionaryRef classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); + if (classesToMatch) + { + CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDModemType)); + kresult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, &serialPortIterator); + if (kresult == KERN_SUCCESS) + { + io_object_t serialService; + while ((serialService = IOIteratorNext(serialPortIterator))) + { + int iVendor = 0, iProduct = 0; + CFTypeRef bsdPathAsCFString; + + // fetch the device path. + bsdPathAsCFString = IORegistryEntryCreateCFProperty(serialService, + CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0); + if (bsdPathAsCFString) + { + // convert the path from a CFString to a C (NUL-terminated) string. + CFStringGetCString((CFStringRef)bsdPathAsCFString, bsdPath, MAXPATHLEN - 1, kCFStringEncodingUTF8); + CFRelease(bsdPathAsCFString); + + // now walk up the hierarchy until we find the entry with vendor/product IDs + io_registry_entry_t parent; + CFTypeRef vendorIdAsCFNumber = NULL; + CFTypeRef productIdAsCFNumber = NULL; + kern_return_t kresult = IORegistryEntryGetParentEntry(serialService, kIOServicePlane, &parent); + while (kresult == KERN_SUCCESS) + { + vendorIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, + kIOServicePlane, CFSTR(kUSBVendorID), kCFAllocatorDefault, 0); + productIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, + kIOServicePlane, CFSTR(kUSBProductID), kCFAllocatorDefault, 0); + if (vendorIdAsCFNumber && productIdAsCFNumber) + { + CFNumberGetValue((CFNumberRef)vendorIdAsCFNumber, kCFNumberIntType, &iVendor); + CFRelease(vendorIdAsCFNumber); + CFNumberGetValue((CFNumberRef)productIdAsCFNumber, kCFNumberIntType, &iProduct); + CFRelease(productIdAsCFNumber); + IOObjectRelease(parent); + break; + } + io_registry_entry_t oldparent = parent; + kresult = IORegistryEntryGetParentEntry(parent, kIOServicePlane, &parent); + IOObjectRelease(oldparent); + } + if (strlen(bsdPath) && iVendor == CEC_VID && iProduct == CEC_PID) + { + if (!strDevicePath || !strcmp(bsdPath, strDevicePath)) + { + // on darwin, the device path is the same as the comm path. + snprintf(deviceList[iFound ].path, sizeof(deviceList[iFound].path), "%s", bsdPath); + snprintf(deviceList[iFound++].comm, sizeof(deviceList[iFound].path), "%s", bsdPath); + } + } + } + IOObjectRelease(serialService); + } + } + IOObjectRelease(serialPortIterator); + } + +#elif !defined(__WINDOWS__) struct udev *udev; if (!(udev = udev_new())) return -1;