3

我很少接触 xcode 和 I/Okit 框架。我在 USB 探测器中看到了 USB 设备的设备描述符和配置描述符。在此处输入图像描述

我使用 I/O 套件框架编写了一个 xcode 程序,当我们提供该设备的产品 ID 和供应商 ID 作为输入时,它提供 USB 设备名称作为输出。

/*Take the vendor and product id from console*/

printf("\nEnter the vendor id : ");
scanf("%lx",&usbVendor);

printf("\nEnter the product id :");
scanf("%lx",&usbProduct);


/* Set up a matching dictionary for the class */
matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
if (matchingDict == NULL)
{
    return -1; // fail
}
// Create a CFNumber for the idVendor and set the value in the dictionary
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor);
CFDictionarySetValue(matchingDict, 
                     CFSTR(kUSBVendorID), 
                     numberRef);
CFRelease(numberRef);

// Create a CFNumber for the idProduct and set the value in the dictionary
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct);
CFDictionarySetValue(matchingDict, 
                     CFSTR(kUSBProductID), 
                     numberRef);
CFRelease(numberRef);
numberRef = NULL;

/*Get an iterator.*/
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
if (kr != KERN_SUCCESS)
{
    return -1;// fail
}

/* iterate */
while ((device = IOIteratorNext(iter)))
{
    /*Display the device names */

    io_name_t       deviceName;
    kr = IORegistryEntryGetName(device, deviceName);
    if (KERN_SUCCESS != kr) {
        deviceName[0] = '\0';
    }


    printf("\ndeviceName:%s",deviceName);

    /*Free the reference taken before continuing to the next item */
    IOObjectRelease(device);
}

/*Release the iterator */
IOObjectRelease(iter);
return 0;

}

我需要修改它,以便在提供 USB 设备的供应商和产品 ID 时,我将获得设备描述符和配置描述符(如 USB 探测器中所示)作为输出。

这里我只是举了一个例子,代码可以改变,但输出必须是描述符(至少是设备描述符)。

提前致谢...

4

4 回答 4

6

我认为你应该下载 USBProber 的源代码,而不是自己弄清楚。

USBProber 中提供的所有信息迟早可以通过分析源代码获得。

这是下载IOUSBFamily源代码的链接,其中包含USBProber。 http://opensource.apple.com/tarballs/IOUSBFamily/

于 2011-10-19T17:53:08.067 回答
2

要获取配置描述符,您可以使用如下代码:

IOUSBDeviceInterface650** dev = ...;
IOUSBConfigurationDescriptor* configDesc = nullptr;

// Get the configuration descriptor for the first configuration (configuration 0).
kern_return_t kr = (*dev)->GetConfigurationDescriptorPtr(dev, 0, &configDesc);
if (kr != kIOReturnSuccess)
    return an_error;

// Now use configDesc->...

不幸的是,似乎没有获取设备描述符的功能。有一些功能可以得到

kr = (*dev)->GetDeviceClass(dev, &desc.bDeviceClass);
kr = (*dev)->GetDeviceSubClass(dev, &desc.bDeviceSubClass);
kr = (*dev)->GetDeviceProtocol(dev, &desc.bDeviceProtocol);
kr = (*dev)->GetDeviceVendor(dev, &desc.idVendor);
kr = (*dev)->GetDeviceProduct(dev, &desc.idProduct);
kr = (*dev)->GetDeviceReleaseNumber(dev, &desc.bcdDevice);
kr = (*dev)->GetNumberOfConfigurations(dev, &desc.bNumConfigurations);

但我看不到获得iManufacturer, iProduct, iSerial, bMaxPacketSize0, 或bcdUSB.

有一种方法可以解决这个问题 - 您可以使用控制传输手动执行控制请求以获取设备描述符(以及配置描述符,如果您愿意),而不是使用内置函数。

USB 2.0 规范描述了如何做到这一点。基本上你:

  1. bmRequestType = Device | Standard | In使用, bRequest = USB_GET_DESCRIPTOR_REQUEST, wValue = (USB_DEVICE_DESCRIPTOR_TYPE << 8), wIndex = 0,进行控制转移wLength = 2。这将失败,因为描述符长于 2,但它会为您提供包含其长度的描述符头。

  2. 重复该请求,但长度正确。

  3. 对于配置描述符,使用 length 执行第三个请求wTotalLength

由于您事先知道描述符的大小,因此您可以用更少的请求来完成它,但我喜欢这样做,因为这样您就可以用一种非常通用的getDescriptor()方法来包装它。

从理论上讲,您可以像这样简单地做到这一点:

IOUSBDeviceDescriptor devDesc;

IOUSBDevRequest request;
request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
request.bRequest = kUSBRqGetDescriptor;
request.wValue = kUSBDeviceDesc << 8;
request.wIndex = 0;
request.wLength = sizeof(devDesc); // 18
request.pData = &devDesc;
request.wLenDone = 0;

kern_return_t kr = (*dev)->DeviceRequest(dev, &request);

但由于某种原因,这给了我一个kIOUSBPipeStalled错误。不知道为什么。

编辑:我忘记了<< 8. 现在它起作用了。:-)

于 2017-05-26T13:02:11.633 回答
0

标头IOKit/usb/USBSpec.h有一个记录在案的属性键列表,对应于不同描述符中的值。您可以使用具有IORegistryEntrySearchCFProperty(或类似功能)的那些来获取描述符值。这样您就不需要来自 的设备请求IOUSBDeviceInterface,这是有利的,因为:

  • 文档(评论)说所有设备请求都需要打开的 USB 设备,并且您可能无权对所有设备执行此操作(文档可能是错误的,至少对于描述符请求,但我不能保证这一点,它无论如何似乎更好地遵循它)
  • 设备请求可以阻塞不确定的时间
  • 此请求中不检索制造商、产品和序列号字符串(由设备描述符引用,但在技术上不是其中的一部分)
于 2019-08-30T16:24:25.943 回答
-1

要获取设备描述符和配置描述符,我们可以使用 IOUSBDeviceInterface 类中的函数

链接:http: //developer.apple.com/library/mac/#documentation/Darwin/Reference/IOKit/IOUSBLib_h/Classes/IOUSBDeviceInterface/index.html#//apple_ref/doc/com/intfm/IOUSBDeviceInterface/

要获取接口描述符和端点描述符,我们可以使用 IOUSBInterfaceInterface 类中的函数

链接:http: //developer.apple.com/library/mac/#documentation/Darwin/Reference/IOKit/IOUSBLib_h/Classes/IOUSBInterfaceInterface/

于 2011-10-13T09:11:50.797 回答