Skip to content

About

Goodix GF3658 fingerprint sensor driver for libfprint — porting skeleton based on RE of gfspi.dll, AlgoMilan.dll, EngineAdapter.dll (Windows UMDF 2.15 driver, Huawei Kepler project)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

libfprint-goodix — Goodix GF3658 fingerprint driver

CI

Linux driver for Goodix GF3658 fingerprint sensors (USB VID 27C6), targeting libfprint 2.x.

The protocol was reverse-engineered from the Windows driver stack shipped on Huawei Kepler laptops:

  • gfspi.dll — UMDF 2.15 driver (v1.1.124.12): SPI-over-USB transport, command set, status codes
  • AlgoMilan.dll — fingerprint algorithm (calibration, template pack/unpack)
  • AlgoChicago.dll — coating variant (IS_COATING=1), template-compatible
  • EngineAdapter.dll — Windows Biometric engine adapter

Status

The protocol layer, calibration architecture, template serialisation, image processing, firmware extraction, and OTP/config download are complete and unit-tested. The driver has not yet been validated on real hardware — SPI commands do not get a response on the 27c6:5117 CDC-ACM composite device and a Windows USB capture is required to confirm the real transport.

A USB hardware emulator is included via LD_PRELOAD — see Emulator below.

Supported hardware

USB VID USB PID Model
27C6 5117 GF3658 var. A
27C6 5110 GF3658 var. B
27C6 5130 GF3658 var. C

Sensor geometry: 108 x 800 pixels, 16-bit raw, 8-bit processed.

Architecture

┌───────────────────────────────────────────────────────────┐
│ tools/goodix-cli.c       standalone diagnostic CLI (libusb)│
├───────────────────────────────────────────────────────────┤
│ drivers/goodix.c         libfprint FpImageDevice driver    │
├───────────────────────────────────────────────────────────┤
│ libfprint/goodix-*.c     sensor interface + protocol       │
│   goodix-dev.c    device lifecycle (new/free/reset)        │
│   goodix-proto.c  USB transport (bulk/ctrl/intr, SPI frame)│
│   goodix-cmd.c    sensor command wrappers                  │
│   goodix-calib.c  calibration (config table, OTP, DAC)     │
│   goodix-img.c    image pipeline (normalize, quality, ROI) │
│   goodix-tpl.c    template pack/unpack (TLV + CRC32)       │
│   goodix-fw.h     firmware upload protocol (4-phase UPFW)  │
├───────────────────────────────────────────────────────────┤
│ libfprint/goodix-*.h     protocol definitions (headers)    │
│   goodix-spi.h    SPI frame format, command set, status    │
│   goodix-proto.h  USB endpoints, vendor requests, errors  │
│   goodix-cmd.h    chip info, capture, reg, nav, fw update  │
│   goodix-calib.h  calibration structures and constants    │
│   goodix-img.h    image processing prototypes              │
│   goodix-tpl.h    template serialisation format            │
├───────────────────────────────────────────────────────────┤
│ emu/goodix-emu.c       LD_PRELOAD USB emulator (no HW)    │
└───────────────────────────────────────────────────────────┘

Calibration

Reverse engineering of gfspi.dll revealed that GF3658 on Huawei Kepler does not use a monolithic NVRAM calibration blob. Calibration is built from three sources at init time:

  1. Embedded config tables — 256 bytes per sensor type, stored in the DLL .rdata section, indexed by sensor_type from the CMD_CHIP response.
  2. Factory OTP — 32 bytes (MilanL) / 64 bytes (ChicagoHS), read via GOODIX_ACTION_READ_OTP.
  3. Live DAC registers — TCODE + DAC1-4, read via CMD_REG_READ.

The runtime context is struct goodix_calib (see goodix-calib.h).

Firmware

The sensor MCU firmware was extracted from gfspi.dll's .rdata section:

Property Value
Size 13,641 bytes
Arch ARM Cortex-M Thumb
Version 0x0101
Checksum 0x00137B44
Embedded drivers/goodix-firmware.c

Upload uses the 4-phase UPFW protocol (START -> DATA chunks -> END -> reset). Never tested on hardware — use with caution.

Build

Meson (recommended)

meson setup builddir
meson compile -C builddir
sudo meson install -C builddir          # installs udev rules
sudo udevadm control --reload-rules && sudo udevadm trigger

Standalone CLI (no libfprint)

cd tools && make
./goodix-cli --help

Header syntax check

gcc -fsyntax-only -std=c11 -I. libfprint/goodix.h

Inside the libfprint tree

cp drivers/goodix.c libfprint/drivers/
# then follow libfprint's CONTRIBUTING.md for the build

Tests

Self-contained unit tests (no hardware required):

cd tests && make && ./run-tests
Suite Coverage
test-tpl template pack/unpack, CRC32, round-trip, tamper
test-calib calibration constants, chip IDs, DAC regs, geometry
test-img normalize, quality, ROI, flip, bad pixels, bg subtract
test-spi commands, flags, frames, status codes, USB endpoints

CI

The CI pipeline runs on every push and pull request:

  • Build & test matrix — gcc + clang, meson + make
  • Static analysis — cppcheck + strict compiler warnings (-Werror)
  • Format check — clang-format (non-blocking)
  • Alpine/musl — portability build in a minimal container

Run the same checks locally:

./scripts/ci-local.sh

CLI usage

goodix-cli [options] <command>

Options:
  -v, --verbose       Verbose output
  -V, --vid HEX        USB Vendor ID  (default 27c6)
  -P, --pid HEX        USB Product ID (default 5117)
  -o, --output DIR     Output directory for images (default .)
  -h, --help           This help

Commands:
  list                  List Goodix USB devices
  init                  Open and initialise sensor
  info                  Print chip information
  capture               Capture fingerprint and save as PGM
  raw                   Capture raw 16-bit data and save as .raw
  calib                 Show calibration status
  reset                 Send USB vendor reset request
  close                 Close device and release resources
  all                   Full sequence: init -> capture -> close
  regdump <addr> <cnt>  Dump sensor registers
  rawcapture [file]    Capture raw 16-bit data to file
  navtest <on|off>      Enable/disable gesture mode (polls 5s)
  stream <count> <ms>   Continuous capture of N frames with delay
  tracedump <hex>      Send SPI command, dump all USB traffic
  preamble [try|custom] Show/set compact frame preamble pattern
  gpio read|cs          Read GPIO or control SPI chip select

Examples:

goodix-cli list
goodix-cli -v init
goodix-cli -o /tmp/captures all
goodix-cli init && goodix-cli regdump 1000 16
goodix-cli init && goodix-cli stream 10 100
goodix-cli init && goodix-cli navtest on

Emulator

A USB hardware emulator is provided at emu/goodix-emu.so. It intercepts libusb calls via LD_PRELOAD and simulates a GF3658 sensor — no real hardware needed. All 15 SPI commands, vendor control requests, CDC ACM setup, and fingerprint image capture are emulated.

Build

make -C emu/

Usage

# Run goodix-cli with the emulator
./emu/emu-run.sh list
./emu/emu-run.sh init
./emu/emu-run.sh all

# Specify a synthetic fingerprint image (108x800, 16-bit raw)
python3 emu/gen_image.py /tmp/fingerprint.raw
EMU_RAW_IMAGE=/tmp/fingerprint.raw ./emu/emu-run.sh all

# Simulate no finger
EMU_FINGER=0 ./emu/emu-run.sh capture

# MilanL variant instead of ChicagoHS
EMU_CHIP_ID=0x2205 ./emu/emu-run.sh info

# Debug logs
EMU_LOG_LEVEL=3 ./emu/emu-run.sh init

Environment variables

Variable Default Description
EMU_FINGER 1 Simulate finger present (0/1)
EMU_CHIP_ID 0x2504 Sensor chip ID (0x2504=ChicagoHS, 0x2205=MilanL)
EMU_RAW_IMAGE built-in Path to 16-bit raw 108x800 image
EMU_LOG_LEVEL 1 Verbosity: 0=quiet, 1=normal, 2=debug, 3=trace

Known limitations

  • No hardware validation yet. SPI commands time out on the 27c6:5117 CDC-ACM composite device; a Windows USB capture is needed to confirm the real transport protocol. Use the emulator instead.
  • Image calibration apply is currently a simple high-byte 16->8 bit conversion; the per-pixel gain/offset pipeline needs wiring to the new struct goodix_calib context.
  • Firmware upload never tested. Risk of bricking the sensor MCU.
  • Dual SPI frame format. The driver supports both the standard 8-byte header and the compact 7-byte header with 4-byte preamble; the correct variant for 27c6:5117 is still unknown.

License

LGPL-2.1+ — same as libfprint.

About

Goodix GF3658 fingerprint sensor driver for libfprint — porting skeleton based on RE of gfspi.dll, AlgoMilan.dll, EngineAdapter.dll (Windows UMDF 2.15 driver, Huawei Kepler project)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages