[FEATURE] Common ioctl API for Contactless (NFC&RFID) cards and readers
Is your feature request related to a problem? Please describe.
Currently NuttX has no common API for NFC/RFID cards and contactless readers (from now on referred as contactless). As result contactless drivers are not portable, hard to maintain and understand. Also the absence of documentation further complicates development.
Additionally, the PN532 driver is undocumented and in a broken state. Attempts to repair and extend its functionality have been challenging due to its current condition.
Describe the solution you'd like
To address these issues, I have been developing a common API for contactless devices, along with a new PN532 driver that adheres to this API. The API definition can be found here: NuttX Contactless IOCTL API
A flow diagram illustrating the design is shown below:
(Type A and Type B refers to two examples of card standards. Mifare type A and Mifare type B)
** --- Future --- **
This API does not contain all features for contactless. Currently it only supports passive reading of UIDs and card info data, which is the bare minimum nearly all card readers support. In the future features can be added to add a standard write() and read() implementation, for example to read and write card contents. Also commands can be added to allow different scan modes, such as communication between NFC scanners and card emulation.
** --- Usage example --- **
This is a test application using the API features that follows the flow diagram above. https://pastebin.com/sXzwUALk
** --- PN532 --- **
The PN532 driver has been completely rewritten (with future expansion in mind), as discussed in Issue #15942. However, this driver will be submitted in a separate PR after the new API is merged. As part of this transition, all legacy PN532 IOCTL commands will be removed. Maintaining backward compatibility would require significant effort, and given the state of the old driver, it is unlikely to have many active users.
Feedback and suggestions are highly welcome.
Describe alternatives you've considered
The alternative is to not create a common API and have individual drivers that are not portable. But regarding the way this common API is written is hopefully discussed in this issue.
Verification
- [x] I have verified before submitting the report.
could we use file_operations::poll callback instead POLL_STATUS for waiting result?
could we use file_operations::poll callback instead POLL_STATUS for waiting result?
Maybe yes. I thought these are more commonly used for read/ write operations? Also can it give various custom states?
Actually, the callback feature is very nice. I'll look into this and can change "poll status" to get status.
the benefit of poll is that a single thread could poll multiple fd at the same time, and it's hard to implement by POLL_STATUS ioctl.
That is interesting. Good suggestion thank you
I've realized that modern NFC reader ICs use firmwares with the NFC forum NCI interface. To get the specification for this NCI interface, you get hit by a 2000 dollar paywall. So, this is something I'm not excited to work with.
This proposition was made with the usage of NFC readers with on-chip firmware in mind, like the PN532. The PN532 does not use the NCI interface and the datasheet tells you everything you need to know.
As result, this API might not be very well suited for the future.
There is a way out of this situation. You can still often communicate with the cards directly, but you need to do all the parsing and controlling yourself. These protocols are quite standardized and well documented. I know the Flipper Zero does this.
However, this would require the API, or NuttX to require code to do all of this for you. Perhaps it is a good idea to create a common "in-between" driver or "sub system" for this.
@xiaoxiang781216 thoughts?
I am a bit blocked on this project because https://github.com/apache/nuttx/issues/16139 . Most of my development boards run on RP2040.
I need to find an alternative development board to connect this thing to.