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