Skip to content

[rodin] NFC-B / Type-B (ISO 14443-B) not working — missing libonebinary.so causes NFC firmware download failure #976

@Tinlera

Description

@Tinlera

Issue type

Feature not working as intended

Device

POCO X7 Pro (rodin)

crDroid version

crDroid 12

Exact version / Build date

crDroid 12.9 (Android 16) — ro.build.id=BP4A.251205.006, ro.build.version.incremental=1777607940, kernel 6.6.89-capybara-aosp-gki-5.2. Maintainer: Pedro Araujo. Build date 2026-05-01 (Monthly), downloaded from crdroid.net/rodin/12.

Bug description

NFC-B (ISO/IEC 14443 Type B) reader-mode polling is completely non-functional on rodin under crDroid. NFC-A polling works (NFC-A bank cards are detected as NfcA + IsoDep in NFC Tools), but Type-B cards — Turkish national ID (TC Kimlik Kartı) and ICAO 9303 e-passports (MRTDs) — are never detected by any reader app (NFC Tools, ReadID Free, Yapı Kredi banking app). The same physical card + same hardware reads correctly on the stock HyperOS partition (verified prior to flashing crDroid).

Root cause identified: the NXP NFC HAL never successfully downloads firmware to the SN220 NFCC, because the firmware-loader wrapper blob libonebinary.so is missing from the build. The chip therefore runs in its default ROM mode, in which Type-B polling/reader-mode is not properly supported. The HAL emits:

Error : opening (/system/vendor/lib64/libonebinary.so) !!
Failed to load FW binary image file!!!
phNxpNciHal_core_initialized: Restore UICC params failed

and dumpsys nfc reports Firmware version=<Unknown> (whereas a successful flash would report a concrete FW Version: …).

The blob is not present anywhere on the device (verified as root):

# find / -name 'libonebinary*' 2>/dev/null
(no results)

strings on the HAL library /vendor/lib64/nfc_nci_nxp_snxxx.so confirms the HAL expects to dlopen /system/vendor/lib64/libonebinary.so for firmware download, and tries to read libsn220u_fw (the SN220 firmware container, which IS shipped on rodin at /vendor/lib64/libsn220u_fw.so) through that wrapper. Without the wrapper, the firmware container alone is unusable.

libonebinary.so is also not listed in the rodin device tree's proprietary-files.txt (gimmebackmysandwich/device_xiaomi_rodin → 16 → proprietary-files.txt) — only vendor/lib64/libsn220u_fw.so is included.

Note about paths: /system/vendor/lib64/libonebinary.so and /vendor/lib64/libonebinary.so refer to the same location on Android 11+ (the /vendor partition is bind-mounted at /system/vendor). The HAL prints the /system/vendor/... form, but the file is missing from /vendor/lib64 regardless of which path is checked.

Steps to reproduce

  1. Flash and boot crDroid 12.9 on POCO X7 Pro (rodin) — official build, no modifications.
  2. Enable NFC in Settings.
  3. Install a Type-B reader app, e.g. ReadID Free (reads ICAO 9303 e-passports / Turkish ID) or NFC Tools.
  4. Hold a Type-B card (Turkish national ID / TC Kimlik, or any ICAO 9303 e-passport) against the NFC antenna.
  5. Expected: the card is detected and the app starts BAC/PACE handshake.
    Actual: the card is never detected. NFC-A test cards are detected normally.
  6. Confirm the chip never received firmware:
    adb shell dumpsys nfc | grep -i "firmware version"
    # → Firmware version=<Unknown>
    
  7. Capture the HAL logs that prove the firmware load failure:
    adb shell settings put global nfc_debug_enabled 1
    adb shell setprop persist.nfc.nxp.logging.level 5
    adb shell svc nfc disable && adb shell svc nfc enable
    adb shell logcat -d -s NxpHal NxpTml | grep -E "libonebinary|FW binary|Restore UICC"
    
    You will see Error : opening (/system/vendor/lib64/libonebinary.so) !! followed by Failed to load FW binary image file!!!.

Relevant log (logcat/build log)

NFC HAL log (with `nfc_debug_enabled=1`, `persist.nfc.nxp.logging.level=5`):

D NxpHal  : Error : opening (/system/vendor/lib64/libonebinary.so) !!
D NxpHal  : Failed to load FW binary image file!!!
D NxpTml  : NFCC - Error in Write.....
D NxpHal  : write error status = 0x1ff
D NxpHal  : write_unlocked failed - NFCC Maybe in Standby Mode - Retry
D NxpHal  : Performing SRD Timeout settings
E NxpHal  : phNxpNciHal_core_initialized: Restore UICC params failed


`dumpsys nfc` excerpt (chip is up but un-flashed):

mState=on
listenTech=0xf
pollTech=0x2f          # A + B + F + V + Barcode requested
mEnableReader: false
Firmware version=<Unknown>


`strings` evidence from the HAL library showing the dlopen target:

$ adb shell su -c 'strings /vendor/lib64/nfc_nci_nxp_snxxx.so' \
    | grep -E 'libonebinary|libsn[0-9]+u_fw|/vendor/lib'
/system/vendor/lib64/libonebinary.so
/vendor/lib64/libsn220u_fw.so
libsn220u_fw
Opening (...)
Error : opening (/system/vendor/lib64/libonebinary.so) !!
closing libonebinary.so
firmware file format mismatch!!!


NFC blobs present on device (everything except the loader):

$ adb shell su -c 'find /vendor /odm /system_ext -name "libsn*fw*" -o -name "libonebinary*" 2>/dev/null'
/vendor/lib64/libsn220u_fw.so          ← firmware container (present)
                                       ← libonebinary.so MISSING


NFC HAL service binary in use (AOSP generic, not Xiaomi's `nqnfc-service.nxp`):

$ adb shell ls /vendor/bin/hw/ | grep -i nfc
android.hardware.nfc-service.nxp

Screenshots or videos

No response

Solution

The minimum fix is to add the missing firmware-loader blob to the rodin device tree's proprietary-files.txt (extracted from a stock HyperOS vendor dump for rodin):

vendor/lib64/libonebinary.so

This single blob is what the AOSP android.hardware.nfc-service.nxp HAL dlopens to push libsn220u_fw.so to the NFCC over I²C. With it present, firmware download will succeed and Type-B polling will work.

If the AOSP HAL turns out to be incompatible with the stock libonebinary.so (ABI mismatch), the alternative is to ship Xiaomi's stock NFC HAL stack instead — i.e. add to proprietary-files.txt:

vendor/bin/hw/android.hardware.nqnfc-service.nxp
vendor/etc/init/nqnfc-service-nxp.rc
vendor/etc/vintf/manifest/nqnfc-service-nxp.xml
vendor/lib64/libonebinary.so

and switch the device.mk over to declare android.hardware.nqnfc-service.nxp as the NFC HAL (this is the approach used by other Xiaomi/MediaTek device trees, e.g. Risgit/device-xiaomi-missi, which ships nqnfc-service.nxp + sn100u_nfcon.pnscr).

Additional context

Verified working on stock HyperOS with the exact same hardware, antenna, card, and reader apps — so this is purely a software/blob packaging issue, not an antenna/hardware regression.

  • NFC chip: NXP SN220 (single chip, no kernel chip driver — accessed over I²C from userspace HAL; the only loaded NFC kernel module is the generic Linux nfc core).
  • HAL paths: HAL searches /etc/libnfc-nxp.conf, /odm/etc/libnfc-nxp.conf, /vendor/etc/libnfc-nxp.conf (in that order). On rodin, /odm/etc/libnfc-nxp.conf is the correct SN220 config (sets NXP_FW_NAME="libsn220u_fw.so"). /vendor/etc/libnfc-nxp-pnscr.conf exists but references SN100 firmware and is not consumed by this HAL.
  • /vendor/libnfc-nxp_RF.conf (RF tuning, 14125 bytes) is present and looks valid.
  • Tweaks I tried that did NOT help (because they cannot fix a missing loader): /data/vendor/nfc/libnfc-nxpTransit.conf overrides NFA_POLL_BAIL_OUT_MODE=0x00, NXP_FLASH_CONFIG=0x01, NFA_DM_DISC_DURATION_POLL=1000; deleting the cached *State.bin files in /data/vendor/nfc/; toggling nfc_debug_enabled. None of these can substitute for the missing firmware download.
  • No SELinux denials related to NFC are visible in dmesg | grep avc — this is purely a missing-blob issue, not a policy issue.
  • Other NFC-related blobs referenced by the HAL (per strings) but not strictly needed on SN220 hardware: libsn100u_fw_pku.so, libsn100u_fw_platform.so, hal_libnfc.so. These are SN100-variant blobs and can be ignored for rodin.

Acknowledgements

  • I've checked device is officially supported and that no support is provided for unofficial devices (for device specific reports and not source related).
  • I'm running latest version available on crdroid.net for this device and that the device is still maintainer supported (not flagged unsupported on download page)
  • I have searched the existing issues and this is a new and no duplicate or related to another open issue.
  • I have written a short but informative title.
  • I filled out all of the requested information in this issue properly and understand that not doing so will automatically result in closing of ticket.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

Devices

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions