• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2019-2020, 2022-2023 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 #include <semaphore.h>
24 
25 #define NxpMfcReaderInstance (NxpMfcReader::getInstance())
26 
27 #define MAX_MFC_BUFF_SIZE 300
28 #define MFC_TAG_INCR_DECR_CMD_PART1_LEN 5
29 #define MFC_TAG_INCR_DECR_CMD_PART2_LEN 4
30 
31 #define MFC_4K_BLK128 128  /*Block number 128 for Mifare 4k */
32 #define MFC_SECTOR_NO32 32 /* Sector 32 for Mifare 4K*/
33 #define MFC_BYTES_PER_BLOCK 16
34 #define MFC_BLKS_PER_SECTOR (0x04)
35 
36 #define MFC_EXTN_ID_SIZE (0x01U)     /* Size of Mfc Req/Rsp Id */
37 #define MFC_EXTN_STATUS_SIZE (0x01U) /* Size of Mfc Resp Status Byte */
38 
39 #define MFC_AUTHKEYLEN 0x06 /* Authentication key length */
40 #define MFC_AUTHENTICATION_KEY                      \
41   (0x00U) /* Authentication key passed in extension \
42              command header of authentication command */
43 #define MFC_ENABLE_KEY_B (0x80U)
44 #define MFC_EMBEDDED_KEY (0x10)
45 #define MFC_NUM_OF_KEYS (0x03U)
46 #define MFC_KEY_SIZE (0x06U)
47 #define MFC_KEYS                              \
48   {                                           \
49     {0xA0, 0XA1, 0xA2, 0XA3, 0xA4, 0XA5},     \
50         {0xD3, 0XF7, 0xD3, 0XF7, 0xD3, 0XF7}, \
51         {0xFF, 0XFF, 0xFF, 0XFF, 0xFF, 0XFF}, \
52   } /* Key used during NDEF format */
53 
54 typedef enum MifareCmdList {
55   eMifareRaw = 0x00U,         /* This command performs raw transcations */
56   eMifareAuthentA = 0x60U,    /* This command performs an authentication with
57                                        KEY A for a sector. */
58   eMifareAuthentB = 0x61U,    /* This command performs an authentication with
59                                        KEY B for a sector. */
60   eMifareRead16 = 0x30U,      /* Read 16 Bytes from a Mifare Standard block */
61   eMifareRead = 0x30U,        /* Read Mifare Standard */
62   eMifareWrite16 = 0xA0U,     /* Write 16 Bytes to a Mifare Standard block */
63   eMifareWrite4 = 0xA2U,      /* Write 4 bytes. */
64   eMifareInc = 0xC1U,         /* Increment */
65   eMifareDec = 0xC0U,         /* Decrement */
66   eMifareTransfer = 0xB0U,    /* Transfer */
67   eMifareRestore = 0xC2U,     /* Restore.   */
68   eMifareReadSector = 0x38U,  /* Read Sector.   */
69   eMifareWriteSector = 0xA8U, /* Write Sector.   */
70 } MifareCmdList_t;
71 
72 /*
73  * Request Id for different commands
74  */
75 typedef enum MfcCmdReqId {
76   eMfRawDataXchgHdr = 0x10,   /* MF Raw Data Request from DH */
77   eMfWriteNReq = 0x31,        /* MF N bytes write request from DH */
78   eMfReadNReq = 0x32,         /* MF N bytes read request from DH */
79   eMfSectorSelReq = 0x33,     /* MF Block select request from DH */
80   eMfPlusProxCheckReq = 0x28, /* MF + Prox check request for NFCC from DH */
81   eMfcAuthReq = 0x40,         /* MFC Authentication request for NFCC from DH */
82   eInvalidReq                 /* Invalid ReqId */
83 } MfcCmdReqId_t;
84 
85 /*
86  * Response Ids for different command response
87  */
88 typedef enum MfcRespId {
89   eMfXchgDataRsp = 0x10,      /* DH gets Raw data from MF on successful req */
90   eMfWriteNRsp = 0x31,        /* DH gets write status */
91   eMfReadNRsp = 0x32,         /* DH gets N Bytes read from MF, if successful */
92   eMfSectorSelRsp = 0x33,     /* DH gets the Sector Select cmd status */
93   eMfPlusProxCheckRsp = 0x29, /* DH gets the MF+ Prox Check cmd status */
94   eMfcAuthRsp = 0x40,         /* DH gets the authenticate cmd status */
95   eInvalidRsp                 /* Invalid RspId */
96 } MfcRespId_t;
97 
98 typedef struct MfcTagCmdIntfData {
99   uint8_t byAddr;      /* Start address to perform operation*/
100   uint16_t sendBufLen; /* Holds the length of the received data. */
101   uint8_t sendBuf[MAX_MFC_BUFF_SIZE]; /*Holds the ack of some initial commands*/
102 } MfcTagCmdIntfData_t;
103 
104 class NxpMfcReader {
105  private:
106   MfcTagCmdIntfData_t mMfcTagCmdIntfData;
107   sem_t mNacksem;
108   bool isAck;
109   void BuildMfcCmd(uint8_t* pData, uint16_t* pLength);
110   void BuildAuthCmd();
111   void BuildReadCmd();
112   void BuildWrite16Cmd();
113   void BuildRawCmd();
114   void BuildIncDecCmd();
115   void CalcSectorAddress();
116   void AuthForWrite();
117   void SendIncDecRestoreCmdPart2(uint16_t mfcDataLen, const uint8_t* mfcData);
118 
119  public:
120   int Write(uint16_t mfcDataLen, const uint8_t* pMfcData);
121   NFCSTATUS AnalyzeMfcResp(uint8_t* pBuff, uint16_t* pBufflen);
122   NFCSTATUS CheckMfcResponse(uint8_t* pTransceiveData,
123                              uint16_t transceiveDataLen);
124   void MfcNotifyOnAckReceived(uint8_t* buff);
125   NFCSTATUS MfcWaitForAck();
126   static NxpMfcReader& getInstance();
127   bool checkIsMFCIncDecRestore(uint8_t cmd);
128 };
129