首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >监控雷电端口连接的变化

监控雷电端口连接的变化
EN

Stack Overflow用户
提问于 2015-09-24 10:54:32
回答 2查看 1.3K关注 0票数 4

我是工作在一个要求,我需要监测在雷霆端口连接的变化。(当雷电电缆连接或断开时)。

我尝试使用来自IOKit framework的IOKit,但我无法监视Thunderbolt端口上的更改。

有什么办法我能做到吗?任何帮助都是非常感谢的。

EN

回答 2

Stack Overflow用户

发布于 2015-09-25 10:10:13

雷电设备(使用雷电端口的DisplayPort部分的显示器除外)是PCI设备,而不是USB,因此它们将以IOPCIDevices的形式出现在IOService注册表中。然而,它们也将在Thunderbolt子树中显示为IOThunderboltPort对象,其中"PCI Path“属性将指示到相关IOPCIDevice的IOService路径。通过监视IOThunderboltPort服务的出现和消失,并检查它们的PCI路径属性,可以避免匹配其他类型的PCI设备。

为了说明我所讲的内容,打开IORegistryExplorer或IOJones,然后打开一个雷电设备;您应该可以看到IOThunderboltPort (以及一些其他类型的相关对象,如AppleThunderboltPCIUpAdapter等)。IOPCIDevice (以及雷电总线工作所通过的PCI2PCI桥)出现。(或者,您可以使用ioreg在热插拔之前和之后拍摄快照。)

因此,总之,我将匹配IOThunderboltPort服务,忽略任何没有PCI路径属性的服务,并在ignore中查找相应的IOPCIDevice,以找到能够访问实际设备的IOPCIDevice

票数 2
EN

Stack Overflow用户

发布于 2015-10-01 07:58:50

最后,我想出了一种方法来监控雷电连接。感谢苹果技术人员给我指明了正确的方向。监控IOEthernetInterface条目的I/O注册表。过滤掉雷电网络相对容易(我不知道最好的选择是什么,但一个简单的选择是在父IOEthernetController的“IOModel”属性中查找“ThunderboltIP”)。这是苹果的一位技术人员在苹果论坛上的回应。使用上面的信息,我写了一个代码,它将返回您的状态的雷霆端口。

代码语言:javascript
复制
 #include <IOKit/network/IOEthernetController.h>

- (void) monitorThunderboltConnection
{    
  CFMutableDictionaryRef matchingDict;
  io_iterator_t iter;
  io_object_t   controllerService;
  kern_return_t kr;
  UInt8 MACAddress[kIOEthernetAddressSize];

  QNInterfaceModel *interfaceModel = [[QNInterfaceModel alloc] initWithInterfaceModel];

 /* set up a matching dictionary for the class */
 matchingDict = IOServiceMatching(kIOEthernetInterfaceClass);

if (matchingDict == NULL)
{
    NSLog(@"Failed");

    return;
}

/* Now we have a dictionary, get an iterator.*/
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
if (kr == kIOReturnSuccess)
{
    // Actually iterate through the found devices.
    io_registry_entry_t serviceObject;


    while ((serviceObject = IOIteratorNext(iter)))
    {
        // Put this services object into a dictionary object.

        kr = IORegistryEntryGetParentEntry(serviceObject,
                                           kIOServicePlane,
                                           &controllerService);

        if (KERN_SUCCESS != kr)
        {
            printf("IORegistryEntryGetParentEntry returned 0x%08x\n", kr);
        }
        else
        {
            CFMutableDictionaryRef serviceDictionary;

            CFTypeRef   networkType;
            CFTypeRef   MACAddressAsCFData;
            NSNumber    *linkStatus;


            if (IORegistryEntryCreateCFProperties(serviceObject,
                                                  &serviceDictionary,
                                                  kCFAllocatorDefault,
                                                  kNilOptions) == kIOReturnSuccess)
            {

                networkType = IORegistryEntryCreateCFProperty(controllerService,
                                                              CFSTR(kIOModel),
                                                              kCFAllocatorDefault,
                                                              0);
                if(networkType)
                {
                    if (CFGetTypeID(networkType) == CFStringGetTypeID())
                    {
                        CFStringRef networkName = networkType;

                        interfaceModel.interfaceName = (__bridge NSString *)networkName;
                    }

                    CFRelease(networkType);
                }

                if([interfaceModel.interfaceName isEqualToString:@"ThunderboltIP"])
                {
                    MACAddressAsCFData = IORegistryEntryCreateCFProperty(controllerService,
                                                                         CFSTR(kIOMACAddress),
                                                                         kCFAllocatorDefault,
                                                                         0);
                    if (MACAddressAsCFData)
                    {
                        CFShow(MACAddressAsCFData); // for display purposes only; output goes to stderr

                        // Get the raw bytes of the MAC address from the CFData
                        CFDataGetBytes(MACAddressAsCFData, CFRangeMake(0, kIOEthernetAddressSize), MACAddress);

                        if (KERN_SUCCESS != kr)
                        {
                            printf("GetMACAddress returned 0x%08x\n", kr);
                        }
                        else
                        {
                            interfaceModel.macAddress = [[NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",MACAddress[0], MACAddress[1], MACAddress[2], MACAddress[3], MACAddress[4], MACAddress[5]] uppercaseString];
                        }

                        CFRelease(MACAddressAsCFData);
                    }

                    linkStatus = (__bridge NSNumber *)(IORegistryEntryCreateCFProperty(controllerService,
                                                                                       CFSTR(kIOLinkStatus),
                                                                                       kCFAllocatorDefault,
                                                                                       0));
                    if (linkStatus)
                    {
                        NSLog(@"%@", [linkStatus stringValue]);

                        if([linkStatus integerValue] == 3) // Thunderbolt IP is Connnected
                        {
                            interfaceModel.connectedStatus = YES;
                        }
                        else
                        {
                            interfaceModel.connectedStatus = NO;
                        }
                    }

                    CFStringRef bsdName = ( CFStringRef ) IORegistryEntrySearchCFProperty (controllerService,
                                                                                           kIOServicePlane,
                                                                                           CFSTR ( kIOBSDNameKey ),
                                                                                           kCFAllocatorDefault,
                                                                                           kIORegistryIterateRecursively);

                    interfaceModel.interfaceName = (__bridge NSString *) bsdName;

                    if(interfaceModel.connectedStatus == YES)
                    {
                        NSLog(@"Connected");
                    }
                    else
                    {
                        NSLog(@"DisConnected");
                    }
                }

                // Failed to create a service dictionary, release and go on.
                IOObjectRelease(serviceObject);

                // Done with the parent Ethernet controller object so we release it.
                (void) IOObjectRelease(controllerService);

                continue;
            }
        }
    }
}

/* Done, release the iterator */
IOObjectRelease(iter);
}

注:我正在使用接口模型收集所有雷电信息,如硬件地址,BSD名称,链接状态等。您还需要添加I/O工具包框架到您的项目。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32759554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档