| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| * NFC Ndef Mapping For Remote Devices. |
| * |
| */ |
| |
| #include <phFriNfc_MifStdFormat.h> |
| #include <phFriNfc_MifareStdMap.h> |
| #include <phNfcCompId.h> |
| #include <phNxpExtns_MifareStd.h> |
| |
| /**************** local methods used in this file only ************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_RdABlock(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_WrABlock(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_AuthSector(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd4k_H_CheckNdef(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd_H_fillAIDarray(phFriNfc_NdefMap_t* NdefMap); |
| static uint8_t phFriNfc_MifStd_H_GetSect(uint8_t BlockNumber); |
| static NFCSTATUS phFriNfc_MifStd_H_BlkChk(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_RdAcsBit(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ChkAcsBit(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ChkRdWr(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd_H_ChkNdefCmpltSects(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_RemainTLV(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* Flag, |
| uint8_t* Temp16Bytes); |
| static NFCSTATUS phFriNfc_MifStd_H_ChkIntLen(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_IntLenWioutNdef(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* Flag, |
| uint8_t* TempintBytes); |
| static uint8_t phFriNfc_MifStd_H_UpdateTLV(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_WriteNdefLen(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd_H_SetNdefBlkAuth(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd_H_RdWrReset(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_RdtoWrNdefLen(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_GetActCardLen(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ChkTLVs(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* CRFlag); |
| static NFCSTATUS phFriNfc_MifStd_H_GetNxtTLV(phFriNfc_NdefMap_t* NdefMap, |
| uint16_t* TempLength, |
| uint8_t* TL4bytesFlag); |
| static NFCSTATUS phFriNfc_MifStd_H_Chk16Bytes(phFriNfc_NdefMap_t* NdefMap, |
| uint16_t TempLength); |
| static NFCSTATUS phFriNfc_MifStd_H_ChkRemainTLVs(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* CRFlag, |
| uint8_t* NDEFFlag); |
| static void phFriNfc_MifStd_H_Complete(phFriNfc_NdefMap_t* NdefMap, |
| NFCSTATUS Result); |
| static void phFriNfc_MifStd_H_Get1kStTrail(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd_H_Get4kStTrail(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ProChkNdef(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ProAuth(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_Rd16Bytes(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t BlockNo); |
| static NFCSTATUS phFriNfc_MifStd_H_ProAcsBits(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_GPBChk(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ProStatNotValid(phFriNfc_NdefMap_t* NdefMap, |
| NFCSTATUS status); |
| static NFCSTATUS phFriNfc_MifStd_H_RdBeforeWr(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ProBytesToWr(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_fillSendBuf(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t Length); |
| static NFCSTATUS phFriNfc_MifStd_H_WrTLV(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ProWrTLV(phFriNfc_NdefMap_t* NdefMap); |
| static uint8_t phFriNfc_MifStd_H_UpdRemTLV(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd_H_fillTLV1(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd_H_fillTLV2(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_CallWrNdefLen(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_BlkChk_1(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd_H_fillTLV1_1(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd_H_fillTLV2_1(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_RdTLV(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ProRdTLV(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_WrTermTLV(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ProWrABlock(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_CallConnect(phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_CallDisCon(phFriNfc_NdefMap_t* NdefMap); |
| static void phFriNfc_MifStd1k_H_BlkChk(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t SectorID, uint8_t* callbreak); |
| static uint8_t phFriNfc_MifStd_H_GetSectorTrailerBlkNo(uint8_t SectorID); |
| static NFCSTATUS phFriNfc_MifStd_H_ProSectorTrailorAcsBits( |
| phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_WrSectorTrailorBlock( |
| phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MifStd_H_ProWrSectorTrailor( |
| phFriNfc_NdefMap_t* NdefMap); |
| static NFCSTATUS phFriNfc_MapTool_ChkSpcVer(const phFriNfc_NdefMap_t* NdefMap, |
| uint8_t VersionIndex) |
| __attribute__((unused)); |
| |
| /* Mifare Standard Mapping - Constants */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT1 \ |
| 0xA0 /* internal Authenticate Command for MAD Sector */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT2 \ |
| 0xA1 /* internal Authenticate Command for MAD Sector */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT3 \ |
| 0xA2 /* internal Authenticate Command for MAD Sector */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT4 \ |
| 0xA3 /* internal Authenticate Command for MAD Sector */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT5 \ |
| 0xA4 /* internal Authenticate Command for MAD Sector */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT6 \ |
| 0xA5 /* internal Authenticate Command for MAD Sector */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1 \ |
| 0xD3 /* internal Authenticate Command for NDEF Sectors 1 */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2 \ |
| 0xF7 /* internal Authenticate Command for NDEF Sectors 2 */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL2 \ |
| 0x03 /* internal Ndef Compliant command 1 */ |
| #define PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL1 \ |
| 0xE1 /* internal Ndef Compliant command 2 */ |
| |
| /* Enable access bits check for the MAD sector |
| #define ENABLE_ACS_BIT_CHK_FOR_MAD */ |
| |
| #define PH_FRINFC_NDEFMAP_MFUL_VAL0 0 |
| |
| /****************************************************************************** |
| * Function phFriNfc_MapTool_SetCardState |
| * |
| * Description This function sets the appropriate card state. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| NFCSTATUS phFriNfc_MapTool_SetCardState(phFriNfc_NdefMap_t* NdefMap, |
| uint32_t Length) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| if (Length == PH_FRINFC_NDEFMAP_MFUL_VAL0) { |
| /* As the NDEF LEN / TLV Len is Zero, irrespective of any state the card |
| shall be set to INITIALIZED STATE*/ |
| NdefMap->CardState = |
| (uint8_t)(((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY) || |
| (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID)) |
| ? PH_NDEFMAP_CARD_STATE_INVALID |
| : PH_NDEFMAP_CARD_STATE_INITIALIZED); |
| } else { |
| switch (NdefMap->CardState) { |
| case PH_NDEFMAP_CARD_STATE_INITIALIZED: |
| NdefMap->CardState = |
| (uint8_t)((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) |
| ? NdefMap->CardState |
| : PH_NDEFMAP_CARD_STATE_READ_WRITE); |
| break; |
| |
| case PH_NDEFMAP_CARD_STATE_READ_ONLY: |
| NdefMap->CardState = |
| (uint8_t)((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) |
| ? NdefMap->CardState |
| : PH_NDEFMAP_CARD_STATE_READ_ONLY); |
| break; |
| |
| case PH_NDEFMAP_CARD_STATE_READ_WRITE: |
| NdefMap->CardState = |
| (uint8_t)((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) |
| ? NdefMap->CardState |
| : PH_NDEFMAP_CARD_STATE_READ_WRITE); |
| if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) { |
| if (NdefMap->StdMifareContainer.ReadOnlySectorIndex && |
| NdefMap->StdMifareContainer.SectorTrailerBlockNo == |
| NdefMap->StdMifareContainer.currentBlock) { |
| NdefMap->CardState = |
| (uint8_t)((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) |
| ? NdefMap->CardState |
| : PH_NDEFMAP_CARD_STATE_READ_ONLY); |
| } |
| } |
| break; |
| |
| default: |
| NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| break; |
| } |
| } |
| Result = ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) |
| ? PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT) |
| : Result); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifareStdMap_H_Reset |
| * |
| * Description This function resets the component instance to the initial |
| * state and lets the component forget about the list of |
| * registered items. Moreover, the lower device is set. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| NFCSTATUS phFriNfc_MifareStdMap_H_Reset(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| uint8_t index = PH_FRINFC_MIFARESTD_VAL0; |
| |
| if (NdefMap == NULL) { |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } else { |
| /* Current Block stores the present block accessed in the card */ |
| NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_VAL0; |
| |
| for (index = PH_FRINFC_MIFARESTD_VAL0; |
| index < PH_FRINFC_NDEFMAP_MIFARESTD_ST15_BYTES; index++) { |
| /* internal buffer to store the odd bytes of length < 15 */ |
| NdefMap->StdMifareContainer.internalBuf[index] = PH_FRINFC_MIFARESTD_VAL0; |
| } |
| |
| for (index = 0; index < PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK; index++) { |
| /* aid buffer reset to non ndef compliant */ |
| NdefMap->StdMifareContainer.aid[index] = |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP; |
| } |
| |
| /* odd bytes length stored in the internal buffer */ |
| NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED; |
| |
| /* Flag to get that last few bytes are taken from the user buffer */ |
| NdefMap->StdMifareContainer.RemainingBufFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| /* Flag to find that the read/write operation has reached the end of the |
| card. Further reading/writing is not possible */ |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| PH_FRINFC_MIFARESTD_FLAG0; |
| |
| /* Flag to get that last few bytes are taken from the internal buffer */ |
| NdefMap->StdMifareContainer.internalBufFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| /* Authentication Flag for every sector */ |
| NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| /* Used in Check Ndef for storing the sector ID */ |
| NdefMap->StdMifareContainer.SectorIndex = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->StdMifareContainer.NdefBlocks = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->StdMifareContainer.NoOfNdefCompBlocks = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->StdMifareContainer.ReadAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.remSizeUpdFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->TLVStruct.prevLenByteValue = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->StdMifareContainer.remainingSize = PH_FRINFC_MIFARESTD_VAL0; |
| |
| NdefMap->StdMifareContainer.ReadNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.ChkNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.aidCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.ProprforumSectFlag = |
| PH_FRINFC_MIFARESTD_PROP_1ST_CONFIG; |
| |
| NdefMap->StdMifareContainer.ReadCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL1; |
| |
| NdefMap->StdMifareContainer.ChkNdefCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.TotalNoSectors = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->StdMifareContainer.SectorTrailerBlockNo = |
| PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| |
| return status; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifareStdMap_ChkNdef |
| * |
| * Description The function checks whether the peer device is NDEF |
| *compliant. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| NFCSTATUS phFriNfc_MifareStdMap_ChkNdef(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS status = NFCSTATUS_PENDING; |
| uint8_t atq, sak; |
| |
| if (NdefMap == NULL) { |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } else { |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE; |
| NdefMap->StdMifareContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF; |
| |
| /* Get the Select Response and Sense Response to get |
| the exact Card Type either Mifare 1k or 4k */ |
| sak = NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; |
| atq = NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0]; |
| |
| if (0x08 == (sak & 0x18)) { |
| /* Total Number of Blocks in Mifare 1k Card */ |
| NdefMap->StdMifareContainer.NoOfNdefCompBlocks = |
| PH_FRINFC_NDEFMAP_MIFARESTD_1KNDEF_COMPBLOCK; |
| NdefMap->StdMifareContainer.remainingSize = |
| ((NdefMap->CardType == PH_FRINFC_MIFARESTD_VAL0) |
| ? (PH_FRINFC_NDEFMAP_MIFARESTD_1KNDEF_COMPBLOCK * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES) |
| : NdefMap->StdMifareContainer.remainingSize); |
| NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD; |
| } else if (0x19 == (sak & 0x19)) { |
| /* Total Number of Blocks in Mifare 2k Card */ |
| NdefMap->StdMifareContainer.NoOfNdefCompBlocks = |
| PH_FRINFC_NDEFMAP_MIFARESTD_2KNDEF_COMPBLOCK; |
| NdefMap->StdMifareContainer.remainingSize = |
| ((NdefMap->CardType == PH_FRINFC_MIFARESTD_VAL0) |
| ? (PH_FRINFC_NDEFMAP_MIFARESTD_2KNDEF_COMPBLOCK * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES) |
| : NdefMap->StdMifareContainer.remainingSize); |
| NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD; |
| } else { |
| /* Total Number of Blocks in Mifare 4k Card */ |
| NdefMap->StdMifareContainer.NoOfNdefCompBlocks = |
| PH_FRINFC_NDEFMAP_MIFARESTD_4KNDEF_COMPBLOCK; |
| NdefMap->StdMifareContainer.remainingSize = |
| ((NdefMap->CardType == PH_FRINFC_MIFARESTD_VAL0) |
| ? (PH_FRINFC_NDEFMAP_MIFARESTD_4KNDEF_COMPBLOCK * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES) |
| : NdefMap->StdMifareContainer.remainingSize); |
| NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD; |
| } |
| |
| /* phFriNfc_MifareStdMap_ChkNdef should be called only |
| when currentBlock is 0 OR 64,65 and 66 (for Mifare 4k). |
| Otherwise return error */ |
| /* and also Check the Authentication Flag */ |
| if ((NdefMap->StdMifareContainer.currentBlock != 0) && |
| (NdefMap->StdMifareContainer.currentBlock != 1) && |
| (NdefMap->StdMifareContainer.currentBlock != 2) && |
| (NdefMap->StdMifareContainer.currentBlock != 64) && |
| (NdefMap->StdMifareContainer.currentBlock != 65) && |
| (NdefMap->StdMifareContainer.currentBlock != 66)) { |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } else if (NdefMap->StdMifareContainer.AuthDone == 0) { |
| /* Block 0 contains Manufacturer information and |
| also other informaton. So go for block 1 which |
| contains AIDs. Authenticating any of the block |
| in a sector, Authenticates the whole sector */ |
| if (NdefMap->StdMifareContainer.currentBlock == 0) { |
| NdefMap->StdMifareContainer.currentBlock = 1; |
| } |
| status = phFriNfc_MifStd_H_AuthSector(NdefMap); |
| } else { |
| /** |
| * Mifare 1k, sak = 0x08 atq = 0x04 |
| * Mifare 2k, sak = 0x19 atq = 0x02 |
| * Mifare 4k, sak = 0x18 atq = 0x02 |
| */ |
| if ((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) || |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) || |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) { |
| /* Change the state to Check Ndef Compliant */ |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_CHK_NDEF_COMP; |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE; |
| NdefMap->StdMifareContainer.ChkNdefFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| |
| NdefMap->MapCompletionInfo.CompletionRoutine = |
| phFriNfc_MifareStdMap_Process; |
| NdefMap->MapCompletionInfo.Context = NdefMap; |
| |
| NdefMap->Cmd.MfCmd = phHal_eMifareRead; |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| NdefMap->SendRecvBuf[0] = NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ; |
| |
| /* Call the Overlapped HAL Transceive function */ |
| status = phFriNfc_ExtnsTransceive( |
| NdefMap->pTransceiveInfo, NdefMap->Cmd, NdefMap->SendRecvBuf, |
| NdefMap->SendLength, NdefMap->SendRecvLength); |
| } else { |
| /* Since we have decided temporarily not to go |
| for any new error codes we are using |
| NFCSTATUS_INVALID_PARAMETER even though it is not |
| the relevant error code here TBD */ |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } |
| } |
| } |
| |
| return status; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifareStdMap_RdNdef |
| * |
| * Description The function initiates the reading of NDEF information from |
| * a Remote Device. It performs a reset of the state and starts |
| * the action (state machine). A periodic call of the |
| * phFriNfcNdefMap_Process has to be done once the action |
| * has been triggered. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| NFCSTATUS phFriNfc_MifareStdMap_RdNdef(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* PacketData, |
| uint32_t* PacketDataLength, |
| uint8_t Offset) { |
| NFCSTATUS status = NFCSTATUS_PENDING; |
| |
| NdefMap->ApduBufferSize = *PacketDataLength; |
| NdefMap->NumOfBytesRead = PacketDataLength; |
| *NdefMap->NumOfBytesRead = 0; |
| NdefMap->ApduBuffIndex = 0; |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; |
| NdefMap->StdMifareContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF; |
| |
| if ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) || |
| (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED)) { |
| /* Card state is not correct */ |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } else { |
| if ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || |
| (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE)) { |
| phFriNfc_MifStd_H_RdWrReset(NdefMap); |
| NdefMap->StdMifareContainer.ReadNdefFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| /* Offset = Current, but the read has reached the End of Card */ |
| if ((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && |
| (NdefMap->StdMifareContainer.ReadWriteCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1)) { |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); |
| } else { |
| NdefMap->Offset = |
| (((Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) && |
| (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE)) |
| ? PH_FRINFC_NDEFMAP_SEEK_BEGIN |
| : Offset); |
| status = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| if (status == NFCSTATUS_SUCCESS) { |
| NdefMap->ApduBuffer = PacketData; |
| |
| /* Read Operation in Progress */ |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| PH_FRINFC_MIFARESTD_FLAG0; |
| |
| /* Check Authentication Flag */ |
| status = |
| ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MifStd_H_RdABlock(NdefMap) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } |
| } |
| } |
| |
| return status; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifareStdMap_WrNdef |
| * |
| * Description The function initiates the writing of NDEF information to |
| * a Remote Device. It performs a reset of the state and starts |
| * the action (state machine). A periodic call of the |
| * phFriNfcNdefMap_Process has to be done once the action |
| * has been triggered. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| NFCSTATUS phFriNfc_MifareStdMap_WrNdef(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* PacketData, |
| uint32_t* PacketDataLength, |
| uint8_t Offset) { |
| NFCSTATUS status = NFCSTATUS_PENDING; |
| |
| NdefMap->ApduBuffer = PacketData; |
| NdefMap->ApduBufferSize = *PacketDataLength; |
| NdefMap->ApduBuffIndex = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->WrNdefPacketLength = PacketDataLength; |
| *NdefMap->WrNdefPacketLength = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; |
| NdefMap->StdMifareContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF; |
| |
| if ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) || |
| (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY)) { |
| /* Card state is not correct */ |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } else { |
| if ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || |
| (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE)) { |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.NdefTLVAuthFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.remainingSize = |
| (NdefMap->StdMifareContainer.NoOfNdefCompBlocks * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES); |
| NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_BLK4; |
| NdefMap->StdMifareContainer.NdefBlocks = PH_FRINFC_MIFARESTD_VAL1; |
| NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* This macro is added, to be compliant with the previous HAL 2.0 |
| For HAL 2.0, polling is done before writing data to the mifare |
| std (if the offset is BEGIN), because if an error is reported |
| during read or write and again write is called, the PN531 state is |
| unchanged (so write will fail), to bring the PN531 to the correct |
| state, polling is done. |
| Changed on 13th Jan 2009 |
| */ |
| NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->StdMifareContainer.FirstWriteFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| |
| if (((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && |
| (NdefMap->StdMifareContainer.ReadWriteCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1)) || |
| ((NdefMap->StdMifareContainer.PollFlag == PH_FRINFC_MIFARESTD_FLAG1) && |
| (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR))) { |
| /* Offset = Current, but the read has reached the End of Card */ |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); |
| } else { |
| NdefMap->Offset = |
| (((Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) && |
| (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE)) |
| ? PH_FRINFC_NDEFMAP_SEEK_BEGIN |
| : Offset); |
| NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; |
| status = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| PH_FRINFC_MIFARESTD_FLAG0; |
| if (status == NFCSTATUS_SUCCESS) { |
| if (NdefMap->StdMifareContainer.PollFlag == PH_FRINFC_MIFARESTD_FLAG1) { |
| /* if poll flag is set then call disconnect because the authentication |
| has failed so reactivation of card is required */ |
| status = phFriNfc_MifStd_H_CallDisCon(NdefMap); |
| } |
| /* Check Authentication Flag */ |
| else if (NdefMap->StdMifareContainer.AuthDone == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| status = ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) |
| ? phFriNfc_MifStd_H_RdBeforeWr(NdefMap) |
| : phFriNfc_MifStd_H_WrABlock(NdefMap)); |
| } else { |
| status = phFriNfc_MifStd_H_AuthSector(NdefMap); |
| } |
| } |
| } |
| } |
| |
| return status; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifareStdMap_Process |
| * |
| * Description This function is a Completion Routine, Processing function, |
| * needed to avoid long blocking. |
| * This function as a Completion Routine in order to be able |
| * to notify the component that an I/O has finished and data |
| * are ready to be processed. |
| |
| * Returns void |
| * |
| ******************************************************************************/ |
| void phFriNfc_MifareStdMap_Process(void* Context, NFCSTATUS Status) { |
| phFriNfc_NdefMap_t* NdefMap; |
| uint8_t NDEFFlag = 0, CRFlag = 0, Temp16Bytes = 0, i = 0; |
| |
| NdefMap = (phFriNfc_NdefMap_t*)Context; |
| |
| if ((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER)) { |
| switch (NdefMap->State) { |
| case PH_FRINFC_NDEFMAP_STATE_CHK_NDEF_COMP: |
| Status = phFriNfc_MifStd_H_ProChkNdef(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_READ: |
| /* Receive Length for read shall always be equal to 16 */ |
| if ((*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) && |
| (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize)) { |
| Temp16Bytes = PH_FRINFC_MIFARESTD_VAL0; |
| NDEFFlag = (uint8_t)PH_FRINFC_MIFARESTD_FLAG1; |
| if (NdefMap->TLVStruct.BytesRemainLinTLV != 0) { |
| NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* To read the remaining length (L) in TLV */ |
| Status = |
| phFriNfc_MifStd_H_RemainTLV(NdefMap, &NDEFFlag, &Temp16Bytes); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| } |
| |
| /* check the NDEFFlag is set. if this is not set, then |
| in the above RemainTLV function all the 16 bytes has been |
| read */ |
| } else { |
| Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_RECEIVE_LENGTH); |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_WRITE: |
| Status = phFriNfc_MifStd_H_ProWrABlock(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| /* Call Completion Routine if CR Flag is Set to 1 */ |
| if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) { |
| *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_AUTH: |
| NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| Status = phFriNfc_MifStd_H_ProAuth(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_RD_ACS_BIT: |
| Status = phFriNfc_MifStd_H_ProAcsBits(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_WR_NDEF_LEN: |
| if (NdefMap->StdMifareContainer.RdAfterWrFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| Status = phFriNfc_MifStd_H_CallWrNdefLen(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| } else { |
| /* Check this */ |
| if (NdefMap->StdMifareContainer.TempBlockNo == |
| NdefMap->StdMifareContainer.currentBlock) { |
| memcpy(NdefMap->StdMifareContainer.internalBuf, |
| NdefMap->StdMifareContainer.Buffer, |
| NdefMap->StdMifareContainer.internalLength); |
| } |
| *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; |
| NdefMap->StdMifareContainer.currentBlock = |
| NdefMap->StdMifareContainer.TempBlockNo; |
| NdefMap->CardState = (uint8_t)( |
| (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED) |
| ? PH_NDEFMAP_CARD_STATE_READ_WRITE |
| : NdefMap->CardState); |
| CRFlag = (uint8_t)PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_RD_TO_WR_NDEF_LEN: |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| Status = |
| PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST); |
| if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) { |
| /* Size of NdefMap->SendRecvBuf is set by phLibNfc_Gen_NdefMapReset to |
| * PH_LIBNFC_GEN_MAX_BUFFER */ |
| /* We don't have to check memory here */ |
| for (i = PH_FRINFC_MIFARESTD_BYTES_READ; i > 0; i--) { |
| NdefMap->SendRecvBuf[i] = NdefMap->SendRecvBuf[i - 1]; |
| } |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| NdefMap->StdMifareContainer.currentBlock; |
| Status = phFriNfc_MifStd_H_WriteNdefLen(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_GET_ACT_CARDSIZE: |
| NDEFFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| if (NdefMap->TLVStruct.NoLbytesinTLV > PH_FRINFC_MIFARESTD_VAL0) { |
| NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| Status = phFriNfc_MifStd_H_ChkRemainTLVs(NdefMap, &CRFlag, &NDEFFlag); |
| NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0; |
| } |
| if ((NDEFFlag == PH_FRINFC_MIFARESTD_FLAG1) && |
| (CRFlag != PH_FRINFC_MIFARESTD_FLAG1)) { |
| Status = phFriNfc_MifStd_H_ChkTLVs(NdefMap, &CRFlag); |
| } |
| if (((NdefMap->StdMifareContainer.ReadNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) || |
| (NdefMap->StdMifareContainer.WrNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1)) && |
| (Status != NFCSTATUS_PENDING)) { |
| NdefMap->StdMifareContainer.NFCforumSectFlag = |
| PH_FRINFC_MIFARESTD_FLAG1; |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* if the card state has changed to initialised and |
| read ndef is called then error is returned */ |
| if (((NdefMap->StdMifareContainer.WrNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY)) || |
| ((NdefMap->StdMifareContainer.ReadNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED))) { |
| Status = |
| PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| } |
| if (NdefMap->StdMifareContainer.AuthDone == |
| PH_FRINFC_MIFARESTD_FLAG0) { |
| Status = phFriNfc_MifStd_H_AuthSector(NdefMap); |
| } else { |
| Status = ((NdefMap->StdMifareContainer.ReadNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MifStd_H_RdTLV(NdefMap) |
| : phFriNfc_MifStd_H_RdBeforeWr(NdefMap)); |
| } |
| NdefMap->StdMifareContainer.ReadNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| |
| if (NdefMap->StdMifareContainer.ChkNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_RD_BEF_WR: |
| /* Read flag says that already part of TLV has been written */ |
| Status = phFriNfc_MifStd_H_ProBytesToWr(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_WR_TLV: |
| Status = phFriNfc_MifStd_H_ProWrTLV(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_RD_TLV: |
| Status = phFriNfc_MifStd_H_ProRdTLV(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_TERM_TLV: |
| phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap); |
| NdefMap->StdMifareContainer.currentBlock = |
| NdefMap->TLVStruct.NdefTLVBlock; |
| Status = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_DISCONNECT: |
| NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| Status = phFriNfc_MifStd_H_CallConnect(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_CONNECT: |
| if (NdefMap->StdMifareContainer.FirstReadFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| Status = phFriNfc_MifStd_H_AuthSector(NdefMap); |
| } else if ((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || |
| NdefMap->CardType == |
| PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) && |
| (NdefMap->StdMifareContainer.ReadOnlySectorIndex && |
| NdefMap->StdMifareContainer.SectorTrailerBlockNo == |
| NdefMap->StdMifareContainer.currentBlock)) { |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex = |
| PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.SectorTrailerBlockNo = |
| PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_FLAG0; |
| Status = NFCSTATUS_FAILED; |
| } else { |
| Status = |
| ((((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && |
| (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE)) || |
| (NdefMap->StdMifareContainer.WrLength > |
| PH_FRINFC_MIFARESTD_VAL0)) |
| ? phFriNfc_MifStd_H_ProStatNotValid(NdefMap, Status) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT: |
| Status = phFriNfc_MifStd_H_ProSectorTrailorAcsBits(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| if ((CRFlag == PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->StdMifareContainer.WriteAcsBitFlag == |
| PH_FRINFC_MIFARESTD_FLAG0)) { |
| Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_DEVICE_REQUEST); |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_STATE_WRITE_SEC: |
| /* Set flag for writing of Acs bit */ |
| NdefMap->StdMifareContainer.WriteAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| |
| /* The first NDEF sector is already made read only, |
| set card state to read only and proceed*/ |
| if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY) { |
| Status = phFriNfc_MapTool_SetCardState( |
| NdefMap, NdefMap->TLVStruct.BytesRemainLinTLV); |
| if (Status != NFCSTATUS_SUCCESS) { |
| CRFlag = (uint8_t)PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| } |
| |
| if (CRFlag != PH_FRINFC_MIFARESTD_FLAG1) { |
| Status = phFriNfc_MifStd_H_ProWrSectorTrailor(NdefMap); |
| CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| } |
| break; |
| |
| default: |
| Status = |
| PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST); |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| break; |
| } |
| } else if (NdefMap->State == PH_FRINFC_NDEFMAP_STATE_AUTH) { |
| NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| if (NdefMap->StdMifareContainer.FirstWriteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| NdefMap->StdMifareContainer.FirstWriteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.WrLength = |
| ((NdefMap->StdMifareContainer.NFCforumSectFlag == |
| PH_FRINFC_MIFARESTD_FLAG0) |
| ? PH_FRINFC_MIFARESTD_VAL1 |
| : NdefMap->StdMifareContainer.WrLength); |
| } |
| if (NdefMap->StdMifareContainer.WrLength == PH_FRINFC_MIFARESTD_VAL0) { |
| Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } else { |
| /* Authentication has failed */ |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; /* Call Completion Routine */ |
| Status = NFCSTATUS_FAILED; /* Update Status Flag */ |
| } |
| } else { |
| Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST); |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| /* Call Completion Routine if CR Flag is Set to 1 */ |
| if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) { |
| phFriNfc_MifStd_H_Complete(NdefMap, Status); |
| } |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_RdABlock |
| * |
| * Description This function is a Helper function for Mifare Std. It Reads |
| * a block from the card. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_RdABlock(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS status = NFCSTATUS_PENDING; |
| |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_READ; |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; |
| NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; |
| NdefMap->MapCompletionInfo.Context = NdefMap; |
| |
| if (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize) { |
| if (NdefMap->StdMifareContainer.internalLength > PH_FRINFC_MIFARESTD_VAL0) { |
| status = phFriNfc_MifStd_H_ChkIntLen(NdefMap); |
| } /* internal Length Check */ |
| else { |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ; |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| |
| NdefMap->Cmd.MfCmd = phHal_eMifareRead; |
| |
| /* Call the Overlapped HAL Transceive function */ |
| status = phFriNfc_ExtnsTransceive( |
| NdefMap->pTransceiveInfo, NdefMap->Cmd, NdefMap->SendRecvBuf, |
| NdefMap->SendLength, NdefMap->SendRecvLength); |
| } |
| } else { |
| /* Check for the Card Size */ |
| if ((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks - |
| NdefMap->StdMifareContainer.NdefBlocks) * |
| PH_FRINFC_MIFARESTD_BYTES_READ) == 0) || |
| (NdefMap->ApduBufferSize == NdefMap->ApduBuffIndex)) { |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| (uint8_t)((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks - |
| NdefMap->StdMifareContainer.NdefBlocks) * |
| PH_FRINFC_MIFARESTD_BYTES_READ) == 0) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; |
| status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS); |
| } else { |
| /* Error: The control should not ideally come here. Return Error. */ |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED); |
| } |
| } |
| |
| return status; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_WrABlock |
| * |
| * Description This function writes into a block of the card. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_WrABlock(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS status = NFCSTATUS_PENDING; |
| |
| uint16_t RemainingBytes = 0, BytesRemained = 0, index = 0; |
| uint8_t Temp16Bytes = 0; |
| |
| NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; |
| NdefMap->MapCompletionInfo.Context = NdefMap; |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; |
| |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WRITE; |
| |
| /* User Buffer Check */ |
| if (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize) { |
| RemainingBytes = |
| (((uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < |
| NdefMap->StdMifareContainer.remainingSize) |
| ? (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) |
| : NdefMap->StdMifareContainer.remainingSize); |
| |
| NdefMap->SendRecvBuf[0] = NdefMap->StdMifareContainer.currentBlock; |
| Temp16Bytes += PH_FRINFC_MIFARESTD_INC_1; |
| |
| /* Check for internal bytes */ |
| if (NdefMap->StdMifareContainer.internalLength > 0) { |
| /* copy the bytes previously written in the internal Buffer */ |
| memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]), |
| NdefMap->StdMifareContainer.internalBuf, |
| NdefMap->StdMifareContainer.internalLength); |
| |
| Temp16Bytes += (uint8_t)(NdefMap->StdMifareContainer.internalLength); |
| if (RemainingBytes >= (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)) { |
| /* Copy the Remaining bytes from the user buffer to make the send |
| data and length = 16 */ |
| memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]), NdefMap->ApduBuffer, |
| (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)); |
| |
| NdefMap->NumOfBytesWritten = |
| (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); |
| Temp16Bytes += (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); |
| *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1); |
| } else { |
| memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]), NdefMap->ApduBuffer, |
| RemainingBytes); |
| |
| NdefMap->StdMifareContainer.internalBufFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->NumOfBytesWritten = RemainingBytes; |
| Temp16Bytes += (uint8_t)(RemainingBytes); |
| *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1); |
| |
| BytesRemained = (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); |
| /* Pad empty bytes with Zeroes to complete 16 bytes*/ |
| for (index = 0; index < BytesRemained; index++) { |
| NdefMap->SendRecvBuf[(Temp16Bytes + index)] = |
| (uint8_t)((index == PH_FRINFC_MIFARESTD_VAL0) |
| ? PH_FRINFC_MIFARESTD_TERMTLV_T |
| : PH_FRINFC_MIFARESTD_NULLTLV_T); |
| NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| Temp16Bytes += (uint8_t)(BytesRemained); |
| } |
| } else { |
| if (RemainingBytes >= (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)) { |
| /* Bytes left to write < 16, copy remaining bytes */ |
| memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]), |
| &(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), |
| (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)); |
| |
| NdefMap->NumOfBytesWritten = |
| (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); |
| Temp16Bytes += (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); |
| *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1); |
| } else { |
| /* Bytes left to write < 16, copy remaining bytes */ |
| memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]), |
| &(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), RemainingBytes); |
| |
| NdefMap->StdMifareContainer.RemainingBufFlag = |
| PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->NumOfBytesWritten = RemainingBytes; |
| Temp16Bytes += (uint8_t)(RemainingBytes); |
| *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1); |
| |
| /* Pad empty bytes with Zeroes to complete 16 bytes */ |
| for (index = Temp16Bytes; index < MIFARE_MAX_SEND_BUF_TO_WRITE; |
| index++) { |
| NdefMap->SendRecvBuf[index] = |
| (uint8_t)((index == Temp16Bytes) ? PH_FRINFC_MIFARESTD_TERMTLV_T |
| : PH_FRINFC_MIFARESTD_NULLTLV_T); |
| |
| NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| } |
| } |
| /* Buffer to store 16 bytes which is writing to the present block */ |
| memcpy(NdefMap->StdMifareContainer.Buffer, |
| &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_INC_1]), |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES); |
| |
| /* Write from here */ |
| NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE; |
| NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| /* Call the Overlapped HAL Transceive function */ |
| status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd, |
| NdefMap->SendRecvBuf, NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| } else /* Check User Buffer */ |
| { |
| if (NdefMap->StdMifareContainer.NdefBlocks > |
| NdefMap->StdMifareContainer.NoOfNdefCompBlocks) { |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| PH_FRINFC_MIFARESTD_FLAG1; |
| status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS); |
| } else if (NdefMap->ApduBuffIndex == (uint16_t)NdefMap->ApduBufferSize) { |
| status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS); |
| } else { |
| /* Error: The control should not ideally come here. Return Error. */ |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED); |
| } |
| } |
| |
| return status; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_AuthSector |
| * |
| * Description This function authenticates one sector at a time. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_AuthSector(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS status = NFCSTATUS_PENDING; |
| |
| NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; |
| NdefMap->MapCompletionInfo.Context = NdefMap; |
| |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_AUTH; |
| |
| /* Authenticate */ |
| NdefMap->Cmd.MfCmd = phHal_eMifareAuthentA; |
| |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| ((NdefMap->TLVStruct.NdefTLVAuthFlag == PH_FRINFC_MIFARESTD_FLAG1) |
| ? NdefMap->TLVStruct.NdefTLVBlock |
| : NdefMap->StdMifareContainer.currentBlock); |
| |
| /* if MAD blocks then authentication key is |
| 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 else |
| 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 */ |
| if (((NdefMap->StdMifareContainer.currentBlock != |
| PH_FRINFC_MIFARESTD_MAD_BLK0) && |
| (NdefMap->StdMifareContainer.currentBlock != |
| PH_FRINFC_MIFARESTD_MAD_BLK1) && |
| (NdefMap->StdMifareContainer.currentBlock != |
| PH_FRINFC_MIFARESTD_MAD_BLK2) && |
| (NdefMap->StdMifareContainer.currentBlock != |
| PH_FRINFC_MIFARESTD_MAD_BLK64) && |
| (NdefMap->StdMifareContainer.currentBlock != |
| PH_FRINFC_MIFARESTD_MAD_BLK65) && |
| (NdefMap->StdMifareContainer.currentBlock != |
| PH_FRINFC_MIFARESTD_MAD_BLK66)) || |
| (NdefMap->TLVStruct.NdefTLVAuthFlag == |
| (uint8_t)PH_FRINFC_MIFARESTD_FLAG1)) { |
| NdefMap->SendRecvBuf[1] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ |
| NdefMap->SendRecvBuf[2] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ |
| NdefMap->SendRecvBuf[3] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ |
| NdefMap->SendRecvBuf[4] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ |
| NdefMap->SendRecvBuf[5] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ |
| NdefMap->SendRecvBuf[6] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ |
| } else { |
| NdefMap->SendRecvBuf[1] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT1; /* 0xA0 */ |
| NdefMap->SendRecvBuf[2] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT2; /* 0xA1 */ |
| NdefMap->SendRecvBuf[3] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT3; /* 0xA2 */ |
| NdefMap->SendRecvBuf[4] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT4; /* 0xA3 */ |
| NdefMap->SendRecvBuf[5] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT5; /* 0xA4 */ |
| NdefMap->SendRecvBuf[6] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT6; /* 0xA5 */ |
| } |
| |
| if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) { |
| if (NdefMap->StdMifareContainer.ReadOnlySectorIndex && |
| NdefMap->StdMifareContainer.SectorTrailerBlockNo == |
| NdefMap->StdMifareContainer.currentBlock) { |
| memcpy(&NdefMap->SendRecvBuf[1], |
| &NdefMap->StdMifareContainer.UserScrtKeyB[0], |
| PH_FRINFC_MIFARESTD_KEY_LEN); |
| |
| /* Authenticate with KeyB */ |
| NdefMap->Cmd.MfCmd = phHal_eMifareAuthentB; |
| } |
| } |
| |
| NdefMap->SendLength = MIFARE_AUTHENTICATE_CMD_LENGTH; |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| /* Call the Overlapped HAL Transceive function */ |
| status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd, |
| NdefMap->SendRecvBuf, NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| |
| return status; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_Complete |
| * |
| * Description It is used to call the Completion Routine |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_Complete(phFriNfc_NdefMap_t* NdefMap, |
| NFCSTATUS Result) { |
| /* set the state back to the Reset_Init state */ |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT; |
| |
| /* set the completion routine */ |
| NdefMap->CompletionRoutine[NdefMap->StdMifareContainer.CRIndex] |
| .CompletionRoutine(NdefMap->CompletionRoutine->Context, Result); |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd4k_H_CheckNdef |
| * |
| * Description This function is used for Mifare 4k Check Ndef to |
| * get the next AID blocks. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd4k_H_CheckNdef(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| /* Get the AID Block */ |
| if (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK2) { |
| NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_MAD_BLK64; |
| NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; |
| } else if (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK64) { |
| NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_MAD_BLK65; |
| } else { |
| NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_MAD_BLK66; |
| } |
| |
| Result = phFriNfc_MifareStdMap_ChkNdef(NdefMap); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_fillAIDarray |
| * |
| * Description This function storew the AIDs for check ndef. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_fillAIDarray(phFriNfc_NdefMap_t* NdefMap) { |
| uint8_t byteindex = 0; |
| |
| if ((NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK1) || |
| (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK64)) { |
| /* The First Two Bytes in Receive Buffer |
| are CRC bytes so it is not copied |
| instead, 0 is copied in AID[0] & AID[1] */ |
| NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.SectorIndex] = |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP; |
| NdefMap->StdMifareContainer.SectorIndex++; |
| byteindex = 2; |
| } |
| |
| while (byteindex < PH_FRINFC_MIFARESTD_BYTES_READ) { |
| if ((NdefMap->SendRecvBuf[byteindex] == |
| PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL2) && |
| (NdefMap->SendRecvBuf[(byteindex + 1)] == |
| PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL1)) { |
| /* This flag is set when a NFC forum sector is found in a |
| MAD block for the first time */ |
| NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.SectorIndex] = |
| PH_FRINFC_MIFARESTD_NDEF_COMP; |
| NdefMap->StdMifareContainer.SectorIndex++; |
| } else { |
| NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.SectorIndex] = |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP; |
| NdefMap->StdMifareContainer.SectorIndex++; |
| /* AID complete flag is set when a non NFC forum sector is found in a |
| MAD block after the NFC forum sector. After setting this, all other |
| values are ignored and are NOT NDEF compliant */ |
| NdefMap->StdMifareContainer.aidCompleteFlag = |
| ((NdefMap->StdMifareContainer.NFCforumSectFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| if (NdefMap->StdMifareContainer.aidCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| break; |
| } |
| } |
| byteindex += 2; |
| } |
| |
| /* If "aidCompleteFlag" is set then the remaining sectors are made NOT |
| NDEF compliant */ |
| if ((NdefMap->StdMifareContainer.aidCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) { |
| /* for Mifare 1k there are 16 sectors, till this number all sectors |
| are made NOT NDEF compliant */ |
| for (byteindex = NdefMap->StdMifareContainer.SectorIndex; |
| byteindex < PH_FRINFC_MIFARESTD1K_TOTAL_SECTOR; byteindex++) { |
| NdefMap->StdMifareContainer.aid[byteindex] = |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP; |
| } |
| } else if ((NdefMap->StdMifareContainer.aidCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) { |
| /* for Mifare 2k there are 32 sectors, till this number all sectors |
| are made NOT NDEF compliant */ |
| for (byteindex = NdefMap->StdMifareContainer.SectorIndex; |
| byteindex < PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR; byteindex++) { |
| NdefMap->StdMifareContainer.aid[byteindex] = |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP; |
| } |
| } else { |
| /* for Mifare 4k there are 40 sectors, till this number all sectors |
| are made NOT NDEF compliant */ |
| if ((NdefMap->StdMifareContainer.aidCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)) { |
| for (byteindex = NdefMap->StdMifareContainer.SectorIndex; |
| byteindex < PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR; byteindex++) { |
| NdefMap->StdMifareContainer.aid[byteindex] = |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP; |
| } |
| } |
| } |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_BlkChk |
| * |
| * Description This function is to check the Ndef compliance of the |
| * current block, if the block is not Ndef Compliant, |
| * increment the block till the next Ndef compliant block |
| * using the Get Sector Helper function |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_BlkChk(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint8_t SectorID = 0, callbreak = 0; |
| |
| for (;;) { |
| /* Get a Sector ID for the Current Block */ |
| SectorID = |
| phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock); |
| /* Check the card Type 1k or 4k */ |
| /* enter if Mifare 1k card. For Mifare 4k go to else */ |
| if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) { |
| /* if Sector Id > 15 No Sectors to write */ |
| if (SectorID > 15) { |
| SectorID = |
| phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock); |
| /*Error: No Ndef Compliant Sectors present */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| callbreak = 1; |
| } else { |
| phFriNfc_MifStd1k_H_BlkChk(NdefMap, SectorID, &callbreak); |
| } |
| } /* End of if */ /* End of Mifare 1k check */ |
| else if (NdefMap->CardType == |
| PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) /* Mifare 2k check starts |
| here */ |
| { |
| /* Sector > 39 no ndef compliant sectors found*/ |
| if (SectorID > PH_FRINFC_MIFARESTD_SECTOR_NO31) { |
| /*Error: No Ndef Compliant Sectors present */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| callbreak = 1; |
| } else if (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK64) { |
| NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; |
| } else if (SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32) /* sector < 32 |
| contains 4 |
| blocks in each |
| sector */ |
| { |
| /* If the block checked is 63, the 3 blocks after this |
| are AID(MAD) blocks so its need to be skipped */ |
| if (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK63) { |
| NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; |
| } else { |
| phFriNfc_MifStd1k_H_BlkChk(NdefMap, SectorID, &callbreak); |
| } |
| } else { |
| phFriNfc_MifStd1k_H_BlkChk(NdefMap, SectorID, &callbreak); |
| } |
| } /* End of if*/ /* End of Mifare 2k check*/ |
| else /* Mifare 4k check starts here */ |
| { |
| /* Sector > 39 no ndef compliant sectors found*/ |
| if (SectorID > PH_FRINFC_MIFARESTD_SECTOR_NO39) { |
| /*Error: No Ndef Compliant Sectors present */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| callbreak = 1; |
| } else if (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK64) { |
| NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; |
| } else if (SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32) /* sector < 32 |
| contains 4 |
| blocks in each |
| sector */ |
| { |
| /* If the block checked is 63, the 3 blocks after this |
| are AID(MAD) blocks so its need to be skipped */ |
| if (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK63) { |
| NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; |
| } else { |
| phFriNfc_MifStd1k_H_BlkChk(NdefMap, SectorID, &callbreak); |
| } |
| } else { |
| /* every last block of a sector needs to be skipped */ |
| if (((NdefMap->StdMifareContainer.currentBlock + 1) % |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES) == 0) { |
| NdefMap->StdMifareContainer.currentBlock++; |
| } else { |
| if (NdefMap->StdMifareContainer.aid[SectorID] == |
| PH_FRINFC_MIFARESTD_NDEF_COMP) { |
| /* Check whether the block is first block of a (next)new sector and |
| also check if it is first block then internal length is zero |
| or not. Because once Authentication is done for the sector again |
| we should not authenticate it again */ |
| /* In this case 32 sectors contains 4 blocks and next remaining 8 |
| sectors contains 16 blocks that is why (32 * 4) + (sectorID - 32) |
| *16*/ |
| if ((NdefMap->StdMifareContainer.currentBlock == |
| ((PH_FRINFC_MIFARESTD_SECTOR_NO32 * PH_FRINFC_MIFARESTD_BLK4) + |
| ((SectorID - PH_FRINFC_MIFARESTD_SECTOR_NO32) * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES))) && |
| (NdefMap->StdMifareContainer.internalLength == 0)) { |
| NdefMap->StdMifareContainer.AuthDone = 0; |
| } |
| callbreak = 1; |
| } else { |
| NdefMap->StdMifareContainer.currentBlock += 16; |
| } |
| } |
| } |
| } |
| if (callbreak == 1) { |
| break; |
| } |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_GetSect |
| * |
| * Description This function to get the Sector from the current block |
| * |
| * Returns uint8_t SectorID |
| * |
| ******************************************************************************/ |
| static uint8_t phFriNfc_MifStd_H_GetSect(uint8_t BlockNumber) { |
| uint8_t SectorID = 0; |
| |
| if (BlockNumber >= PH_FRINFC_MIFARESTD4K_BLK128) { |
| SectorID = (uint8_t)(PH_FRINFC_MIFARESTD_SECTOR_NO32 + |
| ((BlockNumber - PH_FRINFC_MIFARESTD4K_BLK128) / |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES)); |
| } else { |
| SectorID = (BlockNumber / PH_FRINFC_MIFARESTD_BLK4); |
| } |
| |
| return SectorID; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_RdAcsBit |
| * |
| * Description It read the access bits of each sector. |
| * NCI messages. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_RdAcsBit(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_ACS_BIT; |
| |
| if (NdefMap->StdMifareContainer.ReadOnlySectorIndex && |
| NdefMap->StdMifareContainer.currentBlock == |
| NdefMap->StdMifareContainer.SectorTrailerBlockNo) { |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT; |
| } |
| |
| if (NdefMap->StdMifareContainer.ReadAcsBitFlag == PH_FRINFC_MIFARESTD_FLAG1) { |
| /* Get the sector trailer */ |
| ((NdefMap->StdMifareContainer.currentBlock > 127) |
| ? phFriNfc_MifStd_H_Get4kStTrail(NdefMap) |
| : phFriNfc_MifStd_H_Get1kStTrail(NdefMap)); |
| } else { |
| /* Give the current block to read */ |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| NdefMap->StdMifareContainer.currentBlock; |
| } |
| |
| Result = phFriNfc_MifStd_H_Rd16Bytes( |
| NdefMap, NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0]); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ChkAcsBit |
| * |
| * Description This function check the access bits of each sector. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ChkAcsBit(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| /* Blocks from 0 to 3 and from 64 to 67(MAD blocks) */ |
| if ((NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK0) || |
| (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK1) || |
| (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK2) || |
| (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK3) || |
| (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK64) || |
| (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK65) || |
| (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK66)) { |
| /* Access bits check removed for the MAD blocks */ |
| #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD |
| |
| if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL6] & |
| PH_FRINFC_MIFARESTD_MASK_FF) == |
| PH_FRINFC_MIFARESTD_MADSECT_ACS_BYTE6) && |
| ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL7] & |
| PH_FRINFC_MIFARESTD_MASK_FF) == |
| PH_FRINFC_MIFARESTD_MADSECT_ACS_BYTE7) && |
| ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL8] & |
| PH_FRINFC_MIFARESTD_MASK_FF) == PH_FRINFC_MIFARESTD_ACS_BYTE8)) { |
| NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } else { |
| NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| |
| #else /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ |
| |
| NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED; |
| |
| #endif /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ |
| } else { |
| /* Check for Access bytes 6, 7 and 8 value = |
| 0x7F, 0x07, 0x88 NFC forum sectors*/ |
| if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL6] & |
| PH_FRINFC_MIFARESTD_MASK_FF) == |
| PH_FRINFC_MIFARESTD_NFCSECT_ACS_BYTE6) && |
| ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL7] & |
| PH_FRINFC_MIFARESTD_MASK_FF) == |
| PH_FRINFC_MIFARESTD_NFCSECT_ACS_BYTE7) && |
| ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL8] & |
| PH_FRINFC_MIFARESTD_MASK_FF) == PH_FRINFC_MIFARESTD_ACS_BYTE8)) { |
| NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } else if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL6] & |
| PH_FRINFC_MIFARESTD_MASK_FF) == |
| PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE6) && |
| ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL7] & |
| PH_FRINFC_MIFARESTD_MASK_FF) == |
| PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE7) && |
| ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL8] & |
| PH_FRINFC_MIFARESTD_MASK_FF) == |
| PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE8)) { |
| /* Read Only state */ |
| /* Check for Access bytes 6, 7 and 8 value = |
| 0x55, 0xAD, 0x2A NFC forum Sectors */ |
| NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } else { |
| NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| |
| #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD |
| /* Do nothing */ |
| #else /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ |
| Result = phFriNfc_MifStd_H_GPBChk(NdefMap); |
| #endif /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ |
| } |
| |
| #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD |
| Result = phFriNfc_MifStd_H_GPBChk(NdefMap); |
| #endif /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ChkRdWr |
| * |
| * Description This function is for read access bits, depending |
| * on the read/write/check ndef function called. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ChkRdWr(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| switch (NdefMap->PrevOperation) { |
| case PH_FRINFC_NDEFMAP_CHECK_OPE: |
| if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) { |
| /* No permission to read */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_READ_FAILED); |
| } else if ((NdefMap->StdMifareContainer.currentBlock > 3) && |
| (NdefMap->StdMifareContainer.ChkNdefCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->StdMifareContainer.currentBlock != |
| PH_FRINFC_MIFARESTD_MAD_BLK65) && |
| (NdefMap->StdMifareContainer.currentBlock != |
| PH_FRINFC_MIFARESTD_MAD_BLK66)) { |
| Result = ((NdefMap->StdMifareContainer.ReadAcsBitFlag == |
| PH_FRINFC_MIFARESTD_FLAG0) |
| ? phFriNfc_MifStd_H_RdAcsBit(NdefMap) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } else { |
| Result = phFriNfc_MifareStdMap_ChkNdef(NdefMap); |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_READ_OPE: |
| if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) { |
| /* No permission to Read */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_READ_FAILED); |
| } else if (NdefMap->StdMifareContainer.ReadNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); |
| } else { |
| Result = phFriNfc_MifStd_H_RdABlock(NdefMap); |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_WRITE_OPE: |
| if ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) || |
| (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY)) { |
| /* No permission to Read */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_WRITE_FAILED); |
| } else if (NdefMap->StdMifareContainer.WrNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); |
| } else if (NdefMap->StdMifareContainer.RdBeforeWrFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| /*NdefMap->StdMifareContainer.ReadFlag = |
| PH_FRINFC_MIFARESTD_FLAG0;*/ |
| Result = phFriNfc_MifStd_H_RdBeforeWr(NdefMap); |
| } else if (NdefMap->StdMifareContainer.RdAfterWrFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); |
| } else { |
| Result = (((NdefMap->TLVStruct.NdefTLVBlock == |
| NdefMap->StdMifareContainer.currentBlock) && |
| (NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)) |
| ? phFriNfc_MifStd_H_RdBeforeWr(NdefMap) |
| : phFriNfc_MifStd_H_WrABlock(NdefMap)); |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE: |
| Result = |
| ((NdefMap->StdMifareContainer.ReadFlag == PH_FRINFC_MIFARESTD_FLAG0) |
| ? (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_READ_FAILED)) |
| : phFriNfc_MifStd_H_GetActCardLen(NdefMap)); |
| break; |
| |
| default: |
| /* Operation is not correct */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| |
| break; |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ChkNdefCmpltSects |
| * |
| * Description This function is used to check ndef to check the |
| * ndef compliant sectors. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_ChkNdefCmpltSects(phFriNfc_NdefMap_t* NdefMap) { |
| uint8_t index = 0; |
| uint8_t index_max_4k_2k = 0; |
| if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) { |
| index_max_4k_2k = PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR; |
| } else { |
| index_max_4k_2k = PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR; |
| } |
| |
| if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) { |
| for (index = PH_FRINFC_MIFARESTD_SECTOR_NO1; index < index_max_4k_2k; |
| index++) /*Block 0 is MAD block, so it should start with 1*/ |
| { |
| /* For Mifare 4k, Block 0 to 31 contains 4 blocks */ |
| /* sector 0 and 15 are aid blocks */ |
| if (index != PH_FRINFC_MIFARESTD_SECTOR_NO16) { |
| if (((index < 32) && (index != PH_FRINFC_MIFARESTD_SECTOR_NO0)) && |
| (NdefMap->StdMifareContainer.aid[index] == |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP)) { |
| /* Only 3 blocks can be read/written till sector 31 */ |
| NdefMap->StdMifareContainer.NoOfNdefCompBlocks -= |
| PH_FRINFC_MIFARESTD_MAD_BLK3; |
| |
| } else { |
| /* For Mifare 4k, Block 32 to 39 contains 16 blocks */ |
| if (NdefMap->StdMifareContainer.aid[index] == |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP) { |
| /* Only 15 blocks can be read/written from sector 31 */ |
| NdefMap->StdMifareContainer.NoOfNdefCompBlocks -= |
| PH_FRINFC_MIFARESTD_BLK15; |
| } |
| } |
| } |
| } /* For index > 40 */ |
| } else { |
| for (index = PH_FRINFC_MIFARESTD_SECTOR_NO1; |
| index < PH_FRINFC_MIFARESTD_SECTOR_NO16; index++) { |
| if (NdefMap->StdMifareContainer.aid[index] == |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP) { |
| /* Only three blocks can be read/written in |
| a sector. So if a sector is non-ndef |
| compliant, decrement 3 */ |
| NdefMap->StdMifareContainer.NoOfNdefCompBlocks -= |
| PH_FRINFC_MIFARESTD_MAD_BLK3; |
| } |
| } |
| } |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_RemainTLV |
| * |
| * Description This function is used for read ndef to process the |
| * remaining bytes of length (L) in the TLV. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_RemainTLV(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* Flag, |
| uint8_t* Temp16Bytes) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint8_t CRFlag = 0; |
| uint16_t RemainingBytes = 0; |
| |
| RemainingBytes = ((uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); |
| |
| if (NdefMap->StdMifareContainer.remainingSize < RemainingBytes) { |
| /* If the user Buffer is greater than the Card Size |
| set LastBlockFlag = 1. This Flag is used to read bytes |
| till the end of the card only */ |
| RemainingBytes = NdefMap->StdMifareContainer.remainingSize; |
| } |
| |
| /* Remaining Bytes of length (L) in TLV <= 16 */ |
| if ((NdefMap->TLVStruct.BytesRemainLinTLV <= |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) && |
| (RemainingBytes <= NdefMap->TLVStruct.BytesRemainLinTLV)) { |
| /* Copy data to user buffer */ |
| memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), |
| &(NdefMap->SendRecvBuf[(*Temp16Bytes)]), RemainingBytes); |
| |
| NdefMap->ApduBuffIndex += RemainingBytes; |
| NdefMap->StdMifareContainer.remainingSize -= RemainingBytes; |
| |
| /* copy the bytes to internal buffer, that are read, |
| but not used for the user buffer */ |
| if (RemainingBytes != NdefMap->TLVStruct.BytesRemainLinTLV) { |
| memcpy( |
| NdefMap->StdMifareContainer.internalBuf, |
| &(NdefMap->SendRecvBuf[((*Temp16Bytes) + RemainingBytes)]), |
| ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes)); |
| |
| /* internal buffer length */ |
| NdefMap->StdMifareContainer.internalLength = |
| ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes); |
| } |
| *Temp16Bytes += ((uint8_t)RemainingBytes); |
| /* Remaining Bytes of length value in TLV */ |
| NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; |
| |
| if (NdefMap->StdMifareContainer.internalLength == |
| PH_FRINFC_MIFARESTD_VAL0) { |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| /* internal length bytes completed */ |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| } |
| |
| if (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0) { |
| /* Remaining Bytes of length (L) in TLV is Zero means that the next |
| coming bytes are containing type (T), length (L) in TLV */ |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| /* call completion routine */ |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| *Flag = PH_FRINFC_MIFARESTD_FLAG0; |
| } else if ((NdefMap->TLVStruct.BytesRemainLinTLV <= |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) && |
| (RemainingBytes > NdefMap->TLVStruct.BytesRemainLinTLV)) { |
| /* Copy data to user buffer */ |
| memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), |
| &(NdefMap->SendRecvBuf[(*Temp16Bytes)]), |
| NdefMap->TLVStruct.BytesRemainLinTLV); |
| |
| NdefMap->ApduBuffIndex += NdefMap->TLVStruct.BytesRemainLinTLV; |
| NdefMap->StdMifareContainer.remainingSize -= |
| NdefMap->TLVStruct.BytesRemainLinTLV; |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| *Temp16Bytes += ((uint8_t)NdefMap->TLVStruct.BytesRemainLinTLV); |
| NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0; |
| |
| *Flag = PH_FRINFC_MIFARESTD_FLAG1; |
| |
| NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* 16 bytes completed */ |
| if (NdefMap->TLVStruct.BytesRemainLinTLV == |
| PH_FRINFC_MIFARESTD_BYTES_READ) { |
| *Flag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.BytesRemainLinTLV = |
| PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0; |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| if (Result == NFCSTATUS_SUCCESS) { |
| if (NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) { |
| Result = phFriNfc_MifStd_H_RdABlock(NdefMap); |
| } else { |
| Result = phFriNfc_MifStd_H_AuthSector(NdefMap); |
| } |
| } |
| } else { |
| NdefMap->TLVStruct.BytesRemainLinTLV = |
| PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0; |
| /* The read operation has finished. so, completion routine |
| can be called. set the Completion routine(CR) flag */ |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| } else if ((NdefMap->TLVStruct.BytesRemainLinTLV > |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) && |
| (RemainingBytes <= |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)))) { |
| /* Copy data to user buffer */ |
| memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), |
| &(NdefMap->SendRecvBuf[(*Temp16Bytes)]), RemainingBytes); |
| NdefMap->ApduBuffIndex += RemainingBytes; |
| NdefMap->StdMifareContainer.remainingSize -= RemainingBytes; |
| |
| /* Remaining Bytes of length (L) in TLV */ |
| NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; |
| /* copy the bytes to internal buffer, that are read, |
| but not used for the user buffer */ |
| memcpy( |
| NdefMap->StdMifareContainer.internalBuf, |
| &(NdefMap->SendRecvBuf[(RemainingBytes + (*Temp16Bytes))]), |
| ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes)); |
| |
| /* internal buffer length */ |
| NdefMap->StdMifareContainer.internalLength = |
| ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes); |
| |
| if (RemainingBytes == (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) { |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| /* internal length bytes completed */ |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| } |
| *Temp16Bytes += ((uint8_t)RemainingBytes); |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| *Flag = PH_FRINFC_MIFARESTD_FLAG0; |
| } else { |
| if ((NdefMap->TLVStruct.BytesRemainLinTLV > |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) && |
| (RemainingBytes > (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)))) { |
| *Flag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* Copy data to user buffer */ |
| memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), |
| &(NdefMap->SendRecvBuf[(*Temp16Bytes)]), |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))); |
| NdefMap->ApduBuffIndex += |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)); |
| NdefMap->StdMifareContainer.remainingSize -= |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)); |
| NdefMap->TLVStruct.BytesRemainLinTLV -= |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)); |
| *Temp16Bytes += (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)); |
| if (NdefMap->TLVStruct.BytesRemainLinTLV != |
| PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0) { |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| /* 16 bytes completed */ |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| if (Result == NFCSTATUS_SUCCESS) { |
| Result = |
| ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MifStd_H_RdABlock(NdefMap) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } |
| } |
| } |
| |
| if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) { |
| *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ChkIntLen |
| * |
| * Description This function reads ndef to process the internal bytes. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success, |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ChkIntLen(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint8_t NDEFFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| uint8_t TempintBytes = 0; |
| |
| if (NdefMap->TLVStruct.BytesRemainLinTLV != 0) { |
| NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* To read the remaining length (L) in TLV */ |
| Result = |
| phFriNfc_MifStd_H_IntLenWioutNdef(NdefMap, &NDEFFlag, &TempintBytes); |
| } |
| NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* check the NDEFFlag is set. if this is not set, then |
| in the above RemainTLV function all the 16 bytes has been |
| read */ |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_IntLenWioutNdef |
| * |
| * Description This function reads ndef to check the internal bytes |
| * without ndef tlv flag. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success, |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_IntLenWioutNdef(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* Flag, |
| uint8_t* TempintBytes) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint8_t CRFlag = 0; |
| uint16_t RemainingBytes = 0; |
| |
| RemainingBytes = ((uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); |
| |
| if (NdefMap->StdMifareContainer.remainingSize < RemainingBytes) { |
| /* If the user Buffer is greater than the Card Size |
| set LastBlockFlag = 1. This Flag is used to read bytes |
| till the end of the card only */ |
| RemainingBytes = NdefMap->StdMifareContainer.remainingSize; |
| } |
| |
| /* Remaining Bytes of length (L) in TLV <= internal length */ |
| if ((NdefMap->TLVStruct.BytesRemainLinTLV <= |
| NdefMap->StdMifareContainer.internalLength) && |
| (RemainingBytes <= NdefMap->TLVStruct.BytesRemainLinTLV)) { |
| memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), |
| &(NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]), |
| RemainingBytes); |
| NdefMap->ApduBuffIndex += RemainingBytes; |
| NdefMap->StdMifareContainer.remainingSize -= RemainingBytes; |
| *TempintBytes += ((uint8_t)RemainingBytes); |
| |
| /* copy the bytes to internal buffer, that are read, |
| but not used for the user buffer */ |
| memcpy(NdefMap->StdMifareContainer.internalBuf, |
| &(NdefMap->StdMifareContainer.internalBuf[RemainingBytes]), |
| (NdefMap->StdMifareContainer.internalLength - RemainingBytes)); |
| |
| /* internal buffer length */ |
| NdefMap->StdMifareContainer.internalLength -= RemainingBytes; |
| |
| NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; |
| if (NdefMap->StdMifareContainer.internalLength == |
| PH_FRINFC_MIFARESTD_VAL0) { |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| /* internal length bytes completed */ |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| } |
| |
| /* Remaining Bytes of length value in TLV */ |
| if (NdefMap->TLVStruct.BytesRemainLinTLV == 0) { |
| /* Remaining Bytes of length (L) in TLV is Zero means that the next |
| coming bytes are containing type (T), length (L) in TLV */ |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| /* call completion routine */ |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| *Flag = PH_FRINFC_MIFARESTD_FLAG0; |
| } else if ((NdefMap->TLVStruct.BytesRemainLinTLV <= |
| NdefMap->StdMifareContainer.internalLength) && |
| (RemainingBytes > NdefMap->TLVStruct.BytesRemainLinTLV)) { |
| memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), |
| &(NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]), |
| NdefMap->TLVStruct.BytesRemainLinTLV); |
| |
| NdefMap->ApduBuffIndex += NdefMap->TLVStruct.BytesRemainLinTLV; |
| NdefMap->StdMifareContainer.remainingSize -= |
| NdefMap->TLVStruct.BytesRemainLinTLV; |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| |
| *TempintBytes += ((uint8_t)NdefMap->TLVStruct.BytesRemainLinTLV); |
| *Flag = PH_FRINFC_MIFARESTD_FLAG1; |
| |
| NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| if (PH_FRINFC_MIFARESTD_FLAG1 == |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag) { |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| |
| if (NdefMap->TLVStruct.BytesRemainLinTLV == |
| NdefMap->StdMifareContainer.internalLength) { |
| /* Remaining Bytes in Length (L) field of TLV is 0 */ |
| NdefMap->TLVStruct.BytesRemainLinTLV = |
| PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0; |
| NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; |
| *Flag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* internal length bytes completed */ |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| if (Result == NFCSTATUS_SUCCESS) { |
| Result = |
| ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MifStd_H_RdABlock(NdefMap) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } |
| } else { |
| /* Remaining Bytes in Length (L) field of TLV is 0 */ |
| NdefMap->TLVStruct.BytesRemainLinTLV = |
| PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0; |
| *Flag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| } else if ((NdefMap->TLVStruct.BytesRemainLinTLV > |
| NdefMap->StdMifareContainer.internalLength) && |
| (RemainingBytes <= NdefMap->StdMifareContainer.internalLength)) { |
| memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), |
| &(NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]), |
| RemainingBytes); |
| |
| NdefMap->ApduBuffIndex += RemainingBytes; |
| NdefMap->StdMifareContainer.remainingSize -= RemainingBytes; |
| *TempintBytes += ((uint8_t)RemainingBytes); |
| /* Remaining Bytes of length (L) in TLV */ |
| NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; |
| |
| /* copy the bytes to internal buffer, that are read, |
| but not used for the user buffer */ |
| memcpy(NdefMap->StdMifareContainer.internalBuf, |
| &(NdefMap->StdMifareContainer.internalBuf[RemainingBytes]), |
| (NdefMap->StdMifareContainer.internalLength - RemainingBytes)); |
| |
| /* internal buffer length */ |
| NdefMap->StdMifareContainer.internalLength -= RemainingBytes; |
| if (NdefMap->StdMifareContainer.internalLength == |
| PH_FRINFC_MIFARESTD_VAL0) { |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| /* internal length bytes completed */ |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| } |
| |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| *Flag = PH_FRINFC_MIFARESTD_FLAG0; |
| } else { |
| if ((NdefMap->TLVStruct.BytesRemainLinTLV > |
| NdefMap->StdMifareContainer.internalLength) && |
| (RemainingBytes > NdefMap->StdMifareContainer.internalLength)) { |
| memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), |
| &(NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]), |
| NdefMap->StdMifareContainer.internalLength); |
| *Flag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->ApduBuffIndex += NdefMap->StdMifareContainer.internalLength; |
| NdefMap->StdMifareContainer.remainingSize -= |
| NdefMap->StdMifareContainer.internalLength; |
| NdefMap->TLVStruct.BytesRemainLinTLV -= |
| NdefMap->StdMifareContainer.internalLength; |
| |
| if (NdefMap->TLVStruct.BytesRemainLinTLV != |
| PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0) { |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| |
| NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; |
| /* internal length bytes completed */ |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| if (Result == NFCSTATUS_SUCCESS) { |
| Result = |
| ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MifStd_H_RdABlock(NdefMap) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } |
| } |
| } |
| |
| if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) { |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_WriteNdefLen |
| * |
| * Description This function is Helper function for write ndef |
| * to write the Length TLV. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_WriteNdefLen(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WR_NDEF_LEN; |
| |
| /* If Current block = Ndef TLV block then the starting point |
| is writing from type of TLV |
| Else */ |
| |
| if (NdefMap->StdMifareContainer.currentBlock == |
| NdefMap->TLVStruct.NdefTLVBlock) { |
| if (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) { |
| phFriNfc_MifStd_H_fillTLV1(NdefMap); |
| } else { |
| phFriNfc_MifStd_H_fillTLV2(NdefMap); |
| } |
| } else { |
| if (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) { |
| phFriNfc_MifStd_H_fillTLV1_1(NdefMap); |
| } else { |
| phFriNfc_MifStd_H_fillTLV2_1(NdefMap); |
| } |
| } |
| |
| memcpy(NdefMap->StdMifareContainer.Buffer, |
| &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1]), |
| PH_FRINFC_MIFARESTD_BYTES_READ); |
| |
| /* Write from here */ |
| NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE; |
| |
| NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; |
| |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| /* Call the Overlapped HAL Transceive function */ |
| Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd, |
| NdefMap->SendRecvBuf, NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_RdWrReset |
| * |
| * Description It resets ndef TLV values. This is used when the offset |
| * is BEGIN. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_RdWrReset(phFriNfc_NdefMap_t* NdefMap) { |
| NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_BLK4; |
| NdefMap->StdMifareContainer.NdefBlocks = PH_FRINFC_MIFARESTD_VAL1; |
| NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.NdefTLVAuthFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_MIFARESTD_MAD_BLK0; |
| NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.remainingSize = |
| (uint16_t)(NdefMap->StdMifareContainer.NoOfNdefCompBlocks * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES); |
| NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL1; |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_RdtoWrNdefLen |
| * |
| * Description This function is used to read the first ndef compliant |
| * block to change the length. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_RdtoWrNdefLen(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_TO_WR_NDEF_LEN; |
| |
| if (NdefMap->TLVStruct.NdefTLVAuthFlag == PH_FRINFC_MIFARESTD_FLAG1) { |
| NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; |
| Result = phFriNfc_MifStd_H_AuthSector(NdefMap); |
| } else { |
| NdefMap->SendRecvBuf[0] = NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ; |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| |
| NdefMap->Cmd.MfCmd = phHal_eMifareRead; |
| |
| /* Call the Overlapped HAL Transceive function */ |
| Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd, |
| NdefMap->SendRecvBuf, NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_SetNdefBlkAuth |
| * |
| * Description This function is used to set the authentication flag |
| * for the ndef TLV block. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_SetNdefBlkAuth(phFriNfc_NdefMap_t* NdefMap) { |
| NdefMap->TLVStruct.NdefTLVAuthFlag = |
| ((phFriNfc_MifStd_H_GetSect(NdefMap->TLVStruct.NdefTLVBlock) == |
| phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock)) |
| ? PH_FRINFC_MIFARESTD_FLAG0 |
| : PH_FRINFC_MIFARESTD_FLAG1); |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_GetActCardLen |
| * |
| * Description Helper function to get the actual length of card. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_GetActCardLen(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_GET_ACT_CARDSIZE; |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE; |
| |
| Result = ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG0) |
| ? phFriNfc_MifStd_H_AuthSector(NdefMap) |
| : phFriNfc_MifStd_H_Rd16Bytes( |
| NdefMap, NdefMap->StdMifareContainer.currentBlock)); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ChkTLVs |
| * |
| * Description Helper function to check all the TLVs. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ChkTLVs(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* CRFlag) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint16_t TempLength = PH_FRINFC_MIFARESTD_VAL0, |
| ShiftLength = PH_FRINFC_MIFARESTD_VAL0; |
| uint8_t TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE; |
| TempLength = NdefMap->TLVStruct.NdefTLVByte; |
| |
| for (;;) { |
| if ((NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_TERMTLV_T) && |
| (NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_NULLTLV_T) && |
| (NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_NDEFTLV_T) && |
| (false == NdefMap->TLVStruct.NdefTLVFoundFlag)) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| NdefMap->TLVStruct.BytesRemainLinTLV = 0; |
| NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| break; |
| |
| } else if ((NdefMap->SendRecvBuf[TempLength] != |
| PH_FRINFC_MIFARESTD_TERMTLV_T) && |
| (NdefMap->SendRecvBuf[TempLength] != |
| PH_FRINFC_MIFARESTD_NULLTLV_T)) { |
| if (NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_NDEFTLV_T) { |
| NdefMap->TLVStruct.NdefTLVBlock = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->TLVStruct.NdefTLVByte = (uint8_t)TempLength; |
| NdefMap->TLVStruct.NdefTLVFoundFlag = |
| ((NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_NDEFTLV_T) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| NdefMap->TLVStruct.NULLTLVCount = |
| ((NdefMap->TLVStruct.NULLTLVCount == PH_FRINFC_MIFARESTD_VAL1) |
| ? PH_FRINFC_MIFARESTD_VAL0 |
| : NdefMap->TLVStruct.NULLTLVCount); |
| } else { |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| } |
| |
| TempLength++; |
| if (TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) { |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL3; |
| } |
| Result = phFriNfc_MifStd_H_Chk16Bytes(NdefMap, TempLength); |
| if (Result != NFCSTATUS_SUCCESS) { |
| *CRFlag = (uint8_t)((Result == NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG0 |
| : PH_FRINFC_MIFARESTD_FLAG1); |
| break; |
| } |
| |
| if (((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks - |
| NdefMap->StdMifareContainer.NdefBlocks) * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES) + |
| (PH_FRINFC_MIFARESTD_BLOCK_BYTES - TempLength)) < |
| NdefMap->SendRecvBuf[TempLength]) && |
| ((NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L) && |
| (NdefMap->TLVStruct.NdefTLVFoundFlag != PH_FRINFC_MIFARESTD_VAL1))) { |
| /* Result = Error */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| break; |
| } |
| |
| if (((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks - |
| NdefMap->StdMifareContainer.NdefBlocks) * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES) + |
| (PH_FRINFC_MIFARESTD_BLOCK_BYTES - TempLength)) < |
| NdefMap->SendRecvBuf[TempLength]) && |
| ((NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_VAL0) && |
| (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_VAL1))) { |
| /* Result = Error */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| break; |
| } |
| |
| if ((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L)) { |
| Result = phFriNfc_MapTool_SetCardState( |
| NdefMap, NdefMap->SendRecvBuf[TempLength]); |
| NdefMap->TLVStruct.BytesRemainLinTLV = NdefMap->SendRecvBuf[TempLength]; |
| NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL2; |
| /* This flag is set */ |
| NdefMap->StdMifareContainer.remSizeUpdFlag = (uint8_t)( |
| (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) |
| ? PH_FRINFC_MIFARESTD_FLAG0 |
| : PH_FRINFC_MIFARESTD_FLAG1); |
| |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| break; |
| } |
| |
| NdefMap->StdMifareContainer.remainingSize -= |
| ((NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L) |
| ? (NdefMap->SendRecvBuf[TempLength] + PH_FRINFC_MIFARESTD_VAL2) |
| : PH_FRINFC_MIFARESTD_VAL0); |
| |
| if (NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_VAL0) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| break; |
| } |
| |
| TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* get the next TLV after the proprietary TLV */ |
| Result = |
| ((NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L) |
| ? phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, |
| &TL4bytesFlag) |
| : NFCSTATUS_PENDING); |
| |
| if ((TempLength >= PH_FRINFC_MIFARESTD_BYTES_READ) && |
| (Result == NFCSTATUS_SUCCESS)) { |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0; |
| |
| Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); |
| *CRFlag = (uint8_t)((Result != NFCSTATUS_PENDING) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| break; |
| } else { |
| if (Result == NFCSTATUS_PENDING) { |
| TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| Result = ((NdefMap->SendRecvBuf[TempLength] == |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) |
| ? NFCSTATUS_SUCCESS |
| : (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_PARAMETER))); |
| |
| if (Result != NFCSTATUS_SUCCESS) { |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| break; |
| } |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| TempLength++; |
| /* Check 0xFF */ |
| if (TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) { |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL2; |
| } |
| Result = phFriNfc_MifStd_H_Chk16Bytes(NdefMap, TempLength); |
| if (Result != NFCSTATUS_SUCCESS) { |
| break; |
| } |
| |
| ShiftLength = NdefMap->SendRecvBuf[TempLength]; |
| TempLength++; |
| if (TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) { |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL1; |
| NdefMap->TLVStruct.prevLenByteValue = |
| NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)]; |
| } |
| Result = phFriNfc_MifStd_H_Chk16Bytes(NdefMap, TempLength); |
| if (Result != NFCSTATUS_SUCCESS) { |
| break; |
| } |
| |
| if ((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks - |
| NdefMap->StdMifareContainer.NdefBlocks) * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES) + |
| (PH_FRINFC_MIFARESTD_BLOCK_BYTES - TempLength)) < |
| ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLength])) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_REMOTE_DEVICE); |
| |
| break; |
| } |
| |
| if (NdefMap->TLVStruct.NdefTLVFoundFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| ShiftLength = |
| ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLength]); |
| NdefMap->TLVStruct.BytesRemainLinTLV = ShiftLength; |
| Result = phFriNfc_MapTool_SetCardState(NdefMap, ShiftLength); |
| NdefMap->StdMifareContainer.remainingSize -= |
| PH_FRINFC_MIFARESTD_VAL4; |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| break; |
| } |
| |
| NdefMap->StdMifareContainer.remainingSize -= |
| ((ShiftLength << 8) + |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]); |
| TempLength++; |
| |
| /* get the next TLV after the proprietary TLV */ |
| Result = |
| phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, &TL4bytesFlag); |
| |
| if ((TempLength >= PH_FRINFC_MIFARESTD_BYTES_READ) && |
| (Result == NFCSTATUS_SUCCESS)) { |
| NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0; |
| Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); |
| |
| break; |
| } |
| break; |
| } |
| } |
| } else if ((NdefMap->SendRecvBuf[TempLength] == |
| PH_FRINFC_MIFARESTD_TERMTLV_T) && |
| (NdefMap->TLVStruct.NdefTLVFoundFlag == |
| PH_FRINFC_MIFARESTD_FLAG0)) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| PH_FRINFC_MIFARESTD_FLAG1; |
| break; |
| |
| } else if (NdefMap->SendRecvBuf[TempLength] == |
| PH_FRINFC_MIFARESTD_NULLTLV_T) { |
| TempLength++; |
| NdefMap->TLVStruct.NULLTLVCount += PH_FRINFC_MIFARESTD_VAL1; |
| ShiftLength = |
| NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)]; |
| NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL1; |
| if (NdefMap->StdMifareContainer.remainingSize < |
| ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLength])) { |
| Result = |
| PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE); |
| break; |
| } |
| Result = phFriNfc_MifStd_H_Chk16Bytes(NdefMap, TempLength); |
| if (Result != NFCSTATUS_SUCCESS) { |
| NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0; |
| break; |
| } |
| } else { |
| if ((NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_TERMTLV_T) && |
| (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1)) { |
| TempLength++; |
| Result = NFCSTATUS_SUCCESS; |
| NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL1; |
| } |
| } |
| } |
| |
| if (NdefMap->TLVStruct.BytesRemainLinTLV > |
| NdefMap->StdMifareContainer.remainingSize) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT); |
| } else { |
| if (NdefMap->StdMifareContainer.remainingSize == PH_FRINFC_MIFARESTD_VAL0) { |
| Result = |
| ((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1) |
| ? NFCSTATUS_SUCCESS |
| : (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_PARAMETER))); |
| } |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_GetNxtTLV |
| * |
| * Description This is a Helper function to get the next TLV. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_GetNxtTLV(phFriNfc_NdefMap_t* NdefMap, |
| uint16_t* TempLength, |
| uint8_t* TL4bytesFlag) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint16_t LengthRemaining = PH_FRINFC_MIFARESTD_VAL0, |
| TempLen = PH_FRINFC_MIFARESTD_VAL0, |
| ShiftLength = PH_FRINFC_MIFARESTD_VAL0; |
| |
| TempLen = (*TempLength); |
| LengthRemaining = |
| (PH_FRINFC_MIFARESTD_BYTES_READ - (TempLen + PH_FRINFC_MIFARESTD_VAL1)); |
| |
| if (*TL4bytesFlag == PH_FRINFC_MIFARESTD_FLAG0) { |
| (*TempLength) += (NdefMap->SendRecvBuf[TempLen] + PH_FRINFC_MIFARESTD_VAL1); |
| |
| if (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG0) { |
| LengthRemaining = |
| (((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ) |
| ? PH_FRINFC_MIFARESTD_VAL0 |
| : (NdefMap->SendRecvBuf[TempLen] - LengthRemaining)); |
| } else { |
| LengthRemaining = |
| (((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ) |
| ? PH_FRINFC_MIFARESTD_VAL0 |
| : (NdefMap->SendRecvBuf[TempLen] - LengthRemaining)); |
| } |
| } else { |
| *TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| if (NdefMap->TLVStruct.NoLbytesinTLV == PH_FRINFC_MIFARESTD_VAL1) { |
| ShiftLength = NdefMap->TLVStruct.prevLenByteValue; |
| (*TempLength) += ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLen] + |
| PH_FRINFC_MIFARESTD_VAL1); |
| |
| LengthRemaining = (((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLen]) - |
| LengthRemaining); |
| } else { |
| ShiftLength = NdefMap->SendRecvBuf[(TempLen - PH_FRINFC_MIFARESTD_VAL1)]; |
| (*TempLength) += ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLen] + |
| PH_FRINFC_MIFARESTD_VAL1); |
| |
| LengthRemaining = (((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLen]) - |
| LengthRemaining); |
| } |
| } |
| |
| NdefMap->TLVStruct.NdefTLVByte = |
| (uint8_t)(((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ) |
| ? (*TempLength) |
| : (LengthRemaining % PH_FRINFC_MIFARESTD_BYTES_READ)); |
| |
| while (LengthRemaining != PH_FRINFC_MIFARESTD_VAL0) { |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| LengthRemaining -= ((LengthRemaining <= PH_FRINFC_MIFARESTD_BYTES_READ) |
| ? LengthRemaining |
| : PH_FRINFC_MIFARESTD_BYTES_READ); |
| } |
| |
| if (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL0) { |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_Chk16Bytes |
| * |
| * Description This Helper function is used to know whether the read |
| * 16 bytes are parsed completely. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_Chk16Bytes(phFriNfc_NdefMap_t* NdefMap, |
| uint16_t TempLength) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| if (TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) { |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| |
| Result = |
| ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MifStd_H_GetActCardLen(NdefMap) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ChkRemainTLVs |
| * |
| * Description This function is used to know whether the read |
| * 16 bytes are parsed completely. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ChkRemainTLVs(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t* CRFlag, |
| uint8_t* NDEFFlag) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint16_t TempLength = PH_FRINFC_MIFARESTD_VAL0, |
| ShiftLength = PH_FRINFC_MIFARESTD_VAL0; |
| uint8_t TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| switch (NdefMap->TLVStruct.NoLbytesinTLV) { |
| case PH_FRINFC_MIFARESTD_VAL3: |
| /* if TLV is found then set card state */ |
| Result = |
| ((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MapTool_SetCardState(NdefMap, |
| NdefMap->SendRecvBuf[TempLength]) |
| : Result); |
| |
| Result = |
| ((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1) |
| ? 1 |
| : Result); |
| |
| /* Check the length field is less than or |
| equal to 0xFF if yes enter below statement |
| else enter else if*/ |
| if ((NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L) && |
| (Result == NFCSTATUS_SUCCESS)) { |
| NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL2; |
| |
| Result = |
| ((NdefMap->SendRecvBuf[TempLength] > |
| NdefMap->StdMifareContainer.remainingSize) |
| ? (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT)) |
| : Result); |
| TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| if ((NdefMap->TLVStruct.NdefTLVFoundFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (Result == NFCSTATUS_SUCCESS)) { |
| NdefMap->TLVStruct.BytesRemainLinTLV = |
| NdefMap->SendRecvBuf[TempLength]; |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| |
| } else if (Result == NFCSTATUS_SUCCESS) { |
| TempLength++; |
| Result = |
| phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, &TL4bytesFlag); |
| |
| NdefMap->StdMifareContainer.remainingSize -= |
| NdefMap->SendRecvBuf[TempLength]; |
| if ((TempLength >= PH_FRINFC_MIFARESTD_BYTES_READ) && |
| (*CRFlag == PH_FRINFC_MIFARESTD_FLAG0)) { |
| *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); |
| } |
| } |
| |
| else { |
| /* do nothing */ |
| } |
| } else if ((NdefMap->SendRecvBuf[TempLength] == |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) && |
| (Result == NFCSTATUS_SUCCESS)) { |
| TempLength++; |
| NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL4; |
| TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| Result = |
| (((((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) + |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]) > |
| NdefMap->StdMifareContainer.remainingSize) |
| ? (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT)) |
| : Result); |
| if ((NdefMap->TLVStruct.NdefTLVFoundFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (Result == NFCSTATUS_SUCCESS)) { |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.BytesRemainLinTLV = |
| (((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) + |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]); |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } else if (Result == NFCSTATUS_SUCCESS) { |
| TempLength++; |
| |
| Result = |
| phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, &TL4bytesFlag); |
| NdefMap->StdMifareContainer.remainingSize -= |
| (((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) + |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]); |
| |
| *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); |
| } else { |
| /* do nothing */ |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| } else { |
| /* Result = Error */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT); |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL2: |
| case PH_FRINFC_MIFARESTD_VAL1: |
| ShiftLength = |
| ((NdefMap->TLVStruct.NoLbytesinTLV == PH_FRINFC_MIFARESTD_VAL1) |
| ? ((NdefMap->TLVStruct.prevLenByteValue << 8) + |
| NdefMap->SendRecvBuf[TempLength]) |
| : (((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) + |
| NdefMap |
| ->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)])); |
| if ((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks - |
| NdefMap->StdMifareContainer.NdefBlocks) * |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES) + |
| (PH_FRINFC_MIFARESTD_BLOCK_BYTES - TempLength)) < ShiftLength) { |
| /* Result = Error */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } else { |
| NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL2; |
| if (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1) { |
| NdefMap->TLVStruct.BytesRemainLinTLV = ShiftLength; |
| if (NdefMap->TLVStruct.BytesRemainLinTLV > |
| NdefMap->StdMifareContainer.remainingSize) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT); |
| } |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } else { |
| NdefMap->StdMifareContainer.remainingSize -= ShiftLength; |
| *CRFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| TempLength += PH_FRINFC_MIFARESTD_VAL2; |
| TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| Result = ((NdefMap->TLVStruct.NdefTLVFoundFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? NFCSTATUS_SUCCESS |
| : phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, |
| &TL4bytesFlag)); |
| |
| *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); |
| } |
| } |
| break; |
| |
| default: |
| break; |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_Get1kStTrail |
| * |
| * Description This function is used to get the Mifare 1k Sector Trailer. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_Get1kStTrail(phFriNfc_NdefMap_t* NdefMap) { |
| switch ((NdefMap->StdMifareContainer.currentBlock % 4)) { |
| case PH_FRINFC_MIFARESTD_VAL0: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_MAD_BLK3); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL1: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_MAD_BLK2); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL2: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_MAD_BLK1); |
| break; |
| |
| default: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| NdefMap->StdMifareContainer.currentBlock; |
| break; |
| } |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_Get4kStTrail |
| * |
| * Description This function gets the Mifare 4k Sector Trailer. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_Get4kStTrail(phFriNfc_NdefMap_t* NdefMap) { |
| switch ((NdefMap->StdMifareContainer.currentBlock % 16)) { |
| case PH_FRINFC_MIFARESTD_MAD_BLK0: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_BLK15); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_MAD_BLK1: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_BLK14); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_MAD_BLK2: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_BLK13); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_MAD_BLK3: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_BLK12); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK4: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_BLK11); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK5: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_BLK10); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK6: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK9); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK7: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK8); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK8: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK7); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK9: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK6); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK10: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK5); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK11: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK4); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK12: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_MAD_BLK3); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK13: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_MAD_BLK2); |
| break; |
| |
| case PH_FRINFC_MIFARESTD_BLK14: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| (NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_MAD_BLK1); |
| break; |
| |
| default: |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| NdefMap->StdMifareContainer.currentBlock; |
| break; |
| } |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProChkNdef |
| * |
| * Description This function processes the check ndef call. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProChkNdef(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| /* Copy remaining bytes into the AID array |
| from Receive Buffer till array number 7 in aid */ |
| if (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_VAL1) { |
| /* Helper Function to Store AID Information */ |
| phFriNfc_MifStd_H_fillAIDarray(NdefMap); |
| |
| NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_VAL2; |
| /* read remaining AIDs from block number 2 */ |
| Result = ((NdefMap->StdMifareContainer.aidCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? Result |
| : phFriNfc_MifareStdMap_ChkNdef(NdefMap)); |
| } else if (((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) && |
| (NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK2)) || |
| ((NdefMap->StdMifareContainer.currentBlock == |
| PH_FRINFC_MIFARESTD_MAD_BLK66) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD))) { |
| /* Helper Function to Store AID Information */ |
| phFriNfc_MifStd_H_fillAIDarray(NdefMap); |
| |
| NdefMap->StdMifareContainer.aidCompleteFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } /* Mifare 1k and Mifare 4k end Check */ |
| else if ((NdefMap->StdMifareContainer.currentBlock > |
| PH_FRINFC_MIFARESTD_VAL1) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) { |
| phFriNfc_MifStd_H_fillAIDarray(NdefMap); |
| /* read remaining AIDs from block number 2 */ |
| /* Mifare 4k Helper Function */ |
| Result = ((NdefMap->StdMifareContainer.aidCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? Result |
| : phFriNfc_MifStd4k_H_CheckNdef(NdefMap)); |
| } /* Card Type 4k Check */ |
| else { |
| /* Since we have decided temporarily not to go |
| for any new error codes we are using |
| NFCSTATUS_INVALID_PARAMETER even though it is not |
| the relevant error code here TBD */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } |
| |
| if (NdefMap->StdMifareContainer.aidCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| NdefMap->StdMifareContainer.ChkNdefCompleteFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| /* The check for NDEF compliant information is now over for |
| the Mifare 1K card. |
| Update(decrement) the NoOfNdefCompBlocks as much required, |
| depending on the NDEF compliant information found */ |
| /* Check the Sectors are Ndef Compliant */ |
| phFriNfc_MifStd_H_ChkNdefCmpltSects(NdefMap); |
| if ((NdefMap->StdMifareContainer.NoOfNdefCompBlocks == 0) || |
| (NdefMap->StdMifareContainer.NoOfNdefCompBlocks > 255)) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| } else { |
| NdefMap->StdMifareContainer.aidCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_BLK4; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| Result = ((Result != NFCSTATUS_SUCCESS) |
| ? Result |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProAuth |
| * |
| * Description This function process the authentication of a sector. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProAuth(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| if (NdefMap->TLVStruct.NdefTLVAuthFlag == PH_FRINFC_MIFARESTD_FLAG1) { |
| NdefMap->TLVStruct.NdefTLVAuthFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG1; |
| Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); |
| } else { |
| NdefMap->StdMifareContainer.AuthDone = 1; |
| NdefMap->StdMifareContainer.ReadAcsBitFlag = 1; |
| Result = phFriNfc_MifStd_H_RdAcsBit(NdefMap); |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_Rd16Bytes |
| * |
| * Description This function reads 16 bytes from a specifed block no. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_Rd16Bytes(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t BlockNo) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = BlockNo; |
| NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ; |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| NdefMap->Cmd.MfCmd = phHal_eMifareRead; |
| NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; |
| NdefMap->MapCompletionInfo.Context = NdefMap; |
| |
| /* Call the Overlapped HAL Transceive function */ |
| Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd, |
| NdefMap->SendRecvBuf, NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProAcsBits |
| * |
| * Description It processes access bits of the sector trailer. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProAcsBits(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint8_t CRFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) { |
| if (NdefMap->StdMifareContainer.ReadAcsBitFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| /* check for the correct access bits */ |
| Result = phFriNfc_MifStd_H_ChkAcsBit(NdefMap); |
| |
| if ((NdefMap->StdMifareContainer.ChkNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (Result == NFCSTATUS_SUCCESS)) { |
| if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) { |
| NdefMap->StdMifareContainer.NoOfNdefCompBlocks = |
| ((NdefMap->StdMifareContainer.currentBlock >= |
| PH_FRINFC_MIFARESTD4K_BLK128) |
| ? (NdefMap->StdMifareContainer.NoOfNdefCompBlocks - |
| PH_FRINFC_MIFARESTD_BLK15) |
| : (NdefMap->StdMifareContainer.NoOfNdefCompBlocks - |
| PH_FRINFC_MIFARESTD_MAD_BLK3)); |
| |
| NdefMap->StdMifareContainer.ProprforumSectFlag = |
| ((NdefMap->StdMifareContainer.NFCforumSectFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG |
| : PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG); |
| |
| Result = phFriNfc_MifStd_H_ProStatNotValid(NdefMap, Result); |
| } else { |
| NdefMap->StdMifareContainer.NFCforumSectFlag = |
| (((NdefMap->StdMifareContainer.currentBlock == 64) && |
| ((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) || |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD))) |
| ? NdefMap->StdMifareContainer.NFCforumSectFlag |
| : PH_FRINFC_MIFARESTD_FLAG1); |
| } |
| |
| if (NdefMap->StdMifareContainer.ProprforumSectFlag != |
| PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG) { |
| NdefMap->StdMifareContainer.ReadAcsBitFlag = |
| PH_FRINFC_MIFARESTD_FLAG0; |
| /* ((NdefMap->StdMifareContainer.ReadCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1)? |
| PH_FRINFC_MIFARESTD_FLAG0: |
| PH_FRINFC_MIFARESTD_FLAG1);*/ |
| |
| NdefMap->StdMifareContainer.ReadCompleteFlag = (uint8_t)( |
| (((((NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_VAL4) >= |
| PH_FRINFC_MIFARESTD1K_MAX_BLK) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) && |
| (NdefMap->StdMifareContainer.ReadCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG0)) || |
| (NdefMap->StdMifareContainer.ReadCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| NdefMap->StdMifareContainer.ReadCompleteFlag = (uint8_t)( |
| (((((uint16_t)(NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_VAL4) >= |
| PH_FRINFC_MIFARESTD4K_MAX_BLK) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) && |
| (NdefMap->StdMifareContainer.ReadCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG0)) || |
| (NdefMap->StdMifareContainer.ReadCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| NdefMap->StdMifareContainer.ReadCompleteFlag = (uint8_t)( |
| (((((uint16_t)(NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_VAL4) >= |
| PH_FRINFC_MIFARESTD4K_MAX_BLK) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)) && |
| (NdefMap->StdMifareContainer.ReadCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG0)) || |
| (NdefMap->StdMifareContainer.ReadCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| NdefMap->StdMifareContainer.currentBlock = |
| ((NdefMap->StdMifareContainer.ReadCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? PH_FRINFC_MIFARESTD_BLK4 |
| : NdefMap->StdMifareContainer.currentBlock); |
| |
| Result = ((NdefMap->StdMifareContainer.ReadCompleteFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MifStd_H_BlkChk(NdefMap) |
| : Result); |
| } |
| } |
| |
| Result = |
| ((Result != NFCSTATUS_SUCCESS) ? Result |
| : phFriNfc_MifStd_H_ChkRdWr(NdefMap)); |
| } else { |
| NdefMap->StdMifareContainer.ChkNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* Here its required to read the entire card to know the */ |
| /* Get exact ndef size of the card */ |
| Result = phFriNfc_MifStd_H_ChkTLVs(NdefMap, &CRFlag); |
| } |
| } else { |
| /* Since we have decided temporarily not to go |
| for any new error codes we are using |
| NFCSTATUS_INVALID_PARAMETER even though it is not |
| the relevant error code here TBD */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_GPBChk |
| * |
| * Description This function is checks the GPB bytes. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_GPBChk(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| /* Spec version needs to be checked every time (Version check is not enabled) |
| */ |
| /* Result = phFriNfc_MapTool_ChkSpcVer(NdefMap, PH_FRINFC_MIFARESTD_VAL9); */ |
| |
| /* Check rhe read and write access field |
| in GPB is 00b |
| bit 0 and 1 for write access check |
| bit 2 and 3 for read access check */ |
| if (Result == NFCSTATUS_SUCCESS) { |
| if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL9] & |
| PH_FRINFC_MIFARESTD_MASK_GPB_WR) == |
| PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL) && |
| ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL9] & |
| PH_FRINFC_MIFARESTD_MASK_GPB_RD) == |
| PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL)) { |
| NdefMap->CardState = (((NdefMap->StdMifareContainer.ChkNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) || |
| (NdefMap->StdMifareContainer.ReadNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) || |
| (NdefMap->StdMifareContainer.WrNdefFlag == |
| PH_FRINFC_MIFARESTD_FLAG1)) |
| ? PH_NDEFMAP_CARD_STATE_INITIALIZED |
| : PH_NDEFMAP_CARD_STATE_READ_WRITE); |
| } else if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL9] & |
| PH_FRINFC_MIFARESTD_MASK_GPB_WR) != |
| PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL) && |
| ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL9] & |
| PH_FRINFC_MIFARESTD_MASK_GPB_RD) == |
| PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL)) { |
| /* write access not given |
| only read access check */ |
| NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY; |
| } else { |
| NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; |
| } |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProStatNotValid |
| * |
| * Description This function checks for the different status value in the |
| * process because of proprietary forum sector. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProStatNotValid(phFriNfc_NdefMap_t* NdefMap, |
| NFCSTATUS status) { |
| NFCSTATUS Result = status; |
| |
| /* if NFC forum sector is not found before the proprietary one then |
| authenticate the next sector |
| Else it is a error*/ |
| if (NdefMap->StdMifareContainer.NFCforumSectFlag == |
| PH_FRINFC_MIFARESTD_FLAG0) { |
| NdefMap->StdMifareContainer.ProprforumSectFlag = |
| PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG; |
| if (NdefMap->StdMifareContainer.currentBlock < |
| PH_FRINFC_MIFARESTD4K_BLK128) { |
| /* Fix for the disovery problem, |
| if 1st sector is invalid then ignore the remaining sectors and |
| send an error if the card is mifare 1k, |
| if the card is mifare 4k, then update the block number to 67 and |
| continue. |
| Even if the authentication of that block fails then send error */ |
| if (((NdefMap->StdMifareContainer.currentBlock < |
| PH_FRINFC_MIFARESTD_BLK4) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) || |
| ((NdefMap->StdMifareContainer.currentBlock <= |
| PH_FRINFC_MIFARESTD_MAD_BLK67) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD))) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| } else if ((NdefMap->StdMifareContainer.currentBlock < |
| PH_FRINFC_MIFARESTD_BLK4) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || |
| NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) { |
| Result = NFCSTATUS_SUCCESS; |
| NdefMap->StdMifareContainer.currentBlock = |
| PH_FRINFC_MIFARESTD_MAD_BLK67; |
| } else if (((NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_BLK4) > PH_FRINFC_MIFARESTD1K_MAX_BLK) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| } else { |
| NdefMap->StdMifareContainer.remainingSize -= |
| (PH_FRINFC_MIFARESTD_MAD_BLK3 * PH_FRINFC_MIFARESTD_BLOCK_BYTES); |
| NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| } |
| } else if ((NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_BLK15) > PH_FRINFC_MIFARESTD4K_MAX_BLK) { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| } else { |
| NdefMap->StdMifareContainer.remainingSize -= |
| (PH_FRINFC_MIFARESTD_BLK15 * PH_FRINFC_MIFARESTD_BLOCK_BYTES); |
| NdefMap->StdMifareContainer.currentBlock += |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| } |
| Result = |
| ((Result != NFCSTATUS_SUCCESS) |
| ? (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT)) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } else if ((NdefMap->StdMifareContainer.ProprforumSectFlag == |
| PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG) && |
| (NdefMap->StdMifareContainer.NFCforumSectFlag == |
| PH_FRINFC_MIFARESTD_FLAG1)) { |
| /* if the proprietary forum sector are found before |
| NFC forum sector then again a proprietary |
| forum sector are found after the NFC forum |
| sector */ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| } else { |
| NdefMap->StdMifareContainer.ProprforumSectFlag = |
| PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG; |
| switch (NdefMap->PrevOperation) { |
| case PH_FRINFC_NDEFMAP_CHECK_OPE: |
| case PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE: |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| break; |
| |
| case PH_FRINFC_NDEFMAP_READ_OPE: |
| if ((NdefMap->TLVStruct.NdefTLVFoundFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->TLVStruct.NoLbytesinTLV == PH_FRINFC_MIFARESTD_VAL0)) { |
| *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; |
| Result = NFCSTATUS_SUCCESS; |
| } else { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| } |
| break; |
| |
| case PH_FRINFC_NDEFMAP_WRITE_OPE: |
| default: |
| /* This means the further write is not possible, |
| EOF_NDEF_CONTAINER_REACHED */ |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| PH_FRINFC_MIFARESTD_FLAG1; |
| /* Write the length to the L field in the TLV */ |
| NdefMap->StdMifareContainer.TempBlockNo = |
| NdefMap->StdMifareContainer.currentBlock; |
| phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap); |
| NdefMap->StdMifareContainer.currentBlock = |
| NdefMap->TLVStruct.NdefTLVBlock; |
| Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); |
| break; |
| } |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_RdBeforeWr |
| * |
| * Description This function is used to read the NDEF TLV block. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_RdBeforeWr(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_BEF_WR; |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; |
| |
| Result = phFriNfc_MifStd_H_Rd16Bytes( |
| NdefMap, NdefMap->StdMifareContainer.currentBlock); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProBytesToWr |
| * |
| * Description This function processes the NDEF TLV block read bytes to |
| * start write from the NDEF TLV. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProBytesToWr(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0; |
| |
| if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) { |
| memcpy(&NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1], |
| NdefMap->SendRecvBuf, PH_FRINFC_MIFARESTD_BLOCK_BYTES); |
| |
| /* Write to Ndef TLV Block */ |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| NdefMap->StdMifareContainer.currentBlock; |
| |
| TempLength = ((NdefMap->StdMifareContainer.currentBlock == |
| NdefMap->TLVStruct.NdefTLVBlock) |
| ? phFriNfc_MifStd_H_UpdateTLV(NdefMap) |
| : phFriNfc_MifStd_H_UpdRemTLV(NdefMap)); |
| |
| NdefMap->StdMifareContainer.remainingSize -= |
| ((NdefMap->StdMifareContainer.remSizeUpdFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? PH_FRINFC_MIFARESTD_VAL2 |
| : PH_FRINFC_MIFARESTD_VAL0); |
| |
| NdefMap->StdMifareContainer.remSizeUpdFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WR_TLV; |
| Result = ((TempLength == PH_FRINFC_MIFARESTD_BLOCK_BYTES) |
| ? phFriNfc_MifStd_H_WrTLV(NdefMap) |
| : phFriNfc_MifStd_H_fillSendBuf(NdefMap, TempLength)); |
| } else { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_READ_FAILED); |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_UpdateTLV |
| * |
| * Description This function writes ndef to add the TLV structure. |
| * |
| * Returns uint8_t TempLength |
| * |
| ******************************************************************************/ |
| static uint8_t phFriNfc_MifStd_H_UpdateTLV(phFriNfc_NdefMap_t* NdefMap) { |
| uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0; |
| |
| TempLength = |
| (uint8_t)(NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL1); |
| /* Creating TLV */ |
| if (NdefMap->TLVStruct.NULLTLVCount >= 2) { |
| if ((PH_FRINFC_MIFARESTD_BYTES_READ - TempLength) == |
| PH_FRINFC_MIFARESTD_VAL0) { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; |
| } |
| } else { |
| switch ((PH_FRINFC_MIFARESTD_BYTES_READ - TempLength)) { |
| case PH_FRINFC_MIFARESTD_VAL0: |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL1: |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->TLVStruct.prevLenByteValue = (uint16_t)( |
| (NdefMap->SendRecvBuf[TempLength] >= PH_FRINFC_MIFARESTD_NDEFTLV_L) |
| ? PH_FRINFC_MIFARESTD_VAL0 |
| : NdefMap->SendRecvBuf[TempLength]); |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL2: |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->TLVStruct.prevLenByteValue = (uint16_t)( |
| (NdefMap->SendRecvBuf[TempLength] >= PH_FRINFC_MIFARESTD_NDEFTLV_L) |
| ? NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] |
| : NdefMap->SendRecvBuf[TempLength]); |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| break; |
| |
| default: |
| NdefMap->TLVStruct.prevLenByteValue = NdefMap->SendRecvBuf[TempLength]; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; |
| break; |
| } |
| } |
| |
| return TempLength; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_fillSendBuf |
| * |
| * Description It fill the send buffer to write. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_fillSendBuf(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t Length) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint16_t RemainingBytes = PH_FRINFC_MIFARESTD_VAL0, |
| BytesToWrite = PH_FRINFC_MIFARESTD_VAL0; |
| uint8_t index = PH_FRINFC_MIFARESTD_VAL0; |
| |
| Length = (Length + PH_FRINFC_MIFARESTD_VAL1); |
| |
| RemainingBytes = |
| (uint16_t)((NdefMap->StdMifareContainer.remainingSize < |
| (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)) |
| ? NdefMap->StdMifareContainer.remainingSize |
| : (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); |
| |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| NdefMap->StdMifareContainer.currentBlock; |
| /* Get the number of bytes that can be written after copying |
| the internal buffer */ |
| BytesToWrite = |
| ((RemainingBytes < ((PH_FRINFC_MIFARESTD_WR_A_BLK - Length) - |
| NdefMap->StdMifareContainer.internalLength)) |
| ? RemainingBytes |
| : ((PH_FRINFC_MIFARESTD_WR_A_BLK - Length) - |
| NdefMap->StdMifareContainer.internalLength)); |
| |
| if (NdefMap->StdMifareContainer.internalLength > PH_FRINFC_MIFARESTD_VAL0) { |
| /* copy the internal buffer to the send buffer */ |
| memcpy(&(NdefMap->SendRecvBuf[Length]), |
| NdefMap->StdMifareContainer.internalBuf, |
| NdefMap->StdMifareContainer.internalLength); |
| } |
| |
| /* Copy Bytes to write in the send buffer */ |
| memcpy(&(NdefMap->SendRecvBuf[(Length + |
| NdefMap->StdMifareContainer.internalLength)]), |
| &(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), BytesToWrite); |
| |
| /* update number of bytes written from the user buffer */ |
| NdefMap->NumOfBytesWritten = BytesToWrite; |
| |
| /* check the exact number of bytes written to a block including the |
| internal length */ |
| *NdefMap->DataCount = |
| ((BytesToWrite + NdefMap->StdMifareContainer.internalLength + Length) - |
| PH_FRINFC_MIFARESTD_VAL1); |
| |
| /* if total bytes to write in the card is less than 4 bytes then |
| pad zeroes till 4 bytes */ |
| if ((BytesToWrite + NdefMap->StdMifareContainer.internalLength + Length) < |
| PH_FRINFC_MIFARESTD_WR_A_BLK) { |
| for (index = (uint8_t)(BytesToWrite + |
| NdefMap->StdMifareContainer.internalLength + Length); |
| index < PH_FRINFC_MIFARESTD_WR_A_BLK; index++) { |
| NdefMap->SendRecvBuf[index] = |
| (uint8_t)((index == (BytesToWrite + Length + |
| NdefMap->StdMifareContainer.internalLength)) |
| ? PH_FRINFC_MIFARESTD_TERMTLV_T |
| : PH_FRINFC_MIFARESTD_NULLTLV_T); |
| |
| NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| } |
| } |
| |
| NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| |
| /* A temporary buffer to hold four bytes of data that is |
| written to the card */ |
| memcpy(NdefMap->StdMifareContainer.Buffer, |
| &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1]), |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES); |
| |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WR_TLV; |
| Result = phFriNfc_MifStd_H_WrTLV(NdefMap); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_WrTLV |
| * |
| * Description This function writes 16 bytes in a block. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_WrTLV(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; |
| NdefMap->MapCompletionInfo.Context = NdefMap; |
| /* Write from here */ |
| NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE; |
| |
| NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; |
| |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| |
| /* Call the Overlapped HAL Transceive function */ |
| Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd, |
| NdefMap->SendRecvBuf, NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProWrTLV |
| * |
| * Description This function processes the write TLV bytes in a block. |
| * |
| * Returns This function return NFCSTATUS_SUCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProWrTLV(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| /* Check that if complete TLV has been written in the |
| card if yes enter the below check or go to else*/ |
| if (((((PH_FRINFC_MIFARESTD_BLOCK_BYTES - NdefMap->TLVStruct.NdefTLVByte) == |
| PH_FRINFC_MIFARESTD_VAL1) && |
| (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2)) || |
| (((PH_FRINFC_MIFARESTD_BLOCK_BYTES - NdefMap->TLVStruct.NdefTLVByte) <= |
| PH_FRINFC_MIFARESTD_VAL3) && |
| (NdefMap->TLVStruct.NULLTLVCount == PH_FRINFC_MIFARESTD_VAL0))) && |
| (NdefMap->StdMifareContainer.currentBlock == |
| NdefMap->TLVStruct.NdefTLVBlock)) { |
| /* increment the block and chekc the block is in the same sector |
| using the block check function */ |
| NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| if (Result == NFCSTATUS_SUCCESS) { |
| Result = |
| ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG0) |
| ? phFriNfc_MifStd_H_AuthSector(NdefMap) |
| : phFriNfc_MifStd_H_RdBeforeWr(NdefMap)); |
| } |
| } else { |
| NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| if (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize) { |
| if (*NdefMap->DataCount < PH_FRINFC_MIFARESTD_BLOCK_BYTES) { |
| /* Write complete, so next byte shall be */ |
| NdefMap->StdMifareContainer.internalLength = *NdefMap->DataCount; |
| |
| /* Copy bytes less than 16 to internal buffer |
| for the next write this can be used */ |
| memcpy(NdefMap->StdMifareContainer.internalBuf, |
| NdefMap->StdMifareContainer.Buffer, |
| NdefMap->StdMifareContainer.internalLength); |
| } |
| |
| /* Increment the Send Buffer index */ |
| NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten; |
| |
| NdefMap->StdMifareContainer.remainingSize -= NdefMap->NumOfBytesWritten; |
| |
| /* Check for the End of Card */ |
| if ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize)) { |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| (uint8_t)((NdefMap->StdMifareContainer.remainingSize == 0) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| if (NdefMap->StdMifareContainer.internalLength == |
| PH_FRINFC_MIFARESTD_VAL0) { |
| NdefMap->StdMifareContainer.currentBlock++; |
| /* Mifare 4k Card, After 128th Block |
| each sector = 16 blocks in Mifare 4k */ |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| } |
| |
| NdefMap->TLVStruct.SetTermTLVFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| } else { |
| NdefMap->StdMifareContainer.currentBlock++; |
| /* Mifare 4k Card, After 128th Block |
| each sector = 16 blocks in Mifare 4k */ |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| if (Result == NFCSTATUS_SUCCESS) { |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = ((NdefMap->StdMifareContainer.AuthDone == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MifStd_H_WrABlock(NdefMap) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } |
| } |
| } |
| } |
| |
| if ((Result == NFCSTATUS_SUCCESS) && |
| (NdefMap->TLVStruct.SetTermTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->StdMifareContainer.remainingSize > PH_FRINFC_MIFARESTD_VAL0)) { |
| Result = phFriNfc_MifStd_H_WrTermTLV(NdefMap); |
| } else { |
| if ((Result == NFCSTATUS_SUCCESS) && |
| (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1)) { |
| /* Write the length to the L field in the TLV */ |
| NdefMap->StdMifareContainer.TempBlockNo = |
| NdefMap->StdMifareContainer.currentBlock; |
| phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap); |
| NdefMap->StdMifareContainer.currentBlock = |
| NdefMap->TLVStruct.NdefTLVBlock; |
| Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); |
| } |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_UpdRemTLV |
| * |
| * Description This function updates the remaining TLV. |
| * |
| * Returns uint8_t TempLength : length value |
| * |
| ******************************************************************************/ |
| static uint8_t phFriNfc_MifStd_H_UpdRemTLV(phFriNfc_NdefMap_t* NdefMap) { |
| uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL1; |
| |
| if (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) { |
| NdefMap->TLVStruct.prevLenByteValue = NdefMap->SendRecvBuf[TempLength]; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; |
| } else { |
| switch ( |
| (PH_FRINFC_MIFARESTD_BLOCK_BYTES - NdefMap->TLVStruct.NdefTLVByte)) { |
| case PH_FRINFC_MIFARESTD_VAL1: |
| NdefMap->TLVStruct.prevLenByteValue = |
| (((NdefMap->SendRecvBuf[TempLength] == |
| PH_FRINFC_MIFARESTD_NDEFTLV_L)) |
| ? (((uint16_t)NdefMap |
| ->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] |
| << PH_FRINFC_MIFARESTD_LEFTSHIFT8) + |
| NdefMap |
| ->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL2)]) |
| : NdefMap->SendRecvBuf[TempLength]); |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL2: |
| NdefMap->TLVStruct.prevLenByteValue = |
| (((NdefMap->SendRecvBuf[TempLength] == |
| PH_FRINFC_MIFARESTD_NDEFTLV_L)) |
| ? (((uint16_t)NdefMap->SendRecvBuf[TempLength] |
| << PH_FRINFC_MIFARESTD_LEFTSHIFT8) + |
| NdefMap |
| ->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]) |
| : NdefMap->SendRecvBuf[TempLength]); |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL3: |
| default: |
| NdefMap->TLVStruct.prevLenByteValue = |
| ((NdefMap->TLVStruct.prevLenByteValue |
| << PH_FRINFC_MIFARESTD_LEFTSHIFT8) + |
| NdefMap->SendRecvBuf[TempLength]); |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; |
| break; |
| } |
| } |
| |
| return TempLength; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_fillTLV1 |
| * |
| * Description This function updates the length field if more than one |
| * NULL TLVs exists before of the NDEF TLV. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_fillTLV1(phFriNfc_NdefMap_t* NdefMap) { |
| uint8_t TempLength = |
| (uint8_t)(NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL1); |
| |
| NdefMap->TLVStruct.prevLenByteValue = |
| ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) |
| ? (NdefMap->TLVStruct.prevLenByteValue + NdefMap->ApduBuffIndex) |
| : NdefMap->ApduBuffIndex); |
| |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| switch (NdefMap->TLVStruct.NdefTLVByte) { |
| case PH_FRINFC_MIFARESTD_VAL0: |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> |
| PH_FRINFC_MIFARESTD_RIGHTSHIFT8); |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL1: |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| NdefMap->SendRecvBuf[TempLength - PH_FRINFC_MIFARESTD_VAL1] = |
| PH_FRINFC_MIFARESTD_NDEFTLV_L; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> |
| PH_FRINFC_MIFARESTD_RIGHTSHIFT8); |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| } |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL15: |
| /* if "Type" of TLV present at byte 15 */ |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| /* Update the null TLV, ndef TLV block and ndef TLV byte */ |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.NdefTLVBlock = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->TLVStruct.NdefTLVByte = |
| (TempLength - PH_FRINFC_MIFARESTD_VAL3); |
| |
| NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL2)] = |
| PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)] = |
| PH_FRINFC_MIFARESTD_NDEFTLV_L; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> |
| PH_FRINFC_MIFARESTD_RIGHTSHIFT8); |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| } |
| break; |
| |
| default: |
| /* Already the TLV is present so just append the length field */ |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| /* Update the null TLV, ndef TLV block and ndef TLV byte */ |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.NdefTLVBlock = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->TLVStruct.NdefTLVByte = |
| (TempLength - PH_FRINFC_MIFARESTD_VAL3); |
| |
| NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL2)] = |
| (uint8_t)PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)] = |
| (uint8_t)PH_FRINFC_MIFARESTD_NDEFTLV_L; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> |
| PH_FRINFC_MIFARESTD_RIGHTSHIFT8); |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| break; |
| } |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_fillTLV2 |
| * |
| * Description This function is updates the length field if more than one |
| * NULL TLVs does not exists before the TLV. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_fillTLV2(phFriNfc_NdefMap_t* NdefMap) { |
| uint8_t TempLength = |
| (uint8_t)(NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL1); |
| |
| NdefMap->TLVStruct.prevLenByteValue = |
| ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) |
| ? (NdefMap->TLVStruct.prevLenByteValue + NdefMap->ApduBuffIndex) |
| : NdefMap->ApduBuffIndex); |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| switch (NdefMap->TLVStruct.NdefTLVByte) { |
| case PH_FRINFC_MIFARESTD_VAL13: |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> |
| PH_FRINFC_MIFARESTD_RIGHTSHIFT8); |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| |
| /* Update the null TLV, ndef TLV block and ndef TLV byte */ |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2; |
| NdefMap->TLVStruct.NdefTLVBlock = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->TLVStruct.NdefTLVByte = |
| (TempLength - PH_FRINFC_MIFARESTD_VAL1); |
| |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| } |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL14: |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L; |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| } |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL15: |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| } |
| break; |
| |
| default: |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> |
| PH_FRINFC_MIFARESTD_RIGHTSHIFT8); |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| |
| /* Update the null TLV, ndef TLV block and ndef TLV byte */ |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2; |
| NdefMap->TLVStruct.NdefTLVBlock = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->TLVStruct.NdefTLVByte = |
| (TempLength - PH_FRINFC_MIFARESTD_VAL1); |
| |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| break; |
| } |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_CallWrNdefLen |
| * |
| * Description This function is used to increment/decrement the ndef tlv |
| *block and read the block. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_CallWrNdefLen(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| if (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) { |
| if ((NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL1)) { |
| /* In this case, current block is decremented because the |
| NULL TLVs are in the previous block */ |
| NdefMap->StdMifareContainer.currentBlock--; |
| Result = phFriNfc_MifStd_H_BlkChk_1(NdefMap); |
| } else { |
| /* case NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL15: |
| Current block is incremented to update the remaining TLV |
| structure */ |
| NdefMap->StdMifareContainer.currentBlock++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| } |
| } else { |
| if ((NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL13) || |
| (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL14) || |
| (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL15)) { |
| /* Current block is incremented to update the remaining TLV |
| structure */ |
| NdefMap->StdMifareContainer.currentBlock++; |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| } |
| } |
| |
| Result = |
| ((Result == NFCSTATUS_SUCCESS) ? phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap) |
| : Result); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_BlkChk_1 |
| * |
| * Description This function check the current block is valid or not |
| * if not valid decrement the current block till the valid |
| *block. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_BlkChk_1(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint8_t SectorID = PH_FRINFC_MIFARESTD_VAL0; |
| |
| /* Get a Sector ID for the Current Block */ |
| SectorID = |
| phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock); |
| |
| /* Check the sector id is valid or not and if valid then check the |
| current block is greater than 128 */ |
| if ((NdefMap->StdMifareContainer.aid[SectorID] == |
| PH_FRINFC_MIFARESTD_NDEF_COMP) && |
| (((SectorID <= PH_FRINFC_MIFARESTD_VAL15) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) || |
| ((SectorID <= PH_FRINFC_MIFARESTD_SECTOR_NO31) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) || |
| ((SectorID <= PH_FRINFC_MIFARESTD_SECTOR_NO39) && |
| (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)))) { |
| if (NdefMap->StdMifareContainer.currentBlock > 128) { |
| NdefMap->TLVStruct.NdefTLVAuthFlag = |
| ((((NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_VAL1) % |
| PH_FRINFC_MIFARESTD_MAD_BLK16) == PH_FRINFC_MIFARESTD_VAL0) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| NdefMap->StdMifareContainer.currentBlock -= |
| ((((NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_VAL1) % |
| PH_FRINFC_MIFARESTD_MAD_BLK16) == PH_FRINFC_MIFARESTD_VAL0) |
| ? PH_FRINFC_MIFARESTD_VAL1 |
| : PH_FRINFC_MIFARESTD_VAL0); |
| |
| } else { |
| NdefMap->TLVStruct.NdefTLVAuthFlag = |
| ((((NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_VAL1) % |
| PH_FRINFC_MIFARESTD_BLK4) == PH_FRINFC_MIFARESTD_VAL0) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| NdefMap->StdMifareContainer.currentBlock -= |
| ((((NdefMap->StdMifareContainer.currentBlock + |
| PH_FRINFC_MIFARESTD_VAL1) % |
| PH_FRINFC_MIFARESTD_BLK4) == PH_FRINFC_MIFARESTD_VAL1) |
| ? PH_FRINFC_MIFARESTD_VAL1 |
| : PH_FRINFC_MIFARESTD_VAL0); |
| } |
| } else { |
| /*Error: No Ndef Compliant Sectors present.*/ |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_fillTLV1_1 |
| * |
| * Description This function updates the length of the TLV if NULL TLVs |
| * greater than or equal to 2. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_fillTLV1_1(phFriNfc_NdefMap_t* NdefMap) { |
| switch (NdefMap->TLVStruct.NdefTLVByte) { |
| case PH_FRINFC_MIFARESTD_VAL0: |
| /* In the first write ndef length procedure, the |
| length is updated, in this case T and L = 0xFF of TLV are |
| updated */ |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.NdefTLVBlock = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL14; |
| |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL15] = |
| PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL16] = |
| PH_FRINFC_MIFARESTD_NDEFTLV_L; |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL1: |
| /* In the first write ndef length procedure, the |
| length is updated, in this case T of TLV is |
| updated */ |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->TLVStruct.NdefTLVBlock = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL15; |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL16] = |
| PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL15: |
| default: |
| /* In the first ndef write length, part of the L field or only T |
| (if update length is less than 255) is updated */ |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| break; |
| } |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_fillTLV2_1 |
| * |
| * Description This function updates the length of the TLV if NULL TLVs |
| * less than 2. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd_H_fillTLV2_1(phFriNfc_NdefMap_t* NdefMap) { |
| uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL1; |
| switch (NdefMap->TLVStruct.NdefTLVByte) { |
| case PH_FRINFC_MIFARESTD_VAL13: |
| /* In last write ndef length, part of length (L) field of TLV |
| is updated now */ |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL14: |
| /* In last write ndef length, part of length (L) field of TLV |
| is updated now */ |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> |
| PH_FRINFC_MIFARESTD_RIGHTSHIFT8); |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } else { |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2; |
| NdefMap->TLVStruct.NdefTLVBlock = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->TLVStruct.NdefTLVByte = |
| (TempLength - PH_FRINFC_MIFARESTD_VAL1); |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } |
| break; |
| |
| case PH_FRINFC_MIFARESTD_VAL15: |
| default: |
| if (NdefMap->TLVStruct.prevLenByteValue >= |
| PH_FRINFC_MIFARESTD_NDEFTLV_L) { |
| /* In last write ndef length, only T of TLV is updated and |
| length (L) field of TLV is updated now */ |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> |
| PH_FRINFC_MIFARESTD_RIGHTSHIFT8); |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } else { |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| TempLength++; |
| NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2; |
| NdefMap->TLVStruct.NdefTLVBlock = |
| NdefMap->StdMifareContainer.currentBlock; |
| NdefMap->TLVStruct.NdefTLVByte = |
| (TempLength - PH_FRINFC_MIFARESTD_VAL1); |
| NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; |
| TempLength++; |
| NdefMap->SendRecvBuf[TempLength] = |
| (uint8_t)NdefMap->TLVStruct.prevLenByteValue; |
| } |
| break; |
| } |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_RdTLV |
| * |
| * Description This function reads the TLV block. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_RdTLV(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_TLV; |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; |
| |
| Result = phFriNfc_MifStd_H_Rd16Bytes( |
| NdefMap, NdefMap->StdMifareContainer.currentBlock); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProRdTLV |
| * |
| * Description This function processes the read TLV block. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProRdTLV(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = |
| PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST); |
| uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0, |
| NDEFFlag = PH_FRINFC_MIFARESTD_FLAG1; |
| |
| /*TempLength = (uint8_t)(((NdefMap->TLVStruct.NULLTLVCount >= |
| PH_FRINFC_MIFARESTD_VAL2) && |
| (NdefMap->TLVStruct.BytesRemainLinTLV > 0xFE))? |
| ((NdefMap->TLVStruct.NdefTLVByte + |
| PH_FRINFC_MIFARESTD_VAL2)% |
| PH_FRINFC_MIFARESTD_VAL16): |
| ((NdefMap->TLVStruct.NdefTLVByte + |
| PH_FRINFC_MIFARESTD_VAL4)% |
| PH_FRINFC_MIFARESTD_VAL16));*/ |
| |
| TempLength = (uint8_t)( |
| (NdefMap->TLVStruct.BytesRemainLinTLV <= 0xFE) |
| ? ((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL2) % |
| PH_FRINFC_MIFARESTD_VAL16) |
| : ((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL4) % |
| PH_FRINFC_MIFARESTD_VAL16)); |
| |
| if ((*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) && |
| (NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize)) { |
| if (NdefMap->TLVStruct.BytesRemainLinTLV != 0) { |
| NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* To read the remaining length (L) in TLV */ |
| Result = phFriNfc_MifStd_H_RemainTLV(NdefMap, &NDEFFlag, &TempLength); |
| } |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_WrTermTLV |
| * |
| * Description This function is used to write the terminator TLV. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_WrTermTLV(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| uint8_t index = PH_FRINFC_MIFARESTD_VAL0; |
| |
| /* Change the state to check ndef compliancy */ |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_TERM_TLV; |
| |
| NdefMap->SendRecvBuf[index] = NdefMap->StdMifareContainer.currentBlock; |
| index++; |
| NdefMap->SendRecvBuf[index] = PH_FRINFC_MIFARESTD_TERMTLV_T; |
| index++; |
| |
| while (index < PH_FRINFC_MIFARESTD_WR_A_BLK) { |
| NdefMap->SendRecvBuf[index] = PH_FRINFC_MIFARESTD_NULLTLV_T; |
| index++; |
| } |
| |
| NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| Result = phFriNfc_MifStd_H_WrTLV(NdefMap); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProWrABlock |
| * |
| * Description This function processes the write a block. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProWrABlock(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL0; |
| if (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize) { |
| /* Remaining bytes to write < 16 */ |
| if (NdefMap->StdMifareContainer.RemainingBufFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| /* Write complete, so next byte shall be */ |
| NdefMap->StdMifareContainer.internalLength = *NdefMap->DataCount; |
| |
| /* Copy bytes less than 16 to internal buffer |
| for the next write this can be used */ |
| memcpy(NdefMap->StdMifareContainer.internalBuf, |
| NdefMap->StdMifareContainer.Buffer, |
| NdefMap->StdMifareContainer.internalLength); |
| |
| /* Increment the Send Buffer index */ |
| NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten; |
| |
| NdefMap->StdMifareContainer.remainingSize -= NdefMap->NumOfBytesWritten; |
| |
| NdefMap->StdMifareContainer.RemainingBufFlag = PH_FRINFC_MIFARESTD_VAL0; |
| /* Check for the End of Card */ |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| (uint8_t)((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| NdefMap->TLVStruct.SetTermTLVFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| } /* internal Buffer > Send Buffer */ |
| else if (NdefMap->StdMifareContainer.internalBufFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| memcpy(NdefMap->StdMifareContainer.internalBuf, |
| NdefMap->StdMifareContainer.Buffer, *NdefMap->DataCount); |
| |
| NdefMap->StdMifareContainer.internalLength = *NdefMap->DataCount; |
| |
| /* Increment the Send Buffer index */ |
| NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten; |
| |
| NdefMap->StdMifareContainer.remainingSize -= NdefMap->NumOfBytesWritten; |
| |
| NdefMap->StdMifareContainer.internalBufFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| /* Check for the End of Card */ |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| (uint8_t)(((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) && |
| (NdefMap->StdMifareContainer.internalLength == |
| PH_FRINFC_MIFARESTD_VAL0)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| NdefMap->TLVStruct.SetTermTLVFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| } else { |
| NdefMap->StdMifareContainer.internalLength = 0; |
| /* Increment the Send Buffer index */ |
| NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten; |
| NdefMap->StdMifareContainer.remainingSize -= NdefMap->NumOfBytesWritten; |
| |
| /* Check for the End of Card */ |
| if ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize)) { |
| NdefMap->StdMifareContainer.ReadWriteCompleteFlag = |
| (uint8_t)((NdefMap->StdMifareContainer.remainingSize == 0) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| |
| if (NdefMap->StdMifareContainer.internalLength == |
| PH_FRINFC_MIFARESTD_VAL0) { |
| NdefMap->StdMifareContainer.currentBlock++; |
| /* Mifare 4k Card, After 128th Block |
| each sector = 16 blocks in Mifare 4k */ |
| Result = ((NdefMap->StdMifareContainer.remainingSize == 0) |
| ? Result |
| : phFriNfc_MifStd_H_BlkChk(NdefMap)); |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| } |
| NdefMap->TLVStruct.SetTermTLVFlag = (uint8_t)( |
| ((NdefMap->StdMifareContainer.remainingSize == |
| PH_FRINFC_MIFARESTD_VAL0) || |
| (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1)) |
| ? PH_FRINFC_MIFARESTD_FLAG1 |
| : PH_FRINFC_MIFARESTD_FLAG0); |
| } else { |
| NdefMap->StdMifareContainer.currentBlock++; |
| NdefMap->StdMifareContainer.WrLength = |
| (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); |
| /* Mifare 4k Card, After 128th Block |
| each sector = 16 blocks in Mifare 4k */ |
| Result = phFriNfc_MifStd_H_BlkChk(NdefMap); |
| if (Result == NFCSTATUS_SUCCESS) { |
| NdefMap->StdMifareContainer.NdefBlocks++; |
| Result = ((NdefMap->StdMifareContainer.AuthDone == |
| PH_FRINFC_MIFARESTD_FLAG1) |
| ? phFriNfc_MifStd_H_WrABlock(NdefMap) |
| : phFriNfc_MifStd_H_AuthSector(NdefMap)); |
| } |
| } |
| } |
| } else { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST); |
| } |
| |
| if ((Result == NFCSTATUS_SUCCESS) && |
| (NdefMap->TLVStruct.SetTermTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) && |
| (NdefMap->StdMifareContainer.remainingSize > PH_FRINFC_MIFARESTD_VAL0)) { |
| Result = phFriNfc_MifStd_H_WrTermTLV(NdefMap); |
| } else { |
| if ((Result == NFCSTATUS_SUCCESS) && |
| (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1)) { |
| /* Write the length to the L field in the TLV */ |
| NdefMap->StdMifareContainer.TempBlockNo = |
| NdefMap->StdMifareContainer.currentBlock; |
| phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap); |
| NdefMap->StdMifareContainer.currentBlock = |
| NdefMap->TLVStruct.NdefTLVBlock; |
| Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); |
| } |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_CallDisCon |
| * |
| * Description This function trigger disconnect after the authentication |
| * has failed. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_CallDisCon(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| /* Set Ndef State */ |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_DISCONNECT; |
| NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; |
| NdefMap->MapCompletionInfo.Context = NdefMap; |
| |
| Result = phNxNciExtns_MifareStd_Reconnect(); |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_CallConnect |
| * |
| * Description This function sets card state to connect after the |
| * authentication has failed. |
| * |
| * Returns NFCSTATUS_SUCCESS |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_CallConnect(phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| /* Set Ndef State */ |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_CONNECT; |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd1k_H_BlkChk |
| * |
| * Description This function used to update the current block. |
| * |
| * Returns void |
| * |
| ******************************************************************************/ |
| static void phFriNfc_MifStd1k_H_BlkChk(phFriNfc_NdefMap_t* NdefMap, |
| uint8_t SectorID, uint8_t* callbreak) { |
| /* every last block of a sector needs to be skipped */ |
| if (((NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_INC_1) % |
| PH_FRINFC_MIFARESTD_BLK4) == 0) { |
| NdefMap->StdMifareContainer.currentBlock++; |
| } else { |
| if (NdefMap->StdMifareContainer.aid[SectorID] == |
| PH_FRINFC_MIFARESTD_NDEF_COMP) { |
| /* Check whether the block is first block of a (next)new sector and |
| also check if it is first block then internal length is zero |
| or not. Because once Authentication is done for the sector again |
| we should not authenticate it again */ |
| if ((NdefMap->StdMifareContainer.currentBlock == |
| (SectorID * PH_FRINFC_MIFARESTD_BLK4)) && |
| (NdefMap->StdMifareContainer.internalLength == 0)) { |
| NdefMap->StdMifareContainer.AuthDone = 0; |
| } |
| *callbreak = 1; |
| } else { |
| NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; |
| } |
| } |
| |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function phFrinfc_MifareClassic_GetContainerSize |
| * |
| * Description This function calculate the card size. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| NFCSTATUS |
| phFrinfc_MifareClassic_GetContainerSize(const phFriNfc_NdefMap_t* NdefMap, |
| uint32_t* maxSize, |
| uint32_t* actualSize) { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| uint16_t valid_no_of_bytes = 0; |
| uint8_t sect_aid_index = 0; |
| /* Mifare std card */ |
| |
| /* Max size is the number of NDEF compliant blocks in the card |
| multiplied by 16 bytes */ |
| |
| /* Skip all the non ndef sectors */ |
| while ((sect_aid_index < PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK) && |
| (PH_FRINFC_MIFARESTD_NON_NDEF_COMP == |
| NdefMap->StdMifareContainer.aid[sect_aid_index])) { |
| sect_aid_index++; |
| } |
| |
| /* Parse only the contiguous NDEF sectors for the max size calculation */ |
| while ((sect_aid_index < PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK) && |
| (PH_FRINFC_MIFARESTD_NDEF_COMP == |
| NdefMap->StdMifareContainer.aid[sect_aid_index])) { |
| if (((PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD == NdefMap->CardType) || |
| (PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD == NdefMap->CardType)) && |
| (sect_aid_index >= 32)) { |
| /* Mifare classic card of 4k size, sector >= 32 has |
| 16 blocks per sector and in that 15 blocks are valid data blocks |
| 16 is the block number in a sector |
| 15 is the number of valid data blocks in a sector |
| */ |
| valid_no_of_bytes += (uint16_t)(16 * 15); |
| } else { |
| valid_no_of_bytes += (uint16_t)(16 * 3); |
| } |
| |
| sect_aid_index++; |
| if (16 == sect_aid_index) { |
| /* Because sector index is 16, that is "MAD 2" block |
| For calculating size MAD block shall be ignored |
| */ |
| sect_aid_index++; |
| } |
| } |
| /* The below check is for the 3 byte length format of the NDEF TLV |
| If the length field > 255, Max size will less by 4 |
| else Max size will less by 2 (Type and Length of the NDEF TLV |
| has to be skipped to provide the maximum size in the card */ |
| *maxSize = (valid_no_of_bytes > 0xFF) ? (valid_no_of_bytes - 4) |
| : (valid_no_of_bytes - 2); |
| |
| *actualSize = NdefMap->TLVStruct.BytesRemainLinTLV; |
| |
| return result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifareStdMap_ConvertToReadOnly |
| * |
| * Description This function converts the Mifare card to read-only. |
| * It check preconditions before converting to read only. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| NFCSTATUS |
| phFriNfc_MifareStdMap_ConvertToReadOnly(phFriNfc_NdefMap_t* NdefMap, |
| const uint8_t* ScrtKeyB) { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| uint8_t totalNoSectors = 0, sectorTrailerBlockNo = 0; |
| |
| if (NdefMap == NULL) { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } else if (PH_NDEFMAP_CARD_STATE_INVALID == NdefMap->CardState) { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_STATE); |
| } else { |
| /* card state is PH_NDEFMAP_CARD_STATE_READ_WRITE now */ |
| /* get AID array and parse */ |
| if (PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD == NdefMap->CardType) { |
| totalNoSectors = PH_FRINFC_MIFARESTD1K_TOTAL_SECTOR; |
| } else if (PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD == NdefMap->CardType) { |
| totalNoSectors = PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR; |
| } else if (PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD == NdefMap->CardType) { |
| totalNoSectors = PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR; |
| } |
| |
| /* Store Key B in the context */ |
| if (ScrtKeyB == NULL) { |
| memset(NdefMap->StdMifareContainer.UserScrtKeyB, |
| PH_FRINFC_MIFARESTD_DEFAULT_KEY, PH_FRINFC_MIFARESTD_KEY_LEN); |
| } else { |
| memcpy(NdefMap->StdMifareContainer.UserScrtKeyB, ScrtKeyB, |
| PH_FRINFC_MIFARESTD_KEY_LEN); |
| } |
| |
| NdefMap->StdMifareContainer.TotalNoSectors = totalNoSectors; |
| if (totalNoSectors == 0) { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } else { |
| NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; |
| NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| NdefMap->StdMifareContainer.WriteAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG0; |
| |
| /* Sector 0 is MAD sector .Start from Sector 1 */ |
| for (NdefMap->StdMifareContainer.ReadOnlySectorIndex = |
| PH_FRINFC_MIFARESTD_FLAG1; |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex < totalNoSectors; |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex++) { |
| /* skip MAD sectors */ |
| if (PH_FRINFC_MIFARESTD_SECTOR_NO16 == |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex) { |
| continue; |
| } |
| |
| /* if not NDEF compliant skip */ |
| if (PH_FRINFC_MIFARESTD_NON_NDEF_COMP == |
| NdefMap->StdMifareContainer |
| .aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) { |
| continue; |
| } |
| |
| if (PH_FRINFC_MIFARESTD_NDEF_COMP == |
| NdefMap->StdMifareContainer |
| .aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) { |
| /*get the sector trailer block number */ |
| sectorTrailerBlockNo = phFriNfc_MifStd_H_GetSectorTrailerBlkNo( |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex); |
| NdefMap->StdMifareContainer.currentBlock = sectorTrailerBlockNo; |
| NdefMap->StdMifareContainer.SectorTrailerBlockNo = |
| sectorTrailerBlockNo; |
| |
| /* Proceed to authenticate the sector with Key B |
| and modify the sector trailor bits to make it read only*/ |
| result = phFriNfc_MifStd_H_AuthSector(NdefMap); |
| |
| if (result == NFCSTATUS_PENDING) { |
| break; |
| } |
| } |
| } /* end for */ |
| |
| /* There are no NDEF sectors in this card , return */ |
| if (NdefMap->StdMifareContainer.ReadOnlySectorIndex == totalNoSectors && |
| NFCSTATUS_PENDING != result) { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); |
| } |
| } /* end else */ |
| } |
| |
| return result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_GetSectorTrailerBlkNo |
| * |
| * Description This function returns the block number of the sector |
| * trailor for the given sector trailer Id. |
| * |
| * Returns uint8_t sectorTrailerblockNumber : sector trailor |
| * |
| ******************************************************************************/ |
| static uint8_t phFriNfc_MifStd_H_GetSectorTrailerBlkNo(uint8_t SectorID) { |
| uint8_t sectorTrailerblockNumber = 0; |
| |
| /* every last block of a sector needs to be skipped */ |
| if (SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32) { |
| sectorTrailerblockNumber = (SectorID * PH_FRINFC_MIFARESTD_BLK4) + 3; |
| } else { |
| sectorTrailerblockNumber = |
| ((PH_FRINFC_MIFARESTD_SECTOR_NO32 * PH_FRINFC_MIFARESTD_BLK4) + |
| ((SectorID - PH_FRINFC_MIFARESTD_SECTOR_NO32) * |
| PH_FRINFC_MIFARESTD_SECTOR_BLOCKS)) + |
| 15; |
| } |
| |
| return sectorTrailerblockNumber; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProSectorTrailorAcsBits |
| * |
| * Description This function is called during ConvertToReadonly process to |
| * Authenticate NDEF compliant Sector. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProSectorTrailorAcsBits( |
| phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS Result = NFCSTATUS_SUCCESS; |
| |
| if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) { |
| if (NdefMap->StdMifareContainer.ReadAcsBitFlag == |
| PH_FRINFC_MIFARESTD_FLAG1) { |
| /* check for the correct access bits */ |
| Result = phFriNfc_MifStd_H_ChkAcsBit(NdefMap); |
| if (Result == NFCSTATUS_SUCCESS) { |
| if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY) { |
| /* Go to next sector */ |
| Result = phFriNfc_MifStd_H_ProWrSectorTrailor(NdefMap); |
| } else { |
| /* tranceive to write the data into SendRecvBuff */ |
| Result = phFriNfc_MifStd_H_WrSectorTrailorBlock(NdefMap); |
| } |
| } |
| } |
| } else { |
| Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); |
| } |
| |
| return Result; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_WrSectorTrailorBlock |
| * |
| * Description This function makes current NDEF compliant Sector ReadOnly |
| * modify the sector trailor bits and write it to the card. |
| * |
| * Returns This function return NFCSTATUS_PENDING in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_WrSectorTrailorBlock( |
| phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS status = NFCSTATUS_PENDING; |
| |
| NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; |
| NdefMap->MapCompletionInfo.Context = NdefMap; |
| NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; |
| |
| /* next state (update sector index) */ |
| NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WRITE_SEC; |
| |
| /* Buffer Check */ |
| if (NdefMap->SendRecvBuf != NULL) { |
| NdefMap->SendRecvBuf[10] = 0x00; |
| NdefMap->SendRecvBuf[10] = NdefMap->SendRecvBuf[9] | |
| PH_FRINFC_MIFARESTD_MASK_GPB_WR; /* WR bits 11*/ |
| |
| /*The NdefMap->SendRecvBuf already has the sector trailor. |
| modify the bits to make Read Only */ |
| NdefMap->SendRecvBuf[1] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ |
| NdefMap->SendRecvBuf[2] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ |
| NdefMap->SendRecvBuf[3] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ |
| NdefMap->SendRecvBuf[4] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ |
| NdefMap->SendRecvBuf[5] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ |
| NdefMap->SendRecvBuf[6] = |
| PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ |
| |
| NdefMap->SendRecvBuf[7] = |
| PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE6; /* 0x0F */ |
| NdefMap->SendRecvBuf[8] = |
| PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE7; /* 0x07 */ |
| NdefMap->SendRecvBuf[9] = |
| PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE8; /* 0x8F */ |
| |
| NdefMap->SendRecvBuf[11] = NdefMap->StdMifareContainer.UserScrtKeyB[0]; |
| NdefMap->SendRecvBuf[12] = NdefMap->StdMifareContainer.UserScrtKeyB[1]; |
| NdefMap->SendRecvBuf[13] = NdefMap->StdMifareContainer.UserScrtKeyB[2]; |
| NdefMap->SendRecvBuf[14] = NdefMap->StdMifareContainer.UserScrtKeyB[3]; |
| NdefMap->SendRecvBuf[15] = NdefMap->StdMifareContainer.UserScrtKeyB[4]; |
| NdefMap->SendRecvBuf[16] = NdefMap->StdMifareContainer.UserScrtKeyB[5]; |
| |
| /* Write to Ndef Sector Block */ |
| NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = |
| NdefMap->StdMifareContainer.currentBlock; |
| |
| /* Copy Ndef Sector Block into buffer */ |
| memcpy(NdefMap->StdMifareContainer.Buffer, |
| &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1]), |
| PH_FRINFC_MIFARESTD_BLOCK_BYTES); |
| |
| /* Write from here */ |
| NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE; |
| NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; |
| *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; |
| |
| /* Call the Overlapped HAL Transceive function */ |
| status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd, |
| NdefMap->SendRecvBuf, NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| } else { |
| /* Error: The control should not ideally come here. |
| Return Error.*/ |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED); |
| } |
| |
| return status; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProWrSectorTrailor |
| * |
| * Description This function makes next NDEF compliant Sector ReadOnly. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MifStd_H_ProWrSectorTrailor( |
| phFriNfc_NdefMap_t* NdefMap) { |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| uint8_t sectorTrailerBlockNo = 0; |
| |
| /*Increment Sector Index */ |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex++; |
| |
| /* skip if MAD2 */ |
| if (PH_FRINFC_MIFARESTD_SECTOR_NO16 == |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex) { |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex++; |
| } |
| |
| /* if current sector index exceeds total sector index then |
| all ndef sectors are made readonly then return success |
| If a NON def sector is encountered return success*/ |
| if (NdefMap->StdMifareContainer.ReadOnlySectorIndex >= |
| NdefMap->StdMifareContainer.TotalNoSectors || |
| PH_FRINFC_MIFARESTD_NON_NDEF_COMP == |
| NdefMap->StdMifareContainer |
| .aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) { |
| status = NFCSTATUS_SUCCESS; |
| } else if (PH_FRINFC_MIFARESTD_NDEF_COMP == |
| NdefMap->StdMifareContainer |
| .aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) { |
| /* Convert next NDEF sector to read only */ |
| sectorTrailerBlockNo = phFriNfc_MifStd_H_GetSectorTrailerBlkNo( |
| NdefMap->StdMifareContainer.ReadOnlySectorIndex); |
| NdefMap->StdMifareContainer.currentBlock = sectorTrailerBlockNo; |
| NdefMap->StdMifareContainer.SectorTrailerBlockNo = sectorTrailerBlockNo; |
| |
| status = phFriNfc_MifStd_H_AuthSector(NdefMap); |
| } |
| |
| return status; |
| } |
| |
| /****************************************************************************** |
| * Function phFriNfc_MifStd_H_ProWrSectorTrailor |
| * |
| * Description This function checks mapping spec version. |
| * |
| * Returns This function return NFCSTATUS_SUCCESS in case of success |
| * In case of failure returns other failure value. |
| * |
| ******************************************************************************/ |
| static NFCSTATUS phFriNfc_MapTool_ChkSpcVer(const phFriNfc_NdefMap_t* NdefMap, |
| uint8_t VersionIndex) { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| |
| uint8_t TagVerNo = NdefMap->SendRecvBuf[VersionIndex]; |
| |
| if (TagVerNo == 0) { |
| /* Return Status Error invalid format */ |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT); |
| } else { |
| switch (NdefMap->CardType) { |
| case PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD: |
| case PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD: |
| case PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD: { |
| /* calculate the major and minor version number of Mifare std version |
| * number */ |
| status = |
| ((((PH_NFCFRI_MFSTDMAP_NFCDEV_MAJOR_VER_NUM == |
| PH_NFCFRI_MFSTDMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) && |
| (PH_NFCFRI_MFSTDMAP_NFCDEV_MINOR_VER_NUM == |
| PH_NFCFRI_MFSTDMAP_GET_MINOR_TAG_VERNO(TagVerNo))) || |
| ((PH_NFCFRI_MFSTDMAP_NFCDEV_MAJOR_VER_NUM == |
| PH_NFCFRI_MFSTDMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) && |
| (PH_NFCFRI_MFSTDMAP_NFCDEV_MINOR_VER_NUM < |
| PH_NFCFRI_MFSTDMAP_GET_MINOR_TAG_VERNO(TagVerNo)))) |
| ? NFCSTATUS_SUCCESS |
| : PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT)); |
| break; |
| } |
| |
| default: { |
| /* calculate the major and minor version number of T3VerNo */ |
| if (((PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM == |
| PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) && |
| (PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM == |
| PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo))) || |
| ((PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM == |
| PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) && |
| (PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM < |
| PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo)))) { |
| status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS); |
| } else { |
| if ((PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM < |
| PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) || |
| (PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM > |
| PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo))) { |
| status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT); |
| } |
| } |
| break; |
| } |
| } |
| } |
| |
| return (status); |
| } |