简体   繁体   English

如何在 Mac 中获取 USB 设备的设备描述符和配置描述符?

[英]How to get device descriptor and configuration descriptor of usb device in Mac?

I have minimum exposure to xcode and I/Okit framework.我对 xcode 和 I/Okit 框架的接触最少。 I have seen device descriptor and configuration descriptor of a usb device in USB prober.我在 USB 探测器中看到了 USB 设备的设备描述符和配置描述符。在此处输入图片说明

I have written an xcode program using I/O kit framework which gives the usb device name as output, when we give product id and vendor id of that device as input.我已经使用 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;

} }

I need to modify this, so that on giving vendor and product id of usb device, i will get the device descriptor and configuration descriptor( as shown in USB prober) as output.我需要修改它,以便在提供 USB 设备的供应商和产品 ID 时,我将获得设备描述符和配置描述符(如 USB 探测器中所示)作为输出。

Here i just gave an example, code can change but the output must be the descriptor( atleast the device decriptor).在这里我只是举了一个例子,代码可以改变,但输出必须是描述符(至少是设备描述符)。

Thanks in advance...提前致谢...

I think u should download the source code of USBProber rather than figure it out by yourself.我认为你应该下载 USBProber 的源代码而不是自己弄清楚。

All the information presents in the USBProber u could get sooner or later by analyzing the source code.通过分析源代码,您迟早会获得 USBProber 中提供的所有信息。

Here is link to download the source code of IOUSBFamily, with USBProber inside it.这是下载 IOUSBFamily 源代码的链接,其中包含 USBProber。 http://opensource.apple.com/tarballs/IOUSBFamily/ http://opensource.apple.com/tarballs/IOUSBFamily/

To get the configuration descriptors you can use code like this:要获取配置描述符,您可以使用如下代码:

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->...

Unfortunately there doesn't seem to be a function to get the device descriptor.不幸的是,似乎没有获取设备描述符的函数。 There are functions to get some of it:有一些函数可以获取其中的一些

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);

But I don't see a way to get iManufacturer , iProduct , iSerial , bMaxPacketSize0 , or bcdUSB .但我看不到获取iManufactureriProductiSerialbMaxPacketSize0bcdUSB

There is a way around this - instead of using the built-in functions you can just do a control request to get the device descriptor (and configuration descriptors if you like) manually using a control transfer.有一种方法可以解决这个问题 - 而不是使用内置函数,您只需执行控制请求即可使用控制传输手动获取设备描述符(以及配置描述符,如果您愿意)。

The USB 2.0 spec describes how to do this. USB 2.0 规范描述了如何做到这一点。 Basically you:基本上你:

  1. Do a control transfer with bmRequestType = Device | Standard | In使用bmRequestType = Device | Standard | In进行控制传输bmRequestType = Device | Standard | In bmRequestType = Device | Standard | In , bRequest = USB_GET_DESCRIPTOR_REQUEST , wValue = (USB_DEVICE_DESCRIPTOR_TYPE << 8) , wIndex = 0 , wLength = 2 . bmRequestType = Device | Standard | In , bRequest = USB_GET_DESCRIPTOR_REQUEST , wValue = (USB_DEVICE_DESCRIPTOR_TYPE << 8) , wIndex = 0 , wLength = 2 That will fail because the descriptor is longer than 2, but it gets you the descriptor header which includes its length.这将失败,因为描述符长于 2,但它会为您提供包含其长度的描述符标头。

  2. Repeat that request but with the correct length.重复该请求,但长度正确。

  3. For configuration descriptors, do a third request with length wTotalLength .对于配置描述符,执行长度为wTotalLength的第三个请求。

You can do it with one less request since you know the size of the descriptors in advance, but I like to do it like that because then you can wrap it up in a very general getDescriptor() method.由于您事先知道描述符的大小,因此您可以减少一个请求,但我喜欢这样做,因为这样您就可以将它封装在一个非常通用的getDescriptor()方法中。

In theory you can do it as simply as this:从理论上讲,您可以像这样简单地做到这一点:

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);

But for some reason that is giving me a kIOUSBPipeStalled error. 但出于某种原因,这给了我一个 kIOUSBPipeStalled错误。 Not sure why. 不知道为什么。

Edit: I forgot the << 8 .编辑:我忘记了<< 8 Now it works.现在它起作用了。 :-) :-)

The header IOKit/usb/USBSpec.h has a documented list of property keys corresponding to values inside the different descriptors.头文件IOKit/usb/USBSpec.h有一个记录的属性键列表,对应于不同描述符中的值。 You can use those with IORegistryEntrySearchCFProperty (or similar functions) to get the descriptor values.您可以将它们与IORegistryEntrySearchCFProperty (或类似函数)一起使用来获取描述符值。 This way you don't need a device request from an IOUSBDeviceInterface , which is advantageous because:这样您就不需要来自IOUSBDeviceInterface的设备请求,这是有利的,因为:

  • the documentation (comments) say that all device requests require an opened USB device and you may not have permission to do that for all devices (it's possible the documentation is wrong, at least for descriptor requests, but I have no guarantee of that and it seems better to follow it anyway)文档(评论)说所有设备请求都需要一个打开的 USB 设备,您可能没有权限为所有设备执行此操作(文档可能是错误的,至少对于描述符请求,但我不能保证这一点,它无论如何似乎更好地遵循它)
  • device requests can block for an indeterminate amount of time设备请求可能会阻塞一段不确定的时间
  • the manufacturer, product, and serial number strings (which are referenced by the device descriptor, but are not technically part of it) are not retrieved in this request在此请求中未检索制造商、产品和序列号字符串(由设备描述符引用,但在技术上不是它的一部分)

For getting device descriptor and configuration decriptor, we can use functions in IOUSBDeviceInterface class为了获取设备描述符和配置描述符,我们可以使用 IOUSBDeviceInterface 类中的函数

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

For getting interface descriptor and end point descriptor, we can use functions in IOUSBInterfaceInterface class为了获取接口描述符和端点描述符,我们可以使用 IOUSBInterfaceInterface 类中的函数

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM