 d92b0a82cc
			
		
	
	
		d92b0a82cc
		
			
		
	
	
	
	
		
			
			"A long time ago in a galaxy far, far away...." we started NFC subsystem refactoring. Starring: - @gornekich - NFC refactoring project lead, architect, senior developer - @gsurkov - architect, senior developer - @RebornedBrain - senior developer Supporting roles: - @skotopes, @DrZlo13, @hedger - general architecture advisors, code review - @Astrrra, @doomwastaken, @Hellitron, @ImagineVagon333 - quality assurance Special thanks: @bettse, @pcunning, @nxv, @noproto, @AloneLiberty and everyone else who has been helping us all this time and contributing valuable knowledges, ideas and source code.
		
			
				
	
	
		
			175 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|  * @file nfc_protocol.c
 | |
|  * @brief Main protocol hierarchy definitions.
 | |
|  *
 | |
|  * To reduce code duplication, all NFC protocols are described as a tree, whose
 | |
|  * structure is shown in the diagram below. The (Start) node is actually
 | |
|  * nonexistent and is there only for clarity.
 | |
|  *
 | |
|  * All its child protocols are considered base protocols, which in turn serve
 | |
|  * as parents to other, usually vendor-specific ones.
 | |
|  *
 | |
|  * ```
 | |
|  * **************************** Protocol tree structure ***************************
 | |
|  *
 | |
|  *                                                  (Start)
 | |
|  *                                                     |
 | |
|  *                            +------------------------+-----------+---------+------------+
 | |
|  *                            |                        |           |         |            |
 | |
|  *                       ISO14443-3A              ISO14443-3B    Felica  ISO15693-3    ST25TB
 | |
|  *                            |                        |                     |
 | |
|  *            +---------------+-------------+     ISO14443-4B              SLIX
 | |
|  *            |               |             |
 | |
|  *       ISO14443-4A   Mf Ultralight   Mf Classic
 | |
|  *            |
 | |
|  *       Mf Desfire
 | |
|  * ```
 | |
|  *
 | |
|  * When implementing a new protocol, its place in the tree must be determined first.
 | |
|  * If no appropriate base protocols exists, then it must be a base protocol itself.
 | |
|  *
 | |
|  * This file is to be modified upon adding a new protocol (see below).
 | |
|  *
 | |
|  */
 | |
| #include "nfc_protocol.h"
 | |
| 
 | |
| #include <furi/furi.h>
 | |
| 
 | |
| /**
 | |
|  * @brief Tree node describing a protocol.
 | |
|  *
 | |
|  * All base protocols (see above) have NfcProtocolInvalid
 | |
|  * in the parent_protocol field.
 | |
|  */
 | |
| typedef struct {
 | |
|     NfcProtocol parent_protocol; /**< Parent protocol identifier. */
 | |
|     size_t children_num; /** < Number of the child protocols. */
 | |
|     const NfcProtocol* children_protocol; /**< Pointer to an array of child protocol identifiers. */
 | |
| } NfcProtocolTreeNode;
 | |
| 
 | |
| /** List of ISO14443-3A child protocols. */
 | |
| static const NfcProtocol nfc_protocol_iso14443_3a_children_protocol[] = {
 | |
|     NfcProtocolIso14443_4a,
 | |
|     NfcProtocolMfUltralight,
 | |
| };
 | |
| 
 | |
| /** List of ISO14443-3B child protocols. */
 | |
| static const NfcProtocol nfc_protocol_iso14443_3b_children_protocol[] = {
 | |
|     NfcProtocolIso14443_4b,
 | |
| };
 | |
| 
 | |
| /** List of ISO14443-4A child protocols. */
 | |
| static const NfcProtocol nfc_protocol_iso14443_4a_children_protocol[] = {
 | |
|     NfcProtocolMfDesfire,
 | |
| };
 | |
| 
 | |
| /** List of ISO115693-3 child protocols. */
 | |
| static const NfcProtocol nfc_protocol_iso15693_3_children_protocol[] = {
 | |
|     NfcProtocolSlix,
 | |
| };
 | |
| 
 | |
| /* Add new child protocol lists here (if necessary) */
 | |
| 
 | |
| /**
 | |
|  * @brief Flattened description of the NFC protocol tree.
 | |
|  *
 | |
|  * When implementing a new protocol, add the node here under its
 | |
|  * own index defined in nfc_protocol.h.
 | |
|  *
 | |
|  * Additionally, if it has an already implemented protocol as a parent,
 | |
|  * add its identifier to its respective list of child protocols (see above).
 | |
|  */
 | |
| static const NfcProtocolTreeNode nfc_protocol_nodes[NfcProtocolNum] = {
 | |
|     [NfcProtocolIso14443_3a] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolInvalid,
 | |
|             .children_num = COUNT_OF(nfc_protocol_iso14443_3a_children_protocol),
 | |
|             .children_protocol = nfc_protocol_iso14443_3a_children_protocol,
 | |
|         },
 | |
|     [NfcProtocolIso14443_3b] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolInvalid,
 | |
|             .children_num = COUNT_OF(nfc_protocol_iso14443_3b_children_protocol),
 | |
|             .children_protocol = nfc_protocol_iso14443_3b_children_protocol,
 | |
|         },
 | |
|     [NfcProtocolIso14443_4a] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolIso14443_3a,
 | |
|             .children_num = COUNT_OF(nfc_protocol_iso14443_4a_children_protocol),
 | |
|             .children_protocol = nfc_protocol_iso14443_4a_children_protocol,
 | |
|         },
 | |
|     [NfcProtocolIso14443_4b] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolIso14443_3b,
 | |
|             .children_num = 0,
 | |
|             .children_protocol = NULL,
 | |
|         },
 | |
|     [NfcProtocolIso15693_3] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolInvalid,
 | |
|             .children_num = COUNT_OF(nfc_protocol_iso15693_3_children_protocol),
 | |
|             .children_protocol = nfc_protocol_iso15693_3_children_protocol,
 | |
|         },
 | |
|     [NfcProtocolFelica] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolInvalid,
 | |
|             .children_num = 0,
 | |
|             .children_protocol = NULL,
 | |
|         },
 | |
|     [NfcProtocolMfUltralight] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolIso14443_3a,
 | |
|             .children_num = 0,
 | |
|             .children_protocol = NULL,
 | |
|         },
 | |
|     [NfcProtocolMfClassic] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolIso14443_3a,
 | |
|             .children_num = 0,
 | |
|             .children_protocol = NULL,
 | |
|         },
 | |
|     [NfcProtocolMfDesfire] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolIso14443_4a,
 | |
|             .children_num = 0,
 | |
|             .children_protocol = NULL,
 | |
|         },
 | |
|     [NfcProtocolSlix] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolIso15693_3,
 | |
|             .children_num = 0,
 | |
|             .children_protocol = NULL,
 | |
|         },
 | |
|     [NfcProtocolSt25tb] =
 | |
|         {
 | |
|             .parent_protocol = NfcProtocolInvalid,
 | |
|             .children_num = 0,
 | |
|             .children_protocol = NULL,
 | |
|         },
 | |
|     /* Add new protocols here */
 | |
| };
 | |
| 
 | |
| NfcProtocol nfc_protocol_get_parent(NfcProtocol protocol) {
 | |
|     furi_assert(protocol < NfcProtocolNum);
 | |
| 
 | |
|     return nfc_protocol_nodes[protocol].parent_protocol;
 | |
| }
 | |
| 
 | |
| bool nfc_protocol_has_parent(NfcProtocol protocol, NfcProtocol parent_protocol) {
 | |
|     furi_assert(protocol < NfcProtocolNum);
 | |
|     furi_assert(parent_protocol < NfcProtocolNum);
 | |
| 
 | |
|     bool parent_found = false;
 | |
|     const NfcProtocolTreeNode* iter = &nfc_protocol_nodes[protocol];
 | |
| 
 | |
|     while(iter->parent_protocol != NfcProtocolInvalid) {
 | |
|         if(iter->parent_protocol == parent_protocol) {
 | |
|             parent_found = true;
 | |
|             break;
 | |
|         }
 | |
|         iter = &nfc_protocol_nodes[iter->parent_protocol];
 | |
|     }
 | |
| 
 | |
|     return parent_found;
 | |
| }
 |