Top-level NFC protocol definitions. More...
#include <stdbool.h>
Go to the source code of this file.
Enumerations | |
enum | NfcProtocol { NfcProtocolIso14443_3a , NfcProtocolIso14443_3b , NfcProtocolIso14443_4a , NfcProtocolIso14443_4b , NfcProtocolIso15693_3 , NfcProtocolFelica , NfcProtocolMfUltralight , NfcProtocolMfClassic , NfcProtocolMfPlus , NfcProtocolMfDesfire , NfcProtocolSlix , NfcProtocolSt25tb , NfcProtocolNum , NfcProtocolInvalid } |
Enumeration of all available NFC protocols. More... | |
Functions | |
NfcProtocol | nfc_protocol_get_parent (NfcProtocol protocol) |
Get the immediate parent of a specific protocol. | |
bool | nfc_protocol_has_parent (NfcProtocol protocol, NfcProtocol parent_protocol) |
Determine if a specific protocol has a parent on an arbitrary level. | |
Top-level NFC protocol definitions.
This file is to be modified upon adding a new protocol (see below).
Having proper protocol documentation would be ideal, although they are often available only for a fee, or given under an NDA. As an alternative, reading code from relevant open-source projects or notes gathered by means of reverse engineering will do.
Check whether the NFC technology required for the protocol is supported. If no support exists, adding the protocol may be problematic, since it is highly hardware-dependent.
Check whether the protocol to be implemented is built on top of some already supported protocol.
If the answer is "yes", then the protocol to be implemented is a child protocol. If no, then it will become a base protocol. Sometimes it will be necessary to implement both, e.g. when the target protocol is built on top of a base one, but the latter is currently not supported.
The recommended file structure for a protocol is as follows:
Additionally, an arbitrary amount of private protocol_name_*_i.h
header files may be created. Do not put implementation details in the regular header files, as they will be exposed in the public firmware API later on.
Filename | Explanation |
---|---|
protocol_name.h | Main protocol data structure and associated functions declarations. It is recommended to keep the former as opaque pointer. |
protocol_name.c | Implementations of functions declared in protocol_name.h . |
protocol_name_device_defs.h | Declarations for use by the NfcDevice library. See nfc_device_base_i.h for more info. |
protocol_name_poller.h | Protocol-specific poller and associated functions declarations. |
protocol_name_poller.c | Implementation of functions declared in protocol_name_poller.h . |
protocol_name_poller_defs.h | Declarations for use by the NfcPoller library. See nfc_poller_base.h for more info. |
protocol_name_listener.h | Protocol-specific listener and associated functions declarations. Optional, needed for emulation support. |
protocol_name_listener.c | Implementation of functions declared in protocol_name_listener.h . Optional, needed for emulation support. |
protocol_name_listener_defs.h | Declarations for use by the NfcListener library. See nfc_listener_base.h for more info. Optional, needed for emulation support. |
protocol_name_sync.h | Synchronous API declarations. (See below for sync API explanation). Optional. |
protocol_name_sync.c | Synchronous API implementation. Optional. |
A protocol data structure is what holds all data that can be possibly read from a card of a certain type. It may include a unique identifier (UID), configuration bytes and flags, built-in memory, and so on. Additionally, it must implement the NfcDevice interface so that it could be used by the firmware.
If the protocol being implemented is a child protocol, then its data must include a pointer to the parent protocol data structure. It is the protocol's responsibility to correctly create and delete the instance the pointer is pointing to.
A poller contains the functions necessary to successfully read a card of supported type. It must also implement a specific interface, namely described by the NfcPollerBase type.
Upon creation, a poller instance will receive either a pointer to the Nfc instance (if it's a base protocol), or a pointer to another poller instance (if it is a child protocol) as the alloc()
parameter.
A listener implementation is optional, needed only when emulation is required/possible.
Same considerations apply to the listener as for the poller. Additionally, upon creation it will receive an additional parameter in the form of a pointer to the matching protocol data structure, which will be used during emulation. The listener instance does not own this data and does not need to worry about its deletion.
Synchronous API does exaclty what it says – it provides a set of blocking functions for easier use of pollers. Instead of creating all necessary instances and setting up callbacks manually, it does it automatically, at the expense of some flexibility.
The most notable use of sync API is in the supported card plugins, so it's a good idea to implement it if such a plugin is to be implemented afterwards.
After completing the protocol, it must be registered within the NfcProtocol system in order for it to be usable.
nfc_protocol_nodes[]
array under the appropriate index.nfc_base_protocol_name_children_protocol[]
array.nfc_protocol_name_children_protocol[]
array with respective identifiers and register it in the protocol entry added in step 2.protocol_name_device_defs.h
and add a pointer to the protocol_name_device_defs
structure under the appropriate index.protocol_name_poller_defs.h
and add a pointer to the protocol_name_poller_defs
structure under the appropriate index.protocol_name.h
, protocol_name_poller.h
, and optionally, protocol_name_listener.h
and protocol_name_sync.h
into the SDK_HEADERS
list in the SConscript file. This will export the protocol's types and functions for use by the applications.It's about time to integrate the newly implemented protocol into the main NFC application. Without that, reading a card of this type would crash it.
After having done that, a supported card plugin may be implemented to take further advantage of the new protocol.
enum NfcProtocol |
NfcProtocol nfc_protocol_get_parent | ( | NfcProtocol | protocol | ) |
Get the immediate parent of a specific protocol.
[in] | protocol | identifier of the protocol in question. |
bool nfc_protocol_has_parent | ( | NfcProtocol | protocol, |
NfcProtocol | parent_protocol ) |
Determine if a specific protocol has a parent on an arbitrary level.
Unlike nfc_protocol_get_parent(), this function will traverse the full protocol hierarchy and check each parent node for the matching protocol type.
[in] | protocol | identifier of the protocol in question. |
[in] | parent_protocol | identifier of the parent protocol in question. |