 c00776ca22
			
		
	
	
		c00776ca22
		
			
		
	
	
	
	
		
			
			* drivers: expose st25r3916 driver API * nfc poller: add start with custom callback * mf classic: rework sync API with poller custom start * mf ultralight: rework sync API with poller custom start * iso14443_3a poller: remove unused col res state * nfc: rework nfc poller custom start * mf ultralight: rename sync API * mf classic: rename sync API * iso14443-3a: rename sync API * nfc: remove async prefix in internal functions * nfc: expose internal API * nfc: fix sync api include and docs * targets: fix f18 build * nfc: rework NfcGenericEventEx type * nfc poller: add documentation * iso14443-3a poller: add documentation * felica poller: add documentation * iso14443_3b poller: add documentation * so14443_4a poller: add documentation * iso14443_4b poller: add documentation * iso15693 poller: add documentation * slix poller: add documentation * mf desfire poller: add documentation * mf ultralight poller: fix API and add documentation * mf classic poller: add documentation Co-authored-by: あく <alleteam@gmail.com>
		
			
				
	
	
		
			220 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			220 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|  * @file nfc_protocol.h
 | |
|  * @brief Top-level NFC protocol definitions.
 | |
|  *
 | |
|  * This file is to be modified upon adding a new protocol (see below).
 | |
|  *
 | |
|  * # How to add a new NFC protocol
 | |
|  *
 | |
|  * ## 1. Gather information
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * ### 1.1 Technology
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * @see NfcTech for the enumeration of supported NFC technologies.
 | |
|  *
 | |
|  * ### 1.2 Base protocols
 | |
|  *
 | |
|  * Check whether the protocol to be implemented is built on top of some already supported protocol.
 | |
|  *
 | |
|  * @see NfcProtocol for the enumeration of supported NFC protocols.
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * ## 2. Create the files
 | |
|  *
 | |
|  * ### 2.1 Recommended file structure
 | |
|  *
 | |
|  * The recommended file structure for a protocol is as follows:
 | |
|  *
 | |
|  * ```text
 | |
|  * protocols
 | |
|  *     |
 | |
|  *     +- protocol_name
 | |
|  *             |
 | |
|  *             +- protocol_name.h
 | |
|  *             |
 | |
|  *             +- protocol_name.c
 | |
|  *             |
 | |
|  *             +- protocol_name_device_defs.h
 | |
|  *             |
 | |
|  *             +- protocol_name_poller.h
 | |
|  *             |
 | |
|  *             +- protocol_name_poller.c
 | |
|  *             |
 | |
|  *             +- protocol_name_poller_defs.h
 | |
|  *             |
 | |
|  *             .
 | |
|  *             . (files below are optional)
 | |
|  *             .
 | |
|  *             |
 | |
|  *             +- protocol_name_listener.h       |
 | |
|  *             |                                 |
 | |
|  *             +- protocol_name_listener.c       |- add for emulation support
 | |
|  *             |                                 |
 | |
|  *             +- protocol_name_listener_defs.h  |
 | |
|  *             |
 | |
|  *             +- protocol_name_sync.h           |
 | |
|  *             |                                 |- add for synchronous API support
 | |
|  *             +- protocol_name_sync.c           |
 | |
|  *             |
 | |
|  * ```
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * ### 2.2 File structure explanation
 | |
|  *
 | |
|  * | 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. |
 | |
|  *
 | |
|  * ## 3 Implement the code
 | |
|  *
 | |
|  * ### 3.1 Protocol data structure
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * @see nfc_device_base_i.h for the device interface description.
 | |
|  *
 | |
|  * @note It is strongly recommended to implement such a structure as an opaque type and access it via specialised methods only.
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * ### 3.2 Poller (reading functionality)
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * @see nfc_poller_base.h for the poller interface description.
 | |
|  *
 | |
|  * ### 3.3 Listener (emulation functionality)
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * @see nfc_listener_base.h for the listener interface description.
 | |
|  *
 | |
|  * ### 3.4 Synchronous API
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * ### 3.5 Registering the protocol
 | |
|  *
 | |
|  * After completing the protocol, it must be registered within the NfcProtocol system in order for it to be usable.
 | |
|  *
 | |
|  * 1. In nfc_protocol.h, add a new entry in the NfcProtocol enum in the form of NfcProtocolProtocolName.
 | |
|  * 2. In nfc_protocol.c, add a new entry in the `nfc_protocol_nodes[]` array under the appropriate index.
 | |
|  *  1. If it is a child protocol, register it as a child in the respective `nfc_base_protocol_name_children_protocol[]` array.
 | |
|  *  2. If the protocol has children on its own, create a `nfc_protocol_name_children_protocol[]` array
 | |
|  *     with respective identifiers and register it in the protocol entry added in step 2.
 | |
|  * 3. In nfc_device_defs.c, include `protocol_name_device_defs.h` and add a pointer to the
 | |
|  *    `protocol_name_device_defs` structure under the appropriate index.
 | |
|  * 4. In nfc_poller_defs.c, include `protocol_name_poller_defs.h` and add a pointer to the
 | |
|  *    `protocol_name_poller_defs` structure under the appropriate index.
 | |
|  * 5. (Optional) If emulation support was implemented, do the step 4, but for the listener.
 | |
|  * 6. Add `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.
 | |
|  * 7. Done!
 | |
|  *
 | |
|  * ## What's next?
 | |
|  *
 | |
|  * 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.
 | |
|  *
 | |
|  * @see nfc_protocol_support.h for more information on protocol integration.
 | |
|  *
 | |
|  * After having done that, a supported card plugin may be implemented to take further advantage of the new protocol.
 | |
|  *
 | |
|  * @see nfc_supported_card_plugin.h for more information on supported card plugins.
 | |
|  *
 | |
|  */
 | |
| #pragma once
 | |
| 
 | |
| #include <stdbool.h>
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| /**
 | |
|  * @brief Enumeration of all available NFC protocols.
 | |
|  *
 | |
|  * When implementing a new protocol, add its identifier before the
 | |
|  * NfcProtocolNum entry.
 | |
|  */
 | |
| typedef enum {
 | |
|     NfcProtocolIso14443_3a,
 | |
|     NfcProtocolIso14443_3b,
 | |
|     NfcProtocolIso14443_4a,
 | |
|     NfcProtocolIso14443_4b,
 | |
|     NfcProtocolIso15693_3,
 | |
|     NfcProtocolFelica,
 | |
|     NfcProtocolMfUltralight,
 | |
|     NfcProtocolMfClassic,
 | |
|     NfcProtocolMfDesfire,
 | |
|     NfcProtocolSlix,
 | |
|     NfcProtocolSt25tb,
 | |
|     /* Add new protocols here */
 | |
| 
 | |
|     NfcProtocolNum, /**< Special value representing the number of available protocols. */
 | |
| 
 | |
|     NfcProtocolInvalid, /**< Special value representing an invalid state. */
 | |
| } NfcProtocol;
 | |
| 
 | |
| /**
 | |
|  * @brief Get the immediate parent of a specific protocol.
 | |
|  *
 | |
|  * @param[in] protocol identifier of the protocol in question.
 | |
|  * @returns parent protocol identifier if it has one, or NfcProtocolInvalid otherwise.
 | |
|  */
 | |
| NfcProtocol nfc_protocol_get_parent(NfcProtocol protocol);
 | |
| 
 | |
| /**
 | |
|  * @brief 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.
 | |
|  *
 | |
|  * @param[in] protocol identifier of the protocol in question.
 | |
|  * @param[in] parent_protocol identifier of the parent protocol in question.
 | |
|  * @returns true if the parent of given type exists, false otherwise.
 | |
|  */
 | |
| bool nfc_protocol_has_parent(NfcProtocol protocol, NfcProtocol parent_protocol);
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 |