华为USB耳机UAC音量及静音控制实例分析
手中的华为耳机是一个复合设备,使用的是USB Composite Device(usbccgp.sys)来驱动。复合的设备为音频设备和HID设备,其中音频设备又使用UAC规范复合了一个麦克风和耳机。
设备管理器中如下:
使用USBTreeViewer分析其配置描述符其内容如下:
------- Audio Control Input Terminal Descriptor -------
bLength : 0x0C (12 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x02 (Input Terminal)
bTerminalID : 0x01
wTerminalType : 0x0101 (USB Streaming)
bAssocTerminal : 0x00
bNrChannels : 0x02 (2 channels)
wChannelConfig : 0x0003 (L, R)
iChannelNames : 0x00 (No String Descriptor)
iTerminal : 0x00 (No String Descriptor)
Data (HexDump) : 0C 24 02 01 01 01 00 02 03 00 00 00 .$..........
-------- Audio Control Feature Unit Descriptor --------
bLength : 0x0D (13 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x06 (Feature Unit)
bUnitID : 0x02 (2)
bSourceID : 0x01 (1)
bControlSize : 0x02 (2 bytes per control)
bmaControls[0] : 0x03, 0x00
D0: Mute : 1
D1: Volume : 1
D2: Bass : 0
D3: Mid : 0
D4: Treble : 0
D5: Graphic Equalizer : 0
D6: Automatic Gain : 0
D7: Delay : 0
D8: Bass Boost : 0
D9: Loudness : 0
D10: Reserved : 0
D11: Reserved : 0
D12: Reserved : 0
D13: Reserved : 0
D14: Reserved : 0
D15: Reserved : 0
bmaControls[1] : 0x00, 0x00
D0: Mute : 0
D1: Volume : 0
D2: Bass : 0
D3: Mid : 0
D4: Treble : 0
D5: Graphic Equalizer : 0
D6: Automatic Gain : 0
D7: Delay : 0
D8: Bass Boost : 0
D9: Loudness : 0
D10: Reserved : 0
D11: Reserved : 0
D12: Reserved : 0
D13: Reserved : 0
D14: Reserved : 0
D15: Reserved : 0
bmaControls[2] : 0x00, 0x00
D0: Mute : 0
D1: Volume : 0
D2: Bass : 0
D3: Mid : 0
D4: Treble : 0
D5: Graphic Equalizer : 0
D6: Automatic Gain : 0
D7: Delay : 0
D8: Bass Boost : 0
D9: Loudness : 0
D10: Reserved : 0
D11: Reserved : 0
D12: Reserved : 0
D13: Reserved : 0
D14: Reserved : 0
D15: Reserved : 0
iFeature : 0x00 (No String Descriptor)
Data (HexDump) : 0D 24 06 02 01 02 03 00 00 00 00 00 00 .$...........
------- Audio Control Output Terminal Descriptor ------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype : 0x03 (Output Terminal)
bTerminalID : 0x03
wTerminalType : 0x0302 (Headphones)
bAssocTerminal : 0x00 (0)
bSourceID : 0x02 (2)
iTerminal : 0x00 (No String Descriptor)
Data (HexDump) : 09 24 03 03 02 03 00 02 00 .$.......
其UAC拓扑结构如下:
从拓扑结构可以看到,数据从输入终端到特性终端,最终到输出终端。
其中输入终端的数据来源于系统,即播放音频的应用软件,而输出终端最终为我们的耳机终端。
通过特性描述符我们可以看到,其支持静音和音量调整,这是可以通过UAC的特定类请求SET_CUR,GET_CUR来控制。
当我们把音量调整为0,通过BUSHOUND抓取的包如下:
44.0 CTL 21 01 00 02 00 02 02 00 SET CUR
44.0 2 OUT 00 d3 ..
44.0 CTL 21 01 00 01 00 02 01 00 SET CUR
44.0 1 OUT 01 .
44.0 CTL 01 0b 01 00 02 00 00 00 SET INTERFACE
44.0 CTL 22 01 00 01 03 00 03 00 SET CUR
44.0 3 OUT 80 bb 00 ...
44.0 CTL 01 0b 00 00 02 00 00 00 SET INTERFACE
音量控制
音量控制是特性描述符支持的,我们可查看其枚举过程获取的最大和最小的值。
44.0 CTL a1 81 00 02 00 02 02 00 GET CUR
44.0 2 IN 00 00 ..
44.0 CTL a1 82 00 02 00 02 02 00 GET MIN
44.0 2 IN 00 d3 ..
44.0 CTL a1 83 00 02 00 02 02 00 GET MAX
44.0 2 IN 00 00 ..
44.0 CTL a1 84 00 02 00 02 02 00 GET RES
44.0 2 IN 00 01
当静音为时,其音量为最小值。这里使用的请求:
44.0 CTL 21 01 00 02 00 02 02 00 SET CUR
44.0 2 OUT 00 d3 ..
其选择子为02,表示VOLUME_CONTROL=2,表求的是音量控制。
音量的值为db,2字节这里内容为 00 d3,其支持的最小值,这与其枚举过时的内容一致。
而当音量设置为最大时:
44.0 CTL 21 01 00 02 00 02 02 00 SET CUR
44.0 2 OUT b6 ff ..
44.0 CTL 21 01 00 02 00 02 02 00 SET CUR
44.0 2 OUT 00 00 ..
其值为00 00。
静音MUTE
通过UAC 特性单元控制请求:https://www.usbzh.com/article/detail-249.html 一文,参照特定类清求可知:
44.0 CTL 21 01 00 01 00 02 01 00 SET CUR
44.0 1 OUT 01 .
这其实就是使用的选择子为1,即MUTE_CONTROL,而unitid=2表示的是特类描描述符。
其数据长度为1,而内容是否静音为1,表示静音。
设备的打开与关闭
另外,我们在调整音量时,发现有设备的打开与关闭:
44.0 CTL 01 0b 01 00 02 00 00 00 SET INTERFACE
44.0 CTL 22 01 00 01 03 00 03 00 SET CUR
44.0 3 OUT 80 bb 00 ...
44.0 CTL 01 0b 00 00 02 00 00 00 SET INTERFACE
其中
44.0 CTL 01 0b 01 00 02 00 00 00 SET INTERFACE
是选择耳机的接口SET_INTERFACE:
0x01, // bmRequestType: Dir: H2D, Type: Standard, Recipient: Interface
0x0B, // bRequest (Set Interface)
0x01, 0x00, // wValue Alt Setting: 1
0x02, 0x00, // wIndex Interface: 2
0x00, 0x00, // wLength = 0
然后是设置采样率:
44.0 CTL 22 01 00 01 03 00 03 00 SET CUR
44.0 3 OUT 80 bb 00 ...
UAC音频流端点控制请求https://www.usbzh.com/article/detail-216.html ,其选择子为SAMPLING_FREQ_CONTROL=0x01,端点为0x03,输出端点。
----------------- Endpoint Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x05 (Endpoint Descriptor)
bEndpointAddress : 0x03 (Direction=OUT EndpointID=3)
bmAttributes : 0x0D (TransferType=Isochronous SyncType=Synchronous EndpointType=Data)
wMaxPacketSize : 0x0240 (576 bytes)
bInterval : 0x01 (1 ms)
bRefresh : 0x00
bSynchAddress : 0x00
Data (HexDump) : 09 05 03 0D 40 02 01 00 00 ....@....
而SET_CUR请求输出有3字节为80 bb 00 ,表示48000采样率。