Initial GXFP5130 userspace prototype
This commit is contained in:
267
docs/protocol.md
Normal file
267
docs/protocol.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# GXFP5130 protocol notes
|
||||
|
||||
This document describes the protocol implemented by this repository for the
|
||||
tested Goodix GXFP5130, chip ID `0x2504`, using the ChicagoHU configuration
|
||||
profile. It replaces the earlier point-in-time PDF report with documentation
|
||||
that can evolve together with the source.
|
||||
|
||||
The labels below have precise meanings:
|
||||
|
||||
- **Hardware verified:** repeatedly observed on the physical sensor.
|
||||
- **Windows-derived:** recovered from the Windows implementation and then used
|
||||
to guide the implementation.
|
||||
- **Unknown:** retained as opaque data without assigning semantics.
|
||||
|
||||
## 1. Layering
|
||||
|
||||
```text
|
||||
application / libfprint prototype
|
||||
|
|
||||
v
|
||||
GXFP session, configuration, TLS and image parser
|
||||
|
|
||||
v
|
||||
/dev/gxfp record-oriented userspace ABI
|
||||
|
|
||||
v
|
||||
kernel EC mailbox transport
|
||||
|
|
||||
v
|
||||
Goodix GXFP5130
|
||||
```
|
||||
|
||||
The kernel driver transports opaque mailbox records, manages MMIO/GPIO/IRQ and
|
||||
owns the userspace ABI. Sensor commands, configuration policy, TLS and image
|
||||
processing remain in userspace.
|
||||
|
||||
## 2. `/dev/gxfp` records
|
||||
|
||||
The UAPI structures are mirrored in `include/gxfp/goodix_ec_uapi.h`.
|
||||
|
||||
Userspace writes a `goodix_ec_tx_header` followed by exactly `payload_len`
|
||||
bytes. A read returns one complete `goodix_ec_record_header` followed by its
|
||||
payload; records are never split across reads.
|
||||
|
||||
Observed normalized MP types:
|
||||
|
||||
| MP type | Purpose | Status |
|
||||
| --- | --- | --- |
|
||||
| `0x0a` | Normal Goodix commands, replies, ACKs and FDT | Hardware verified |
|
||||
| `0x0b` | TLS records exchanged with the sensor MCU | Hardware verified |
|
||||
| `0xb0` | Host-to-sensor TLS transmit flag | Hardware verified |
|
||||
|
||||
The kernel may receive a raw normal MP value represented as `0xa0` at the
|
||||
mailbox level. The userspace ABI exposes its normalized type as `0x0a`.
|
||||
|
||||
## 3. Normal Goodix frame
|
||||
|
||||
Normal command traffic uses this byte layout:
|
||||
|
||||
```text
|
||||
offset size field
|
||||
0 1 command
|
||||
1 2 declared length, little-endian
|
||||
3 n payload
|
||||
3+n 1 Goodix checksum
|
||||
```
|
||||
|
||||
The declared length covers the payload and checksum. The checksum is selected
|
||||
so the eight-bit sum of the command, both length bytes, payload and checksum is
|
||||
zero.
|
||||
|
||||
Responses may use the direction bit in the command byte. The request layer
|
||||
matches the normalized command and skips unrelated asynchronous records while
|
||||
continuing to wait for the expected response.
|
||||
|
||||
## 4. Identification and OTP
|
||||
|
||||
Register `0x0000` returns the chip identification. The tested response is:
|
||||
|
||||
```text
|
||||
command: 0x82
|
||||
payload: a2 04 25 00
|
||||
chip ID: 0x2504
|
||||
```
|
||||
|
||||
The sensor exposes a 64-byte OTP block. The implementation validates the CP,
|
||||
FT and MT sections independently using the recovered eight-bit CRC algorithm.
|
||||
The tested sensor produces valid values for all three sections.
|
||||
|
||||
The OTP is also used to select and patch the DAC calibration values rather
|
||||
than applying a single machine-wide constant. A captured example yielded:
|
||||
|
||||
```text
|
||||
raw DAC values: 0x00ba 0x00bc 0x00ba 0x00ba
|
||||
0x0220: 0x0ba8
|
||||
0x0236: 0x00bc
|
||||
0x0238: 0x00ba
|
||||
0x023a: 0x00ba
|
||||
```
|
||||
|
||||
These exact values are device calibration data, not universal constants.
|
||||
|
||||
## 5. ChicagoHU configuration
|
||||
|
||||
For chip ID `0x2504`, userspace constructs a 224-byte ChicagoHU configuration,
|
||||
patches its OTP-derived fields and recomputes the 16-bit configuration
|
||||
checksum. The tested device used:
|
||||
|
||||
```text
|
||||
t-code: 0x0100
|
||||
FDT delta: 0x1d
|
||||
FDT offset: 0x00
|
||||
size: 224 bytes
|
||||
```
|
||||
|
||||
The exact checksum depends on the patched device calibration values. The
|
||||
configuration is downloaded only after reset and is acknowledged by the
|
||||
sensor.
|
||||
|
||||
## 6. TLS transport
|
||||
|
||||
The host userspace implementation acts as a TLS server and the sensor MCU acts
|
||||
as a TLS client.
|
||||
|
||||
| Parameter | Value |
|
||||
| --- | --- |
|
||||
| Protocol | TLS 1.2 |
|
||||
| Verified cipher suite | `TLS-PSK-WITH-AES-256-GCM-SHA384` (`0x00a9`) |
|
||||
| PSK identity | `Client_identity` |
|
||||
| MCU-to-host MP type | `0x0b` |
|
||||
| Host-to-MCU MP flag | `0xb0` |
|
||||
|
||||
A hardware-verified handshake contains ClientHello, ClientKeyExchange,
|
||||
ChangeCipherSpec and Finished. Capture data subsequently arrives as TLS
|
||||
application data and is decrypted through `mbedtls_ssl_read()`.
|
||||
|
||||
Normal `0x0a` ACKs can be interleaved with TLS traffic. The TLS receive path
|
||||
must ignore non-TLS MP records, while the normal request path must not consume
|
||||
TLS records intended for mbedTLS.
|
||||
|
||||
## 7. Finger detection
|
||||
|
||||
The verified FDT commands are implemented in `src/fdt.c`:
|
||||
|
||||
| Command | Function |
|
||||
| --- | --- |
|
||||
| `0x36` | Set/arm FDT mode |
|
||||
| `0x32` | Finger-down path |
|
||||
| `0x34` | Finger-up path |
|
||||
| `0xda` | FDT status/event report |
|
||||
|
||||
A typical finger-down sequence reports:
|
||||
|
||||
```text
|
||||
cmd=0x36 status=0x0100 -> ready
|
||||
cmd=0x32 status=0x0002 -> finger down
|
||||
```
|
||||
|
||||
Capture must begin while the finger remains present. After a successful image,
|
||||
userspace arms finger-up, waits for removal and returns the session to ACTIVE.
|
||||
|
||||
## 8. Image capture
|
||||
|
||||
The hardware-verified capture frame is sent through the normal MP path:
|
||||
|
||||
```text
|
||||
20 03 00 01 00 86
|
||||
```
|
||||
|
||||
Decoded:
|
||||
|
||||
| Bytes | Meaning |
|
||||
| --- | --- |
|
||||
| `20` | Image-capture command |
|
||||
| `03 00` | Payload plus checksum length |
|
||||
| `01 00` | Capture payload |
|
||||
| `86` | Goodix checksum |
|
||||
|
||||
The command ACK arrives as a normal `0x0a` record. The image does not arrive
|
||||
there; it arrives encrypted as TLS application data over MP `0x0b`.
|
||||
|
||||
After TLS stream reassembly, one capture has this verified layout:
|
||||
|
||||
```text
|
||||
offset size field
|
||||
0 1 command (0x20)
|
||||
1 2 declared length (7690, little-endian)
|
||||
3 5 opaque image header
|
||||
8 7680 packed 12-bit pixels
|
||||
7688 4 CRC-32/MPEG-2, Goodix byte order
|
||||
7692 1 opaque trailer/status
|
||||
total 7693 bytes
|
||||
```
|
||||
|
||||
The Windows-derived parser relationship is consistent with this layout:
|
||||
|
||||
```c
|
||||
image_data = frame_payload + 5;
|
||||
image_data_length = frame_payload_length - 6;
|
||||
```
|
||||
|
||||
The CRC covers the 7680 packed-pixel bytes. It does not cover the five-byte
|
||||
opaque header or the final trailer byte. Stored and calculated CRC values have
|
||||
matched across repeated live captures.
|
||||
|
||||
## 9. Packed 12-bit pixels
|
||||
|
||||
Six packed bytes decode to four 12-bit samples. A complete image contains:
|
||||
|
||||
```text
|
||||
7680 packed bytes
|
||||
5120 samples
|
||||
64 x 80 pixels
|
||||
```
|
||||
|
||||
The session API exposes the decoded samples as `uint16_t`. Conversion to an
|
||||
8-bit `FpImage` is intentionally separate from protocol parsing so that image
|
||||
orientation, normalization and matching policy can evolve without changing
|
||||
the validated capture layer.
|
||||
|
||||
## 10. Session state sequence
|
||||
|
||||
```text
|
||||
OPEN
|
||||
-> activate (identification, OTP, config, TLS)
|
||||
ACTIVE
|
||||
-> arm finger down
|
||||
WAITING_FINGER_DOWN
|
||||
-> finger detected
|
||||
FINGER_PRESENT
|
||||
-> capture
|
||||
CAPTURING
|
||||
-> CRC-valid image
|
||||
FINGER_PRESENT
|
||||
-> arm/wait finger up
|
||||
WAITING_FINGER_UP
|
||||
-> finger removed
|
||||
ACTIVE
|
||||
```
|
||||
|
||||
Timeout and cancellation paths deactivate and reinitialize the hardware rather
|
||||
than leaving FDT armed across the next process invocation. The regression tool
|
||||
tests cancellation during finger-down wait, finger-up timeout recovery and a
|
||||
normal capture after both recoveries.
|
||||
|
||||
## 11. Known unknowns
|
||||
|
||||
The following values are deliberately kept opaque:
|
||||
|
||||
- semantics of the five-byte image header; it is consistently all zero on the
|
||||
tested profile
|
||||
- meaning of trailer value `0x88`
|
||||
- whether command `0x21` selects a separate image or calibration mode
|
||||
- orientation/inversion policy appropriate for final libfprint matching
|
||||
- fixed-pattern-noise and dark-frame correction policy
|
||||
- applicability of this profile and TLS material to another chip ID
|
||||
|
||||
No resynchronization heuristic, guessed checksum or alternate capture command
|
||||
is used in the validated session path.
|
||||
|
||||
## 12. Current project boundary
|
||||
|
||||
The transport, sensor setup, TLS, FDT, capture, CRC and image decoding layers
|
||||
are hardware-validated prototypes. The libfprint driver remains experimental:
|
||||
final enroll/verify behavior, multi-capture policy, image enhancement and
|
||||
matcher quality still require validation before production use.
|
||||
|
||||
Reference in New Issue
Block a user