From bd6099b1b868b9dcd02c82a6224f138da9382084 Mon Sep 17 00:00:00 2001 From: Tafil Avdyli Date: Sat, 24 Jan 2026 21:54:21 +0100 Subject: [PATCH 01/15] CMakeLists: remove linking to librt This is not required anymore. Quoting glibc 2.30 NEWS: > * The functions clock_gettime, clock_getres, clock_settime, > clock_getcpuclockid, clock_nanosleep were removed from the librt library > for new applications (on architectures which had them). Instead, the > definitions in libc will be used automatically, which have been available > since glibc 2.17. When building in a BitBake devshell as shared library and inspecting the resulting .so file with readelf reveals that librt.so is never linked to: 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6] 0x0000000000000001 (NEEDED) Shared library: [libm.so.6] 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x0000000000000001 (NEEDED) Shared library: [ld-linux-aarch64.so.1] 0x000000000000000e (SONAME) Library soname: [liblibnfc_nci.so] This will also fix do_package_qa: QA Issue: File /usr/lib/cmake/libnfc-nci/libnfc-nci-targets.cmake in package libnfc-nci-dev contains reference to TMPDIR [buildpaths] in yocto builds since it contained a full path to librt.so. Signed-off-by: Tafil Avdyli --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f6aea0..e432b1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,6 @@ find_package(everest-cmake 0.1 REQUIRED PATHS ../everest-cmake ) find_package(Threads REQUIRED) -find_library(LIBRT rt) option(LIBNFCNCI_BUILD_EXAMPLES "enable building of examples" OFF) option(LIBNFCNCI_INSTALL "Install the library (shared data might be installed anyway)" ${EVC_MAIN_PROJECT}) @@ -261,7 +260,6 @@ target_include_directories(libnfc_nci target_link_libraries(libnfc_nci PRIVATE Threads::Threads - ${LIBRT} ) # From d5ad18496ed8f8dbf2a53d2faedc8b9ddf1324dd Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Mon, 27 Apr 2026 15:57:34 +0200 Subject: [PATCH 02/15] .gitignore: add build directories Signed-off-by: Michael Heimpold --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 64f9553..905cdbd 100644 --- a/.gitignore +++ b/.gitignore @@ -65,4 +65,7 @@ Makefile # Editor *.orig -*.rej \ No newline at end of file +*.rej + +# build dirs +build-* From 109cb080e1f54d368e1b1c18a63448ef78fb43dd Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Mon, 27 Apr 2026 17:07:54 +0200 Subject: [PATCH 03/15] NfccAltTransport: fix methods and members protection classes Signed-off-by: Michael Heimpold --- .../tml/transport/NfccAltI2cTransport.h | 10 ++-- .../tml/transport/NfccAltSpiTransport.h | 10 ++-- .../halimpl/tml/transport/NfccAltTransport.h | 59 ++++++++++++------- .../halimpl/tml/transport/NfccI2cTransport.cc | 1 + .../halimpl/tml/transport/NfccI2cTransport.h | 32 +++++----- 5 files changed, 65 insertions(+), 47 deletions(-) diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.h index 0877a10..a567c7a 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.h @@ -21,7 +21,7 @@ #include class NfccAltI2cTransport : public NfccAltTransport { - public: +public: /***************************************************************************** ** ** Function OpenAndConfigure @@ -36,7 +36,7 @@ class NfccAltI2cTransport : public NfccAltTransport { ** NFCSTATUS_INVALID_DEVICE - device open operation failure ** ****************************************************************************/ - NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void** pLinkHandle); + virtual NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void** pLinkHandle) override; /***************************************************************************** ** @@ -54,7 +54,7 @@ class NfccAltI2cTransport : public NfccAltTransport { ** -1 - read operation failure ** ****************************************************************************/ - int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead); + virtual int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) override; /***************************************************************************** ** @@ -71,6 +71,6 @@ class NfccAltI2cTransport : public NfccAltTransport { ** -1 - write operation failure ** *****************************************************************************/ - int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite); - void Close(void* pDevHandle); + virtual int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override; + virtual void Close(void* pDevHandle) override; }; diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.h index f806475..9ac4d1f 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.h @@ -21,7 +21,7 @@ #include class NfccAltSpiTransport : public NfccAltTransport { - public: +public: /***************************************************************************** ** ** Function OpenAndConfigure @@ -36,7 +36,7 @@ class NfccAltSpiTransport : public NfccAltTransport { ** NFCSTATUS_INVALID_DEVICE - device open operation failure ** ****************************************************************************/ - NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void** pLinkHandle); + virtual NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void** pLinkHandle) override; /***************************************************************************** ** @@ -54,7 +54,7 @@ class NfccAltSpiTransport : public NfccAltTransport { ** -1 - read operation failure ** ****************************************************************************/ - int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead); + virtual int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) override; /***************************************************************************** ** @@ -71,6 +71,6 @@ class NfccAltSpiTransport : public NfccAltTransport { ** -1 - write operation failure ** *****************************************************************************/ - int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite); - void Close(void* pDevHandle); + virtual int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override; + virtual void Close(void* pDevHandle) override; }; diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h index 335e2b4..78829c9 100755 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h @@ -41,22 +41,10 @@ extern phTmlNfc_i2cfragmentation_t fragmentation_enabled; class NfccAltTransport : public NfccTransport { - public: +public: NfccAltTransport(); - bool_t bFwDnldFlag = false; - sem_t mTxRxSemaphore; - int iEnableFd; - int iInterruptFd; - int iFwDnldFd; + virtual ~NfccAltTransport() = default; - public: - void gpio_set_ven(int value); - void gpio_set_fwdl(int value); - int verifyPin(int pin, int isoutput, int edge); - void wait4interrupt(void); - int SemTimedWait(); - void SemPost(); - int Flushdata(void* pDevHandle, uint8_t* pBuffer, int numRead); /***************************************************************************** ** ** Function Reset @@ -70,7 +58,7 @@ class NfccAltTransport : public NfccTransport { ** -1 - reset operation failure ** ****************************************************************************/ - int NfccReset(void* pDevHandle, NfccResetType eType); + virtual int NfccReset(void* pDevHandle, NfccResetType eType) override; /***************************************************************************** ** @@ -82,7 +70,7 @@ class NfccAltTransport : public NfccTransport { ** ** Returns None ****************************************************************************/ - void EnableFwDnldMode(bool mode); + virtual void EnableFwDnldMode(bool mode) override; /***************************************************************************** ** @@ -94,9 +82,9 @@ class NfccAltTransport : public NfccTransport { ** ** Returns Current mode download/NCI ****************************************************************************/ - bool_t IsFwDnldModeEnabled(void); + virtual bool_t IsFwDnldModeEnabled(void) override; - /******************************************************************************* + /***************************************************************************** ** ** Function GetIrqState ** @@ -108,9 +96,38 @@ class NfccAltTransport : public NfccTransport { *Zer0. ** In the case of IOCTL error, it returns -ve value. ** - *******************************************************************************/ - int GetIrqState(void* pDevHandle); - int GetNfcState(void* pDevHandle); + ****************************************************************************/ + virtual int GetIrqState(void* pDevHandle) override; + + /***************************************************************************** + ** + ** Function GetNfcState + ** + ** Description Get NFC state + ** + ** Parameters pDevHandle - valid device handle + ** Returns 0 - unknown + ** 1 - FW DWL + ** 2 - NCI + ** + ****************************************************************************/ + virtual int GetNfcState(void* pDevHandle) override; + +protected: + bool_t bFwDnldFlag = false; + sem_t mTxRxSemaphore; + int iEnableFd; + int iInterruptFd; + int iFwDnldFd; + + void gpio_set_ven(int value); + void gpio_set_fwdl(int value); + int verifyPin(int pin, int isoutput, int edge); + void wait4interrupt(void); + int SemTimedWait(); + void SemPost(); + int Flushdata(void* pDevHandle, uint8_t* pBuffer, int numRead); + /***************************************************************************** ** ** Function ConfigurePin diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccI2cTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccI2cTransport.cc index 2f22a3b..c69b726 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccI2cTransport.cc +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccI2cTransport.cc @@ -442,6 +442,7 @@ int NfccI2cTransport::GetNfcState(void *pDevHandle) { NXPLOG_TML_D("%s :nfc state = %d", __func__, ret); return ret; } + /******************************************************************************* ** ** Function EnableFwDnldMode diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccI2cTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccI2cTransport.h index 2721052..d9e1060 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccI2cTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccI2cTransport.h @@ -58,7 +58,7 @@ extern phTmlNfc_i2cfragmentation_t fragmentation_enabled; class NfccI2cTransport : public NfccTransport { - private: +private: bool_t bFwDnldFlag = false; sem_t mTxRxSemaphore; /***************************************************************************** @@ -87,7 +87,7 @@ class NfccI2cTransport : public NfccTransport { int Flushdata(void* pDevHandle, uint8_t* pBuffer, int numRead); - public: +public: /***************************************************************************** ** ** Function Close @@ -99,7 +99,7 @@ class NfccI2cTransport : public NfccTransport { ** Returns None ** *****************************************************************************/ - void Close(void *pDevHandle); + virtual void Close(void *pDevHandle) override; /***************************************************************************** ** @@ -115,7 +115,7 @@ class NfccI2cTransport : public NfccTransport { ** NFCSTATUS_INVALID_DEVICE - device open operation failure ** ****************************************************************************/ - NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void **pLinkHandle); + virtual NFCSTATUS OpenAndConfigure(pphTmlNfc_Config_t pConfig, void **pLinkHandle) override; /***************************************************************************** ** @@ -133,7 +133,7 @@ class NfccI2cTransport : public NfccTransport { ** -1 - read operation failure ** ****************************************************************************/ - int Read(void *pDevHandle, uint8_t *pBuffer, int nNbBytesToRead); + virtual int Read(void *pDevHandle, uint8_t *pBuffer, int nNbBytesToRead) override; /***************************************************************************** ** @@ -150,7 +150,7 @@ class NfccI2cTransport : public NfccTransport { ** -1 - write operation failure ** *****************************************************************************/ - int Write(void *pDevHandle, uint8_t *pBuffer, int nNbBytesToWrite); + virtual int Write(void *pDevHandle, uint8_t *pBuffer, int nNbBytesToWrite) override; /***************************************************************************** ** @@ -165,7 +165,7 @@ class NfccI2cTransport : public NfccTransport { ** -1 - reset operation failure ** ****************************************************************************/ - int NfccReset(void *pDevHandle, NfccResetType eType); + virtual int NfccReset(void *pDevHandle, NfccResetType eType) override; /***************************************************************************** ** @@ -180,7 +180,7 @@ class NfccI2cTransport : public NfccTransport { ** else - reset operation failure ** ****************************************************************************/ - int EseReset(void *pDevHandle, EseResetType eType); + virtual int EseReset(void *pDevHandle, EseResetType eType) override; /***************************************************************************** ** @@ -195,7 +195,7 @@ class NfccI2cTransport : public NfccTransport { ** else - reset operation failure ** ****************************************************************************/ - int EseGetPower(void *pDevHandle, long level); + virtual int EseGetPower(void *pDevHandle, long level) override; /***************************************************************************** ** @@ -209,7 +209,7 @@ class NfccI2cTransport : public NfccTransport { ** 1 - i3c ** ****************************************************************************/ - int GetPlatform(void *pDevHandle); + virtual int GetPlatform(void *pDevHandle) override; /***************************************************************************** ** @@ -223,7 +223,7 @@ class NfccI2cTransport : public NfccTransport { ** 2 - NCI ** *****************************************************************************/ - int GetNfcState(void *pDevHandle); + virtual int GetNfcState(void *pDevHandle) override; /***************************************************************************** ** @@ -235,7 +235,7 @@ class NfccI2cTransport : public NfccTransport { ** ** Returns None ****************************************************************************/ - void EnableFwDnldMode(bool mode); + virtual void EnableFwDnldMode(bool mode) override; /***************************************************************************** ** @@ -247,9 +247,9 @@ class NfccI2cTransport : public NfccTransport { ** ** Returns Current mode download/NCI ****************************************************************************/ - bool_t IsFwDnldModeEnabled(void); + virtual bool_t IsFwDnldModeEnabled(void) override; - /******************************************************************************* + /***************************************************************************** ** ** Function GetIrqState ** @@ -260,6 +260,6 @@ class NfccI2cTransport : public NfccTransport { ** Returns The state of IRQ line i.e. +ve if read is pending else Zer0. ** In the case of IOCTL error, it returns -ve value. ** - *******************************************************************************/ - int GetIrqState(void *pDevHandle); + ****************************************************************************/ + virtual int GetIrqState(void *pDevHandle) override; }; From 4b43422acefa71742456778f777c95253becf501 Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Mon, 27 Apr 2026 17:09:05 +0200 Subject: [PATCH 04/15] NfccAltTransport: drop unused method Flushdata Signed-off-by: Michael Heimpold --- .../halimpl/tml/transport/NfccAltTransport.cc | 38 ------------------- .../halimpl/tml/transport/NfccAltTransport.h | 1 - 2 files changed, 39 deletions(-) diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc index d1dbd4a..e68638a 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc @@ -53,44 +53,6 @@ NfccAltTransport::NfccAltTransport() { iInterruptFd = 0; } -/******************************************************************************* -** -** Function Flushdata -** -** Description Reads payload of FW rsp from NFCC device into given buffer -** -** Parameters pDevHandle - valid device handle -** pBuffer - buffer for read data -** numRead - number of bytes read by calling function -** -** Returns always returns -1 -** -*******************************************************************************/ -int NfccAltTransport::Flushdata(void* pDevHandle, uint8_t* pBuffer, - int numRead) { - int retRead = 0; - uint16_t totalBtyesToRead = - pBuffer[FW_DNLD_LEN_OFFSET] + FW_DNLD_HEADER_LEN + CRC_LEN; - /* we shall read totalBtyesToRead-1 as one byte is already read by calling - * function*/ - retRead = read((intptr_t)pDevHandle, pBuffer + numRead, totalBtyesToRead - 1); - if (retRead > 0) { - numRead += retRead; - phNxpNciHal_print_packet("RECV", pBuffer, numRead); - } else if (retRead == 0) { - NXPLOG_TML_E("%s _i2c_read() [pyld] EOF", __func__); - } else { - if (bFwDnldFlag == false) { - NXPLOG_TML_D("%s _i2c_read() [hdr] received", __func__); - phNxpNciHal_print_packet("RECV", pBuffer - numRead, - NORMAL_MODE_HEADER_LEN); - } - NXPLOG_TML_E("%s _i2c_read() [pyld] errno : %x", __func__, errno); - } - SemPost(); - return -1; -} - /******************************************************************************* ** ** Function Reset diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h index 78829c9..8e4743c 100755 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h @@ -126,7 +126,6 @@ class NfccAltTransport : public NfccTransport { void wait4interrupt(void); int SemTimedWait(); void SemPost(); - int Flushdata(void* pDevHandle, uint8_t* pBuffer, int numRead); /***************************************************************************** ** From a77c359d1f5bf27ee33dab25501f080e4af5927b Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Tue, 28 Apr 2026 09:40:38 +0200 Subject: [PATCH 05/15] NfccAltTransport: fix fd handling and consolidate Close Invalid file descriptor is -1, values >= must be considered valid. While at, get rid of the Close method is derived class since the functionality is the same for all derived classes. Signed-off-by: Michael Heimpold --- .../tml/transport/NfccAltI2cTransport.cc | 23 -------- .../tml/transport/NfccAltI2cTransport.h | 1 - .../tml/transport/NfccAltSpiTransport.cc | 23 -------- .../tml/transport/NfccAltSpiTransport.h | 1 - .../halimpl/tml/transport/NfccAltTransport.cc | 53 ++++++++++++++----- .../halimpl/tml/transport/NfccAltTransport.h | 19 +++++-- .../halimpl/tml/transport/NfccTransport.h | 8 +-- 7 files changed, 61 insertions(+), 67 deletions(-) diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.cc index 085e6fb..8fb55b0 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.cc +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.cc @@ -275,26 +275,3 @@ int NfccAltI2cTransport::Write(void* pDevHandle, uint8_t* pBuffer, NXPLOG_TML_D("%s exit", __func__); return numWrote; } - -/******************************************************************************* -** -** Function Close -** -** Description Closes NFCC device -** -** Parameters pDevHandle - device handle -** -** Returns None -** -*******************************************************************************/ -void NfccAltI2cTransport::Close(void* pDevHandle) { - NXPLOG_TML_D("%s Enter", __func__); - if (NULL != pDevHandle) { - close((intptr_t)pDevHandle); - } - if (iEnableFd) close(iEnableFd); - if (iInterruptFd) close(iInterruptFd); - if (iFwDnldFd) close(iFwDnldFd); - NXPLOG_TML_D("%s exit", __func__); - return; -} diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.h index a567c7a..6cb4934 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltI2cTransport.h @@ -72,5 +72,4 @@ class NfccAltI2cTransport : public NfccAltTransport { ** *****************************************************************************/ virtual int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override; - virtual void Close(void* pDevHandle) override; }; diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.cc index 03dfb86..ae52511 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.cc +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.cc @@ -390,26 +390,3 @@ int NfccAltSpiTransport::Write(void* pDevHandle, uint8_t* pBuffer, NXPLOG_TML_D("%s exit", __func__); return numWrote - PREFIX_LENGTH; } - -/******************************************************************************* -** -** Function Close -** -** Description Closes NFCC device -** -** Parameters pDevHandle - device handle -** -** Returns None -** -*******************************************************************************/ -void NfccAltSpiTransport::Close(void* pDevHandle) { - NXPLOG_TML_D("%s Enter", __func__); - if (NULL != pDevHandle) { - close((intptr_t)pDevHandle); - } - if (iEnableFd) close(iEnableFd); - if (iInterruptFd) close(iInterruptFd); - if (iFwDnldFd) close(iFwDnldFd); - NXPLOG_TML_D("%s exit", __func__); - return; -} diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.h index 9ac4d1f..96cca7a 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltSpiTransport.h @@ -72,5 +72,4 @@ class NfccAltSpiTransport : public NfccAltTransport { ** *****************************************************************************/ virtual int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) override; - virtual void Close(void* pDevHandle) override; }; diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc index e68638a..c77236a 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc @@ -49,8 +49,6 @@ extern phTmlNfc_i2cfragmentation_t fragmentation_enabled; extern phTmlNfc_Context_t* gpphTmlNfc_Context; NfccAltTransport::NfccAltTransport() { - iEnableFd = 0; - iInterruptFd = 0; } /******************************************************************************* @@ -223,7 +221,7 @@ int NfccAltTransport::GetIrqState(void* pDevHandle) { int len; char buf[2]; - if (iInterruptFd <= 0) { + if (iInterruptFd < 0) { NXPLOG_TML_E("Error with interrupt-detect pin (%d)", iInterruptFd); return (-1); } @@ -251,10 +249,10 @@ int NfccAltTransport::verifyPin(int pin, int isoutput, int edge) { sprintf(buf, "/sys/class/gpio/gpio%d", pin); NXPLOG_TML_D("Pin %s\n", buf); int fd = open(buf, O_RDONLY); - if (fd <= 0) { + if (fd < 0) { // Pin not exported yet NXPLOG_TML_D("Create pin %s\n", buf); - if ((fd = open("/sys/class/gpio/export", O_WRONLY)) > 0) { + if ((fd = open("/sys/class/gpio/export", O_WRONLY)) >= 0) { sprintf(buf, "%d", pin); if (write(fd, buf, strlen(buf)) == strlen(buf)) { hasGpio = 1; @@ -275,7 +273,7 @@ int NfccAltTransport::verifyPin(int pin, int isoutput, int edge) { sprintf(buf, "/sys/class/gpio/gpio%d/direction", pin); NXPLOG_TML_D("Direction %s\n", buf); fd = open(buf, O_WRONLY); - if (fd <= 0) { + if (fd < 0) { NXPLOG_TML_E("Could not open direction port '%s' (%s)", buf, strerror(errno)); return -1; @@ -289,14 +287,14 @@ int NfccAltTransport::verifyPin(int pin, int isoutput, int edge) { // Open pin and make sure it is off sprintf(buf, "/sys/class/gpio/gpio%d/value", pin); fd = open(buf, O_RDWR); - if (fd <= 0) { + if (fd < 0) { } close(fd); // Open pin and make sure it is off sprintf(buf, "/sys/class/gpio/gpio%d/value", pin); fd = open(buf, O_RDWR); - if (fd <= 0) { + if (fd < 0) { NXPLOG_TML_E("Could not open value port '%s' (%s)", buf, strerror(errno)); return -1; @@ -317,7 +315,7 @@ int NfccAltTransport::verifyPin(int pin, int isoutput, int edge) { sprintf(buf, "/sys/class/gpio/gpio%d/edge", pin); NXPLOG_TML_D("Edge %s\n", buf); fd = open(buf, O_RDWR); - if (fd <= 0) { + if (fd < 0) { NXPLOG_TML_E("Could not open edge port '%s' (%s)", buf, strerror(errno)); return -1; @@ -347,7 +345,7 @@ int NfccAltTransport::verifyPin(int pin, int isoutput, int edge) { sprintf(buf, "/sys/class/gpio/gpio%d/value", pin); NXPLOG_TML_D("Value %s\n", buf); fd = open(buf, O_RDONLY); - if (fd <= 0) { + if (fd < 0) { NXPLOG_TML_E("Could not open value port '%s' (%s)", buf, strerror(errno)); return -1; @@ -360,7 +358,7 @@ int NfccAltTransport::verifyPin(int pin, int isoutput, int edge) { return (0); } void NfccAltTransport::gpio_set_ven(int value) { - if (iEnableFd > 0) { + if (iEnableFd >= 0) { if (value == 0) { write(iEnableFd, "0", 1); } else { @@ -371,7 +369,7 @@ void NfccAltTransport::gpio_set_ven(int value) { } void NfccAltTransport::gpio_set_fwdl(int value) { - if (iFwDnldFd > 0) { + if (iFwDnldFd >= 0) { if (value == 0) { write(iFwDnldFd, "0", 1); } else { @@ -423,3 +421,34 @@ int NfccAltTransport::ConfigurePin() if (iFwDnldFd < 0) return (NFCSTATUS_INVALID_DEVICE); return NFCSTATUS_SUCCESS; } + +/******************************************************************************* +** +** Function Close +** +** Description Closes NFCC device +** +** Parameters pDevHandle - device handle +** +** Returns None +** +*******************************************************************************/ +void NfccAltTransport::Close(void* pDevHandle) { + NXPLOG_TML_D("%s Enter", __func__); + if (NULL != pDevHandle) { + close((intptr_t)pDevHandle); + } + if (iEnableFd >= 0) { + close(iEnableFd); + iEnableFd = -1; + } + if (iInterruptFd >= 0) { + close(iInterruptFd); + iInterruptFd = -1; + } + if (iFwDnldFd >= 0) { + close(iFwDnldFd); + iFwDnldFd = -1; + } + NXPLOG_TML_D("%s exit", __func__); +} diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h index 8e4743c..7f3fa2b 100755 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h @@ -113,12 +113,25 @@ class NfccAltTransport : public NfccTransport { ****************************************************************************/ virtual int GetNfcState(void* pDevHandle) override; + /***************************************************************************** + ** + ** Function Close + ** + ** Description Closes NFCC device + ** + ** Parameters pDevHandle - device handle + ** + ** Returns None + ** + ****************************************************************************/ + virtual void Close(void *pDevHandle) override; + protected: bool_t bFwDnldFlag = false; sem_t mTxRxSemaphore; - int iEnableFd; - int iInterruptFd; - int iFwDnldFd; + int iEnableFd{-1}; + int iInterruptFd{-1}; + int iFwDnldFd{-1}; void gpio_set_ven(int value); void gpio_set_fwdl(int value); diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccTransport.h index 2d2f2d3..e5cc7b2 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccTransport.h @@ -65,7 +65,7 @@ class NfccTransport { ** ** Returns None ** - *****************************************************************************/ + ****************************************************************************/ virtual void Close(void *pDevHandle) = 0; /***************************************************************************** @@ -117,7 +117,7 @@ class NfccTransport { ** Returns numWrote - number of successfully written bytes ** -1 - write operation failure ** - *****************************************************************************/ + ****************************************************************************/ virtual int Write(void *pDevHandle, uint8_t *pBuffer, int nNbBytesToWrite) = 0; @@ -217,7 +217,7 @@ class NfccTransport { ****************************************************************************/ virtual bool_t IsFwDnldModeEnabled(void); - /******************************************************************************* + /***************************************************************************** ** ** Function GetIrqState ** @@ -229,7 +229,7 @@ class NfccTransport { *Zer0. ** In the case of IOCTL error, it returns -ve value. ** - *******************************************************************************/ + ****************************************************************************/ virtual int GetIrqState(void *pDevHandle); /***************************************************************************** From b68333233f7e80677e2a84cc92dd5b380adc55d7 Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Tue, 28 Apr 2026 10:28:09 +0200 Subject: [PATCH 06/15] NfccAltTransport: drop GetNfcState This uses a proprietary ioctl which will not work with default I2C or SPI interface devices on Linux. I guess this is left-over copy&paste garbage. Remove it since there seems no user of this methods. Signed-off-by: Michael Heimpold --- .../halimpl/tml/transport/NfccAltTransport.cc | 22 ------------------- .../halimpl/tml/transport/NfccAltTransport.h | 14 ------------ 2 files changed, 36 deletions(-) diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc index c77236a..ce53c99 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc @@ -109,28 +109,6 @@ int NfccAltTransport::NfccReset(void* pDevHandle, NfccResetType eType) { return ret; } -/******************************************************************************* -** -** Function GetNfcState -** -** Description Get NFC state -** -** Parameters pDevHandle - valid device handle -** Returns 0 - unknown -** 1 - FW DWL -** 2 - NCI -** -*******************************************************************************/ -int NfccAltTransport::GetNfcState(void* pDevHandle) { - int ret = NFC_STATE_UNKNOWN; - NXPLOG_TML_D("%s ", __func__); - if (NULL == pDevHandle) { - return ret; - } - ret = ioctl((intptr_t)pDevHandle, NFC_GET_NFC_STATE); - NXPLOG_TML_D("%s :nfc state = %d", __func__, ret); - return ret; -} /******************************************************************************* ** ** Function EnableFwDnldMode diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h index 7f3fa2b..3900b82 100755 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h @@ -99,20 +99,6 @@ class NfccAltTransport : public NfccTransport { ****************************************************************************/ virtual int GetIrqState(void* pDevHandle) override; - /***************************************************************************** - ** - ** Function GetNfcState - ** - ** Description Get NFC state - ** - ** Parameters pDevHandle - valid device handle - ** Returns 0 - unknown - ** 1 - FW DWL - ** 2 - NCI - ** - ****************************************************************************/ - virtual int GetNfcState(void* pDevHandle) override; - /***************************************************************************** ** ** Function Close From 076e18014f69bb53143b208993873f1275673110 Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Tue, 28 Apr 2026 16:53:46 +0200 Subject: [PATCH 07/15] Fix potential buffer overflow when reading config strings Destination buffer must not overflow, so check size of buffer and string length. Signed-off-by: Michael Heimpold --- src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp b/src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp index 42f901f..a2365dc 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp @@ -578,7 +578,7 @@ bool CNxpNfcConfig::getValue(const char* name, char* pValue, size_t len) const if (pParam->str_len() > 0) { memset(pValue, 0, len); - memcpy(pValue, pParam->str_value(), pParam->str_len()); + memcpy(pValue, pParam->str_value(), (len - 1 < pParam->str_len()) ? len - 1 : pParam->str_len()); return true; } return false; From 716d79bc3639b8a9a916552790f44c67d2915b28 Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Tue, 28 Apr 2026 16:55:07 +0200 Subject: [PATCH 08/15] Add support for libgpiod Signed-off-by: Michael Heimpold --- CMakeLists.txt | 33 +++- conf/libnfc-nxp.conf | 21 ++- .../halimpl/tml/transport/NfccAltTransport.cc | 173 ++++++++++++++++++ .../halimpl/tml/transport/NfccAltTransport.h | 26 +++ 4 files changed, 247 insertions(+), 6 deletions(-) mode change 100755 => 100644 conf/libnfc-nxp.conf diff --git a/CMakeLists.txt b/CMakeLists.txt index e432b1e..596078c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,18 @@ find_package(everest-cmake 0.1 REQUIRED ) find_package(Threads REQUIRED) + option(LIBNFCNCI_BUILD_EXAMPLES "enable building of examples" OFF) option(LIBNFCNCI_INSTALL "Install the library (shared data might be installed anyway)" ${EVC_MAIN_PROJECT}) +option(LIBNFCNCI_LIBGPIOD "Build with libgpiod support" OFF) + +if (LIBNFCNCI_LIBGPIOD) + # search for package PkgConfig + find_package(PkgConfig REQUIRED) + + # search for libgpiod + pkg_search_module(LIBGPIOD REQUIRED libgpiodcxx) +endif() if (NOT LIBNFCNCI_CONFIG_INSTALL_PATH) set (LIBNFCNCI_CONFIG_INSTALL_PATH "${CMAKE_INSTALL_SYSCONFDIR}/everest/libnfc_config/") @@ -226,6 +236,7 @@ set (COMPILE_DEFINITIONS -DSNEP_ENABLED ) + # # library target # @@ -241,7 +252,9 @@ target_sources(libnfc_nci target_compile_definitions(libnfc_nci PRIVATE - ${COMPILE_DEFINITIONS}) + ${COMPILE_DEFINITIONS} + $<$:USE_LIBGPIOD> +) # NOTE (aw): this is dangerous target_compile_options(libnfc_nci @@ -262,6 +275,18 @@ target_link_libraries(libnfc_nci Threads::Threads ) +if(LIBNFCNCI_LIBGPIOD) + target_include_directories(libnfc_nci + PRIVATE + ${LIBGPIOD_INCLUDE_DIRS} + ) + + target_link_libraries(libnfc_nci + PRIVATE + ${LIBGPIOD_LIBRARIES} + ) +endif() + # # examples # @@ -312,6 +337,10 @@ if (LIBNFCNCI_INSTALL) NAMESPACE libnfc_nci ADDITIONAL_CONTENT "find_dependency(Threads)" + "set(LIBNFCNCI_LIBGPIOD @LIBNFCNCI_LIBGPIOD@)" + "if(LIBNFCNCI_LIBGPIOD)" + " find_dependency(PkgConfig)" + " pkg_search_module(LIBGPIOD REQUIRED libgpiodcxx)" + "endif()" ) endif() - diff --git a/conf/libnfc-nxp.conf b/conf/libnfc-nxp.conf old mode 100755 new mode 100644 index 1d0a16c..e581e00 --- a/conf/libnfc-nxp.conf +++ b/conf/libnfc-nxp.conf @@ -29,19 +29,32 @@ NXPLOG_FWDNLD_LOGLEVEL=0x00 NXPLOG_TML_LOGLEVEL=0x00 ############################################################################### # TRANSPORT Type -# 0x00 - I2C /SPI for noraml nxpnfc driver +# 0x00 - I2C / SPI for normal nxpnfc driver # 0x01 - Not Used, kept to align with Android code -# 0x02 - ALT_I2C -# 0x03 - ALT_SPI +# 0x02 - ALT_I2C: standard I2C Linux interface +# 0x03 - ALT_SPI: standard SPIDEV Linux interface NXP_TRANSPORT=0x02 ############################################################################### -# Nfc Device Node name +# Nfc Device Node name (only used for NXP_TRANSPORT=0x00) NXP_NFC_DEV_NODE="/dev/nxpnfc" ############################################################################### # ALT_I2C/SPI Interface Configuration # [PINs defined as GPIO23/24/25 on RPi4 (choose 594, 595, 596 for RPi5)] +# +# Integer numbers are used for Linux' deprecated sysfs GPIO interface. When +# the library is built against libgpiod, then use GPIO line names. Prefixing +# a line name with '!' signals libgpiod that the line should be handled with +# ACTIVE_LOW semantic. In the following example, however, the 'reset pin' +# has inverted logic and give thus 'enable' functionality without the need +# to mark it as active-low. +# +# Example: +# PIN_INT="RFID_IRQ" +# PIN_ENABLE="nRESET_RFID" +# PIN_FWDNLD="RFID_DWL_REQ" +# PIN_INT=535 PIN_ENABLE=536 PIN_FWDNLD=537 diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc index ce53c99..7c182af 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc @@ -38,6 +38,10 @@ #include #include #include "phNxpNciHal_utils.h" +#include +#include +#include +#include #define CRC_LEN 2 #define NORMAL_MODE_HEADER_LEN 3 @@ -193,6 +197,18 @@ int NfccAltTransport::SemTimedWait() { ** *******************************************************************************/ int NfccAltTransport::GetIrqState(void* pDevHandle) { + (void)pDevHandle; + +#ifdef USE_LIBGPIOD + if (m_GpioDInUse) { + return GetIrqStateLibGpioD(); + } +#endif + + return GetIrqStateSysFS(); +} + +int NfccAltTransport::GetIrqStateSysFS() { int ret = -1; NXPLOG_TML_D("%s Enter", __func__); @@ -335,7 +351,16 @@ int NfccAltTransport::verifyPin(int pin, int isoutput, int edge) { } return (0); } + void NfccAltTransport::gpio_set_ven(int value) { +#ifdef USE_LIBGPIOD + if (m_GpioDInUse) { + SetGpioDPin(*mEnableLineRequest, "Enable", value); + usleep(10 * 1000); + return; + } +#endif + if (iEnableFd >= 0) { if (value == 0) { write(iEnableFd, "0", 1); @@ -347,6 +372,14 @@ void NfccAltTransport::gpio_set_ven(int value) { } void NfccAltTransport::gpio_set_fwdl(int value) { +#ifdef USE_LIBGPIOD + if (m_GpioDInUse) { + SetGpioDPin(*mFWDownloadLineRequest, "FW DL", value); + usleep(10 * 1000); + return; + } +#endif + if (iFwDnldFd >= 0) { if (value == 0) { write(iFwDnldFd, "0", 1); @@ -358,6 +391,20 @@ void NfccAltTransport::gpio_set_fwdl(int value) { } void NfccAltTransport::wait4interrupt(void) { +#ifdef USE_LIBGPIOD + if (m_GpioDInUse) { + gpiod::edge_event_buffer event_buffer(1); + + while (mIRQLineRequest->get_value(mIRQLineRequest->offsets()[0]) != gpiod::line::value::ACTIVE) { + // negative timeout -> sleep until an event is ready + mIRQLineRequest->wait_edge_events(std::chrono::nanoseconds{-1}); + mIRQLineRequest->read_edge_events(event_buffer, 1); + } + + return; + } +#endif + /* Open STREAMS device. */ struct pollfd fds[1]; fds[0].fd = iInterruptFd; @@ -386,6 +433,70 @@ void NfccAltTransport::wait4interrupt(void) { ****************************************************************************/ int NfccAltTransport::ConfigurePin() { +#ifdef USE_LIBGPIOD + NXPLOG_TML_D("ConfigurePin: compiled w/ libgpiod support"); +#else + NXPLOG_TML_D("ConfigurePin: compiled w/o libgpiod support"); +#endif +#ifdef USE_LIBGPIOD + char enable_linename[64]; + char fwdl_linename[64]; + char irq_linename[64]; + + // check whether all three config options are strings and only then try to + // acquire all via libgpiod, otherwise just fallback and let the old code + // handle errors + if (GetNxpStrValue(NAME_EXT_PIN_INT, irq_linename, sizeof(irq_linename)) && + GetNxpStrValue(NAME_EXT_PIN_ENABLE, enable_linename, sizeof(enable_linename)) && + GetNxpStrValue(NAME_EXT_PIN_FWDNLD, fwdl_linename, sizeof(fwdl_linename))) { + + try { + gpiod::line_settings line_settings; + line_settings.set_direction(gpiod::line::direction::OUTPUT); + line_settings.set_output_value(gpiod::line::value::INACTIVE); + + mEnableLineRequest = + std::make_unique(GetGpioDByName(enable_linename, "Enable", line_settings)); + } + catch (const std::runtime_error& e) { + NXPLOG_TML_E("ConfigurePin(Enable): %s", e.what()); + return NFCSTATUS_INVALID_DEVICE; + } + + try { + gpiod::line_settings line_settings; + line_settings.set_direction(gpiod::line::direction::OUTPUT); + line_settings.set_output_value(gpiod::line::value::INACTIVE); + + mFWDownloadLineRequest = + std::make_unique(GetGpioDByName(fwdl_linename, "FWDLReq", line_settings)); + } + catch (const std::runtime_error& e) { + NXPLOG_TML_E("ConfigurePin(FW DL Req): %s", e.what()); + mEnableLineRequest->release(); + return NFCSTATUS_INVALID_DEVICE; + } + + try { + gpiod::line_settings line_settings; + line_settings.set_direction(gpiod::line::direction::INPUT); + line_settings.set_edge_detection(gpiod::line::edge::RISING); + + mIRQLineRequest = + std::make_unique(GetGpioDByName(irq_linename, "IRQ", line_settings)); + } + catch (const std::runtime_error& e) { + NXPLOG_TML_E("ConfigurePin(IRQ): %s", e.what()); + mFWDownloadLineRequest->release(); + mEnableLineRequest->release(); + return NFCSTATUS_INVALID_DEVICE; + } + + m_GpioDInUse = true; + return NFCSTATUS_SUCCESS; + } +#endif + int pin_int = loadIntValueOrDefault(NAME_EXT_PIN_INT, DEFAULT_PIN_INT); int pin_ena = loadIntValueOrDefault(NAME_EXT_PIN_ENABLE, DEFAULT_PIN_ENABLE); int pin_fwd = loadIntValueOrDefault(NAME_EXT_PIN_FWDNLD, DEFAULT_PIN_FWDNLD); @@ -428,5 +539,67 @@ void NfccAltTransport::Close(void* pDevHandle) { close(iFwDnldFd); iFwDnldFd = -1; } +#ifdef USE_LIBGPIOD + if (m_GpioDInUse) { + mEnableLineRequest->release(); + mFWDownloadLineRequest->release(); + mIRQLineRequest->release(); + } +#endif NXPLOG_TML_D("%s exit", __func__); } + +#ifdef USE_LIBGPIOD + +gpiod::line_request NfccAltTransport::GetGpioLineByName(const std::string& name, + const std::string& consumer, + const gpiod::line_settings& settings) { + + for (const auto& entry : std::filesystem::directory_iterator("/dev/")) { + if (gpiod::is_gpiochip_device(entry.path())) { + gpiod::chip chip(entry.path()); + + auto offset = chip.get_line_offset_from_name(name); + if (offset >= 0) { + return chip + .prepare_request() + .set_consumer("libnfc-nci: " + consumer) + .add_line_settings(offset, settings) + .do_request(); + } + } + } + + throw std::runtime_error("No GPIO line with name '" + name + "' found."); +} + +gpiod::line_request NfccAltTransport::GetGpioDByName(const std::string& name, + const std::string& consumer, + gpiod::line_settings& line_settings) { + std::string line_name = name; + bool active_low = false; + + if (!line_name.empty() && line_name.front() == '!') { + active_low = true; + line_name.erase(0, 1); + } + + line_settings.set_active_low(active_low); + + return GetGpioLineByName(line_name, consumer, line_settings); +} + +int NfccAltTransport::GetIrqStateLibGpioD() { + return mIRQLineRequest->get_value(mIRQLineRequest->offsets()[0]) == gpiod::line::value::ACTIVE; +} + +void NfccAltTransport::SetGpioDPin(gpiod::line_request& lq, const char* line_descr, int value) { + try { + lq.set_value(lq.offsets()[0], value ? gpiod::line::value::ACTIVE : gpiod::line::value::INACTIVE); + } + catch (const std::runtime_error& e) { + NXPLOG_TML_E("SetGpioDPin(%s) to '%d' failed: %s\n", line_descr, value, e.what()); + } +} + +#endif // USE_LIBGPIOD diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h index 3900b82..c2f95cd 100755 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.h @@ -27,6 +27,10 @@ #include #include #include +#include +#ifdef USE_LIBGPIOD +#include +#endif #define EDGE_NONE 0 #define EDGE_RISING 1 @@ -137,4 +141,26 @@ class NfccAltTransport : public NfccTransport { ** Returns NFCSTATUS_SUCCESS - on Success/ -1 on Failure ****************************************************************************/ int ConfigurePin(); + + // flag whether libgpiod members are in use instead of deprecated + // file descriptors above + bool_t m_GpioDInUse{false}; + + int GetIrqStateSysFS(); + +#ifdef USE_LIBGPIOD + std::unique_ptr mEnableLineRequest; + std::unique_ptr mFWDownloadLineRequest; + std::unique_ptr mIRQLineRequest; + + gpiod::line_request GetGpioLineByName(const std::string& name, + const std::string& consumer, + const gpiod::line_settings& settings); + gpiod::line_request GetGpioDByName(const std::string& name, + const std::string& consumer, + gpiod::line_settings& settings); + int GetIrqStateLibGpioD(); + void SetGpioDPin(gpiod::line_request& lq, const char* line_descr, int value); +#endif + }; From e0ecbe703b206b245613bf6f879eae3eb8c587b1 Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Tue, 28 Apr 2026 16:59:34 +0200 Subject: [PATCH 09/15] nfc_cb_example: fix syntax error Signed-off-by: Michael Heimpold --- demoapp/nfc_cb_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demoapp/nfc_cb_example.cpp b/demoapp/nfc_cb_example.cpp index e034a01..4e435fa 100644 --- a/demoapp/nfc_cb_example.cpp +++ b/demoapp/nfc_cb_example.cpp @@ -40,7 +40,7 @@ NfcHandler::NfcHandler() { throw std::runtime_error("Only one global nfc handler instance allowed"); } - setConfigPath("../../build/dist/etc/everest/libnfc_config") + setConfigPath("../../build/dist/etc/everest/libnfc_config"); InitializeLogLevel(); From f2ba921f5e183de7d68311ce35dd7aadbda3b37c Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Tue, 28 Apr 2026 21:12:00 +0200 Subject: [PATCH 10/15] Fix stack smashing error during config parsing We need to pass the size of the target variable, not the size of the pointer to it. This is important on platforms where sizeof(pointer) != sizeof(int) Signed-off-by: Michael Heimpold --- src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp b/src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp index a2365dc..e824f61 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/utils/phNxpConfig.cpp @@ -1085,7 +1085,7 @@ extern "C" int GetNxpNumValue(const char* name, void* pValue, unsigned long len) *******************************************************************************/ extern "C" int loadIntValueOrDefault(const char* name, int default_value) { int value; - int isfound = GetNxpNumValue(name, &value, sizeof(&value)); + int isfound = GetNxpNumValue(name, &value, sizeof(value)); if (isfound > 0) { return value; } From 06ba11f9d18e1687d2c2fcbd536245bba2ea08eb Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Wed, 29 Apr 2026 17:31:18 +0200 Subject: [PATCH 11/15] README.md: mention libgpiod stuff Signed-off-by: Michael Heimpold --- README.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b151f56..749ef10 100755 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ The [original upstream source code](https://github.com/NXPNFCLinux/linux_libnfc- - Added CMakeLists.txt - Allow for runtime configuration of interface properties for alternative I²C/SPI interface - Allow configuration files to be in a custom path +- Added support for using GPIO line names via libgpiod ## Building @@ -51,6 +52,13 @@ cmake --install . ``` This will also install the configuration files into the expected folder. +### libgpiod + +Building against `libgpiod` can be enabled by passing the property `LIBNFCNCI_LIBGPIOD` set to `ON` to cmake. +By default, this is disabled. +Using libgpiod and GPIO line names should be the preferred way to access GPIO lines from user-space since +the older Linux' sysfs interface is deprecated since ages. + ## Runtime Configuration Runtime configuration (debug output levels, detailled NFC behaviour, interface specification) happens via the above-mentioned files. @@ -65,7 +73,6 @@ Relevant settings are: ``` NXP_TRANSPORT=0x02 -NXP_NFC_DEV_NODE="/dev/nxpnfc" PIN_INT=535 PIN_ENABLE=536 PIN_FWDNLD=537 @@ -74,6 +81,20 @@ I2C_BUS="/dev/i2c-1" SPI_BUS="/dev/spidev0.0" ``` +When compiled with libgpiod support, then instead of using integers for Linux' legacy sysfs interface, +it is possible to use GPIO line names. These are usually defined via Device Tree for your board. +Such line names must be enclosed in quotation marks to indicate that the configuration value is a string. +And it cannot be mixed: all pin configuration values needs to be GPIO line names. + +``` +NXP_TRANSPORT=0x02 +PIN_INT="RFID_IRQ" +PIN_ENABLE="nRESET_RFID" +PIN_FWDNLD="RFID_DWL_REQ" +I2C_ADDRESS=0x28 +I2C_BUS="/dev/i2c-1" +``` + --- From 9dccf5d2035692e5907782791afbd31dc5f4f8be Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Mon, 4 May 2026 16:36:11 +0200 Subject: [PATCH 12/15] libnfc-nxp.conf: improve/clarify libgpiod example This should make it more clear, that mixing is undefined behavior. Signed-off-by: Michael Heimpold --- conf/libnfc-nxp.conf | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/conf/libnfc-nxp.conf b/conf/libnfc-nxp.conf index e581e00..17a82bc 100644 --- a/conf/libnfc-nxp.conf +++ b/conf/libnfc-nxp.conf @@ -45,12 +45,14 @@ NXP_NFC_DEV_NODE="/dev/nxpnfc" # # Integer numbers are used for Linux' deprecated sysfs GPIO interface. When # the library is built against libgpiod, then use GPIO line names. Prefixing -# a line name with '!' signals libgpiod that the line should be handled with +# a line name with '!' signals to libgpiod that the line should be handled with # ACTIVE_LOW semantic. In the following example, however, the 'reset pin' -# has inverted logic and give thus 'enable' functionality without the need +# has inverted logic and gives thus 'enable' functionality without the need # to mark it as active-low. +# Note: Mixing plain integers and GPIO line names is not supported and results +# in undefined behavior. # -# Example: +# Example for GPIO line names usage: # PIN_INT="RFID_IRQ" # PIN_ENABLE="nRESET_RFID" # PIN_FWDNLD="RFID_DWL_REQ" From bb32183bd0399fa715107393b35610b47e6b54ab Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Mon, 4 May 2026 16:37:52 +0200 Subject: [PATCH 13/15] Don't use magic number and improve debug messages We can re-use kernel's maximum GPIO line name length here instead of a random hard-coded size. While at, improve the debug messages to support users when using the new feature. Signed-off-by: Michael Heimpold --- .../halimpl/tml/transport/NfccAltTransport.cc | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc index 7c182af..6ce94be 100644 --- a/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc +++ b/src/nfcandroid_nfc_hidlimpl/halimpl/tml/transport/NfccAltTransport.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -421,6 +422,9 @@ void NfccAltTransport::wait4interrupt(void) { } } +// use kernel's GPIO_MAX_NAME_SIZE (32 byte) plus potential '!' and plus trailing NUL byte +#define NFCCALTTRANSPORT_MAX_NAME_SIZE (GPIO_MAX_NAME_SIZE + 1 + 1) + /***************************************************************************** ** ** Function ConfigurePin @@ -439,17 +443,23 @@ int NfccAltTransport::ConfigurePin() NXPLOG_TML_D("ConfigurePin: compiled w/o libgpiod support"); #endif #ifdef USE_LIBGPIOD - char enable_linename[64]; - char fwdl_linename[64]; - char irq_linename[64]; + char enable_linename[NFCCALTTRANSPORT_MAX_NAME_SIZE]; + char fwdl_linename[NFCCALTTRANSPORT_MAX_NAME_SIZE]; + char irq_linename[NFCCALTTRANSPORT_MAX_NAME_SIZE]; + // check whether all three config options are strings and only then try to // acquire all via libgpiod, otherwise just fallback and let the old code // handle errors - if (GetNxpStrValue(NAME_EXT_PIN_INT, irq_linename, sizeof(irq_linename)) && - GetNxpStrValue(NAME_EXT_PIN_ENABLE, enable_linename, sizeof(enable_linename)) && - GetNxpStrValue(NAME_EXT_PIN_FWDNLD, fwdl_linename, sizeof(fwdl_linename))) { - + bool cfgstr_irq = GetNxpStrValue(NAME_EXT_PIN_INT, irq_linename, sizeof(irq_linename)); + bool cfgstr_enable = GetNxpStrValue(NAME_EXT_PIN_ENABLE, enable_linename, sizeof(enable_linename)); + bool cfgstr_fwdl = GetNxpStrValue(NAME_EXT_PIN_FWDNLD, fwdl_linename, sizeof(fwdl_linename)); + NXPLOG_TML_D("ConfigurePin: GPIO line names: %s=%d (%s), %s=%d (%s), %s=%d (%s)", + NAME_EXT_PIN_INT, cfgstr_irq, cfgstr_irq ? irq_linename : "", + NAME_EXT_PIN_ENABLE, cfgstr_enable, cfgstr_enable ? enable_linename : "", + NAME_EXT_PIN_FWDNLD, cfgstr_fwdl, cfgstr_fwdl ? fwdl_linename : ""); + + if (cfgstr_irq && cfgstr_enable && cfgstr_fwdl) { try { gpiod::line_settings line_settings; line_settings.set_direction(gpiod::line::direction::OUTPUT); From e44ceb9d8f981777be1acd38c089e6cd110e2cba Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Thu, 11 Jun 2026 16:24:29 +0200 Subject: [PATCH 14/15] Convert to proper shared library Signed-off-by: Michael Heimpold --- CMakeLists.txt | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 596078c..653b69d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ project(libnfcnci DESCRIPTION "NFC NCI library adapted for use with EVerest" LANGUAGES C CXX) +include(GNUInstallDirs) + find_package(everest-cmake 0.1 REQUIRED PATHS ../everest-cmake ) @@ -32,6 +34,14 @@ set (LIBNFCNCI_CONFIG_FILES conf/libnfc-nxp.conf ) +set(LIBNFCNCI_PUBLIC_HEADERS + src/include/linux_nfc_api.h + src/include/linux_nfc_api_compatibility.h + src/include/linux_nfc_factory_api.h +) + +set(LIBNFCNCI_SOVERSION 1) + set (LIBNFCNCI_SOURCES src/android/utility/base/file.cpp src/libnfc-utils/src/ConfigPathProvider.cc @@ -240,7 +250,7 @@ set (COMPILE_DEFINITIONS # # library target # -add_library(libnfc_nci) +add_library(libnfc_nci SHARED) add_library(libnfc_nci::libnfc_nci ALIAS libnfc_nci) target_sources(libnfc_nci @@ -275,6 +285,13 @@ target_link_libraries(libnfc_nci Threads::Threads ) +set_target_properties(libnfc_nci + PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${LIBNFCNCI_SOVERSION} + OUTPUT_NAME nfc_nci +) + if(LIBNFCNCI_LIBGPIOD) target_include_directories(libnfc_nci PRIVATE @@ -320,10 +337,14 @@ if (LIBNFCNCI_INSTALL) install( TARGETS libnfc_nci EXPORT libnfc_nci-targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) install( - DIRECTORY src/include/ + FILES ${LIBNFCNCI_PUBLIC_HEADERS} TYPE INCLUDE ) From ce5f6b2733b89c040f4fa9065e4a1d7e36e0327e Mon Sep 17 00:00:00 2001 From: Michael Heimpold Date: Fri, 12 Jun 2026 18:40:33 +0200 Subject: [PATCH 15/15] CMakeLists.txt: add target to install the test binaries Signed-off-by: Michael Heimpold --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 653b69d..f5fc2a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -317,6 +317,10 @@ if(LIBNFCNCI_BUILD_EXAMPLES) PRIVATE libnfc_nci ) + install( + TARGETS nfc_cb_example + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) add_executable(nfc_demo) target_sources(nfc_demo @@ -328,6 +332,10 @@ if(LIBNFCNCI_BUILD_EXAMPLES) PRIVATE libnfc_nci ) + install( + TARGETS nfc_demo + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) endif() #