December 7, 2023

Let's learn USB! -- CP2102 fakery

As sort of an experiment, I changed two of the descriptors during enumeration to claim that my F103 is a CP2102 usb to uart device. This sort of works, as follows. First of all enumeration works (sort of), at least the linux log shows:
Dec  7 21:50:11 trona kernel: usb 2-1.2: new full-speed USB device number 89 using ehci-pci
Dec  7 21:50:11 trona kernel: usb 2-1.2: New USB device found, idVendor=10c4, idProduct=ea60, bcdDevice= 1.00
Dec  7 21:50:11 trona kernel: usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Dec  7 21:50:11 trona kernel: usb 2-1.2: Manufacturer: ACME computers
Dec  7 21:50:11 trona kernel: cp210x 2-1.2:1.0: cp210x converter detected
Dec  7 21:50:16 trona kernel: cp210x 2-1.2:1.0: failed to get vendor val 0x370b size 1: -110
Dec  7 21:50:16 trona kernel: cp210x 2-1.2:1.0: querying part number failed
Dec  7 21:50:16 trona kernel: usb 2-1.2: cp210x converter now attached to ttyUSB1
Several things can be observed. First is that we only see one of the strings (the manufacturer), An earlier attempt gave us:
Dec  7 21:48:41 trona kernel: usb 2-1.2: Product: Stupid ACM port
Dec  7 21:48:41 trona kernel: usb 2-1.2: Manufacturer: ACME computers
Dec  7 21:48:41 trona kernel: usb 2-1.2: SerialNumber: 1234
Dec  7 21:48:41 trona kernel: cp210x 2-1.2:1.0: cp210x converter detected
Dec  7 21:48:46 trona kernel: cp210x 2-1.2:1.0: failed to get vendor val 0x370b size 1: -110
Dec  7 21:48:46 trona kernel: cp210x 2-1.2:1.0: querying part number failed
Dec  7 21:48:46 trona kernel: usb 2-1.2: cp210x converter now attached to ttyUSB1
Both show the failure to get the part number. My enumeration log looks like:
0 Enum Reset
1 Enum Rx S AB10 EA60 8 8006000100004000
2 Enum Tx   AB10 A2A0 18 1201000200000040C41060EA000101020301
3 Enum Rx   AB10 A220 0
4 Enum Reset
5 Enum Rx S AB10 EA60 8 0005670000000000
6 Enum Tx   AB00 72A0 0
7 Enum Rx S AB10 EA60 8 8006000100001200
8 Enum Tx   AB10 A2A0 18 1201000200000040C41060EA000101020301
9 Enum Rx   AB10 A220 0
10 Enum Rx S AB10 EA60 8 8006000600000A00
11 Enum Tx   AB00 72A0 0
12 Enum Rx   AB10 A220 0
13 Enum Rx S AB10 EA70 8 8006000600000A00
14 Enum Rx   AB10 A230 0
15 Enum Rx S AB10 EA60 8 8006000200000900
16 Enum Tx   AB10 A2A0 9 09022000010100C032
17 Enum Rx   AB10 A220 0
18 Enum Rx S AB10 EA60 8 8006000200002000
19 Enum Tx   AB10 A2A0 32 09022000010100C0320904000002FF0000020705810240000007050102400000
20 Enum Rx   AB10 A220 0
21 Enum Rx S AB10 EA70 8 800600030000FF00
22 Enum Rx   AB10 A230 0
23 Enum Rx S AB10 EA60 8 800600030000FF00
24 Enum Tx   AB10 A2A0 4 04030904
25 Enum Rx   AB10 A220 0
26 Enum Rx S AB10 EA70 8 800602030904FF00
27 Enum Rx   AB10 A230 0
28 Enum Rx S AB10 EA60 8 800602030904FF00
29 Enum Tx   AB10 A2A0 32 20035300740075007000690064002000410043004D00200070006F0072007400
30 Enum Rx   AB10 A220 0
31 Enum Rx S AB10 EA70 8 800601030904FF00
32 Enum Tx   AB10 A2A0 30 1E03410043004D004500200063006F006D00700075007400650072007300
33 Enum Rx   AB10 A220 0
34 Enum Rx S AB10 EA70 8 800603030904FF00
35 Enum Rx   AB10 A230 0
36 Enum Rx S AB10 EA70 8 800603030904FF00
37 Enum Rx   AB10 A230 0
38 Enum Rx S AB10 EA60 8 8006030309040200
39 Enum Tx   AB00 72A0 10 0A033100320033003400
40 Enum Rx S AB10 EA60 8 0009010000000000
41 Enum Tx   AB00 72A0 0
42 Enum Rx S AB10 EA60 8 800602030904FF00
43 Enum Tx   AB10 A2A0 32 20035300740075007000690064002000410043004D00200070006F0072007400
44 Enum Rx   AB10 A220 0
45 Enum Rx S AB10 EA60 8 C0FF0B3700000100
The packet we fail to respond to is the last one. Let's look at it --

We have the S bit set (SETUP packet) and the request is "C0FF". The "C0" says "device to host, vendor" and "FF" is the request. Then we see 0x0b37 for the "value", which corresponds to the complaint in the linux log where 0x370b is asking for a part number with length 1.

Indeed, we saw these requests with a real CP2102 and the response was a single byte with value "2". Once I respond with this, I get:

Dec  8 16:37:01 trona kernel: usb 2-1.2: new full-speed USB device number 115 using ehci-pci
Dec  8 16:37:01 trona kernel: usb 2-1.2: New USB device found, idVendor=10c4, idProduct=ea60, bcdDevice= 1.00
Dec  8 16:37:01 trona kernel: usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Dec  8 16:37:01 trona kernel: usb 2-1.2: Product: Stupid serial port
Dec  8 16:37:01 trona kernel: usb 2-1.2: Manufacturer: ACME computers
Dec  8 16:37:01 trona kernel: usb 2-1.2: SerialNumber: 1234
Dec  8 16:37:01 trona kernel: cp210x 2-1.2:1.0: cp210x converter detected
Dec  8 16:37:01 trona kernel: usb 2-1.2: cp210x converter now attached to ttyUSB1
My enumeration log now looks like this:
0 Enum Reset
1 Enum Rx S AB10 EA60 8 8006000100004000
2 Enum Tx   AB00 72A0 18 1201000200000040C41060EA000101020301
3 Enum Rx   AB10 A220 0
4 Enum Reset
5 Enum Rx S AB10 EA60 8 0005730000000000
6 Enum Tx   AB00 72A0 0
7 Enum Rx S AB10 EA60 8 8006000100001200
8 Enum Tx   AB00 72A0 18 1201000200000040C41060EA000101020301
9 Enum Rx   AB10 A220 0
10 Enum Rx S AB10 EA60 8 8006000600000A00
11 Enum Tx   AB00 72A0 0
12 Enum Rx   AB10 A220 0
13 Enum Rx S AB10 EA60 8 8006000600000A00
14 Enum Tx   AB00 72A0 0
15 Enum Rx   AB10 A220 0
16 Enum Rx S AB10 EA60 8 8006000600000A00
17 Enum Tx   AB00 72A0 0
18 Enum Rx   AB10 A220 0
19 Enum Rx S AB10 EA60 8 8006000200000900
20 Enum Tx   AB00 72A0 9 09022000010100C032
21 Enum Rx   AB10 A220 0
22 Enum Rx S AB10 EA60 8 8006000200002000
23 Enum Tx   AB00 72A0 32 09022000010100C0320904000002FF0000020705810240000007050102400000
24 Enum Rx   AB10 A220 0
25 Enum Rx S AB10 EA60 8 800600030000FF00
26 Enum Tx   AB00 72A0 4 04030904
27 Enum Rx   AB10 A220 0
28 Enum Rx S AB10 EA60 8 800602030904FF00
29 Enum Tx   AB00 72A0 38 26035300740075007000690064002000730065007200690061006C00200070006F0072007400
30 Enum Rx   AB10 A220 0
31 Enum Rx S AB10 EA60 8 800601030904FF00
32 Enum Tx   AB00 72A0 30 1E03410043004D004500200063006F006D00700075007400650072007300
33 Enum Rx   AB10 A220 0
34 Enum Rx S AB10 EA60 8 800603030904FF00
35 Enum Tx   AB00 72A0 10 0A033100320033003400
36 Enum Rx   AB10 A220 0
37 Enum Rx S AB10 EA60 8 0009010000000000
38 Enum Tx   AB00 72A0 0
39 Enum Rx S AB10 EA60 8 800602030904FF00
40 Enum Tx   AB00 72A0 38 26035300740075007000690064002000730065007200690061006C00200070006F0072007400
41 Enum Rx   AB10 A220 0
42 Enum Rx S AB10 EA60 8 C0FF0B3700000100
43 Enum Tx   AB00 72A0 1 02
44 Enum Rx   AB10 A220 0
45 Enum Rx S AB10 EA70 8 C0FF0B3700000200
46 Enum Tx   AB00 72A0 1 02
47 Enum Rx   AB10 A220 0
When I try to use /dev/ttyUSB1 with picocom I just get IO errors, so more work will be needed.
The Linux logs show this:
Dec  8 16:40:45 trona kernel: cp210x ttyUSB1: failed set request 0x0 status: -110
Dec  8 16:40:45 trona kernel: cp210x ttyUSB1: cp210x_open - Unable to enable UART
Dec  8 16:41:05 trona kernel: cp210x ttyUSB1: failed set request 0x0 status: -110
Dec  8 16:41:05 trona kernel: cp210x ttyUSB1: cp210x_open - Unable to enable UART
My code reports:
4100010000000000
We respond to that with a ZLP and now we see all this!:
Setup packet: 8 bytes --  4100010000000000
Setup packet: 8 bytes --  411E000000000400
Control packet: 4 bytes --  80250000
Setup packet: 8 bytes --  4103000800000000
Setup packet: 8 bytes --  4119000000000600
Control packet: 6 bytes --  000000001113
Setup packet: 8 bytes --  C114000000001000
Setup packet: 8 bytes --  4107030300000000
Setup packet: 8 bytes --  C108000000000100
Setup packet: 8 bytes --  C110000000001300
Setup packet: 8 bytes --  4103000800000000
Setup packet: 8 bytes --  C114000000001000
Setup packet: 8 bytes --  C108000000000100
Setup packet: 8 bytes --  C108000000000100
The linux logs show:
cp210x ttyUSB1: failed set request 0x3 status: -110
cp210x ttyUSB1: failed to set line control: -110
cp210x ttyUSB1: failed get req 0x14 size 16 status: -110
cp210x ttyUSB1: failed set request 0x7 status: -110
cp210x ttyUSB1: failed get req 0x8 size 1 status: -110
cp210x ttyUSB1: failed to get comm status: -110
cp210x ttyUSB1: failed set request 0x3 status: -110
cp210x ttyUSB1: failed to set line control: -110
cp210x ttyUSB1: failed get req 0x14 size 16 status: -110
cp210x ttyUSB1: failed get req 0x8 size 1 status: -110
cp210x ttyUSB1: failed get req 0x8 size 1 status: -110
All very exciting. The thing to do now is probably to fire up a real CP2102 and get Wireshark to snoop on the responses.
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org