UAC的规格书可以从usb.org网站下载,目前有1.0,2.0,3.0三个版本,本文以1.0为例分享一个UAC扬声器的实例, 重点在于描述符拓扑。
规格书《UAC1.0/USB_AV_Specification_Rev_1.0》定义了UAC设备类完整的信息,但是比较复杂,《UAC1.0\BasicAudioDevice-10\BasicAudioDevice-10.pdf》定义了其一个最小子集,一般我们实现其子集就够了。所以我们可以参考BasicAudioDevice-10.pdf的最简拓扑结构实现设备,然后具体的描述符,请求等细节可以参考USB_AV_Specification_Rev_1.0。
BasicAudioDevice-10.pdf定义了需要支持的3个设备
Headphone:耳机设备,实际上声音播放的都算,所以PC上叫扬声器或者耳机。
Microphone:麦克风设备。
Headset:以上两者的集合,既有麦克风又有扬声器。
我们接下来就分三篇分享下这个三个设备实例,包括描述符拓扑,枚举过程等。
前文已经分享了扬声器,本文以麦克风为例。
我们这里以最简单的单声道为例。
如下是其拓扑结构,即最简单的有一个输入终端, 一个特征单元,一个输出终端。
数据流是: -> 输入终端 -> 特征单元 -> 输出终端 -> USB IN端点。
可以看到和扬声器的数据流是反向的,USB IN端点绑定到输出终端,这一点要特别注意。
其中特征单元用于静音,音量控制等。
相关描述符参考BasicAudioDevice-10.pdf的第六章
我这里分享一个基于IAD的描述符拓扑实例
一共2个接口,接口2是控制接口,
接口3的alt0是0带宽接口,设置接口选择该alt时关闭流,alt1是数据流接口,设置接口选择该alt时启动流,该接口下有一个IN端点用于发送数据。
控制接口中包括输入终端4,特征单元5和输出终端6。流接口3的alt 1绑定到输出终端,
而输出终端对应的是IN端点0x82
设备描述符和配置描述符如下,字符串描述符就略去了,描述符后有详细的注释和注意说明,不再赘述。
static const uint8_t dev_desc[] =
{
0x12, /* bLength 本描述符长度,固定为0x12 */
0x01, /* bDescriptorType 描述符类型DEVICE=1, 见Table 9-5. Descriptor Types */
0x00,0x02, /* bcdUSB USB规格书发布编号,BCD,小端 */
/* bDeviceClass-bDeviceSubClass-DeviceProtocol决定具体设备类型 见https://www.usb.org/defined-class-codes
* 这里EF-02-01表示IAD设备
*/
0xEF, /* bDeviceClass 设备类类型 */
0x02, /* bDeviceSubClass 设备子类 */
0x01, /* bDeviceProtocol 设备协议 */
0x40, /* bMaxPacketSize0 控制端点最大包大小 */
0x4A,0x4C, /* idVendor 厂商ID VID,小端*/
0x55,0x4C, /* idProduct 产品ID PID,小端*/
0x00,0x01, /* bcdDevice 设备发布号,BCD,小端*/
0x01, /* iManufacturer 制造商字符串描述符索引 */
0x02, /* iProduct 产品字符串描述符索引 */
0x03, /* iSerialNumber 设备序列号字符串描述符索引 0则不使用 */
0x01, /* bNumConfigurations 配置个数 */
};
static const uint8_t cfg_desc[] = {
/* 配置描述符见Table 9-10. Standard Configuration Descriptor */
0x09, /* bLength 本描述符长度,固定为9 */
0x02, /* bDescriptorType 描述符类型CONFIGURATION =0x02, 见Table 9-5. Descriptor Types P251 */
0x75, /* wTotalLength 本配置符所有内容长度,小端 */
0x00,
0x02, /* bNumInterfaces 本配置的接口数 一个控制一个流 */
0x01, /* bConfigurationValue 设置配置请求,选择该配置的对应的设置值 */
0x04, /* iConfiguration 本配置对应的字符串描述符,配置为0则没有 */
0x80, /* bmAttributes 配置特征 D7固定为1 D6:Self-powered D5:Remote Wakeup*/
0xC8, /* bMaxPower 最大消耗电流,单位2mA */
/********************************************************
* 以下是MIC+SPK部分
*******************************************************/
/**
* IAD描述符 参考InterfaceAssociationDescriptor_ecn P4
*/
0x08, /* bLength 本描述符长度,固定为8 */
0x0B, /* bDescriptorType 描述符类型 INTERFACE_ASSOCIATION=0x0B 参考InterfaceAssociationDescriptor_ecn P3 */
MIC_AC_ITF, /* bFirstInterface 本IAD下第一个接口 */
0x02, /* bInterfaceCount 本IAD下接口数,默认一个控制接口一个SPK流接口一个MIC流接口 */
0x01, /* bFunctionClass UAC是接口中说明类功能 这里应该是接口类 见https://www.usb.org/defined-class-codes (Audio=1) 见audio10.pdf P99 Table A-1: Audio Interface Class Code AUDIO=1 */
0x02, /* bFunctionSubClass UAC是接口中说明类功能 这里应该是接口类子类 见audio10.pdf P99 Table A-2: Audio Interface Subclass Codes AUDIOSTREAMING=0x02 */
0x00, /* bFunctionProtocol UAC是接口中说明类功能 这里应该是接口协议号 见audio10.pdf P99 Table A-3: Audio Interface Protocol Codes PR_PROTOCOL_UNDEFINED=0x00 */
0x07, /* iFunction 对应字符串索引 */
/********************************************************
* 控制接口部分
*******************************************************/
/* 接口描述符 UAC是接口描述符说明功能
* 见usb_20 P268 Table 9-12. Standard Interface Descriptor
*/
0x09, /* bLength */
0x04, /* bDescriptorType 见usb_20 P251 Table 9-5. Descriptor Types INTERFACE=4 */
MIC_AC_ITF, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints 本接口下无端点*/
0x01, /* bInterfaceClass (Audio) 见audio10.pdf P99 Table A-1: Audio Interface Class Code AUDIO=1 */
0x01, /* bInterfaceSubClass (Audio Control) 见audio10.pdf P99 Table A-2: Audio Interface Subclass Codes AUDIOCONTROL=0x01 */
0x00, /* bInterfaceProtocol 见audio10.pdf P99 Table A-3: Audio Interface Protocol Codes PR_PROTOCOL_UNDEFINED=0x00 */
0x07, /* iInterface 对应字符串索引 */
/* BasicAudioDevice-10.pdf P57 Table 7-4: Headset Class-Specific AC Interface Header Descriptor */
0x09, /* bLength */
0x24, /* bDescriptorType 见audio10.pdf P99 Table A-4: Audio Class-specific Descriptor Types CS_INTERFACE=0x24 */
0x01, /* bDescriptorSubtype 见audio10.pdf P100 Table A-5: Audio Class-Specific AC Interface Descriptor Subtypes HEADER=0x01 */
0x00,0x01, /* bcdADC Audio 1.0 */
0x27,0x00, /* wTotalLength 本接口下后续所有描述符的长度 包括本描述符 */
0x01, /* bInCollection 1个流接口 */
MIC_AS_ITF, /* baInterfaceNr(1) MIC流接口号 */
/* BasicAudioDevice-10.pdf P59 7.3.3.1.6 Headset Microphone Input Terminal ID4 Descriptor
* BasicAudioDevice-10.pdf P40 6.3.3.1.3 Microphone Input Terminal ID4 Descriptor
* BasicAudioDevice-10.pdf P22 Table 5-3: Mono Input Terminal Descriptor
*/
0x0C, /* bLength */
0x24, /* bDescriptorType 见audio10.pdf P99 Table A-4: Audio Class-specific Descriptor Types CS_INTERFACE=0x24 */
0x02, /* bDescriptorSubtype 见audio10.pdf P100 Table A-5: Audio Class-Specific AC Interface Descriptor Subtypes INPUT_TERMINAL=0x02 */
MIC_INPUT_TID,/* bTerminalID TID=4*/
0x01,0x02, /* wTerminalType TT Terminal is Microphone. */
0x00, /* bAssocTerminal */
0x01, /* bNrChannels 1个通道 */
0x04,0x00, /* wChannelConfig Center Front channel. @todo 0x0000改为0004*/
0x00, /* iChannelNames 固定为0 */
0x00, /* iTerminal 对应字符串描述符索引 */
/*
* BasicAudioDevice-10.pdf P60 7.3.3.1.10 Headset Feature Unit ID5 Descriptor
*/
0x09, /* bLength */
0x24, /* bDescriptorType 见audio10.pdf P99 Table A-4: Audio Class-specific Descriptor Types CS_INTERFACE=0x24 */
0x06, /* bDescriptorSubtype 见audio10.pdf P100 Table A-5: Audio Class-Specific AC Interface Descriptor Subtypes FEATURE_UNIT=0x06 */
MIC_FEATURE_TID, /* bUnitID */
MIC_INPUT_TID, /* bSourceID */
0x01, /* bControlSize 这里配置不对会枚举失败 */
/**
A bit set to 1 indicates that the mentioned
Control is supported for master channel
0:
D0: Mute
D1: Volume
D2: Bass
D3: Mid
D4: Treble
D5: Graphic Equalizer
D6: Automatic Gain
D7: Delay
D8: Bass Boost
D9: Loudness
D10..(n*8-1): Reserved
*/
0x01, /* bmaControls(0) Mute Control on Master Channel.*/
/*A bit set to 1 indicates that the mentioned
Control is supported for logical channel 1 */
0x02, /* bmaControls(1) Volume Control on Center Front channel */
0x00, /* iFeature 对应字符串描述符索引 */
/*
* BasicAudioDevice-10.pdf P67 7.3.3.1.17 Headset Output Terminal ID6 Descriptor
*/
0x09, /* bLength */
0x24, /* bDescriptorType 见audio10.pdf P99 Table A-4: Audio Class-specific Descriptor Types CS_INTERFACE=0x24 */
0x03, /* bDescriptorSubtype 见audio10.pdf P100 Table A-5: Audio Class-Specific AC Interface Descriptor Subtypes OUTPUT_TERMINAL=0x03 */
MIC_OUTPUT_TID, /* bTerminalID */
0x01,0x01, /* wTerminalType USB Streaming Terminal Type*/
0x02, /* bAssocTerminal */
MIC_FEATURE_TID, /* bSourceID */
0x00, /* iTerminal */
/********************************************************
* MIC流部分
*******************************************************/
/* 接口描述符
* usb_20.pdf P268 Table 9-12. Standard Interface Descriptor
* BasicAudioDevice-10.pdf P30 Table 5-13: Headphone Standard AS Interface Descriptor (Alt. Set. 0)
*/
0x09, /* bLength */
0x04, /* bDescriptorType INTERFACE */
MIC_AS_ITF, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints */
0x01, /* bInterfaceClass 见audio10.pdf P99 Table A-1: Audio Interface Class Code AUDIO=1 */
0x02, /* bInterfaceSubClass 见audio10.pdf P99 Table A-2: Audio Interface Subclass Codes AUDIOSTREAMING=0x02 */
0x00, /* bInterfaceProtocol 见audio10.pdf P99 Table A-3: Audio Interface Protocol Codes PR_PROTOCOL_UNDEFINED = 0x00 */
0x00, /* iInterface */
/* 接口描述符
* usb_20.pdf P268 Table 9-12. Standard Interface Descriptor
BasicAudioDevice-10.pdf P31 Table 5-14: Headphone Standard AS Interface Descriptor (Alt. Set .1)
*/
0x09, /* bLength */
0x04, /* bDescriptorType INTERFACE */
MIC_AS_ITF, /* bInterfaceNumber */
0x01, /* bAlternateSetting */
0x01, /* bNumEndpoints 一个端点 */
0x01, /* bInterfaceClass 见audio10.pdf P99 Table A-1: Audio Interface Class Code AUDIO=1 */
0x02, /* bInterfaceSubClass 见audio10.pdf P99 Table A-2: Audio Interface Subclass Codes AUDIOSTREAMING=0x02 */
0x00, /* bInterfaceProtocol 见audio10.pdf P99 Table A-3: Audio Interface Protocol Codes PR_PROTOCOL_UNDEFINED = 0x00 */
0x00, /* iInterface */
/*
* BasicAudioDevice-10.pdf P31 Table 5-15: Headphone Class-specific AS General Interface Descriptor
*/
0x07, /* bLength */
0x24, /* bDescriptorType 见audio10.pdf P99 Table A-4: Audio Class-specific Descriptor Types CS_INTERFACE=0x24 */
0x01, /* bDescriptorSubtype 见audio10.pdf P100 Table A-6: Audio Class-Specific AS Interface Descriptor Subtypes AS_GENERAL=0x01 */
MIC_OUTPUT_TID, /* bTerminalLink */
0x01, /* bDelay Total interface delay, expressed in frames. Not used and shall be set to 0x00 */
0x01,0x00, /* wFormatTag PCM Format */
/*
* BasicAudioDevice-10.pdf P32 Table 5-16: Mono Headphone Type I Format Type Descriptor
*/
0x0B, /* bLength */
0x24, /* bDescriptorType 见audio10.pdf P99 Table A-4: Audio Class-specific Descriptor Types CS_INTERFACE=0x24 */
0x02, /* bDescriptorSubtype 见audio10.pdf P100 Table A-6: Audio Class-Specific AS Interface Descriptor Subtypes FORMAT_TYPE=0x02 */
0x01, /* bFormatType 见frmts10.pdf P20 Table A-4: Format Type Codes FORMAT_TYPE_I=0x01 */
0x01, /* bNrChannels One channel. */
0x02, /* bSubFrameSize Two bytes per audio subframe. */
0x10, /* bBitResolution 16 bits per sample */
0x01, /* bSamFreqType One frequency supported. */
0x80,0x3E,0x00, /* tSamFreq 0x003E80=16000 */
/* 端点描述符
* usb_20.pdf P269 Table 9-13. Standard Endpoint Descriptor
* BasicAudioDevice-10.pdf P33 Table 5-18: Mono Headphone Standard AS Audio Data Endpoint Descriptor
*/
0x09, /* bLength */
0x05, /* bDescriptorType 见usb_20.pdf P251 Table 9-5. Descriptor Types ENDPOINT=5 */
MIC_IN_EP, /* bEndpointAddress */
0x0D, /* bmAttributes b[1:0] 01 = Isochronous, b[3:2] 11 = Synchronous */
0x20, 0x00, /* wMaxPacketSize */
0x01, /* bInterval 1ms一包 */
0x00, /* bRefresh */
0x00, /* bSynchAddress */
/*
* BasicAudioDevice-10.pdf P33 Table 5-20: Headphone Class-specific Isoc. Audio Data Endpoint Descriptor
*/
0x07, /* bLength */
0x25, /* bDescriptorType 见audio10.pdf P99 Table A-4: Audio Class-specific Descriptor Types CS_ENDPOINT=0x25 */
0x01, /* bDescriptorSubtype 见audio10.pdf P101 Table A-8: Audio Class-Specific Endpoint Descriptor Subtypes EP_GENERAL=0x01. */
0x00, /* bmAttributes No sampling frequency control, no pitch control, no packet padding.*/
0x00, /* bLockDelayUnits */
0x00, 0x00, /* wLockDelay */
};
如下是UsbTreeView抓到的描述符
Device Descriptor ----------------------
bLength : 0x12 (18 bytes)
bDescriptorType : 0x01 (Device Descriptor)
bcdUSB : 0x200 (USB Version 2.0)
bDeviceClass : 0xEF (Miscellaneous)
bDeviceSubClass : 0x02
bDeviceProtocol : 0x01 (IAD - Interface Association Descriptor)
bMaxPacketSize0 : 0x40 (64 bytes)
idVendor : 0x4C4A (Unknown Vendor)
idProduct : 0x4C55
bcdDevice : 0x0100
iManufacturer : 0x01 (String Descriptor 1)
Language 0x0409 : "xxx.Technology"
iProduct : 0x02 (String Descriptor 2)
Language 0x0409 : "USB.Audio"
iSerialNumber : 0x03 (String Descriptor 3)
Language 0x0409 : "0.1"
bNumConfigurations : 0x01 (1 Configuration)
Data (HexDump) : 12 01 00 02 EF 02 01 40 4A 4C 55 4C 00 01 01 02 .......@JLUL....
03 01 ..
Configuration Descriptor -------------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x02 (Configuration Descriptor)
wTotalLength : 0x0075 (117 bytes)
bNumInterfaces : 0x02 (2 Interfaces)
bConfigurationValue : 0x01 (Configuration 1)
iConfiguration : 0x04 (String Descriptor 4)
Language 0x0409 : "UAC"
bmAttributes : 0x80
D7: Reserved, set 1 : 0x01
D6: Self Powered : 0x00 (no)
D5: Remote Wakeup : 0x00 (no)
Reserved, set 0 : 0x00 :
MaxPower : 0xC8 (400 mA)
Data (HexDump) : 09 02 75 00 02 01 04 80 C8 08 0B 02 02 01 02 00 ..u.............
07 09 04 02 00 00 01 01 00 07 09 24 01 00 01 27 ...........$...
00 01 03 0C 24 02 04 01 02 00 01 04 00 00 00 09 ....$...........
24 06 05 04 01 01 02 00 09 24 03 06 01 01 02 05 $........$......
00 09 04 03 00 00 01 02 00 00 09 04 03 01 01 01 ................
02 00 00 07 24 01 06 01 01 00 0B 24 02 01 01 02 ....$......$....
10 01 80 3E 00 09 05 82 0D 20 00 01 00 00 07 25 ...>..... .....%
01 00 00 00 00 .....
IAD Descriptor --------------------
bLength : 0x08 (8 bytes)
bDescriptorType : 0x0B (Interface Association Descriptor)
bFirstInterface : 0x02 (Interface 2)
bInterfaceCount : 0x02 (2 Interfaces)
The total number of interfaces (2) must be greater than or equal to
the highest linked interface number (base 2 + count 2 = 4)
bFunctionClass : 0x01 (Audio)
bFunctionSubClass : 0x02 (Audio Streaming)
bFunctionProtocol : 0x00
iFunction : 0x07 (String Descriptor 7)
Language 0x0409 : "UAC"
Data (HexDump) : 08 0B 02 02 01 02 00 07 ........
Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x02 (Interface 2)
bAlternateSetting : 0x00
bNumEndpoints : 0x00 (Default Control Pipe only)
bInterfaceClass : 0x01 (Audio)
bInterfaceSubClass : 0x01 (Audio Control)
bInterfaceProtocol : 0x00
iInterface : 0x07 (String Descriptor 7)
Language 0x0409 : "UAC"
Data (HexDump) : 09 04 02 00 00 01 01 00 07 .........
Audio Control Interface Header Descriptor ------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x01 (Header)
bcdADC : 0x0100
wTotalLength : 0x0027 (39 bytes)
bInCollection : 0x01
0x03 :
Data (HexDump) : 09 24 01 00 01 27 00 01 03 .$... ...
Audio Control Input Terminal Descriptor -------
bLength : 0x0C (12 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x02 (Input Terminal)
bTerminalID : 0x04
wTerminalType : 0x0201 (Microphone)
bAssocTerminal : 0x00
bNrChannels : 0x01 (1 channel)
wChannelConfig : 0x0004 (C)
iChannelNames : 0x00 (No String Descriptor)
iTerminal : 0x00 (No String Descriptor)
Data (HexDump) : 0C 24 02 04 01 02 00 01 04 00 00 00 .$..........
Audio Control Feature Unit Descriptor --------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x06 (Feature Unit)
bUnitID : 0x05 (5)
bSourceID : 0x04 (4)
bControlSize : 0x01 (1 byte per control)
0x01 :
D0: Mute : 1
D1: Volume : 0
D2: Bass : 0
D3: Mid : 0
D4: Treble : 0
D5: Graphic Equalizer : 0
D6: Automatic Gain : 0
D7: Delay : 0
0x02 :
D0: Mute : 0
D1: Volume : 1
D2: Bass : 0
D3: Mid : 0
D4: Treble : 0
D5: Graphic Equalizer : 0
D6: Automatic Gain : 0
D7: Delay : 0
iFeature : 0x00 (No String Descriptor)
Data (HexDump) : 09 24 06 05 04 01 01 02 00 .$.......
Audio Control Output Terminal Descriptor ------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x03 (Output Terminal)
bTerminalID : 0x06
wTerminalType : 0x0101 (USB Streaming)
bAssocTerminal : 0x02 (2)
bSourceID : 0x05 (5)
iTerminal : 0x00 (No String Descriptor)
Data (HexDump) : 09 24 03 06 01 01 02 05 00 .$.......
Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x03 (Interface 3)
bAlternateSetting : 0x00
bNumEndpoints : 0x00 (Default Control Pipe only)
bInterfaceClass : 0x01 (Audio)
bInterfaceSubClass : 0x02 (Audio Streaming)
bInterfaceProtocol : 0x00
iInterface : 0x00 (No String Descriptor)
Data (HexDump) : 09 04 03 00 00 01 02 00 00 .........
Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x03 (Interface 3)
bAlternateSetting : 0x01
bNumEndpoints : 0x01 (1 Endpoint)
bInterfaceClass : 0x01 (Audio)
bInterfaceSubClass : 0x02 (Audio Streaming)
bInterfaceProtocol : 0x00
iInterface : 0x00 (No String Descriptor)
Data (HexDump) : 09 04 03 01 01 01 02 00 00 .........
Audio Streaming Interface Descriptor ---------
bLength : 0x07 (7 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x01 (AS_GENERAL)
bTerminalLink : 0x06 (Terminal ID 6)
bDelay : 0x01 (1 frame)
wFormatTag : 0x0001 (PCM)
Data (HexDump) : 07 24 01 06 01 01 00 .$.....
Audio Streaming Format Type Descriptor --------
bLength : 0x0B (11 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x02 (Format Type)
bFormatType : 0x01 (FORMAT_TYPE_I)
bNrChannels : 0x01 (1 channel)
bSubframeSize : 0x02 (2 bytes per subframe)
bBitResolution : 0x10 (16 bits per sample)
bSamFreqType : 0x01 (supports 1 sample frequence)
0x03E80 (16000 Hz) :
Data (HexDump) : 0B 24 02 01 01 02 10 01 80 3E 00 .$.......>.
Endpoint Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x05 (Endpoint Descriptor)
bEndpointAddress : 0x82 (Direction=IN EndpointID=2)
bmAttributes : 0x0D (TransferType=Isochronous SyncType=Synchronous EndpointType=Data)
wMaxPacketSize : 0x0020
Bits 15..13 : 0x00 (reserved, must be zero)
Bits 12..11 : 0x00 (0 additional transactions per microframe -> allows 1..1024 bytes per packet)
Bits 10..0 : 0x20 (32 bytes per packet)
bInterval : 0x01 (1 ms)
bRefresh : 0x00
bSynchAddress : 0x00
Data (HexDump) : 09 05 82 0D 20 00 01 00 00 .... ....
Audio Data Endpoint Descriptor ------------
bLength : 0x07 (7 bytes)
bDescriptorType : 0x25 (Audio Endpoint Descriptor)
bDescriptorSubtype : 0x01 (General)
bmAttributes : 0x00
D0 : Sampling Freq : 0x00 (not supported)
D1 : Pitch : 0x00 (not supported)
Reserved : 0x00 :
D7 : MaxPacketsOnly : 0x00 (no)
bLockDelayUnits : 0x00 (Undefined)
wLockDelay : 0x0000
Data (HexDump) : 07 25 01 00 00 00 00 .%.....
Device Qualifier Descriptor (for Full-Speed) --------
bLength : 0x0A (10 bytes)
bDescriptorType : 0x06 (Device_qualifier Descriptor)
bcdUSB : 0x200 (USB Version 2.00)
bDeviceClass : 0xEF (Miscellaneous)
bDeviceSubClass : 0x02
bDeviceProtocol : 0x01 (IAD - Interface Association Descriptor)
bMaxPacketSize0 : 0x40 (64 Bytes)
bNumConfigurations : 0x01 (1 other-speed configuration)
bReserved : 0x00
Data (HexDump) : 0A 06 00 02 EF 02 01 40 01 00 .......@..
Configuration Descriptor -------------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x02 (Configuration Descriptor)
wTotalLength : 0x0075 (117 bytes)
bNumInterfaces : 0x02 (2 Interfaces)
bConfigurationValue : 0x01 (Configuration 1)
iConfiguration : 0x04 (String Descriptor 4)
Language 0x0409 : "UAC"
bmAttributes : 0x80
D7: Reserved, set 1 : 0x01
D6: Self Powered : 0x00 (no)
D5: Remote Wakeup : 0x00 (no)
Reserved, set 0 : 0x00 :
MaxPower : 0xC8 (400 mA)
Data (HexDump) : 09 02 75 00 02 01 04 80 C8 08 0B 02 02 01 02 00 ..u.............
07 09 04 02 00 00 01 01 00 07 09 24 01 00 01 27 ...........$...
00 01 03 0C 24 02 04 01 02 00 01 04 00 00 00 09 ....$...........
24 06 05 04 01 01 02 00 09 24 03 06 01 01 02 05 $........$......
00 09 04 03 00 00 01 02 00 00 09 04 03 01 01 01 ................
02 00 00 07 24 01 06 01 01 00 0B 24 02 01 01 02 ....$......$....
10 01 80 3E 00 09 05 82 0D 20 00 01 00 00 07 25 ...>..... .....%
01 00 00 00 00 .....
IAD Descriptor --------------------
bLength : 0x08 (8 bytes)
bDescriptorType : 0x0B (Interface Association Descriptor)
bFirstInterface : 0x02 (Interface 2)
bInterfaceCount : 0x02 (2 Interfaces)
The total number of interfaces (2) must be greater than or equal to
the highest linked interface number (base 2 + count 2 = 4)
bFunctionClass : 0x01 (Audio)
bFunctionSubClass : 0x02 (Audio Streaming)
bFunctionProtocol : 0x00
iFunction : 0x07 (String Descriptor 7)
Language 0x0409 : "UAC"
Data (HexDump) : 08 0B 02 02 01 02 00 07 ........
Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x02 (Interface 2)
bAlternateSetting : 0x00
bNumEndpoints : 0x00 (Default Control Pipe only)
bInterfaceClass : 0x01 (Audio)
bInterfaceSubClass : 0x01 (Audio Control)
bInterfaceProtocol : 0x00
iInterface : 0x07 (String Descriptor 7)
Language 0x0409 : "UAC"
Data (HexDump) : 09 04 02 00 00 01 01 00 07 .........
Audio Control Interface Header Descriptor ------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x01 (Header)
bcdADC : 0x0100
wTotalLength : 0x0027 (39 bytes)
bInCollection : 0x01
0x03 :
Data (HexDump) : 09 24 01 00 01 27 00 01 03 .$... ...
Audio Control Input Terminal Descriptor -------
bLength : 0x0C (12 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x02 (Input Terminal)
bTerminalID : 0x04
wTerminalType : 0x0201 (Microphone)
bAssocTerminal : 0x00
bNrChannels : 0x01 (1 channel)
wChannelConfig : 0x0004 (C)
iChannelNames : 0x00 (No String Descriptor)
iTerminal : 0x00 (No String Descriptor)
Data (HexDump) : 0C 24 02 04 01 02 00 01 04 00 00 00 .$..........
Audio Control Feature Unit Descriptor --------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x06 (Feature Unit)
bUnitID : 0x05 (5)
bSourceID : 0x04 (4)
bControlSize : 0x01 (1 byte per control)
0x01 :
D0: Mute : 1
D1: Volume : 0
D2: Bass : 0
D3: Mid : 0
D4: Treble : 0
D5: Graphic Equalizer : 0
D6: Automatic Gain : 0
D7: Delay : 0
0x02 :
D0: Mute : 0
D1: Volume : 1
D2: Bass : 0
D3: Mid : 0
D4: Treble : 0
D5: Graphic Equalizer : 0
D6: Automatic Gain : 0
D7: Delay : 0
iFeature : 0x00 (No String Descriptor)
Data (HexDump) : 09 24 06 05 04 01 01 02 00 .$.......
Audio Control Output Terminal Descriptor ------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x03 (Output Terminal)
bTerminalID : 0x06
wTerminalType : 0x0101 (USB Streaming)
bAssocTerminal : 0x02 (2)
bSourceID : 0x05 (5)
iTerminal : 0x00 (No String Descriptor)
Data (HexDump) : 09 24 03 06 01 01 02 05 00 .$.......
Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x03 (Interface 3)
bAlternateSetting : 0x00
bNumEndpoints : 0x00 (Default Control Pipe only)
bInterfaceClass : 0x01 (Audio)
bInterfaceSubClass : 0x02 (Audio Streaming)
bInterfaceProtocol : 0x00
iInterface : 0x00 (No String Descriptor)
Data (HexDump) : 09 04 03 00 00 01 02 00 00 .........
Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x03 (Interface 3)
bAlternateSetting : 0x01
bNumEndpoints : 0x01 (1 Endpoint)
bInterfaceClass : 0x01 (Audio)
bInterfaceSubClass : 0x02 (Audio Streaming)
bInterfaceProtocol : 0x00
iInterface : 0x00 (No String Descriptor)
Data (HexDump) : 09 04 03 01 01 01 02 00 00 .........
Audio Streaming Interface Descriptor ---------
bLength : 0x07 (7 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x01 (AS_GENERAL)
bTerminalLink : 0x06 (Terminal ID 6)
bDelay : 0x01 (1 frame)
wFormatTag : 0x0001 (PCM)
Data (HexDump) : 07 24 01 06 01 01 00 .$.....
Audio Streaming Format Type Descriptor --------
bLength : 0x0B (11 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x02 (Format Type)
bFormatType : 0x01 (FORMAT_TYPE_I)
bNrChannels : 0x01 (1 channel)
bSubframeSize : 0x02 (2 bytes per subframe)
bBitResolution : 0x10 (16 bits per sample)
bSamFreqType : 0x01 (supports 1 sample frequence)
0x03E80 (16000 Hz) :
Data (HexDump) : 0B 24 02 01 01 02 10 01 80 3E 00 .$.......>.
Endpoint Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x05 (Endpoint Descriptor)
bEndpointAddress : 0x82 (Direction=IN EndpointID=2)
bmAttributes : 0x0D (TransferType=Isochronous SyncType=Synchronous EndpointType=Data)
wMaxPacketSize : 0x0020 (32 bytes)
bInterval : 0x01 (1 ms)
bRefresh : 0x00
bSynchAddress : 0x00
Data (HexDump) : 09 05 82 0D 20 00 01 00 00 .... ....
Audio Data Endpoint Descriptor ------------
bLength : 0x07 (7 bytes)
bDescriptorType : 0x25 (Audio Endpoint Descriptor)
bDescriptorSubtype : 0x01 (General)
bmAttributes : 0x00
D0 : Sampling Freq : 0x00 (not supported)
D1 : Pitch : 0x00 (not supported)
Reserved : 0x00 :
D7 : MaxPacketsOnly : 0x00 (no)
bLockDelayUnits : 0x00 (Undefined)
wLockDelay : 0x0000
Data (HexDump) : 07 25 01 00 00 00 00 .%.....
String Descriptors -------------------
String Descriptor 0 ------
bLength : 0x04 (4 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language ID[0] : 0x0409 (English - United States)
Data (HexDump) : 04 03 09 04 ....
String Descriptor 1 ------
bLength : 0x1E (30 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "xxx.Technology"
Data (HexDump) : 1E 03 78 00 78 00 78 00 2E 00 54 00 65 00 63 00 ..x.x.x...T.e.c.
68 00 6E 00 6F 00 6C 00 6F 00 67 00 79 00 h.n.o.l.o.g.y.
String Descriptor 2 ------
bLength : 0x14 (20 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "USB.Audio"
Data (HexDump) : 14 03 55 00 53 00 42 00 2E 00 41 00 75 00 64 00 ..U.S.B...A.u.d.
69 00 6F 00 i.o.
String Descriptor 3 ------
bLength : 0x08 (8 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "0.1"
Data (HexDump) : 08 03 30 00 2E 00 31 00 ..0...1.
String Descriptor 4 ------
bLength : 0x08 (8 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "UAC"
Data (HexDump) : 08 03 55 00 41 00 43 00 ..U.A.C.
String Descriptor 5 ------
bLength : 0x08 (8 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "UAC"
Data (HexDump) : 08 03 55 00 41 00 43 00 ..U.A.C.
String Descriptor 6 ------
bLength : 0x08 (8 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "UAC"
Data (HexDump) : 08 03 55 00 41 00 43 00 ..U.A.C.
String Descriptor 7 ------
bLength : 0x08 (8 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "UAC"
Data (HexDump) : 08 03 55 00 41 00 43 00 ..U.A.C.
String Descriptor 8 ------
bLength : 0x08 (8 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "UAC"
Data (HexDump) : 08 03 55 00 41 00 43 00 ..U.A.C.
见九.抓包文件分享,不再赘述
切换选择麦克风
可以看到如下请求
通过选择流接口的alt 0带宽接口来关闭流,
选择流接口的非0带宽接口,这里只有一个alt1来打开流。
即设置接口标准请求。
我们这里流接口号是3
01 0b 01 00 03 00 00 00
01 0b 00 00 03 00 00 00
系统声音点击静音,可以看到如下请求
静音
发送请求
21 01 00 01 02 05 01 00
数据为
01
取消静音
发送请求
21 01 00 01 02 05 01 00
数据为
00
Audio10.pdf
P66 5.2.1.1 Set Request
P75 5.2.2.4.3.1 Mute Control
所以解释如下
21 | 01 | 00 01 | 02 05 | 01 00 | 数据 |
接口类请求 | SET_CUR | 高字节表示Control Selector (CS) 见P102 Table A-11: Feature Unit Control Selectors 0x01表示静音控制
| 低字节(前面的02表示接口2) 高字节(后面的05)表示unit ID5即特征单元. | 表示后面数据只有一个字节 | 1个字节,1表示静音,0表示不静音 |
类似的系统声音修改音量,可以看到如下请求
21 01 01 02 02 05 02 00 数据为28 f3
解释如下
21 | 01 | 01 02 | 02 05 | 02 00 | 数据 |
SET接口类请求 | SET_CUR | 高字节表示Control Selector (CS) 见P102 Table A-11: Feature Unit Control Selectors 0x02表示音量控制
| 低字节(前面的02表示接口2) 高字节(后面的05)表示unit ID5即特征单元. | 表示后面数据2个字节 | 2个字节音量 |
音量和静音的控制使能要在特征单元描述符中指定
而音量的最小值,最大值,步进值枚举时通过GET请求获取
我这里是0xfc50,0xe3a0,0xff0f,0x0030
请求如下
解释如下
81 | 01 | 01 02 | 02 02 | 02 00 | 数据 |
GET接口类请求 | 81 GET_CUR 82 GET_DEF 83 GET_MAX 84 GET_RES | 高字节表示Control Selector (CS) 见P102 Table A-11: Feature Unit Control Selectors 0x02表示音量控制
| 低字节(前面的02表示接口2) 高字节(后面的05)表示unit ID5即特征单元. | 表示后面数据2个字节 | 2个字节音量 |
16k采样率,16位,单通道,正好是1ms传输32字节。
和描述符对应
/*
* BasicAudioDevice-10.pdf P32 Table 5-16: Mono Headphone Type I Format Type Descriptor
*/
0x0B, /* bLength */
0x24, /* bDescriptorType 见audio10.pdf P99 Table A-4: Audio Class-specific Descriptor Types CS_INTERFACE=0x24 */
0x02, /* bDescriptorSubtype 见audio10.pdf P100 Table A-6: Audio Class-Specific AS Interface Descriptor Subtypes FORMAT_TYPE=0x02 */
0x01, /* bFormatType 见frmts10.pdf P20 Table A-4: Format Type Codes FORMAT_TYPE_I=0x01 */
0x01, /* bNrChannels One channel. */
0x02, /* bSubFrameSize Two bytes per audio subframe. */
0x10, /* bBitResolution 16 bits per sample */
0x01, /* bSamFreqType One frequency supported. */
0x80,0x3E,0x00, /* tSamFreq 0x003E80=16000 */
UAC_MIC.upv
可以使用USB Packet Viewer这个软件回放,方便查看枚举和数据传输过程。
链接:https://pan.baidu.com/s/1JUumn4s0FwDgASHDPRPQow?pwd=y8sb
提取码:y8sb
以上分享了一个完整的UAC的麦克风实例,描述符可以直接使用。USB描述符的正确是能顺利枚举的首要条件,枚举完成了,基本就成功了一半了。有时候描述符一丁点不对就会导致枚举失败,所以有时候这些问题会困扰很久,有一个正确的描述符作为参考显得很有价值。故特分享此案例。