X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2FAdapterDetection.cpp;h=f06809975abc49300558e06780b4445633f6dd6c;hb=4d6f5ac7a660c0b450bff491a16f8bc23944f0ea;hp=5d957a7a0150300bcd582a49616077e79f81e6b2;hpb=25701fa60407a0fc0bc1dfcd4049fc01ad9e4fd1;p=deb_libcec.git diff --git a/src/lib/AdapterDetection.cpp b/src/lib/AdapterDetection.cpp index 5d957a7..f068099 100644 --- a/src/lib/AdapterDetection.cpp +++ b/src/lib/AdapterDetection.cpp @@ -34,15 +34,26 @@ #include "platform/os-dependent.h" #include "util/StdString.h" -#if !defined(__WINDOWS__) +#if defined(__APPLE__) #include -#include -#include -#else +#include +#include +#include +#include +#include +#include +#include +#elif defined(__WINDOWS__) #include // the virtual COM port only shows up when requesting devices with the raw device guid! static GUID USB_RAW_GUID = { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }; +#elif defined(HAVE_LIBUDEV) +#include +#include +extern "C" { +#include +} #endif #define CEC_VID 0x2548 @@ -51,7 +62,7 @@ static GUID USB_RAW_GUID = { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0x using namespace CEC; using namespace std; -#if !defined(__WINDOWS__) +#if defined(HAVE_LIBUDEV) bool TranslateComPort(CStdString &strString) { CStdString strTmp(strString); @@ -104,7 +115,73 @@ 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(HAVE_LIBUDEV) struct udev *udev; if (!(udev = udev_new())) return -1; @@ -152,7 +229,7 @@ uint8_t CAdapterDetection::FindAdapters(cec_adapter *deviceList, uint8_t iBufSiz udev_enumerate_unref(enumerate); udev_unref(udev); -#else +#elif defined(__WINDOWS__) HDEVINFO hDevHandle; DWORD required = 0, iMemberIndex = 0; int nBufferSize = 0; @@ -247,5 +324,7 @@ uint8_t CAdapterDetection::FindAdapters(cec_adapter *deviceList, uint8_t iBufSiz } #endif + iBufSize = 0; /* silence "unused" warning on linux/osx */ + return iFound; }