diff options
Diffstat (limited to 'src/phFriNfc_MifareStdMap.c')
-rw-r--r-- | src/phFriNfc_MifareStdMap.c | 5974 |
1 files changed, 5974 insertions, 0 deletions
diff --git a/src/phFriNfc_MifareStdMap.c b/src/phFriNfc_MifareStdMap.c new file mode 100644 index 0000000..053fd55 --- /dev/null +++ b/src/phFriNfc_MifareStdMap.c @@ -0,0 +1,5974 @@ +/* + * Copyright (C) 2010 NXP Semiconductors + * + * 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. + */ + +/*! + * \file phFriNfc_MifareStdMap.c + * \brief NFC Ndef Mapping For Remote Devices. + * + * Project: NFC-FRI + * + * $Date: Thu May 6 10:01:55 2010 $ + * $Author: ing02260 $ + * $Revision: 1.22 $ + * $Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $ + * + */ + +#ifndef PH_FRINFC_MAP_MIFARESTD_DISABLED + +#include <phFriNfc_MifareStdMap.h> +#include <phFriNfc_OvrHal.h> + +#ifndef PH_HAL4_ENABLE +#include <phFriNfc_OvrHalCmd.h> +#endif + +#include <phFriNfc_MapTools.h> + +/*! \ingroup grp_file_attributes + * \name NDEF Mapping + * + * File: \ref phFriNfcNdefMap.c + * + */ +/*@{*/ +#define PHFRINFCMIFARESTDMAP_FILEREVISION "$Revision: 1.22 $" +#define PHFRINFCMIFARESTDMAP_FILEALIASES "$Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $" +/*@}*/ +/*@}*/ + +/*! + * \name Mifare Standard Mapping - Helper Functions + * + */ +/*@{*/ + +/*! + * \brief \copydoc page_ovr Helper function for Mifare Std. This function Reads + * a block from the card. + */ +static NFCSTATUS phFriNfc_MifStd_H_RdABlock(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare Std. This function writes + * into a block of the card. + */ +static NFCSTATUS phFriNfc_MifStd_H_WrABlock(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare Std. This function authenticates + * one sector at a time. + */ +static NFCSTATUS phFriNfc_MifStd_H_AuthSector(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare 4k Check Ndef to + * get the next AID blocks + */ +static NFCSTATUS phFriNfc_MifStd4k_H_CheckNdef(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Check Ndef to store the AIDs + */ +static void phFriNfc_MifStd_H_fillAIDarray(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to get the Sector from the current block + */ +static uint8_t phFriNfc_MifStd_H_GetSect(uint8_t BlockNumber); + +/*! + * \brief \copydoc page_ovr Helper function 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 + */ +static NFCSTATUS phFriNfc_MifStd_H_BlkChk(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to read the access bits of each sector + */ +static NFCSTATUS phFriNfc_MifStd_H_RdAcsBit(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to check the access bits of each sector + */ +static NFCSTATUS phFriNfc_MifStd_H_ChkAcsBit(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for read access bits, depending + * on the read/write/check ndef function called + */ +static NFCSTATUS phFriNfc_MifStd_H_ChkRdWr(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for check ndef to check the + * ndef compliant sectors + */ +static void phFriNfc_MifStd_H_ChkNdefCmpltSects(phFriNfc_NdefMap_t *NdefMap); + +#if 0 +/*! + * \brief \copydoc page_ovr Helper function for read ndef to check the + * the length L of the ndef TLV + */ +static uint8_t phFriNfc_MifStd_H_ChkNdefLen(phFriNfc_NdefMap_t *NdefMap, + uint8_t NDEFlength, + uint8_t *CRFlag); + +/*! + * \brief \copydoc page_ovr Helper function for read ndef to copy the + * card data to the user buffer + */ +static NFCSTATUS phFriNfc_MifStd_H_RdNdefTLV(phFriNfc_NdefMap_t *NdefMap, + uint8_t *Temp16Bytes); + +#endif + +/*! + * \brief \copydoc page_ovr Helper function for read ndef to process the + * remaining bytes of length (L) in the TLV + */ +static NFCSTATUS phFriNfc_MifStd_H_RemainTLV(phFriNfc_NdefMap_t *NdefMap, + uint8_t *Flag, + uint8_t *Temp16Bytes); + +/*! + * \brief \copydoc page_ovr Helper function for read ndef to process the + * internal bytes + */ +static NFCSTATUS phFriNfc_MifStd_H_ChkIntLen(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for read ndef to check the + * internal bytes without ndef tlv flag + */ +static NFCSTATUS phFriNfc_MifStd_H_IntLenWioutNdef(phFriNfc_NdefMap_t *NdefMap, + uint8_t *Flag, + uint8_t *TempintBytes); +#if 0 +/*! + * \brief \copydoc page_ovr Helper function for read ndef to check the + * internal bytes without ndef tlv flag + */ +static NFCSTATUS phFriNfc_MifStd_H_IntLenWithNdef(phFriNfc_NdefMap_t *NdefMap, + uint8_t *TempintBytes); +#endif +/*! + * \brief \copydoc page_ovr Helper function for write ndef to add the TLV + * structure + */ +static uint8_t phFriNfc_MifStd_H_UpdateTLV(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for write ndef to write the Length TLV + * + */ +static NFCSTATUS phFriNfc_MifStd_H_WriteNdefLen(phFriNfc_NdefMap_t *NdefMap); +#if 0 +/*! + * \brief \copydoc page_ovr Helper function for check ndef to check the ndef + * compliant blocks is 0 + */ +static NFCSTATUS phFriNfc_MifStd_H_ChkNdefCmpltBlocks(phFriNfc_NdefMap_t *NdefMap); +#endif +/*! + * \brief \copydoc page_ovr Helper function to set the authentication flag + * for the ndef TLV block + */ +static void phFriNfc_MifStd_H_SetNdefBlkAuth(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to reset ndef TLV values. This is + * used when the offset is BEGIN + */ +static void phFriNfc_MifStd_H_RdWrReset(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to read the first ndef compliant block to + * change the length + */ +static NFCSTATUS phFriNfc_MifStd_H_RdtoWrNdefLen(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to get the actual length of card + * + */ +static NFCSTATUS phFriNfc_MifStd_H_GetActCardLen(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to check all the TLVs + * + */ +static NFCSTATUS phFriNfc_MifStd_H_ChkTLVs(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag); + +/*! + * \brief \copydoc page_ovr Helper function to get the next TLV + * + */ +static NFCSTATUS phFriNfc_MifStd_H_GetNxtTLV(phFriNfc_NdefMap_t *NdefMap, + uint16_t *TempLength, + uint8_t *TL4bytesFlag); + +/*! + * \brief \copydoc page_ovr Helper function to know whether the read + * 16 bytes are parsed completely + */ +static NFCSTATUS phFriNfc_MifStd_H_Chk16Bytes(phFriNfc_NdefMap_t *NdefMap, + uint16_t TempLength); + +/*! + * \brief \copydoc page_ovr Helper function to know whether the read + * 16 bytes are parsed completely + */ +static NFCSTATUS phFriNfc_MifStd_H_ChkRemainTLVs(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag, + uint8_t *NDEFFlag); + +/*! + * \brief \copydoc page_ovr Helper function to call the Completion Routine + * + */ +static void phFriNfc_MifStd_H_Complete(phFriNfc_NdefMap_t *NdefMap, + NFCSTATUS Result); + +/*! + * \brief \copydoc page_ovr Helper function to get the Mifare 1k Sector Trailer + * + */ +static void phFriNfc_MifStd_H_Get1kStTrail(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to get the Mifare 4k Sector Trailer + * + */ +static void phFriNfc_MifStd_H_Get4kStTrail(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to process the check ndef call + * + */ +static NFCSTATUS phFriNfc_MifStd_H_ProChkNdef(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to process the authentication of a sector + * + */ +static NFCSTATUS phFriNfc_MifStd_H_ProAuth(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to read 16 bytes from a specifed block no. + * + */ +static NFCSTATUS phFriNfc_MifStd_H_Rd16Bytes(phFriNfc_NdefMap_t *NdefMap, + uint8_t BlockNo); + +/*! + * \brief \copydoc page_ovr Helper function to process access bits of the + * sector trailer + */ +static NFCSTATUS phFriNfc_MifStd_H_ProAcsBits(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to check the GPB bytes + */ +static NFCSTATUS phFriNfc_MifStd_H_GPBChk(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to check for the different + * status value in the process because of proprietary forum sector + */ +static NFCSTATUS phFriNfc_MifStd_H_ProStatNotValid(phFriNfc_NdefMap_t *NdefMap, + NFCSTATUS status); + +/*! + * \brief \copydoc page_ovr Helper function to read the NDEF TLV block + */ +static NFCSTATUS phFriNfc_MifStd_H_RdBeforeWr(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to process the NDEF TLV block + * read bytes to start write from the NDEF TLV + */ +static NFCSTATUS phFriNfc_MifStd_H_ProBytesToWr(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to fill the send buffer to write + */ +static NFCSTATUS phFriNfc_MifStd_H_fillSendBuf(phFriNfc_NdefMap_t *NdefMap, + uint8_t Length); + +/*! + * \brief \copydoc page_ovr Helper function to write 16 bytes in a block + */ +static NFCSTATUS phFriNfc_MifStd_H_WrTLV(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to process the write TLV bytes in a block + */ +static NFCSTATUS phFriNfc_MifStd_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to update the remaining TLV + */ +static uint8_t phFriNfc_MifStd_H_UpdRemTLV(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to update the length field if more than one + * NULL TLVs exists before of the NDEF TLV + */ +static void phFriNfc_MifStd_H_fillTLV1(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to update the length field if more than one + * NULL TLVs does not exists before the TLV + */ +static void phFriNfc_MifStd_H_fillTLV2(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to increment/decrement the ndef tlv block + * and read the block + */ +static NFCSTATUS phFriNfc_MifStd_H_CallWrNdefLen(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to check the current block is valid or not + * if not valid decrement the current block till the valid block + */ +static NFCSTATUS phFriNfc_MifStd_H_BlkChk_1(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function update the length of the TLV if NULL TLVs + * greater than or equal to 2 + */ +static void phFriNfc_MifStd_H_fillTLV1_1(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function update the length of the TLV if NULL TLVs + * less than 2 + */ +static void phFriNfc_MifStd_H_fillTLV2_1(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to read the TLV block + */ +static NFCSTATUS phFriNfc_MifStd_H_RdTLV(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to process the read TLV block + */ +static NFCSTATUS phFriNfc_MifStd_H_ProRdTLV(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to write the terminator TLV + */ +static NFCSTATUS phFriNfc_MifStd_H_WrTermTLV(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to process the write a block function + */ +static NFCSTATUS phFriNfc_MifStd_H_ProWrABlock(phFriNfc_NdefMap_t *NdefMap); + +#ifndef PH_HAL4_ENABLE +/*! + * \brief \copydoc page_ovr Helper function to call poll function after the + * authentication has failed + */ +static NFCSTATUS phFriNfc_MifStd_H_CallPoll(phFriNfc_NdefMap_t *NdefMap); +#endif + +/*! + * \brief \copydoc page_ovr Helper function to call connect function after the + * authentication has failed + */ +static NFCSTATUS phFriNfc_MifStd_H_CallConnect(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to call disconnect function after the + * authentication has failed + */ +static NFCSTATUS phFriNfc_MifStd_H_CallDisCon(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function to call know the ndef compliant block using + */ +static void phFriNfc_MifStd1k_H_BlkChk(phFriNfc_NdefMap_t *NdefMap, + uint8_t SectorID, + uint8_t *callbreak); + +/*@}*/ +/** + * \name Mifare Standard Mapping - Constants. + * + */ +/*@{*/ +/* As per the spec, the value of this macro + PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT1 shall be 0xA0 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT1 0xA0 /**< \internal Authenticate Command for MAD Sector */ + +/* As per the spec, the value of this macro + PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT2 shall be 0xA1 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT2 0xA1 /**< \internal Authenticate Command for MAD Sector */ + +/* As per the spec, the value of this macro + PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT3 shall be 0xA2 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT3 0xA2 /**< \internal Authenticate Command for MAD Sector */ + +/* As per the spec, the value of this macro + PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT4 shall be 0xA3 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT4 0xA3 /**< \internal Authenticate Command for MAD Sector */ + +/* As per the spec, the value of this macro + PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT5 shall be 0xA4 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT5 0xA4 /**< \internal Authenticate Command for MAD Sector */ + +/* As per the spec, the value of this macro + PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT6 shall be 0xA5 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT6 0xA5 /**< \internal Authenticate Command for MAD Sector */ + +/* As per the spec, the value of this macro + PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1 shall be 0xD3 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1 0xD3 /**< \internal Authenticate Command for NDEF Sectors 1 */ + +/* As per the spec, the value of this macro + PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2 shall be 0xF7 */ +#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 */ +/*@}*/ + +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; + } + /* 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; + } + + return status; +} + +/*! + * \brief Check whether a particular Remote Device is NDEF compliant. + * + * The function checks whether the peer device is NDEF compliant. + * + * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t + * structure describing the component context. + * + * \retval NFCSTATUS_PENDING The action has been successfully triggered. + * \retval Others An error has occurred. + * + */ + +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 + { + /* set the data for additional data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + NdefMap->psDepAdditionalInfo.NAD = 0; + 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 */ +#ifndef PH_HAL4_ENABLE + sak = NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo106. + Startup106.SelRes; + atq = NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo106. + Startup106.SensRes[0]; +#else + sak = NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; + atq = NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0]; + PHNFC_UNUSED_VARIABLE(atq); +#endif + + 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 + { + /* 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 4k, sak = 0x38 atq = 0x02 */ + if ((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) || + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_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; + +#ifndef PH_HAL4_ENABLE + NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareRead; +#else + NdefMap->Cmd.MfCmd = phHal_eMifareRead; +#endif + *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_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + 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; +} + + +/*! + * \brief Initiates Reading of NDEF information from the Remote Device. + * + * 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 \ref phFriNfcNdefMap_Process has to be done once the action + * has been triggered. + */ +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; +} + +/*! + * \brief Initiates Writing of NDEF information to the Remote Device. + * + * 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 \ref phFriNfcNdefMap_Process has to be done once the action + * has been triggered. + */ +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 + */ +#ifdef PH_HAL4_ENABLE + NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG0; +#else + NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG1; +#endif /* #ifdef PH_HAL4_ENABLE */ + 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; +} + + +/*! + * \brief Completion Routine, Processing function, needed to avoid long blocking. + * \note The lower (Overlapped HAL) layer must register a pointer to 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. + * + */ + +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 */ +#if 0 + if((NDEFFlag == PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1)) + { + /* if the block is NDEF TLV then get data from here */ + Status = phFriNfc_MifStd_H_RdNdefTLV(NdefMap, &Temp16Bytes); + } +#endif + } + 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) + { + (void)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; + } + /*NdefMap->StdMifareContainer.remainingSize -= + (((NdefMap->ApduBufferSize) > (PH_FRINFC_MIFARESTD_NDEFTLV_L - + PH_FRINFC_MIFARESTD_VAL1))? + ((uint16_t)(*NdefMap->WrNdefPacketLength + + PH_FRINFC_MIFARESTD_VAL4)): + ((uint16_t)(*NdefMap->WrNdefPacketLength + + PH_FRINFC_MIFARESTD_VAL2)));*/ + 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; + +#ifndef PH_HAL4_ENABLE + Status = phFriNfc_MifStd_H_CallPoll(NdefMap); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_POLL: +#endif + 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 + { + 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; + + 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 = NFCSTATUS_SUCCESS; + NdefMap->StdMifareContainer.ReadCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + else*/ 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 */ + Status = phFriNfc_MifStd_H_CallDisCon(NdefMap); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + } + } + 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); + } +} + +static NFCSTATUS phFriNfc_MifStd_H_RdABlock(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + /* set the data for additional data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + NdefMap->psDepAdditionalInfo.NAD = 0; + + 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; + +#ifndef PH_HAL4_ENABLE + NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareRead; +#else + NdefMap->Cmd.MfCmd = phHal_eMifareRead; +#endif + /* Call the Overlapped HAL Transceive function */ + status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + 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.*/ +#ifndef PH_HAL4_ENABLE + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_CMD_ABORTED); +#else + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED); +#endif + } + } + return status; +} + + +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; + + /* set the data for additional data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + NdefMap->psDepAdditionalInfo.NAD = 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 */ + (void)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 */ + (void)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 + { + (void)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 */ + (void)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 */ + (void)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 */ + (void)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; +#ifndef PH_HAL4_ENABLE + NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16; +#else + NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; +#endif + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + /* Call the Overlapped HAL Transceive function */ + status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + 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.*/ +#ifndef PH_HAL4_ENABLE + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_CMD_ABORTED); +#else + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED); +#endif + } + } + return status; +} + +static NFCSTATUS phFriNfc_MifStd_H_AuthSector(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + /* set the data for additional data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + NdefMap->psDepAdditionalInfo.NAD = 0; + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_AUTH; + + /* Authenticate */ +#ifndef PH_HAL4_ENABLE + NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareAuthentA; +#else + NdefMap->Cmd.MfCmd = phHal_eMifareAuthentA; +#endif + 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 */ + } + + NdefMap->SendLength = MIFARE_AUTHENTICATE_CMD_LENGTH; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + /* Call the Overlapped HAL Transceive function */ + status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + + return status; +} + +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); +} + +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; + +} + +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_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 + { + /* 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; + } + } + } +} + +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 /* 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; +} + +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; +} + +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.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; +} + +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; +} + +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)) + { + /* NdefMap->StdMifareContainer.currentBlock = + ((NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + NdefMap->StdMifareContainer.currentBlock: + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_VAL4)); + NdefMap->StdMifareContainer.currentBlock = + ((NdefMap->StdMifareContainer.currentBlock == + PH_FRINFC_MIFARESTD_MAD_BLK64)? + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_VAL4): + NdefMap->StdMifareContainer.currentBlock);*/ + + 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; +} + +static void phFriNfc_MifStd_H_ChkNdefCmpltSects(phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t index = 0; + if(NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) + { + for(index = 0; index < PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR; index++) + { + /* 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; + } + } + } +} + +#if 0 +static uint8_t phFriNfc_MifStd_H_ChkNdefLen(phFriNfc_NdefMap_t *NdefMap, + uint8_t NDEFlength, + uint8_t *CRFlag) +{ + uint8_t NoLengthBytesinTLV = 0, + TempBuffer[16] = {0}; + uint16_t TempLength = 0; + + TempLength = ((NdefMap->StdMifareContainer.internalLength > 0)? + NdefMap->StdMifareContainer.internalLength : + PH_FRINFC_MIFARESTD_BYTES_READ); + + if(NdefMap->StdMifareContainer.internalLength > 0) + { + (void)memcpy( TempBuffer, + NdefMap->StdMifareContainer.internalBuf, + TempLength); + } + else + { + (void)memcpy( TempBuffer, + NdefMap->SendRecvBuf, + TempLength); + } + + /* if number of bytes for length (L) in TLV is greater than 0*/ + if(NdefMap->TLVStruct.NoLbytesinTLV != PH_FRINFC_MIFARESTD_VAL0) + { + switch(NdefMap->TLVStruct.NoLbytesinTLV) + { + /* there are two bytes remaining in the length (L) of TLV */ + case PH_FRINFC_MIFARESTD_VAL2: + NoLengthBytesinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES2; + /* Get the value of the length (L) of the TLV */ + NdefMap->TLVStruct.BytesRemainLinTLV = *TempBuffer; + NdefMap->TLVStruct.BytesRemainLinTLV = + ((NdefMap->TLVStruct.BytesRemainLinTLV + << PH_FRINFC_MIFARESTD_LEFTSHIFT8) + (TempBuffer[ + PH_FRINFC_MIFARESTD_INC_1])); + + *CRFlag = (uint8_t)((NdefMap->TLVStruct.BytesRemainLinTLV < + PH_FRINFC_MIFARESTD_NDEFTLV_L)? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + NdefMap->TLVStruct.BytesRemainLinTLV = ((*CRFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + PH_FRINFC_MIFARESTD_VAL0: + NdefMap->TLVStruct.BytesRemainLinTLV); + break; + + /* there is only one byte remaining in the length (L) of TLV */ + case PH_FRINFC_MIFARESTD_VAL1: + NoLengthBytesinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES1; + /* Get the value of the length (L) of the TLV */ + NdefMap->TLVStruct.BytesRemainLinTLV = + NdefMap->TLVStruct.prevLenByteValue; + + NdefMap->TLVStruct.BytesRemainLinTLV = + ((NdefMap->TLVStruct.BytesRemainLinTLV + << PH_FRINFC_MIFARESTD_LEFTSHIFT8) + (*TempBuffer)); + *CRFlag = (uint8_t)((NdefMap->TLVStruct.BytesRemainLinTLV < + PH_FRINFC_MIFARESTD_NDEFTLV_L)? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->TLVStruct.BytesRemainLinTLV = ((*CRFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + PH_FRINFC_MIFARESTD_VAL0: + NdefMap->TLVStruct.BytesRemainLinTLV); + break; + + default: + break; + } + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + else if(TempBuffer[NDEFlength] < + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + NoLengthBytesinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES1; + /* Get the value of the length (L) of the TLV */ + NdefMap->TLVStruct.BytesRemainLinTLV = + TempBuffer[NDEFlength]; + + /* if NDEFLength has reached 16 bytes, then the next coming byte is not of type in TLV */ + NdefMap->TLVStruct.TcheckedinTLVFlag = (((NDEFlength + PH_FRINFC_MIFARESTD_INC_1) + == PH_FRINFC_MIFARESTD_BYTES_READ)? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + /* if NDEFLength has reached 16 bytes, then the next coming byte is not of length in TLV */ + NdefMap->TLVStruct.LcheckedinTLVFlag = (((NDEFlength + PH_FRINFC_MIFARESTD_INC_1) + == PH_FRINFC_MIFARESTD_BYTES_READ)? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + } + else + { + if((NDEFlength + PH_FRINFC_MIFARESTD_INC_1) + == PH_FRINFC_MIFARESTD_BYTES_READ) + { + NoLengthBytesinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES1; + /* Number of bytes left for length (L) field in TLV */ + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL2; + /* if NDEFLength has reached 16 bytes, then the next coming byte is not of type in TLV */ + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + else if((NDEFlength + PH_FRINFC_MIFARESTD_INC_2) + == PH_FRINFC_MIFARESTD_BYTES_READ) + { + NoLengthBytesinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES2; + /* Number of bytes left for length (L) field in TLV */ + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL1; + /* if NDEFLength has reached 16 bytes, then the next byte is not of type in TLV */ + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* copy the value of the length field */ + NdefMap->TLVStruct.prevLenByteValue = + NdefMap->SendRecvBuf[(NDEFlength + PH_FRINFC_MIFARESTD_INC_1)]; + } + else + { + /* if NDEFLength has reached 16 bytes, then the next byte is not of type in TLV */ + NdefMap->TLVStruct.TcheckedinTLVFlag = (((NDEFlength + PH_FRINFC_MIFARESTD_INC_3) + == PH_FRINFC_MIFARESTD_BYTES_READ)? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + /* if NDEFLength has reached 16 bytes, then the next byte is not of length in TLV */ + NdefMap->TLVStruct.LcheckedinTLVFlag = (((NDEFlength + PH_FRINFC_MIFARESTD_INC_1) + == PH_FRINFC_MIFARESTD_BYTES_READ)? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + /* Number of bytes left for length (L) field in TLV */ + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0; + + NoLengthBytesinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES3; + /* Get the value of the length (L) of the TLV */ + NdefMap->TLVStruct.BytesRemainLinTLV = + TempBuffer[(NDEFlength + + PH_FRINFC_MIFARESTD_INC_1)]; + + NdefMap->TLVStruct.BytesRemainLinTLV = + ((NdefMap->TLVStruct.BytesRemainLinTLV + << PH_FRINFC_MIFARESTD_LEFTSHIFT8) + TempBuffer[ + (NDEFlength +PH_FRINFC_MIFARESTD_INC_2)]); + + *CRFlag = (uint8_t)((NdefMap->TLVStruct.BytesRemainLinTLV < + PH_FRINFC_MIFARESTD_NDEFTLV_L)? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + } + } + return NoLengthBytesinTLV; +} +#endif +#if 0 +static NFCSTATUS phFriNfc_MifStd_H_RdNdefTLV(phFriNfc_NdefMap_t *NdefMap, + uint8_t *Temp16Bytes) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t NDEFlength = 0, + RdFlag = 0, + CRFlag = 0; + uint16_t RemainingBytes = 0; + + while(PH_FRINFC_MIFARESTD_FLAG1 == NdefMap->TLVStruct.NdefTLVFoundFlag) + { + RemainingBytes = ((uint16_t)NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex); + if(((( NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) + + PH_FRINFC_MIFARESTD_BLOCK_BYTES) < + 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.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * 16) + + NdefMap->StdMifareContainer.internalLength); + + } + /* Ndef TLV flag to 0 */ + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; + + if((NdefMap->TLVStruct.TcheckedinTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->TLVStruct.LcheckedinTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->TLVStruct.NoLbytesinTLV != PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0)) + { + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + + /* if type (T) of TLV flag is not set then only the below check is valid + because, for eg. assume, type (T) of TLV flag is set then this means + that it is already checked from the previous 16 bytes data (T is the + last byte of 16 bytes */ + if(NdefMap->TLVStruct.TcheckedinTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) + { + CRFlag = ((NdefMap->SendRecvBuf[(*Temp16Bytes)]!= + PH_FRINFC_MIFARESTD_NDEFTLV_T)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + if(CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + RdFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + /* skip Type T of the TLV */ + *Temp16Bytes += PH_FRINFC_MIFARESTD_INC_1; + } + else + { + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + + if((*Temp16Bytes + PH_FRINFC_MIFARESTD_VAL1) == PH_FRINFC_MIFARESTD_BYTES_READ) + { + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + /* 16 bytes completed */ + 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); + } + } + break; + } + /* skip number of bytes taken by L in TLV, if L is already read */ + if(NdefMap->TLVStruct.LcheckedinTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) + { + /*CRFlag = (((*(NdefMap->SendRecvBuf + *Temp16Bytes) == + PH_FRINFC_MIFARESTD_NDEFTLV_L0) && + (NdefMap->TLVStruct.NoLbytesinTLV == + PH_FRINFC_MIFARESTD_VAL0))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0);*/ + + NDEFlength = *Temp16Bytes; + *Temp16Bytes += phFriNfc_MifStd_H_ChkNdefLen(NdefMap, + NDEFlength, + &CRFlag); + if(CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + break; + } + + } + else + { + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + + if(*Temp16Bytes == PH_FRINFC_MIFARESTD_BYTES_READ) + { + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + /* 16 bytes completed */ + 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); + } + } + break; + } + + if((NdefMap->TLVStruct.BytesRemainLinTLV <= + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes)) && + (RemainingBytes <= + NdefMap->TLVStruct.BytesRemainLinTLV)) + { + /* Copy data to user buffer */ + (void)memcpy(&(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + &(NdefMap->SendRecvBuf[ + (*Temp16Bytes)]), + RemainingBytes); + NdefMap->ApduBuffIndex += RemainingBytes; + *Temp16Bytes += ((uint8_t)RemainingBytes); + NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; + + if(NdefMap->TLVStruct.BytesRemainLinTLV == 0) + { + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + else + { + /* copy the bytes to internal buffer that are read, + but not used for the user buffer */ + (void)memcpy(NdefMap->StdMifareContainer.internalBuf, + &(NdefMap->SendRecvBuf[(*Temp16Bytes)]), + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes)); + + /* TempLength of the internal buffer */ + NdefMap->StdMifareContainer.internalLength = + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes); + } + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + else if((NdefMap->TLVStruct.BytesRemainLinTLV <= + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes)) && + (RemainingBytes > + NdefMap->TLVStruct.BytesRemainLinTLV)) + { + /* Copy data to user buffer */ + (void)memcpy(&(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + &(NdefMap->SendRecvBuf[ + (*Temp16Bytes)]), + NdefMap->TLVStruct.BytesRemainLinTLV); + /* increment the user buffer index */ + NdefMap->ApduBuffIndex += NdefMap->TLVStruct.BytesRemainLinTLV; + *Temp16Bytes += ((uint8_t)NdefMap->TLVStruct.BytesRemainLinTLV); + NdefMap->TLVStruct.BytesRemainLinTLV = 0; + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + + /* check for 16 bytes of data been used */ + if(*Temp16Bytes == PH_FRINFC_MIFARESTD_BYTES_READ) + { + /* 16 bytes completed */ + 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); + } + } + break; + } + } + else if((NdefMap->TLVStruct.BytesRemainLinTLV > + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes)) && + (RemainingBytes <= + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes))) + { + /* Copy data to user buffer */ + (void)memcpy(&(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + &(NdefMap->SendRecvBuf[ + (*Temp16Bytes)]), + RemainingBytes); + NdefMap->ApduBuffIndex += RemainingBytes; + NdefMap->TLVStruct.BytesRemainLinTLV -= 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); + + /* 16 bytes completed */ + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + } + else + { + /* copy the bytes to internal buffer, that are read, + but not used for the user buffer */ + (void)memcpy(NdefMap->StdMifareContainer.internalBuf, + &(NdefMap->SendRecvBuf[((*Temp16Bytes) + RemainingBytes)]), + (PH_FRINFC_MIFARESTD_BYTES_READ - + (*Temp16Bytes + RemainingBytes))); + + /* Length of the internal buffer */ + NdefMap->StdMifareContainer.internalLength = + (PH_FRINFC_MIFARESTD_BYTES_READ - + (*Temp16Bytes + RemainingBytes)); + } + *Temp16Bytes += ((uint8_t)RemainingBytes); + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + else + { + if((NdefMap->TLVStruct.BytesRemainLinTLV > + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes)) && + (RemainingBytes > + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes))) + { + /* Copy data to user buffer */ + (void)memcpy(&(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + &(NdefMap->SendRecvBuf[ + (*Temp16Bytes)]), + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes)); + NdefMap->ApduBuffIndex += (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes); + NdefMap->TLVStruct.BytesRemainLinTLV -= + (PH_FRINFC_MIFARESTD_BYTES_READ - *Temp16Bytes); + *Temp16Bytes = PH_FRINFC_MIFARESTD_BYTES_READ; + + + /* 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)); + } + break; + } + } + } + + if(CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + Result = (((RdFlag == PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->ApduBuffIndex == PH_FRINFC_MIFARESTD_VAL0))? + (PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_EOF_CARD_REACHED)): + Result); + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + phFriNfc_MifStd_H_Complete(NdefMap, Result); + } + return Result; +} +#endif + +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 */ + (void)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) + { + (void)memcpy( NdefMap->StdMifareContainer.internalBuf, +#ifdef PH_HAL4_ENABLE + &(NdefMap->SendRecvBuf[((*Temp16Bytes) + RemainingBytes)]), +#else + &(NdefMap->SendRecvBuf[RemainingBytes]), +#endif /* #ifdef PH_HAL4_ENABLE */ + ((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 */ + (void)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 */ + (void)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; + /* + The below macro PH_HAL4_ENABLE is added because, + there is an error with the following sequence + Read begin (for ex : with 10 bytes) + Read current (for ex : with 10 bytes). Here error buffer + is returned + Reason : During first read, internal buffer is updated + with the wrong buffer values + Actually, if we read the first block (means TLV block), it + contains even the TLV structure. so to copy the actual buffer, + the TLV shall be excluded + */ +#ifdef PH_HAL4_ENABLE + /* copy the bytes to internal buffer, that are read, + but not used for the user buffer */ + (void)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); +#else + /* copy the bytes to internal buffer, that are read, + but not used for the user buffer */ + (void)memcpy( NdefMap->StdMifareContainer.internalBuf, + &(NdefMap->SendRecvBuf[RemainingBytes]), + ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) + - RemainingBytes)); + + /* internal buffer length */ + NdefMap->StdMifareContainer.internalLength = + ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes); +#endif /* #ifdef PH_HAL4_ENABLE */ + + 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 */ + (void)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; +} + +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 */ +#if 0 + if((NDEFFlag == PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1)) + { + /* if the block is NDEF TLV then get data from here */ + Result = phFriNfc_MifStd_H_IntLenWithNdef(NdefMap, &TempintBytes); + } +#endif + return Result; +} + +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)) + { + (void)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 */ + (void)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)) + { + (void)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); +#ifdef PH_HAL4_ENABLE + + if (PH_FRINFC_MIFARESTD_FLAG1 == + NdefMap->StdMifareContainer.ReadWriteCompleteFlag) + { + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + +#endif /* #ifdef PH_HAL4_ENABLE */ + + 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)) + { + (void)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 */ + (void)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)) + { + (void)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; +} +#if 0 +static NFCSTATUS phFriNfc_MifStd_H_IntLenWithNdef(phFriNfc_NdefMap_t *NdefMap, + uint8_t *TempintBytes) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t RemainingBytes = 0; + uint8_t CRFlag = PH_FRINFC_MIFARESTD_FLAG0, + RdFlag = PH_FRINFC_MIFARESTD_FLAG0, + NDEFlength = 0; + + RemainingBytes = (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + while(PH_FRINFC_MIFARESTD_FLAG1 == NdefMap->TLVStruct.NdefTLVFoundFlag) + { + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; + RemainingBytes = ((uint16_t)NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex); + if(((( NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) + + (NdefMap->StdMifareContainer.internalLength - + *TempintBytes)) < + 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.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * 16) + + (NdefMap->StdMifareContainer.internalLength - + *TempintBytes)); + + } + + if((NdefMap->TLVStruct.TcheckedinTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->TLVStruct.LcheckedinTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->TLVStruct.NoLbytesinTLV != PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0)) + { + CRFlag = 1; + break; + } + + /* if type (T) of TLV flag is not set then only the below check is valid + because, for eg. assume, type (T) of TLV flag is set then this means + that it is already checked from the previous internal bytes data (T is the + last byte of internal bytes */ + if(NdefMap->TLVStruct.TcheckedinTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) + { + CRFlag =(uint8_t) ((NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]!= + PH_FRINFC_MIFARESTD_NDEFTLV_T)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + if(CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + RdFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + /* skip Type T of the TLV */ + *TempintBytes += PH_FRINFC_MIFARESTD_INC_1; + } + else + { + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + + if(*TempintBytes == NdefMap->StdMifareContainer.internalLength) + { + NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + /* 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)); + } + break; + } + + /* skip number of bytes taken by L in TLV, if L is already read */ + if(NdefMap->TLVStruct.LcheckedinTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) + { + CRFlag = (uint8_t)((NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]== + PH_FRINFC_MIFARESTD_NDEFTLV_L0)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + if(CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + RdFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + NDEFlength = *TempintBytes; + *TempintBytes += phFriNfc_MifStd_H_ChkNdefLen(NdefMap, + NDEFlength, + &CRFlag); + if(CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + RdFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + } + else + { + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + + if(*TempintBytes == NdefMap->StdMifareContainer.internalLength) + { + NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + /* 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)); + } + break; + } + + if( (NdefMap->TLVStruct.BytesRemainLinTLV <= + (NdefMap->StdMifareContainer.internalLength - *TempintBytes)) && + (RemainingBytes <= NdefMap->TLVStruct.BytesRemainLinTLV)) + { + /* Copy the internal bytes to the user buffer */ + (void)memcpy(&(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + &(NdefMap->StdMifareContainer.internalBuf[ + (*TempintBytes)]), + RemainingBytes); + + NdefMap->ApduBuffIndex += RemainingBytes; + *TempintBytes += ((uint8_t)RemainingBytes); + NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; + if(NdefMap->TLVStruct.BytesRemainLinTLV == 0) + { + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + /* Update the internal length */ + (void)memcpy( NdefMap->StdMifareContainer.internalBuf, + &(NdefMap->StdMifareContainer.internalBuf[ + (*TempintBytes)]), + RemainingBytes); + NdefMap->StdMifareContainer.internalLength -= (*TempintBytes + + RemainingBytes); + + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + else if((NdefMap->TLVStruct.BytesRemainLinTLV <= + (NdefMap->StdMifareContainer.internalLength - *TempintBytes)) && + (RemainingBytes > NdefMap->TLVStruct.BytesRemainLinTLV)) + { + /* Copy data to user buffer */ + (void)memcpy(&(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + &(NdefMap->StdMifareContainer.internalBuf[ + (*TempintBytes)]), + NdefMap->TLVStruct.BytesRemainLinTLV); + + /* increment the user buffer index */ + NdefMap->ApduBuffIndex += NdefMap->TLVStruct.BytesRemainLinTLV; + *TempintBytes += ((uint8_t)NdefMap->TLVStruct.BytesRemainLinTLV); + NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + + /* check for internal length bytes of data been used */ + if(*TempintBytes == NdefMap->StdMifareContainer.internalLength) + { + /* 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)); + } + break; + } + } + else if((NdefMap->TLVStruct.BytesRemainLinTLV > + (NdefMap->StdMifareContainer.internalLength - *TempintBytes)) && + (RemainingBytes <= (NdefMap->StdMifareContainer.internalLength - + *TempintBytes))) + { + /* Copy data to user buffer */ + (void)memcpy(&(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + &(NdefMap->StdMifareContainer.internalBuf[ + (*TempintBytes)]), + RemainingBytes); + NdefMap->ApduBuffIndex += RemainingBytes; + *TempintBytes += ((uint8_t)RemainingBytes); + NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; + + /* copy the bytes to internal buffer, that are read, + but not used for the user buffer */ + (void)memcpy(NdefMap->StdMifareContainer.internalBuf, + &(NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]), + (NdefMap->StdMifareContainer.internalLength - *TempintBytes)); + + /* Length of the internal buffer */ + NdefMap->StdMifareContainer.internalLength -= *TempintBytes; + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + else + { + if((NdefMap->TLVStruct.BytesRemainLinTLV > + (NdefMap->StdMifareContainer.internalLength - *TempintBytes)) && + (RemainingBytes > (NdefMap->StdMifareContainer.internalLength - + *TempintBytes))) + { + /* Copy data to user buffer */ + (void)memcpy(&(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + &(NdefMap->StdMifareContainer.internalBuf[ + (*TempintBytes)]), + (NdefMap->StdMifareContainer.internalLength - + *TempintBytes)); + NdefMap->ApduBuffIndex += (NdefMap->StdMifareContainer.internalLength - + *TempintBytes); + NdefMap->TLVStruct.BytesRemainLinTLV -= + (NdefMap->StdMifareContainer.internalLength - *TempintBytes); + *TempintBytes += (uint8_t)(NdefMap->StdMifareContainer.internalLength - + *TempintBytes); + + NdefMap->StdMifareContainer.internalLength -= *TempintBytes; + + /* 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)); + } + break; + } + } + } + + if(((( NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) + + NdefMap->StdMifareContainer.internalLength) == + PH_FRINFC_MIFARESTD_VAL0) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + } + + if(CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + Result = (((RdFlag == PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->ApduBuffIndex == PH_FRINFC_MIFARESTD_VAL0))? + (PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_EOF_NDEF_CONTAINER_REACHED)): + Result); + + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + } + + return Result; +} +#endif + +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); + } + } + + (void)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; + +#ifndef PH_HAL4_ENABLE + NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16; +#else + NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; +#endif + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + /* Call the Overlapped HAL Transceive function */ + Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + + return Result; +} +#if 0 +static NFCSTATUS phFriNfc_MifStd_H_ChkNdefCmpltBlocks(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + /* If NoOfNdefCompBlocks is found to be zero, + should we warn the user */ + if((NdefMap->StdMifareContainer.NoOfNdefCompBlocks != + PH_FRINFC_MIFARESTD_VAL0) && + (NdefMap->StdMifareContainer.NoOfNdefCompBlocks <= + PH_FRINFC_MIFARESTD4K_MAX_BLOCKS)) + { + /* Reading/writing to the card can start only + from the block 4 */ + NdefMap->StdMifareContainer.currentBlock = 4; + NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + if((Result == NFCSTATUS_SUCCESS) && + (NdefMap->StdMifareContainer.AuthDone == + PH_FRINFC_MIFARESTD_FLAG1)) + { + NdefMap->StdMifareContainer.ReadAcsBitFlag = 0; + Result = phFriNfc_MifStd_H_RdAcsBit(NdefMap); + } + else + { + Result = phFriNfc_MifStd_H_AuthSector(NdefMap); + } + } + return Result; +} +#endif + +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; + +} + +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; + +#ifndef PH_HAL4_ENABLE + NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareRead; +#else + NdefMap->Cmd.MfCmd = phHal_eMifareRead; +#endif + /* Call the Overlapped HAL Transceive function */ + Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + } + + return Result; +} + +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); +} + +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; +} + +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(;;) + { +#ifdef PH_HAL4_ENABLE + 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 +#endif /* #ifdef PH_HAL4_ENABLE */ + 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; +} + +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; +} + +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; +} + +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); + + /* 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; +} + +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; + } +} + +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; + } +} + +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))) + { + /* 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)) + { + 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; +} + +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; +} + +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; +#ifndef PH_HAL4_ENABLE + NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareRead; +#else + NdefMap->Cmd.MfCmd = phHal_eMifareRead; +#endif + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + /* Call the Overlapped HAL Transceive function */ + Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + return Result; +} + +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->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_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; +} + +static NFCSTATUS phFriNfc_MifStd_H_GPBChk(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Spec version needs to be checked every time */ + 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; +} + +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) + { +#ifdef PH_HAL4_ENABLE + /* 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))) + { + 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)) + { + Result = NFCSTATUS_SUCCESS; + NdefMap->StdMifareContainer.currentBlock = + PH_FRINFC_MIFARESTD_MAD_BLK67; + } + else +#endif /* #ifdef PH_HAL4_ENABLE */ + 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; +} + +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; +} + +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) + { + (void)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; +} + +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; +} + +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 */ + (void)memcpy(&(NdefMap->SendRecvBuf[ + Length]), + NdefMap->StdMifareContainer.internalBuf, + NdefMap->StdMifareContainer.internalLength); + } + + /* Copy Bytes to write in the send buffer */ + (void)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; + } + } +#ifdef PH_HAL4_ENABLE + + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + +#endif /* #ifdef PH_HAL4_ENABLE */ + + /* A temporary buffer to hold four bytes of data that is + written to the card */ + (void)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; +} + +static NFCSTATUS phFriNfc_MifStd_H_WrTLV(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* set the data for additional data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + NdefMap->psDepAdditionalInfo.NAD = 0; + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + /* Write from here */ + NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE; + +#ifndef PH_HAL4_ENABLE + NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16; +#else + NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; +#endif + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + /* Call the Overlapped HAL Transceive function */ + Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + + + return Result; +} + +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 */ + (void)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; +} + +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; +} + +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; + } +} + +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; + } +} + +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; +} + +static NFCSTATUS phFriNfc_MifStd_H_BlkChk_1(phFriNfc_NdefMap_t *NdefMap) +{ + /* This function is to check the current block is in the authenticated sector and + also check the block does not match with the sector trailer block. If there is a + match then decrement the block and say the caller that the authentication + is required */ + 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_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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +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; +} + + +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 */ + (void)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) + { + (void)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; +} + +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; + +#ifndef PH_HAL4_ENABLE + /*Call the Overlapped HAL POLL function */ + Result = phFriNfc_OvrHal_Disconnect( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo); +#else + /*Call the Overlapped HAL Reconnect function */ + Result = phFriNfc_OvrHal_Reconnect( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo); +#endif + + return Result; +} + +#ifndef PH_HAL4_ENABLE +static NFCSTATUS phFriNfc_MifStd_H_CallPoll(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + /*Set Ndef State*/ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_POLL; + /* Opmodes */ + NdefMap->OpModeType[PH_FRINFC_MIFARESTD_VAL0] = phHal_eOpModesMifare; + NdefMap->OpModeType[PH_FRINFC_MIFARESTD_VAL1] = phHal_eOpModesArrayTerminator; + + /* Number of devices to poll */ + NdefMap->NoOfDevices = PH_FRINFC_MIFARESTD_VAL1; + + /*Call the Overlapped HAL POLL function */ + Result = phFriNfc_OvrHal_Poll( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->OpModeType, + NdefMap->psRemoteDevInfo, + &NdefMap->NoOfDevices, + NdefMap->StdMifareContainer.DevInputParam); + return Result; +} +#endif + +static NFCSTATUS phFriNfc_MifStd_H_CallConnect(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + /*Set Ndef State*/ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_CONNECT; + + /*Call the Overlapped HAL POLL function */ + Result = phFriNfc_OvrHal_Connect( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->StdMifareContainer.DevInputParam); + return Result; +} + +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; + } + } +} + +#ifdef UNIT_TEST +#include <phUnitTestNfc_MifareStd_static.c> +#endif + +#endif /* PH_FRINFC_MAP_MIFARESTD_DISABLED */ |