Im letzten Beitrag zum Thema hatte ich angekündigt, dass ich mir auch den NB-2033-U vornehmen will. Der steckt in einem zweiten Fujitsu Notebook hier, dem von meiner Tochter Maja. Gleicher Hersteller, gleiche Sensorfamilie, sollte ähnlich laufen wie beim NB-2020-U. Dachte ich.
Falsch gedacht.
Hersteller sagt: geht nicht
Ich hatte bei NEXT Biometrics nach Protokolldokumentation oder einem SDK für den NB-2033-U gefragt. Kevin Hung, Director FAE, antwortete freundlich aber eindeutig:
„Both 2020-U and 2033-U have different firmware and USB stack. The code flow (libusb) related to 2033-U and 2020-U is different. This could be the reason for 2033-U failure/unsupported in linux. As of now, it is not supported.“
Kein SDK, keine Doku, kein Support. Und 74 Einträge auf linux-hardware.org mit Status „failed“ für die USB ID 298d:2033. Weltweit kein Linux-Support für dieses Gerät.
Gut. Dann eben Reverse Engineering.
Erster Versuch: Windows-Treiber belauschen
Plan A war klassisch: Windows-Treiber in einer VM laufen lassen, USB-Traffic mitschneiden. VirtualBox installiert, USB-Passthrough konfiguriert, Windows gestartet. Der Fingerabdruckleser tauchte im Gerätemanager auf. Mit Code 31. Treiber konnte das Gerät nicht starten. Secure Boot hatte VirtualBox den Kernel-Treiber nicht signiert, und der USB-Passthrough war damit unbrauchbar.
Plan A verworfen.
Plan B: Das SDK direkt auf Linux
Das SDK von NEXT Biometrics (libNBBiometrics.so) unterstützt den NB-2033-U intern. Es kommuniziert direkt über libusb, ohne Kernel-Treiber. Das heißt: ich kann das SDK-Sample direkt auf dem Linux-Notebook laufen lassen und gleichzeitig den USB-Traffic mit usbmon mitschneiden.
Dafür musste Secure Boot deaktiviert werden. usbmon ist ein Kernel-Modul, und lockdown=integrity (von Secure Boot gesetzt) blockiert es auch für root. Secure Boot im BIOS aus, lockdown=none in GRUB, Neustart. Danach:
modprobe usbmon cat /sys/kernel/debug/usb/usbmon/3u > /tmp/capture.txt & ./NBBSample
7654 Zeilen USB-Traffic. Das komplette Protokoll des NB-2033-U, aufgezeichnet während einer Enrollment-Session.
Was dabei rauskam
Das Protokoll ist komplett anders als beim NB-1010-U/NB-2020-U. Kevins Aussage stimmte. Hier die wesentlichen Unterschiede:
| Eigenschaft | NB-1010-U / NB-2020-U | NB-2033-U |
|---|---|---|
| Bulk IN Endpoint | EP 3 (0x83) | EP 1 (0x81) |
| Kommandoformat | [0x80][CMD][SEQ][0x00]... | [CMD][0x00][LEN_LO][LEN_HI][PAYLOAD] (TLV) |
| Finger-Erkennung | Einzelnes 0x38 | Zwei 0x0D Config + 0x38 |
| Bildübertragung | 90 Chunks à 540 Bytes | 180 Chunks à 268 Bytes |
| Init | Einmal 0x07 | Zweimal 0x07 nötig |
Gleicher Sensor-Die (256×180 Pixel, 385 DPI, aktiv thermisch), aber ein komplett anderer USB-Stack. Der NB-2033-U nutzt ein TLV-Format (Type-Length-Value) statt des festen Kommandoschemas vom NB-1010-U. Jedes Kommando hat eine eigene Längenangabe, und die Antworten sind anders strukturiert.
Die Kommandos im Detail
Aus dem USB-Capture konnte ich sechs Kommandos identifizieren:
0x07— Init/Wake. Muss zweimal gesendet werden, sonst reagiert der Sensor nicht.0x0D— Sensor-Konfiguration. Wird zweimal vor jeder Finger-Erkennung gebraucht, um den „Enhanced“ Modus zu aktivieren.0x38— Finger-Erkennung. Byte 4 der Antwort ist der Detect-Level. Schwellwert 40.0x12— Capture starten. Liefert 180 Zeilen à 256 Pixel, 8-Bit Graustufen.0x13— Geräteinformationen (Hersteller, Modell, Seriennummer).0xF7— Firmware-Version.
Thermischer Sensor: Eigenheiten
Der Sensor misst Temperaturänderungen, nicht statischen Kontakt. Das klingt nach einem Detail, ist aber für die Treiber-Implementierung entscheidend. Finger auflegen erzeugt einen kurzen Spike im Detect-Wert (10 bis 50+). Finger bleibt liegen, und der Wert fällt zurück auf Basisniveau. Der Treiber muss also den Spike erkennen, nicht einen dauerhaften Zustand.
Dazu kommt: Nach dem Init gibt es transiente Spikes, die ungefähr 1,5 Sekunden brauchen, bis sie abklingen. Ohne Settle-Pause nach dem Init erkennt der Treiber Phantom-Finger.
Der Treiber
Rausgekommen ist nb2033.c, ein eigenständiger libfprint-Treiber mit rund 350 Zeilen. Kein proprietärer Code, keine SDK-Abhängigkeit. Das SDK diente nur als Referenz für die Capture-Analyse, der Treiber ist sauber von Grund auf geschrieben. Lizenz: LGPL 2.1+ wie alle libfprint-Treiber.
Die State Machine:
- Init (
0x07× 2) mit 1,5 Sekunden Settle-Pause - Finger-Detect-Polling (
0x0D+0x0D+0x38, Schwellwert 40) - Pre-Capture Config (
0x0D) - Capture (
0x12) mit 150 ms Pause, dann 180 Zeilen lesen - Bild an libfprint übergeben
Test
Getestet auf Majas Fujitsu Notebook mit Linux Mint 22.3:
$ fprintd-enroll Using device /net/reactivated/Fprint/Device/0 Enrolling right-index-finger finger. Enroll result: enroll-stage-passed [... 5/5 Stages ...] Enroll result: enroll-completed
$ fprintd-verify Using device /net/reactivated/Fprint/Device/0 Listing enrolled fingers: - #0: right-index-finger Verify result: verify-match (true)
Richtiger Finger: Match. Falscher Finger: No Match. Enrollment sauber, Verifikation zuverlässig.
Upstream
Der Merge Request ist eingereicht: MR !574 bei libfprint. Fünf Dateien: der neue Treiber, meson.build, autosuspend.hwdb und die Allowlist. CI läuft durch. Der verwandte MR !569 für den NB-2020-U ist noch in Review.
Für die Wiki-Aktualisierung (das Gerät von der „unsupported“ Liste nehmen) gibt es Issue #134.
Fazit
Der Hersteller sagt „not supported“, 74 Linux-User melden „failed“, und trotzdem war das an einem Nachmittag erledigt. SDK auf Linux ausführen, USB-Traffic mitschneiden, Protokoll rekonstruieren, Treiber schreiben, testen, upstream einreichen. Alles mit Open-Source-Tools: usbmon, libusb, libfprint.
Das Ergebnis: Majas Notebook hat jetzt einen funktionierenden Fingerabdruckleser unter Linux. Und sobald der Merge Request durch ist, haben ihn alle anderen auch.
Wie immer: Bei Fragen, fragen.
