X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2FAdapterDetection.cpp;h=98c3a0e60a09a083daf38fc9e8cbc80d03b2a500;hb=56b36fa651f960f501b588b1d5fe069298d980a1;hp=e21d3dc20808a9b2d334b60da8588a0cf8507a9b;hpb=b9187cc6999276ce37a5c9852655fd558ea76b8e;p=deb_libcec.git diff --git a/src/lib/AdapterDetection.cpp b/src/lib/AdapterDetection.cpp index e21d3dc..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 @@ -100,18 +110,85 @@ bool FindComPort(CStdString &strLocation) } #endif -int CAdapterDetection::FindAdapters(vector &deviceList, const char *strDevicePath /* = NULL */) +uint8_t CAdapterDetection::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */) { - int iFound(0); + 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; struct udev_enumerate *enumerate; struct udev_list_entry *devices, *dev_list_entry; - struct udev_device *dev; + struct udev_device *dev, *pdev; enumerate = udev_enumerate_new(udev); udev_enumerate_scan_devices(enumerate); devices = udev_enumerate_get_list_entry(enumerate); @@ -124,32 +201,27 @@ int CAdapterDetection::FindAdapters(vector &deviceList, const char if (!dev) continue; - dev = udev_device_get_parent(udev_device_get_parent(dev)); - if (!dev) - continue; - if (!udev_device_get_sysattr_value(dev,"idVendor") || !udev_device_get_sysattr_value(dev, "idProduct")) + pdev = udev_device_get_parent(udev_device_get_parent(dev)); + if (!pdev || !udev_device_get_sysattr_value(pdev,"idVendor") || !udev_device_get_sysattr_value(pdev, "idProduct")) { udev_device_unref(dev); continue; } int iVendor, iProduct; - sscanf(udev_device_get_sysattr_value(dev, "idVendor"), "%x", &iVendor); - sscanf(udev_device_get_sysattr_value(dev, "idProduct"), "%x", &iProduct); + sscanf(udev_device_get_sysattr_value(pdev, "idVendor"), "%x", &iVendor); + sscanf(udev_device_get_sysattr_value(pdev, "idProduct"), "%x", &iProduct); if (iVendor == CEC_VID && iProduct == CEC_PID) { - CStdString strPath(udev_device_get_syspath(dev)); - if (strDevicePath && strcmp(strPath.c_str(), strDevicePath)) - continue; - - CStdString strComm(strPath); - if (FindComPort(strComm)) + CStdString strPath(udev_device_get_syspath(pdev)); + if (!strDevicePath || !strcmp(strPath.c_str(), strDevicePath)) { - cec_adapter foundDev; - foundDev.path = strPath; - foundDev.comm = strComm; - deviceList.push_back(foundDev); - ++iFound; + CStdString strComm(strPath); + if (FindComPort(strComm)) + { + snprintf(deviceList[iFound ].path, sizeof(deviceList[iFound].path), "%s", strPath.c_str()); + snprintf(deviceList[iFound++].comm, sizeof(deviceList[iFound].path), "%s", strComm.c_str()); + } } } udev_device_unref(dev); @@ -174,7 +246,7 @@ int CAdapterDetection::FindAdapters(vector &deviceList, const char BOOL bResult = true; TCHAR *buffer = NULL; PSP_DEVICE_INTERFACE_DETAIL_DATA devicedetailData; - while(bResult) + while(bResult && iFound < iBufSize) { bResult = SetupDiEnumDeviceInfo(hDevHandle, iMemberIndex, &devInfoData); @@ -217,8 +289,8 @@ int CAdapterDetection::FindAdapters(vector &deviceList, const char CStdString strVendorId; CStdString strProductId; CStdString strTmp(devicedetailData->DevicePath); - strVendorId = strTmp.substr(strTmp.Find("vid_") + 4, 4); - strProductId = strTmp.substr(strTmp.Find("pid_") + 4, 4); + strVendorId.assign(strTmp.substr(strTmp.Find("vid_") + 4, 4)); + strProductId.assign(strTmp.substr(strTmp.Find("pid_") + 4, 4)); if (strTmp.Find("&mi_") >= 0 && strTmp.Find("&mi_00") < 0) continue; @@ -243,11 +315,8 @@ int CAdapterDetection::FindAdapters(vector &deviceList, const char if (_tcslen(strPortName) > 3 && _tcsnicmp(strPortName, _T("COM"), 3) == 0 && _ttoi(&(strPortName[3])) > 0) { - cec_adapter foundDev; - foundDev.path = devicedetailData->DevicePath; - foundDev.comm = strPortName; - deviceList.push_back(foundDev); - ++iFound; + snprintf(deviceList[iFound ].path, sizeof(deviceList[iFound].path), "%s", devicedetailData->DevicePath); + snprintf(deviceList[iFound++].comm, sizeof(deviceList[iFound].path), "%s", strPortName); } }