我最少接触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 prober中所示)作为输出。
这里我举了一个例子,代码可以改变,但输出必须是描述符(至少是设备描述符)。
提前致谢...
答案 0 :(得分:5)
我想你应该下载USBProber的源代码,而不是自己搞清楚。
通过分析源代码,USBProber中提供的所有信息迟早都可以得到。
这是下载IOUSBFamily源代码的链接,其中包含USBProber。 http://opensource.apple.com/tarballs/IOUSBFamily/
答案 1 :(得分:1)
要获取配置描述符,您可以使用以下代码:
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规范描述了如何执行此操作。基本上你:
使用bmRequestType = Device | Standard | In
,bRequest = USB_GET_DESCRIPTOR_REQUEST
,wValue = (USB_DEVICE_DESCRIPTOR_TYPE << 8)
,wIndex = 0
,wLength = 2
进行控件转移。这将失败,因为描述符长于2,但它会获得包含其长度的描述符标题。
重复该请求,但长度正确。
对于配置描述符,请执行长度为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
。现在它有效。 : - )
答案 2 :(得分:0)
为了获取设备描述符和配置描述符,我们可以使用IOUSBDeviceInterface类中的函数
为了获取接口描述符和端点描述符,我们可以使用IOUSBInterfaceInterface类中的函数
答案 3 :(得分:0)
头文件IOKit/usb/USBSpec.h
具有记录的属性键列表,这些属性键与不同描述符中的值相对应。您可以将它们与IORegistryEntrySearchCFProperty
(或类似函数)一起使用以获取描述符值。这样,您就不需要来自IOUSBDeviceInterface
的设备请求,这是有优势的,因为: