UVC UVC驱动接口关联描述符IAD失踪之迷
先说一下,本人所使用的操作系统是WIN10 x64操作系统
Microsoft Windows [版本 10.0.14393]
(c) 2016 Microsoft Corporation。保留所有权利。
这是win10一个相对比较老的版本。
新旧的混淆
在微软件主的官方文档 USB Interface Association Descriptor有一句话
Windows 7, Windows Server 2008, Windows Vista, Microsoft Windows Server 2003 Service Pack 1 (SP1), and Microsoft Windows XP Service Pack 2 (SP2) support IADs.
该文档发于2017.4.20
让人不解的是,IAD Win10难道不支持了,我迷糊了….
故事的开始
在Windbg下,使用编写的USB驱动程序,接收设备的配置描述符。
收到的数据格式如下:
- 配置描述符
- USB_VC_HEADER(UVC控制接口头描述符)
- Video Control Input Terminal Descriptor
- Video Control Processing Unit Descriptor
- Video Control Extension Unit Descriptor
- Video Control Output Terminal Descriptor
- Endpoint Descriptor
- Class-specific VC Interrupt Endpoint Descriptor
- VC-Specific VS Video Input Header Descriptor(视频流接口描述符)
- VS Frame Based Payload Format Type Descriptor
- VS Frame Based Payload Frame Type Descriptor
- Endpoint Descriptor
- USB_VC_HEADER(UVC控制接口头描述符)
整整齐齐的数据格式,看着让人赏心悦目。
不过,IAD这玩意跑那里去了,人家UVC规范里可是这样说的啊,必须有一个的。
A device must use an Interface Association Descriptor to describe a Video Interface Collection
for each device function that requires a VideoControl Interface and one or more VideoStreaming
interfaces. The standard VIC Interface Association Descriptor is identical to the standard
Interface Association Descriptor defined in the Interface Association Descriptor ECN, except
that some fields now have dedicated values.
让人不禁要怀疑写固件的人了,你是没有没有写啊。
这可是有前科的啊,2个接口描述符正常不应该是从0开始编号的吗?可人家偏偏就从1开始了,导致我在
USBD_ParseConfigurationDescriptorEx 时就是找不到另一个接口,都让人怀疑人生了,我一度怀疑这个摄像头只有一个接口。
附REACTOS关于USB的部分代码节选
usbcgp
for (Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++)
{
//
// get interface descriptor
//
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index, 0, -1, -1, -1);
DPRINT1("Index %lu Descriptor %p\n", Index, InterfaceDescriptor);
ASSERT(InterfaceDescriptor);
if (InterfaceDescriptor->bInterfaceClass != 0x1)
{
//
// collection contains non audio class
//
return STATUS_UNSUCCESSFUL;
}
if (FirstDescriptor == NULL)
{
//
// store interface descriptor
//
FirstDescriptor = InterfaceDescriptor;
continue;
}
if (FirstDescriptor->bInterfaceSubClass == InterfaceDescriptor->bInterfaceSubClass)
{
//
// interface subclass must be different from the first interface
//
return STATUS_UNSUCCESSFUL;
}
}
没办法,上BUSBOUND了,一抓还是没有 IAD,后来找同事要了一个UVC的摄像头,一抓也是没有。
但是通过UsbView人家又是有的。
!!!怀疑人生了!!!!
回到前面的那个微软DOC(USB Interface Association Descriptor),里面有一节写的是这样的
Accessing the contents of an IAD>Accessing the contents of an IAD
Client drivers cannot access IAD descriptors directly. The IAD Engineering Change Notification (ECN) specifies that IADs must be included in the configuration information that devices return when they receive a request from host software for the configuration descriptor (GetDescriptor Configuration). Host software cannot retrieve IADs directly with a GetDescriptor request.
However, client drivers can query a USB device’s parent driver for the device’s hardware identifiers (IDs), and the device’s hardware IDs contain embedded information about the fie
这真是一个让人无奈的坑!!!
想说的是总线驱动你直接把IAD传给设备驱动难道不香吗?为什么要中间加一杠子了,IAD这玩意又不是啥重要的东西,就一个结构体。
//
// USB 2.0 ECN: USB ECN : Interface Association Descriptor, 9.X.Y Interface Association,
// Table 9-Z. Standard Interface Association Descriptor
// USB 3.0: 9.6.4 Interface Association, Table 9-16. Standard Interface Association Descriptor
//
typedef struct _USB_INTERFACE_ASSOCIATION_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR bFirstInterface;
UCHAR bInterfaceCount;
UCHAR bFunctionClass;
UCHAR bFunctionSubClass;
UCHAR bFunctionProtocol;
UCHAR iFunction;
} USB_INTERFACE_ASSOCIATION_DESCRIPTOR, *PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR;
虽然到文档截止了,没有看到相关的代码,不过也算是对这1-2天有所交待吧~~~
在REACTOS中有对其进行代码解释,可以查看 USBCCGGP关联接口功能设备枚举 之 USBCCGP_InitInterfaceListOfFunctionDescriptor 的实现。