Problem
All CP2110-based devices share VID 0x10C4 PID 0xEA80, so the user must manually select the device family (UT61E+, UT8803, UT171, UT181A) before connecting. Selecting the wrong one produces confusing checksum mismatch errors.
CH9329 transport (0x1A86:0xE429) is currently only used by UT181A, so that case can be handled trivially.
Proposed approach: probe-and-parse
Phase 1 — Get Name (fast path)
Send Get Name (0x5F) with a ~500ms timeout. Only the UT61E+ family responds, and the reply contains the exact model name ("UT61E+", "UT61B+", etc.). Already implemented and verified on UT61E+.
Open question: Does 0x5F work on UT61B+, UT61D+, and UT161 variants? Currently [UNVERIFIED] — if it does, this single probe covers 6 of 9 device entries.
Phase 2 — Streaming trigger cascade (if Get Name times out)
Try each streaming trigger with short timeouts, parse whatever comes back:
| Order |
Send |
Expect |
Identifies |
| 1 |
0x5A (1 byte) |
21-byte fixed frame, BE checksum |
UT8803 |
| 2 |
SET_MONITOR AB CD 04 00 05 01 0A 00 |
2-byte LE length frame |
UT181A |
| 3 |
Connect AB CD 04 00 0A 01 0F 00 |
1-byte length, LE checksum |
UT171 |
All frame extractors already exist in framing.rs and return clean errors on mismatch.
Shortcut
CH9329 transport → UT181A (only known CH9329 device). Skip probing.
Implementation notes
- New
probe_device() function in the lib crate (~80-100 lines)
- Default to "auto" in both CLI and GUI, keep manual
--device as fallback
- Timeout-based probing adds 0.5-2s for non-UT61E+ devices (cascading through failed probes)
- None of the non-UT61E+ families have a deterministic identification command — frame format differences are the only discrimination signal
Research done
- UT8803, UT171, UT181A have no Get Name or equivalent command (checked protocol docs, vendor software decompilation, and all reference implementations)
- 0x5F is not in the UT181A.exe or UT171C.exe decompilations
- See
docs/research/*/reverse-engineered-protocol.md for full command tables
Problem
All CP2110-based devices share VID
0x10C4PID0xEA80, so the user must manually select the device family (UT61E+, UT8803, UT171, UT181A) before connecting. Selecting the wrong one produces confusing checksum mismatch errors.CH9329 transport (
0x1A86:0xE429) is currently only used by UT181A, so that case can be handled trivially.Proposed approach: probe-and-parse
Phase 1 — Get Name (fast path)
Send
Get Name (0x5F)with a ~500ms timeout. Only the UT61E+ family responds, and the reply contains the exact model name ("UT61E+", "UT61B+", etc.). Already implemented and verified on UT61E+.Open question: Does 0x5F work on UT61B+, UT61D+, and UT161 variants? Currently
[UNVERIFIED]— if it does, this single probe covers 6 of 9 device entries.Phase 2 — Streaming trigger cascade (if Get Name times out)
Try each streaming trigger with short timeouts, parse whatever comes back:
0x5A(1 byte)AB CD 04 00 05 01 0A 00AB CD 04 00 0A 01 0F 00All frame extractors already exist in
framing.rsand return clean errors on mismatch.Shortcut
CH9329 transport → UT181A (only known CH9329 device). Skip probing.
Implementation notes
probe_device()function in the lib crate (~80-100 lines)--deviceas fallbackResearch done
docs/research/*/reverse-engineered-protocol.mdfor full command tables