# 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.