1 /******************************************************************************
2  *
3  *  Copyright 2019 NXP
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 #pragma once
19 
20 /*include files*/
21 #include <phNfcStatus.h>
22 #include <phNfcTypes.h>
23 
24 #define NxpMfcReaderInstance (NxpMfcReader::getInstance())
25 
26 #define MAX_MFC_BUFF_SIZE 32
27 
28 #define MFC_4K_BLK128 128  /*Block number 128 for Mifare 4k */
29 #define MFC_SECTOR_NO32 32 /* Sector 32 for Mifare 4K*/
30 #define MFC_BYTES_PER_BLOCK 16
31 #define MFC_BLKS_PER_SECTOR (0x04)
32 
33 #define MFC_EXTN_ID_SIZE (0x01U)     /* Size of Mfc Req/Rsp Id */
34 #define MFC_EXTN_STATUS_SIZE (0x01U) /* Size of Mfc Resp Status Byte */
35 
36 #define MFC_AUTHKEYLEN 0x06 /* Authentication key length */
37 #define MFC_AUTHENTICATION_KEY                                                 \
38   (0x00U) /* Authentication key passed in extension                            \
39              command header of authentication command */
40 #define MFC_ENABLE_KEY_B (0x80U)
41 #define MFC_EMBEDDED_KEY (0x10)
42 #define MFC_NUM_OF_KEYS (0x03U)
43 #define MFC_KEY_SIZE (0x06U)
44 #define MFC_KEYS                                                               \
45   {                                                                            \
46     {0xA0, 0XA1, 0xA2, 0XA3, 0xA4, 0XA5},                                      \
47         {0xD3, 0XF7, 0xD3, 0XF7, 0xD3, 0XF7},                                  \
48         {0xFF, 0XFF, 0xFF, 0XFF, 0xFF, 0XFF},                                  \
49   } /* Key used during NDEF format */
50 
51 typedef enum MifareCmdList {
52   eMifareRaw = 0x00U,         /* This command performs raw transcations */
53   eMifareAuthentA = 0x60U,    /* This command performs an authentication with
54                                        KEY A for a sector. */
55   eMifareAuthentB = 0x61U,    /* This command performs an authentication with
56                                        KEY B for a sector. */
57   eMifareRead16 = 0x30U,      /* Read 16 Bytes from a Mifare Standard block */
58   eMifareRead = 0x30U,        /* Read Mifare Standard */
59   eMifareWrite16 = 0xA0U,     /* Write 16 Bytes to a Mifare Standard block */
60   eMifareWrite4 = 0xA2U,      /* Write 4 bytes. */
61   eMifareInc = 0xC1U,         /* Increment */
62   eMifareDec = 0xC0U,         /* Decrement */
63   eMifareTransfer = 0xB0U,    /* Transfer */
64   eMifareRestore = 0xC2U,     /* Restore.   */
65   eMifareReadSector = 0x38U,  /* Read Sector.   */
66   eMifareWriteSector = 0xA8U, /* Write Sector.   */
67 } MifareCmdList_t;
68 
69 /*
70  * Request Id for different commands
71  */
72 typedef enum MfcCmdReqId {
73   eMfRawDataXchgHdr = 0x10,   /* MF Raw Data Request from DH */
74   eMfWriteNReq = 0x31,        /* MF N bytes write request from DH */
75   eMfReadNReq = 0x32,         /* MF N bytes read request from DH */
76   eMfSectorSelReq = 0x33,     /* MF Block select request from DH */
77   eMfPlusProxCheckReq = 0x28, /* MF + Prox check request for NFCC from DH */
78   eMfcAuthReq = 0x40,         /* MFC Authentication request for NFCC from DH */
79   eInvalidReq                 /* Invalid ReqId */
80 } MfcCmdReqId_t;
81 
82 /*
83  * Response Ids for different command response
84  */
85 typedef enum MfcRespId {
86   eMfXchgDataRsp = 0x10,      /* DH gets Raw data from MF on successful req */
87   eMfWriteNRsp = 0x31,        /* DH gets write status */
88   eMfReadNRsp = 0x32,         /* DH gets N Bytes read from MF, if successful */
89   eMfSectorSelRsp = 0x33,     /* DH gets the Sector Select cmd status */
90   eMfPlusProxCheckRsp = 0x29, /* DH gets the MF+ Prox Check cmd status */
91   eMfcAuthRsp = 0x40,         /* DH gets the authenticate cmd status */
92   eInvalidRsp                 /* Invalid RspId */
93 } MfcRespId_t;
94 
95 typedef struct MfcTagCmdIntfData {
96   uint8_t byAddr;      /* Start address to perform operation*/
97   uint16_t sendBufLen; /* Holds the length of the received data. */
98   uint8_t sendBuf[MAX_MFC_BUFF_SIZE]; /*Holds the ack of some initial commands*/
99 } MfcTagCmdIntfData_t;
100 
101 class NxpMfcReader {
102 private:
103   MfcTagCmdIntfData_t mMfcTagCmdIntfData;
104   void BuildMfcCmd(uint8_t *pData, uint16_t *pLength);
105   void BuildAuthCmd();
106   void BuildReadCmd();
107   void BuildWrite16Cmd();
108   void BuildRawCmd();
109   void BuildIncDecCmd();
110   void CalcSectorAddress();
111   void AuthForWrite();
112   void SendIncDecRestoreCmdPart2(const uint8_t *mfcData);
113 
114 public:
115   int Write(uint16_t mfcDataLen, const uint8_t *pMfcData);
116   NFCSTATUS AnalyzeMfcResp(uint8_t *pBuff, uint16_t *pBufflen);
117   NFCSTATUS CheckMfcResponse(uint8_t *pTransceiveData,
118                              uint16_t transceiveDataLen);
119   static NxpMfcReader &getInstance();
120 };