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
- Flash and boot crDroid 12.9 on POCO X7 Pro (rodin) — official build, no modifications.
- Enable NFC in Settings.
- Install a Type-B reader app, e.g. ReadID Free (reads ICAO 9303 e-passports / Turkish ID) or NFC Tools.
- Hold a Type-B card (Turkish national ID / TC Kimlik, or any ICAO 9303 e-passport) against the NFC antenna.
- 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.
- Confirm the chip never received firmware:
adb shell dumpsys nfc | grep -i "firmware version"
# → Firmware version=<Unknown>
- 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
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, kernel6.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 + IsoDepin 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.sois 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:and
dumpsys nfcreportsFirmware version=<Unknown>(whereas a successful flash would report a concreteFW Version: …).The blob is not present anywhere on the device (verified as root):
stringson the HAL library/vendor/lib64/nfc_nci_nxp_snxxx.soconfirms the HAL expects to dlopen/system/vendor/lib64/libonebinary.sofor firmware download, and tries to readlibsn220u_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.sois also not listed in the rodin device tree'sproprietary-files.txt(gimmebackmysandwich/device_xiaomi_rodin → 16 → proprietary-files.txt) — onlyvendor/lib64/libsn220u_fw.sois included.Steps to reproduce
Actual: the card is never detected. NFC-A test cards are detected normally.
Error : opening (/system/vendor/lib64/libonebinary.so) !!followed byFailed to load FW binary image file!!!.Relevant log (logcat/build log)
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):This single blob is what the AOSP
android.hardware.nfc-service.nxpHAL dlopens to pushlibsn220u_fw.soto 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 toproprietary-files.txt:and switch the
device.mkover to declareandroid.hardware.nqnfc-service.nxpas the NFC HAL (this is the approach used by other Xiaomi/MediaTek device trees, e.g.Risgit/device-xiaomi-missi, which shipsnqnfc-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.
nfccore)./etc/libnfc-nxp.conf,/odm/etc/libnfc-nxp.conf,/vendor/etc/libnfc-nxp.conf(in that order). On rodin,/odm/etc/libnfc-nxp.confis the correct SN220 config (setsNXP_FW_NAME="libsn220u_fw.so")./vendor/etc/libnfc-nxp-pnscr.confexists 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./data/vendor/nfc/libnfc-nxpTransit.confoverridesNFA_POLL_BAIL_OUT_MODE=0x00,NXP_FLASH_CONFIG=0x01,NFA_DM_DISC_DURATION_POLL=1000; deleting the cached*State.binfiles in/data/vendor/nfc/; togglingnfc_debug_enabled. None of these can substitute for the missing firmware download.dmesg | grep avc— this is purely a missing-blob issue, not a policy issue.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