diff options
Diffstat (limited to 'src/phFriNfc_MifareULMap.c')
-rw-r--r-- | src/phFriNfc_MifareULMap.c | 3270 |
1 files changed, 3270 insertions, 0 deletions
diff --git a/src/phFriNfc_MifareULMap.c b/src/phFriNfc_MifareULMap.c new file mode 100644 index 0000000..6b0ba44 --- /dev/null +++ b/src/phFriNfc_MifareULMap.c @@ -0,0 +1,3270 @@ +/* + * 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_MifareUL.c + * \brief This component encapsulates read/write/check ndef/process functionalities, + * for the Mifare UL card. + * + * Project: NFC-FRI + * + * $Date: Wed Feb 17 15:18:08 2010 $ + * $Author: ing07385 $ + * $Revision: 1.35 $ + * $Aliases: NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $ + * + */ + +#ifndef PH_FRINFC_MAP_MIFAREUL_DISABLED + +#include <phFriNfc_NdefMap.h> +#include <phFriNfc_MifareULMap.h> +#include <phFriNfc_MapTools.h> +#include <phFriNfc_OvrHal.h> +#include <phFriNfc.h> + + +/*! \ingroup grp_file_attributes + * \name NDEF Mapping + * + * File: \ref phFriNfc_MifareUL.c + * + */ +/*@{*/ +#define PHFRINFCNDEFMAP_FILEREVISION "$Revision: 1.35 $" +#define PHFRINFCNDEFMAP_FILEALIASES "$Aliases: NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $" +/*@}*/ +/* Completion Helper */ +static void phFriNfc_MifareUL_H_Complete(phFriNfc_NdefMap_t *NdefMap, + NFCSTATUS Status); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL. This function reads + * a 16 bytes from the card. + */ +static NFCSTATUS phFriNfc_MfUL_H_Rd16Bytes( phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL. This function is + * to find NDEF TLV + */ +static NFCSTATUS phFriNfc_MfUL_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL. This function is + * to check the completing the reading 16 bytes + */ +static NFCSTATUS phFriNfc_MfUL_H_Chk16Bytes(phFriNfc_NdefMap_t *NdefMap, + uint16_t TempLength); + + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL. This function is + * to read 16 bytes for the finding the ndef TLV + */ +static NFCSTATUS phFriNfc_MfUL_H_RdCardfindNdefTLV( phFriNfc_NdefMap_t *NdefMap, + uint8_t BlockNo); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL. This function is + * to check the remaining size of the 3 byte of length field in TLV + */ +static NFCSTATUS phFriNfc_MfUL_H_ChkRemainTLV(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL. This function is + * to byte and block number of the next TLV in the card and updating the + * remaining free space in the card + */ +static void phFriNfc_MfUL_H_UpdateLen(phFriNfc_NdefMap_t *NdefMap, + uint16_t DataLen); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL. Depending on the + * operation (read/write/check ndef), the next function is called + */ +static NFCSTATUS phFriNfc_MfUL_H_NxtOp(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to copy the read bytes to the internal "ReadBuf" buffer + */ +static NFCSTATUS phFriNfc_MfUL_H_CopyRdBytes(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to copy the read bytes to the user buffer + */ +static NFCSTATUS phFriNfc_MfUL_H_CpDataToUserBuf(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to write 4 bytes to 1 block in the card + */ +static NFCSTATUS phFriNfc_MfUL_H_Wr4bytes(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to check the CC bytes in block 3 card + */ +static NFCSTATUS phFriNfc_MfUL_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to read the TLVs and then start writing + */ +static NFCSTATUS phFriNfc_MfUL_H_RdBeforeWrite(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to call write operation after reading the NDEF TLV block + */ +static NFCSTATUS phFriNfc_MfUL_H_CallWrOp(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to process the written data + */ +static NFCSTATUS phFriNfc_MfUL_H_ProWrittenBytes(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to fill the send buffer before write + */ +static NFCSTATUS phFriNfc_MfUL_H_fillSendBufToWr(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to update the length L of the TLV + */ +static NFCSTATUS phFriNfc_MfUL_H_UpdateWrLen(phFriNfc_NdefMap_t *NdefMap); + +/*! + * \brief \copydoc page_ovr Helper function for Mifare UL function. This + * function is to write the terminator TLV after writing all the bytes + */ +static NFCSTATUS phFriNfc_MfUL_H_WrTermTLV(phFriNfc_NdefMap_t *NdefMap); + +#ifdef LOCK_BITS_CHECK_ENABLE + static + void + phFriNfc_MfUL_H_ChkLockBits ( + phFriNfc_NdefMap_t *NdefMap); +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ + +/*! + * \brief \copydoc select sector function for Mifare UL function. This + * function is to write the terminator TLV after writing all the bytes + */ +static NFCSTATUS phFriNfc_MfUL_H_SelectSector(phFriNfc_NdefMap_t *NdefMap, + uint8_t SectorNo, + uint8_t CmdNo, + uint8_t NextState); + + + +static void phFriNfc_MfUL_H_UpdateCrc( uint8_t ch, + uint16_t *lpwCrc ); + +static void phFriNfc_MfUL_H_ComputeCrc( int CRCType, + uint8_t *Data, + int Length, + uint8_t *TransmitFirst, + uint8_t *TransmitSecond + ); + +static void +phFriNfc_MfUL_CalcByteNum(phFriNfc_NdefMap_t *NdefMap); + + +#define CRC_A 0 +#define CRC_B 1 + + +NFCSTATUS phFriNfc_MifareUL_H_Reset(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + if ( NdefMap == NULL) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + } + else + { + /* TLV structure initialisation */ + NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_NDEFMAP_MFUL_VAL4; + NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->TLVStruct.prevLenByteValue = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->TLVStruct.ActualSize = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->TLVStruct.WrLenFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + + /* Mifare UL container initialisation */ + NdefMap->MifareULContainer.ByteNumber = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.CRindex = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.CurrentSector = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.CurrentBlock = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.InternalLength = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.ReadBufIndex = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.ReadWriteCompleteFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->MifareULContainer.RemainingSize = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + /* Fill all the structure related buffer to ZERO */ + (void)memset(NdefMap->TLVStruct.NdefTLVBuffer, + PH_FRINFC_NDEFMAP_MFUL_VAL0, + PH_FRINFC_NDEFMAP_MFUL_VAL4); + (void)memset(NdefMap->MifareULContainer.Buffer, + PH_FRINFC_NDEFMAP_MFUL_VAL0, + PH_FRINFC_NDEFMAP_MFUL_VAL4); + (void)memset(NdefMap->MifareULContainer.InternalBuf, + PH_FRINFC_NDEFMAP_MFUL_VAL0, + PH_FRINFC_NDEFMAP_MFUL_VAL4); + (void)memset(NdefMap->MifareULContainer.ReadBuf, + PH_FRINFC_NDEFMAP_MFUL_VAL0, + PH_FRINFC_NDEFMAP_MFUL_VAL64); + } + return Result; +} + +/*! + * \brief Initiates Reading of NDEF information from the Mifare UL. + * + * 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_MifareUL_RdNdef( phFriNfc_NdefMap_t *NdefMap, + uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset) +{ + NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + + if((NdefMap != NULL) && (PacketData != NULL) && (PacketDataLength != NULL) && + (*PacketDataLength != PH_FRINFC_NDEFMAP_MFUL_VAL0) && + (Offset <= PH_FRINFC_NDEFMAP_SEEK_BEGIN) && + (NdefMap->CompletionRoutine->CompletionRoutine != NULL) && + (NdefMap->CompletionRoutine->Context != NULL ) && + ((NdefMap->CardState != PH_NDEFMAP_CARD_STATE_INITIALIZED) && + (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_INVALID))) + { + /*Register PacketData to Data Buffer of NdefMap */ + NdefMap->ApduBuffer = PacketData; + /*Register PacketDataLength to Data Length of NdefMap */ + NdefMap->ApduBufferSize = *PacketDataLength ; + /* To return actual number of bytes read to the caller */ + NdefMap->NumOfBytesRead = PacketDataLength ; + *NdefMap->NumOfBytesRead = 0; + + if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || ( NdefMap->PrevOperation == + PH_FRINFC_NDEFMAP_WRITE_OPE)) + { + NdefMap->MifareULContainer.CurrentBlock = PH_FRINFC_NDEFMAP_MFUL_BLOCK4; + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_NDEFMAP_MFUL_BLOCK4; + NdefMap->MifareULContainer.RemainingSize = NdefMap->CardMemSize; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.ReadBufIndex = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.ReadWriteCompleteFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + } + + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; + NdefMap->MifareULContainer.CRindex = PH_FRINFC_NDEFMAP_CR_RD_NDEF; + + if( (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && + (NdefMap->MifareULContainer.ReadWriteCompleteFlag == + PH_FRINFC_NDEFMAP_MFUL_FLAG1)) + { + /* No space on card for reading : we have already + reached the end of file ! + Offset is set to Continue Operation */ + Result = 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); + + Result = ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)? + phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, NdefMap->MifareULContainer.CurrentBlock): + phFriNfc_MfUL_H_CpDataToUserBuf(NdefMap)); + } + } + return Result; +} + + +/*! + * \brief Initiates writing of NDEF information to the Mifare UL. + * + * The function initiates the writing of NDEF information to a Mifare UL. + * 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_MifareUL_WrNdef( phFriNfc_NdefMap_t *NdefMap, + uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset) +{ + NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + + + + if((NdefMap != NULL) && (PacketData != NULL) && (PacketDataLength != NULL) && + (*PacketDataLength != PH_FRINFC_NDEFMAP_MFUL_VAL0) && + (Offset <= PH_FRINFC_NDEFMAP_SEEK_BEGIN) && + (NdefMap->CompletionRoutine->CompletionRoutine != NULL) && + (NdefMap->CompletionRoutine->Context != NULL ) && + ((NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY) && + (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_INVALID))) + { + NdefMap->MifareULContainer.CRindex = PH_FRINFC_NDEFMAP_CR_WR_NDEF; + /*Register PacketData to Data Buffer of NdefMap */ + NdefMap->ApduBuffer = PacketData; + /*Register PacketDataLength to Data Length of NdefMap */ + NdefMap->ApduBufferSize = *PacketDataLength ; + /* To return actual number of bytes read to the caller */ + NdefMap->WrNdefPacketLength = PacketDataLength ; + *NdefMap->WrNdefPacketLength = 0; + + if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || ( NdefMap->PrevOperation == + PH_FRINFC_NDEFMAP_READ_OPE)) + { + NdefMap->MifareULContainer.CurrentSector = NdefMap->TLVStruct.NdefTLVSector; + NdefMap->MifareULContainer.CurrentBlock = NdefMap->TLVStruct.NdefTLVBlock; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.ReadBufIndex = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.ReadWriteCompleteFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->TLVStruct.WrLenFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + NdefMap->MifareULContainer.InternalLength = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.RemainingSize = + (NdefMap->CardMemSize - + (((NdefMap->TLVStruct.NdefTLVBlock - + PH_FRINFC_NDEFMAP_MFUL_BYTE4) * + PH_FRINFC_NDEFMAP_MFUL_BYTE4) + + NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + } + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; + NdefMap->MifareULContainer.CRindex = PH_FRINFC_NDEFMAP_CR_WR_NDEF; + + if( (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && + (NdefMap->MifareULContainer.ReadWriteCompleteFlag == + PH_FRINFC_NDEFMAP_MFUL_FLAG1)) + { + /* No space on card for reading : we have already + reached the end of file ! + Offset is set to Continue Operation */ + Result = 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); + + if (NdefMap->TLVStruct.NdefTLVSector == 1) + { + NdefMap->MifareULContainer.CurrentSector = 1; + + /* Change to sector 1 */ + Result = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_WRITE_INIT_1); + + } + else + { + Result = ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)? + phFriNfc_MfUL_H_RdBeforeWrite(NdefMap): + phFriNfc_MfUL_H_fillSendBufToWr(NdefMap)); + } + } + } + + + return Result; +} + + + +/*! + * \brief Check whether a particular Mifare UL is NDEF compliant. + * + * The function checks whether the peer device is NDEF compliant. + * + */ + +NFCSTATUS phFriNfc_MifareUL_ChkNdef( phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + uint8_t index=0, + pSensRes[2] = {0}; + + /* set the data for additional data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + NdefMap->psDepAdditionalInfo.NAD = 0; + + /* + * Changed + * Description: CardInfo106 replase + */ + + /* retrive remote card information */ + pSensRes[0] = NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0]; + + NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_NDEFMAP_MFUL_VAL4; +#ifdef LOCK_BITS_CHECK_ENABLE + NdefMap->MifareULContainer.CurrentBlock = PH_FRINFC_NDEFMAP_MFUL_BLOCK2; +#else + NdefMap->MifareULContainer.CurrentBlock = PH_FRINFC_NDEFMAP_MFUL_BLOCK3; +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ + NdefMap->MifareULContainer.CRindex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF; + + /* Check for Mifare Bit information */ + if (((pSensRes[0] & PH_FRINFC_NDEFMAP_MFUL_CHECK_RESP) == PH_FRINFC_NDEFMAP_MFUL_CHECK_RESP)) + { + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE; + /* set the offset*/ + NdefMap->SendRecvBuf[index] = NdefMap->MifareULContainer.CurrentBlock; + + /*set the send length*/ + NdefMap->SendLength = PH_FRINFC_NDEFMAP_MFUL_MAX_SEND_BUF_TO_READ; + + /* Change the state to check ndef compliancy */ + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_CHK_NDEF_COMP; + + /* Set the card type as Mifare UL */ + NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; + + /* set the cmd to mifare read*/ + /* + * Changed + * Description: phHal_eMifareCmdListMifareRead replace with phHal_eMifareRead + */ + NdefMap->Cmd.MfCmd = phHal_eMifareRead; + + /* Set the CR and context for Mifare operations*/ + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareUL_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + /*Set the Length*/ + *NdefMap->SendRecvLength = PH_FRINFC_NDEFMAP_MF_READ_BLOCK_SIZE; + + + /*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 + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE); + } + return status; +} + +static void +phFriNfc_MfUL_CalcByteNum(phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t i = PH_FRINFC_NDEFMAP_MFUL_VAL0; + uint16_t TemLength = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + + for (i = 0; i < 16; i++) + { + if ((NdefMap->MifareULContainer.ReadBuf[i] == + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_T) && + ((NdefMap->MifareULContainer.ReadBuf[i + 1] == + NdefMap->TLVStruct.ActualSize) || + (NdefMap->MifareULContainer.ReadBuf[i + 1] == 0xFF))) + { + if (NdefMap->MifareULContainer.ReadBuf[i + 1] == 0xFF) + { + TemLength = NdefMap->MifareULContainer.ReadBuf[i + 2] | + ((uint16_t)NdefMap->MifareULContainer.ReadBuf[i + 3] << 8); + + if (TemLength == NdefMap->TLVStruct.ActualSize) + { + NdefMap->MifareULContainer.ByteNumber = i + 1; + break; + } + } + else + { + NdefMap->MifareULContainer.ByteNumber = i + 1; + break; + } + } + } + + return; +} + + +#ifdef LOCK_BITS_CHECK_ENABLE + +#define MIF_UL_LOCK_BIT_CHECK 0xFF +#define MIF_UL_LOCK_BIT_0_VALUE 0x0F +#define MIF_UL_LOCK_BIT_1_VALUE 0x00 + +static +void +phFriNfc_MfUL_H_ChkLockBits ( + phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t index = 2; + + if (((NdefMap->SendRecvBuf[index] & + MIF_UL_LOCK_BIT_CHECK) > MIF_UL_LOCK_BIT_0_VALUE) || + (MIF_UL_LOCK_BIT_1_VALUE != + (NdefMap->SendRecvBuf[(index + 1)] & MIF_UL_LOCK_BIT_CHECK))) + { + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY; + } +} + +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ + +/*! + * \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_MifareUL_Process( void *Context, + NFCSTATUS Status) + +{ + + uint8_t index = PH_FRINFC_NDEFMAP_MFUL_VAL0, + i = PH_FRINFC_NDEFMAP_MFUL_VAL0; + phFriNfc_NdefMap_t *NdefMap; + uint16_t TemLength = PH_FRINFC_NDEFMAP_MFUL_VAL0; + /*uint16_t TempByte = PH_FRINFC_NDEFMAP_MFUL_VAL0; */ + static uint8_t CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + + /* set the context to Map module */ + + NdefMap = (phFriNfc_NdefMap_t *)Context; + + if ( Status == NFCSTATUS_SUCCESS ) + { + switch (NdefMap->State) + { + case PH_FRINFC_NDEFMAP_MFUL_STATE_CHK_NDEF_COMP: + if (*NdefMap->SendRecvLength == + PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16) + { + /* Checks for the Ndef Compliency and validy of the memory size*/ + Status = phFriNfc_MfUL_H_ChkCCBytes(NdefMap); + CRFlag = (uint8_t)((Status != NFCSTATUS_SUCCESS)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + +#ifdef LOCK_BITS_CHECK_ENABLE + + /* Check for lock bits */ + if (NFCSTATUS_SUCCESS == Status) + { + phFriNfc_MfUL_H_ChkLockBits(NdefMap); + } + +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ + + /* Find the NDEF TLV */ + NdefMap->MifareULContainer.CurrentBlock = PH_FRINFC_NDEFMAP_MFUL_BLOCK4; + Status = ((Status != NFCSTATUS_SUCCESS)? + Status: + phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->MifareULContainer.CurrentBlock)); + CRFlag = (uint8_t)(((Status != NFCSTATUS_PENDING ) || + (CRFlag == PH_FRINFC_NDEFMAP_MFUL_FLAG1))? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + +#ifdef PH_HAL4_ENABLE + if ((Status != NFCSTATUS_PENDING ) && + (Status != NFCSTATUS_SUCCESS)) + { + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; + } +#endif /* #ifdef PH_HAL4_ENABLE */ + } + break; + + + case PH_FRINFC_NDEFMAP_MFUL_STATE_READ: + /* check the received bytes size equals 16 bytes*/ + if (*NdefMap->SendRecvLength == + PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16) + { + if(NdefMap->MifareULContainer.ReadBufIndex < + (NdefMap->TLVStruct.ActualSize + (((NdefMap->TLVStruct.NdefTLVBlock - PH_FRINFC_NDEFMAP_MFUL_BLOCK4) + * PH_FRINFC_NDEFMAP_MFUL_VAL4) + (NdefMap->TLVStruct.NdefTLVByte - 1) + 4))) + { + Status = phFriNfc_MfUL_H_CopyRdBytes(NdefMap); + } + + if (Status == NFCSTATUS_SUCCESS) + { + if(NdefMap->MifareULContainer.ReadBufIndex >= + (NdefMap->TLVStruct.ActualSize + (((NdefMap->TLVStruct.NdefTLVBlock - PH_FRINFC_NDEFMAP_MFUL_BLOCK4) + * PH_FRINFC_NDEFMAP_MFUL_VAL4) + (NdefMap->TLVStruct.NdefTLVByte - 1) + 4))) + { + + phFriNfc_MfUL_CalcByteNum(NdefMap); +#if 0 + for (i = 0; i < 16; i++) + { + if ((NdefMap->MifareULContainer.ReadBuf[i] == + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_T) && + ((NdefMap->MifareULContainer.ReadBuf[i + 1] == + NdefMap->TLVStruct.ActualSize) || + (NdefMap->MifareULContainer.ReadBuf[i + 1] == 0xFF))) + { + if (NdefMap->MifareULContainer.ReadBuf[i + 1] == 0xFF) + { + TemLength = NdefMap->MifareULContainer.ReadBuf[i + 2] | + ((uint16_t)NdefMap->MifareULContainer.ReadBuf[i + 3] << 8); + + if (TemLength == NdefMap->TLVStruct.ActualSize) + { + NdefMap->MifareULContainer.ByteNumber = i + 1; + break; + } + } + else + { + NdefMap->MifareULContainer.ByteNumber = i + 1; + break; + } + } + } +#endif + + if (NdefMap->MifareULContainer.ReadBuf + [NdefMap->MifareULContainer.ByteNumber] == 0xFF) + { + NdefMap->MifareULContainer.ByteNumber = + NdefMap->MifareULContainer.ByteNumber + 3; + } + else + { + NdefMap->MifareULContainer.ByteNumber = + NdefMap->MifareULContainer.ByteNumber + 1; + } + + Status = phFriNfc_MfUL_H_CpDataToUserBuf(NdefMap); + if (NdefMap->MifareULContainer.CurrentSector > 0) + { + NdefMap->MifareULContainer.CurrentSector = 0; + NdefMap->PrevState = PH_FRINFC_NDEFMAP_MFUL_STATE_READ; + + Status = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RESET_1); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING )? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + else + { + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + else + { + Status = phFriNfc_MfUL_H_Rd16Bytes(NdefMap); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + } + else + { + + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + } + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_RECEIVE_LENGTH); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_WRITE: + Status = phFriNfc_MfUL_H_ProWrittenBytes(NdefMap); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_FND_NDEF_COMP: + if (*NdefMap->SendRecvLength == + PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16) + { + switch(NdefMap->PrevOperation) + { + case PH_FRINFC_NDEFMAP_CHECK_OPE: + case PH_FRINFC_NDEFMAP_READ_OPE: + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + if(NdefMap->TLVStruct.NoLbytesinTLV > + PH_FRINFC_NDEFMAP_MFUL_VAL0) + { + Status = phFriNfc_MfUL_H_ChkRemainTLV(NdefMap, &CRFlag); + } + else + { + if(NdefMap->TLVStruct.NdefTLVFoundFlag != + PH_FRINFC_NDEFMAP_MFUL_FLAG1) + { + /* Find the NDEF TLV */ + Status = phFriNfc_MfUL_H_findNDEFTLV(NdefMap, &CRFlag); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING )? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + } + if((NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_NDEFMAP_MFUL_FLAG1) && + (NdefMap->TLVStruct.NoLbytesinTLV == + PH_FRINFC_NDEFMAP_MFUL_VAL0)) + { + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + /* Ndef TLV found, so call the next function depending on the + check/read/write ndef operation */ + + if (NdefMap->MifareULContainer.CurrentSector > 0) + { + NdefMap->MifareULContainer.CurrentSector = 0; + NdefMap->PrevState = PH_FRINFC_NDEFMAP_MFUL_STATE_FND_NDEF_COMP; + + Status = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RESET_1); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING )? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + else + { + /* Sector is 0 no need to send sector select */ + Status = phFriNfc_MfUL_H_NxtOp(NdefMap, &CRFlag); + } + } + +#ifdef PH_HAL4_ENABLE + if ((Status != NFCSTATUS_PENDING ) && + (Status != NFCSTATUS_SUCCESS) && + (PH_FRINFC_NDEFMAP_CHECK_OPE == + NdefMap->PrevOperation)) + { + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; + } +#endif /* #ifdef PH_HAL4_ENABLE */ + break; + + case PH_FRINFC_NDEFMAP_WRITE_OPE: + /* Remove UpdateWrLen */ + Status = ((NdefMap->TLVStruct.WrLenFlag == + PH_FRINFC_NDEFMAP_MFUL_FLAG1)? + phFriNfc_MfUL_H_UpdateWrLen(NdefMap): + phFriNfc_MfUL_H_CallWrOp(NdefMap)); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + break; + + default: + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_REMOTE_DEVICE); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + break; + + } + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_TERM_TLV: + Status = phFriNfc_MfUL_H_UpdateWrLen(NdefMap); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_WR_LEN_TLV: + if(((((NdefMap->TLVStruct.NdefTLVByte - + PH_FRINFC_NDEFMAP_MFUL_VAL1) == + PH_FRINFC_NDEFMAP_MFUL_VAL3) && + (NdefMap->MifareULContainer.CurrentBlock == + (NdefMap->TLVStruct.NdefTLVBlock + + PH_FRINFC_NDEFMAP_MFUL_VAL1))) || + (((NdefMap->TLVStruct.NdefTLVByte - + PH_FRINFC_NDEFMAP_MFUL_VAL1) < + PH_FRINFC_NDEFMAP_MFUL_VAL3) && ( + NdefMap->MifareULContainer.CurrentBlock == + NdefMap->TLVStruct.NdefTLVBlock)))) + { + (void)memcpy(NdefMap->MifareULContainer.InternalBuf, + NdefMap->MifareULContainer.Buffer, + NdefMap->MifareULContainer.InternalLength); + } + (void)memcpy(NdefMap->TLVStruct.NdefTLVBuffer, + NdefMap->MifareULContainer.Buffer, + PH_FRINFC_NDEFMAP_MFUL_VAL4); + + NdefMap->CardState =(uint8_t) ((NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INITIALIZED)? + PH_NDEFMAP_CARD_STATE_READ_WRITE: + NdefMap->CardState); + NdefMap->ApduBuffIndex = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->NumOfBytesWritten = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + if (NdefMap->MifareULContainer.CurrentSector > 0) + { + /* Reset sector */ + NdefMap->MifareULContainer.CurrentSector = 0; + NdefMap->PrevState = PH_FRINFC_NDEFMAP_MFUL_STATE_WR_LEN_TLV; + + Status = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RESET_1); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + else + { + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_CHK_1: + /* check the received bytes size equals 1 byte*/ + if (*NdefMap->SendRecvLength == + PH_FRINFC_NDEFMAP_MFUL_VAL1) + { + if (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] == 0x0A) + { + /* Send second command */ + Status = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 2, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_CHK_2); + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_RECEIVE_LENGTH); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_CHK_2: + { + NdefMap->MifareULContainer.CurrentBlock += + PH_FRINFC_NDEFMAP_MFUL_BLOCK4; + + Status = phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->MifareULContainer.CurrentBlock); + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_READ_1: + /* check the received bytes size equals 1 byte*/ + if (*NdefMap->SendRecvLength == + PH_FRINFC_NDEFMAP_MFUL_VAL1) + { + if (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] == 0x0A) + { + /* Send second command */ + Status = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 2, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_READ_2); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG0; + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_RECEIVE_LENGTH); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_READ_2: + { + if (NdefMap->MifareULContainer.CurrentBlock == 0xFF) + { + NdefMap->MifareULContainer.CurrentBlock = 0; + } + else + { + NdefMap->MifareULContainer.CurrentBlock = + (NdefMap->TLVStruct.NdefTLVBlock / 4) * 4; + } + + Status = phFriNfc_MfUL_H_Rd16Bytes(NdefMap); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_WRITE_1: + /* check the received bytes size equals 1 byte*/ + if (*NdefMap->SendRecvLength == + PH_FRINFC_NDEFMAP_MFUL_VAL1) + { + if (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] == 0x0A) + { + /* Send second command */ + Status = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 2, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_WRITE_2); + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_RECEIVE_LENGTH); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_WRITE_2: + { + NdefMap->MifareULContainer.CurrentBlock = 0; + Status = phFriNfc_MfUL_H_fillSendBufToWr(NdefMap); + + if((Status == NFCSTATUS_SUCCESS) && + (NdefMap->TLVStruct.SetTermTLVFlag != + PH_FRINFC_NDEFMAP_MFUL_FLAG1) && + (NdefMap->MifareULContainer.RemainingSize > + PH_FRINFC_NDEFMAP_MFUL_VAL0)) + { + Status = phFriNfc_MfUL_H_WrTermTLV(NdefMap); + } + else + { + if((Status == NFCSTATUS_SUCCESS) && + (NdefMap->TLVStruct.SetTermTLVFlag == + PH_FRINFC_NDEFMAP_MFUL_FLAG1)) + { + Status = phFriNfc_MfUL_H_UpdateWrLen(NdefMap); + } + } + + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_WRITE_INIT_1: + /* check the received bytes size equals 1 byte*/ + if (*NdefMap->SendRecvLength == + PH_FRINFC_NDEFMAP_MFUL_VAL1) + { + if (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] == 0x0A) + { + /* Send second command */ + Status = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 2, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_WRITE_INIT_2); + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_RECEIVE_LENGTH); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_WRITE_INIT_2: + { + Status = ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)? + phFriNfc_MfUL_H_RdBeforeWrite(NdefMap): + phFriNfc_MfUL_H_fillSendBufToWr(NdefMap)); + + + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + break; + + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RW_1: + /* check the received bytes size equals 1 byte*/ + if (*NdefMap->SendRecvLength == + PH_FRINFC_NDEFMAP_MFUL_VAL1) + { + if (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] == 0x0A) + { + /* Send second command */ + Status = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 2, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RW_2); + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_RECEIVE_LENGTH); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RW_2: + { + NdefMap->MifareULContainer.CurrentBlock = 0; + + NdefMap->SendRecvBuf[index] = + NdefMap->MifareULContainer.CurrentBlock; + index++; + NdefMap->SendRecvBuf[index] = + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L; + index++; + + if((((NdefMap->TLVStruct.NdefTLVByte - + PH_FRINFC_NDEFMAP_MFUL_VAL1) == PH_FRINFC_NDEFMAP_MFUL_VAL0) || + ((NdefMap->TLVStruct.NdefTLVByte - PH_FRINFC_NDEFMAP_MFUL_VAL1) + == PH_FRINFC_NDEFMAP_MFUL_VAL3))) + { + /* Length to know how many bytes has to be written to the card */ + TemLength = (((NdefMap->TLVStruct.NdefTLVByte - PH_FRINFC_NDEFMAP_MFUL_VAL1) == + PH_FRINFC_NDEFMAP_MFUL_VAL0)? + PH_FRINFC_NDEFMAP_MFUL_VAL2: + PH_FRINFC_NDEFMAP_MFUL_VAL3); + + if(NdefMap->ApduBufferSize >= TemLength) + { + /* Prepare the receive buffer */ + (void)memcpy(&(NdefMap->SendRecvBuf[ + index]), + &(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + TemLength); + + /* Number of bytes written to the card from user buffer */ + NdefMap->NumOfBytesWritten = TemLength; + + index = index+(uint8_t)TemLength; + /* Exact number of bytes written in the card including TLV */ + *NdefMap->DataCount = (index - PH_FRINFC_NDEFMAP_MFUL_VAL1); + } + else + { + /* Prepare the receive buffer */ + (void)memcpy(&(NdefMap->SendRecvBuf[ + index]), + &(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + (uint16_t)NdefMap->ApduBufferSize); + + /* Number of bytes written to the card from user buffer */ + NdefMap->NumOfBytesWritten = (uint16_t)NdefMap->ApduBufferSize; + + index= index +(uint8_t)NdefMap->ApduBufferSize; + /* Exact number of bytes written in the card including TLV */ + *NdefMap->DataCount = (index - PH_FRINFC_NDEFMAP_MFUL_VAL1); + + for(i = index; i < PH_FRINFC_NDEFMAP_MFUL_WR_A_BLK; i++) + { + NdefMap->SendRecvBuf[i] = (uint8_t)((i == index)? + PH_FRINFC_NDEFMAP_MFUL_TERMTLV: + PH_FRINFC_NDEFMAP_MFUL_NULLTLV); + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + + /* store the bytes in buffer till the bytes are + written in a block */ + (void)memcpy(NdefMap->MifareULContainer.Buffer, + &(NdefMap->SendRecvBuf[ + PH_FRINFC_NDEFMAP_MFUL_VAL1]), + (PH_FRINFC_NDEFMAP_MFUL_WR_A_BLK - + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + (void)memcpy(NdefMap->TLVStruct.NdefTLVBuffer, + NdefMap->MifareULContainer.Buffer, + (PH_FRINFC_NDEFMAP_MFUL_WR_A_BLK - + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + /* Change the state to check ndef compliancy */ + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_WRITE; + + Status = phFriNfc_MfUL_H_Wr4bytes(NdefMap); + } + + + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RESET_1: + /* check the received bytes size equals 1 byte*/ + if (*NdefMap->SendRecvLength == + PH_FRINFC_NDEFMAP_MFUL_VAL1) + { + if (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] == 0x0A) + { + /* Send second command */ + Status = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 2, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RESET_2); + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_RECEIVE_LENGTH); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + + } + break; + + case PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RESET_2: + { + if (NdefMap->PrevState == PH_FRINFC_NDEFMAP_MFUL_STATE_FND_NDEF_COMP) + { + Status = phFriNfc_MfUL_H_NxtOp(NdefMap, &CRFlag); + } + else if (NdefMap->PrevState == PH_FRINFC_NDEFMAP_MFUL_STATE_READ) + { + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + else if (NdefMap->PrevState == PH_FRINFC_NDEFMAP_MFUL_STATE_WRITE) + { + Status = phFriNfc_MfUL_H_UpdateWrLen(NdefMap); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + } + else if (NdefMap->PrevState == PH_FRINFC_NDEFMAP_MFUL_STATE_WR_LEN_TLV) + { + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + else + { + /* read error */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_READ_FAILED); + CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + + } + } + break; + + default: + /*set the invalid state*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST); + phFriNfc_MifareUL_H_Complete(NdefMap, Status); + break; + } + if(CRFlag == PH_FRINFC_NDEFMAP_MFUL_FLAG1) + { + /* call the CR routine*/ + phFriNfc_MifareUL_H_Complete(NdefMap, Status); + } + } + else + { + phFriNfc_MifareUL_H_Complete(NdefMap,Status); + } +} + +static NFCSTATUS phFriNfc_MfUL_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap ) +{ + NFCSTATUS Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + +#ifdef LOCK_BITS_CHECK_ENABLE + switch(NdefMap->SendRecvBuf[7]) +#else + switch(NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_BYTE3]) +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ + { + case PH_FRINFC_NDEFMAP_MFUL_CC_BYTE3_RW: + /* This state can be either INITIALISED or READWRITE. but default + is INITIALISED */ + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED; + break; + + case PH_FRINFC_NDEFMAP_MFUL_CC_BYTE3_RO: + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY; + break; + + default : + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; + } + + + + /* Check for Ndef compliancy : 0 and 1 byte spcifies the ndef compliancy + 2 byte specifies the version of the MF UL tag*/ +#ifdef LOCK_BITS_CHECK_ENABLE + if(( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_BYTE4] == +#else + if(( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_BYTE0] == +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ + PH_FRINFC_NDEFMAP_MFUL_CC_BYTE0) && ( + (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED) || + (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY))) + { + /* Check the version number */ + Result =phFriNfc_MapTool_ChkSpcVer( NdefMap, +#ifdef LOCK_BITS_CHECK_ENABLE + 5); + +#else + PH_FRINFC_NDEFMAP_MFUL_BYTE1); + +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ +#if 0 +#ifdef PH_NDEF_MIFARE_ULC + if (Result == NFCSTATUS_SUCCESS) + { +#ifdef LOCK_BITS_CHECK_ENABLE + + if (NdefMap->SendRecvBuf[6] == 0x06) + { + NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; + } + else if (NdefMap->SendRecvBuf[6] == 0x12) + { +// NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD; + NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; + } + +#else /* #ifdef LOCK_BITS_CHECK_ENABLE */ + + if (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_BYTE2] == 0x06) + { + NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; + } + else if (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_BYTE2] == 0x12) + { +// NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD; + NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; + } + +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ + else + { + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_REMOTE_DEVICE); + } + } +#else + + /* Check the CC header size: Only valid ones are + 0x06 for 48 bytes. */ +#ifdef LOCK_BITS_CHECK_ENABLE + Result = ((( NdefMap->SendRecvBuf[6] != +#else /* #ifdef LOCK_BITS_CHECK_ENABLE */ + Result = ((( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_BYTE2] != +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ + PH_FRINFC_NDEFMAP_MFUL_CC_BYTE2) || (Result != + NFCSTATUS_SUCCESS))? + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_REMOTE_DEVICE)): + Result); +#endif /* #ifdef PH_NDEF_MIFARE_ULC */ +#endif + NdefMap->MifareULContainer.RemainingSize = + NdefMap->CardMemSize = ((Result == NFCSTATUS_SUCCESS)? +#ifdef LOCK_BITS_CHECK_ENABLE + (NdefMap->SendRecvBuf[6] * +#else /* #ifdef LOCK_BITS_CHECK_ENABLE */ + (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_BYTE2] * +#endif /* #ifdef LOCK_BITS_CHECK_ENABLE */ + PH_FRINFC_NDEFMAP_MFUL_MUL8): + NdefMap->CardMemSize); + + if (NdefMap->CardMemSize > 256) + { + NdefMap->CardMemSize = NdefMap->CardMemSize - 2; + NdefMap->MifareULContainer.RemainingSize = NdefMap->CardMemSize; + } + + } + else + { + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; + } + + + return Result; +} + +/*! + * \brief this shall notify the integration software with respective + * success/error status along with the completion routines. + * + * This routine is called from the mifareul process function. + * + */ + +static void phFriNfc_MifareUL_H_Complete(phFriNfc_NdefMap_t *NdefMap, + NFCSTATUS Status) +{ + if(NdefMap!=NULL) + { + if((PH_FRINFC_NDEFMAP_MFUL_STATE_WRITE == NdefMap->State) + && (NFCSTATUS_SUCCESS != Status)) + { + *NdefMap->WrNdefPacketLength = 0; + } + /* set the state back to the Reset_Init state*/ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT; + + /* set the completion routine*/ + NdefMap->CompletionRoutine[NdefMap->MifareULContainer.CRindex]. + CompletionRoutine(NdefMap->CompletionRoutine->Context, Status); + } +} + +static NFCSTATUS phFriNfc_MfUL_H_Rd16Bytes( phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_READ; + + /* Set the previous operation flag to read. */ + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; + + /* Have we already read the entire file? */ + if(NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize) + { + /* set the data for additional data exchange */ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] = + NdefMap->MifareULContainer.CurrentBlock; + NdefMap->SendLength = PH_FRINFC_NDEFMAP_MFUL_VAL1; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + /* + * Changed + * Description: replace with phHal_eMifareRead + */ + + NdefMap->Cmd.MfCmd = phHal_eMifareRead; + + /* 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_MfUL_H_Wr4bytes( phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* set the receive length*/ + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; + + /* + * Changed + * Description: phHal_eMifareCmdListMifareWrite4 replace with phHal_eMifareWrite4 + */ + /* set the cmd to mifare read*/ + NdefMap->Cmd.MfCmd = phHal_eMifareWrite4; + + /* Set the CR and context for Mifare operations*/ + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareUL_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + NdefMap->SendLength = PH_FRINFC_NDEFMAP_MFUL_WR_A_BLK; + /*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_MfUL_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t ShiftLength = PH_FRINFC_NDEFMAP_MFUL_VAL0, + TemLength = PH_FRINFC_NDEFMAP_MFUL_VAL0, + Temp16Bytes = PH_FRINFC_NDEFMAP_MFUL_VAL0; + Temp16Bytes = ((NdefMap->TLVStruct.NdefTLVByte > PH_FRINFC_NDEFMAP_MFUL_VAL0)? + (NdefMap->TLVStruct.NdefTLVByte - PH_FRINFC_NDEFMAP_MFUL_VAL1): + NdefMap->TLVStruct.NdefTLVByte); + for(;;) + { + if(NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_NULLTLV) + { + NdefMap->MifareULContainer.RemainingSize -= + PH_FRINFC_NDEFMAP_MFUL_VAL1; +#ifdef PH_HAL4_ENABLE + /* This check is added to know the remaining size in + the card is not 0, if this is 0, then complete card has + been read */ + if (NdefMap->MifareULContainer.RemainingSize == + PH_FRINFC_NDEFMAP_MFUL_VAL0) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + break; + } + else + { + Result = NFCSTATUS_SUCCESS; + } +#else + Result = ((NdefMap->MifareULContainer.RemainingSize == + PH_FRINFC_NDEFMAP_MFUL_VAL0)? + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT)): + NFCSTATUS_SUCCESS); +#endif /* #ifdef PH_HAL4_ENABLE */ + Temp16Bytes++; +#ifdef PH_HAL4_ENABLE + /* This code is added to read next 16 bytes. This means previous + 16 bytes read contains only NULL TLV, so read further to get the + NDEF TLV */ + Result = phFriNfc_MfUL_H_Chk16Bytes(NdefMap, + Temp16Bytes); + if(NFCSTATUS_SUCCESS != Result) + { + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->TLVStruct.NdefTLVBlock + PH_FRINFC_NDEFMAP_MFUL_VAL4; + break; + } +#endif /* #ifdef PH_HAL4_ENABLE */ + } + else + { + Result = ((NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_TERMTLV)? + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT)): + NFCSTATUS_SUCCESS); + + if(Result != NFCSTATUS_SUCCESS) + { + *CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + break; + } + +#ifdef PH_NDEF_MIFARE_ULC + if ((NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_LOCK_CTRL_TLV) || + (NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_MEM_CTRL_TLV) ) + { + + NdefMap->TLVStruct.NdefTLVByte = + ((Temp16Bytes % + PH_FRINFC_NDEFMAP_MFUL_VAL4) + + PH_FRINFC_NDEFMAP_MFUL_VAL1); + + Result = phFriNfc_MfUL_H_Chk16Bytes(NdefMap, + Temp16Bytes); + if(Result != NFCSTATUS_SUCCESS) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_NDEFMAP_MFUL_FLAG1; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_NDEFMAP_MFUL_VAL3; + break; + } + Temp16Bytes++; + NdefMap->MifareULContainer.RemainingSize -= + PH_FRINFC_NDEFMAP_MFUL_VAL1; + + if(NdefMap->MifareULContainer.RemainingSize == + PH_FRINFC_NDEFMAP_MFUL_VAL0) + { + Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT)); + break; + } + + Result = phFriNfc_MfUL_H_Chk16Bytes(NdefMap, + Temp16Bytes); + if(Result != NFCSTATUS_SUCCESS) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_NDEFMAP_MFUL_FLAG1; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_NDEFMAP_MFUL_VAL3; + break; + } + + + /* If the value of the Length(L) in TLV is FF then enter else + check for the card memory */ + if((NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_LFF) || + ((NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L) && + (NdefMap->TLVStruct.NdefTLVFoundFlag != + PH_FRINFC_NDEFMAP_MFUL_FLAG1))) + { + /* In the present case, the card space is not greater + than 0xFF */ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + + *CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + break; + } + else + { + NdefMap->TLVStruct.BytesRemainLinTLV = + NdefMap->SendRecvBuf[Temp16Bytes]; + + NdefMap->TLVStruct.ActualSize = + NdefMap->SendRecvBuf[Temp16Bytes]; + + if((NdefMap->MifareULContainer.RemainingSize < + NdefMap->SendRecvBuf[Temp16Bytes]) || + (NdefMap->MifareULContainer.RemainingSize < + PH_FRINFC_NDEFMAP_MFUL_VAL2) || + (NdefMap->TLVStruct.BytesRemainLinTLV > + (NdefMap->MifareULContainer.RemainingSize)) || + ((NdefMap->TLVStruct.BytesRemainLinTLV == + PH_FRINFC_NDEFMAP_MFUL_VAL0) && + (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))) + { + /* No NDEF TLV found */ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + *CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + break; + } + + if(NdefMap->TLVStruct.NdefTLVFoundFlag != + PH_FRINFC_NDEFMAP_MFUL_FLAG1) + { + NdefMap->TLVStruct.NdefTLVByte = + (((Temp16Bytes + PH_FRINFC_NDEFMAP_MFUL_VAL1 + + NdefMap->SendRecvBuf[Temp16Bytes]) % + PH_FRINFC_NDEFMAP_MFUL_VAL4) + + PH_FRINFC_NDEFMAP_MFUL_VAL1); +#if 0 + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(NdefMap->TLVStruct.NdefTLVBlock + + ((Temp16Bytes + + NdefMap->SendRecvBuf[Temp16Bytes] + 1)/ + PH_FRINFC_NDEFMAP_MFUL_VAL4)); +#endif + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(((NdefMap->TLVStruct.NdefTLVBlock / PH_FRINFC_NDEFMAP_MFUL_VAL4) * + PH_FRINFC_NDEFMAP_MFUL_VAL4) + + ((Temp16Bytes + NdefMap->SendRecvBuf[Temp16Bytes] + 1)/ + PH_FRINFC_NDEFMAP_MFUL_VAL4)); + + + TemLength = (Temp16Bytes + + NdefMap->SendRecvBuf[Temp16Bytes]); + + NdefMap->MifareULContainer.RemainingSize = + (NdefMap->MifareULContainer.RemainingSize - + (NdefMap->SendRecvBuf[Temp16Bytes] + + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + /* If the Length (L) in TLV < 16 bytes */ + Temp16Bytes = ((TemLength >= + PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16)? + PH_FRINFC_NDEFMAP_MFUL_VAL0: + (TemLength + + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + Result = ((TemLength >= + PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16)? + phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->TLVStruct.NdefTLVBlock): + NFCSTATUS_SUCCESS); + + if(TemLength >= PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16) + { + break; + } + TemLength = Temp16Bytes; + } + } + + + + +#if 0 + + NdefMap->MifareULContainer.RemainingSize = + (NdefMap->MifareULContainer.RemainingSize - + (NdefMap->SendRecvBuf[Temp16Bytes + 1] + + PH_FRINFC_NDEFMAP_MFUL_VAL2)); + + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(NdefMap->TLVStruct.NdefTLVBlock + + ((Temp16Bytes + + NdefMap->SendRecvBuf[Temp16Bytes + 1] + 2)/ + PH_FRINFC_NDEFMAP_MFUL_VAL4)); + + + Temp16Bytes = Temp16Bytes + + NdefMap->SendRecvBuf[Temp16Bytes + 1] + 2; +#endif + } +#endif /* #ifdef PH_NDEF_MIFARE_ULC */ + else { + + /* Check the byte for 0x03 Type of NDEF TLV */ + NdefMap->TLVStruct.NdefTLVFoundFlag = + ((NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_T)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + + if(NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_NDEFMAP_MFUL_FLAG1) + { + ShiftLength = (Temp16Bytes + + NdefMap->SendRecvBuf[Temp16Bytes]); + + NdefMap->TLVStruct.NdefTLVByte = + ((Temp16Bytes % + PH_FRINFC_NDEFMAP_MFUL_VAL4) + + PH_FRINFC_NDEFMAP_MFUL_VAL1); + + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(((NdefMap->TLVStruct.NdefTLVBlock /4) * 4) + + (Temp16Bytes)/ + PH_FRINFC_NDEFMAP_MFUL_VAL4); + + NdefMap->TLVStruct.NdefTLVSector = NdefMap->MifareULContainer.CurrentSector; + + } +#ifdef PH_HAL4_ENABLE + else + { + /* if the Type of the NDEF TLV is not found, then return + error saying no ndef TLV found*/ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + break; +#if 0 + /* This change is added to continue the loop, if the Type of the + NDEF TLV is not found + 16 bytes are read, so for each byte, there is a check for the + Type (T) of the TLV, if T != 0x03, then increment the byte + count and restart the loop, till the T = 0x03 is found or all + the bytes in the card is completely read. + */ + Temp16Bytes = (uint16_t)(Temp16Bytes + 1); + NdefMap->MifareULContainer.RemainingSize -= + PH_FRINFC_NDEFMAP_MFUL_VAL1; + if (NdefMap->MifareULContainer.RemainingSize == + PH_FRINFC_NDEFMAP_MFUL_VAL0) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + break; + } + else + { + Result = NFCSTATUS_SUCCESS; + Result = phFriNfc_MfUL_H_Chk16Bytes(NdefMap, + Temp16Bytes); + if(NFCSTATUS_PENDING == Result) + { + break; + } + continue; + } +#endif /* #if 0 */ + } +#endif /* #ifdef PH_HAL4_ENABLE */ + + Result = phFriNfc_MfUL_H_Chk16Bytes(NdefMap, + Temp16Bytes); + if(Result != NFCSTATUS_SUCCESS) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_NDEFMAP_MFUL_FLAG1; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_NDEFMAP_MFUL_VAL3; + break; + } + Temp16Bytes++; + NdefMap->MifareULContainer.RemainingSize -= + PH_FRINFC_NDEFMAP_MFUL_VAL1; + + if(NdefMap->MifareULContainer.RemainingSize == + PH_FRINFC_NDEFMAP_MFUL_VAL0) + { + Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT)); + break; + } + + Result = phFriNfc_MfUL_H_Chk16Bytes(NdefMap, + Temp16Bytes); + if(Result != NFCSTATUS_SUCCESS) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_NDEFMAP_MFUL_FLAG1; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_NDEFMAP_MFUL_VAL3; + break; + } + + /* If the value of the Length(L) in TLV is FF then enter else + check for the card memory */ + if((NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_LFF) || + ((NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L) && + (NdefMap->TLVStruct.NdefTLVFoundFlag != + PH_FRINFC_NDEFMAP_MFUL_FLAG1))) + { + /* In the present case, the card space is not greater + than 0xFF */ + /* + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + + *CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + break; + */ + + Temp16Bytes++; + Result = phFriNfc_MfUL_H_Chk16Bytes(NdefMap, + Temp16Bytes); + if(Result != NFCSTATUS_SUCCESS) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_NDEFMAP_MFUL_FLAG1; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_NDEFMAP_MFUL_VAL2; + + break; + } + + ShiftLength = (uint16_t) NdefMap->SendRecvBuf[Temp16Bytes]; + NdefMap->MifareULContainer.RemainingSize--; + + Temp16Bytes++; + Result = phFriNfc_MfUL_H_Chk16Bytes(NdefMap, + Temp16Bytes); + if(Result != NFCSTATUS_SUCCESS) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_NDEFMAP_MFUL_FLAG1; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_NDEFMAP_MFUL_VAL1; + NdefMap->TLVStruct.prevLenByteValue = + NdefMap->SendRecvBuf[Temp16Bytes - 1]; + break; + } + + + ShiftLength = + (((uint16_t) (NdefMap->SendRecvBuf[Temp16Bytes]) + << PH_FRINFC_NDEFMAP_MFUL_SHIFT8) | + ShiftLength); + + // NdefMap->MifareULContainer.RemainingSize--; + + if(ShiftLength > (NdefMap->MifareULContainer.RemainingSize)) + { + // Size in the Length(L) of TLV is greater + //than the actual size of the card + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + *CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + break; + } + + // NdefMap->MifareULContainer.RemainingSize--; + /* + NdefMap->TLVStruct.NdefTLVByte = + (NdefMap->SendRecvBuf[Temp16Bytes] % + PH_FRINFC_NDEFMAP_MFUL_VAL4); + + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(NdefMap->MifareULContainer.CurrentBlock + + (Temp16Bytes/PH_FRINFC_NDEFMAP_MFUL_VAL4)); + */ + + NdefMap->TLVStruct.ActualSize = + NdefMap->TLVStruct.BytesRemainLinTLV = ShiftLength; + + NdefMap->TLVStruct.NdefTLVFoundFlag = 1; + + NdefMap->TLVStruct.NdefTLVSector = NdefMap->MifareULContainer.CurrentSector; + + + Result = ((NdefMap->TLVStruct.NoLbytesinTLV == + PH_FRINFC_NDEFMAP_MFUL_VAL0)? + phFriNfc_MapTool_SetCardState( NdefMap, ShiftLength): + Result); +/* + Result = phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->TLVStruct.NdefTLVBlock); +*/ + break; + } + else + { + NdefMap->TLVStruct.BytesRemainLinTLV = + NdefMap->SendRecvBuf[Temp16Bytes]; + + NdefMap->TLVStruct.ActualSize = + NdefMap->SendRecvBuf[Temp16Bytes]; + + if((NdefMap->MifareULContainer.RemainingSize < + NdefMap->SendRecvBuf[Temp16Bytes]) || + (NdefMap->MifareULContainer.RemainingSize < + PH_FRINFC_NDEFMAP_MFUL_VAL2) || + (NdefMap->TLVStruct.BytesRemainLinTLV > + (NdefMap->MifareULContainer.RemainingSize)) || + ((NdefMap->TLVStruct.BytesRemainLinTLV == + PH_FRINFC_NDEFMAP_MFUL_VAL0) && + (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))) + { + /* No NDEF TLV found */ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + *CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + break; + } + + if(NdefMap->TLVStruct.NdefTLVFoundFlag != + PH_FRINFC_NDEFMAP_MFUL_FLAG1) + { + NdefMap->TLVStruct.NdefTLVByte = + (((Temp16Bytes + PH_FRINFC_NDEFMAP_MFUL_VAL1 + + NdefMap->SendRecvBuf[Temp16Bytes]) % + PH_FRINFC_NDEFMAP_MFUL_VAL4) + + PH_FRINFC_NDEFMAP_MFUL_VAL1); + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(NdefMap->TLVStruct.NdefTLVBlock + + ((Temp16Bytes + + NdefMap->SendRecvBuf[Temp16Bytes] + 1)/ + PH_FRINFC_NDEFMAP_MFUL_VAL4)); + + TemLength = (Temp16Bytes + + NdefMap->SendRecvBuf[Temp16Bytes]); + + NdefMap->MifareULContainer.RemainingSize = + (NdefMap->MifareULContainer.RemainingSize - + (NdefMap->SendRecvBuf[Temp16Bytes] + + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + /* If the Length (L) in TLV < 16 bytes */ + Temp16Bytes = ((TemLength >= + PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16)? + PH_FRINFC_NDEFMAP_MFUL_VAL0: + (TemLength + + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + Result = ((TemLength >= + PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16)? + phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->TLVStruct.NdefTLVBlock): + NFCSTATUS_SUCCESS); + + if(TemLength >= PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16) + { + break; + } + TemLength = Temp16Bytes; + } + } + if(NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_NDEFMAP_MFUL_FLAG1) + { +#if 0 + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(NdefMap->TLVStruct.NdefTLVBlock + + ((Temp16Bytes + 1)/ + PH_FRINFC_NDEFMAP_MFUL_VAL4)) - 1; +#endif + NdefMap->MifareULContainer.RemainingSize = + (NdefMap->MifareULContainer.RemainingSize - + PH_FRINFC_NDEFMAP_MFUL_VAL1); + ShiftLength = NdefMap->SendRecvBuf[Temp16Bytes]; + Result = ((NdefMap->TLVStruct.NoLbytesinTLV == + PH_FRINFC_NDEFMAP_MFUL_VAL0)? + phFriNfc_MapTool_SetCardState( NdefMap, ShiftLength): + Result); + + break; + } + } + } + } + + return Result; +} + + +static NFCSTATUS phFriNfc_MfUL_H_Chk16Bytes(phFriNfc_NdefMap_t *NdefMap, + uint16_t TempLength) +{ + uint16_t localCurrentBlock; + + NFCSTATUS Result = NFCSTATUS_SUCCESS; + if(TempLength == PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16) + { + localCurrentBlock = NdefMap->MifareULContainer.CurrentBlock + + PH_FRINFC_NDEFMAP_MFUL_BLOCK4; + + if (localCurrentBlock < 256) + { + NdefMap->MifareULContainer.CurrentBlock += + PH_FRINFC_NDEFMAP_MFUL_BLOCK4; + + Result = phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->MifareULContainer.CurrentBlock); + } + else + { + /* Go to next sector */ + NdefMap->MifareULContainer.CurrentSector++; + + Result = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_CHK_1); + } + } + + return Result; +} + + +static void phFriNfc_MfUL_H_UpdateCrc( uint8_t ch, + uint16_t *lpwCrc ) +{ + ch = (ch^(uint8_t)((*lpwCrc) & 0x00FF)); + ch = (ch^(ch<<4)); + *lpwCrc = (*lpwCrc >> 8)^((uint16_t)ch << 8)^ \ + ((uint16_t)ch<<3)^((uint16_t)ch>>4); + + return; +} + +static void phFriNfc_MfUL_H_ComputeCrc( int CRCType, + uint8_t *Data, + int Length, + uint8_t *TransmitFirst, + uint8_t *TransmitSecond + ) +{ + uint8_t chBlock; + uint16_t wCrc; + switch(CRCType) + { + case CRC_A: + wCrc = 0x6363; /* ITU-V.41 */ + break; + case CRC_B: + wCrc = 0xFFFF; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ + break; + default: + return; + } + + do + { + chBlock = *Data++; + phFriNfc_MfUL_H_UpdateCrc(chBlock, &wCrc); + } while (--Length); + *TransmitFirst = (uint8_t) (wCrc & 0xFF); + *TransmitSecond = (uint8_t) ((wCrc >> 8) & 0xFF); + return; +} + + + +static NFCSTATUS phFriNfc_MfUL_H_SelectSector(phFriNfc_NdefMap_t *NdefMap, + uint8_t SectorNo, + uint8_t CmdNo, + uint8_t NextState) +{ + + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* set the data for additional data exchange */ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + NdefMap->State = NextState; + + if (CmdNo == 1) + { + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] = 0x00; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL1] = 0x00; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL2] = 0xC2; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL3] = 0xFF; + NdefMap->SendLength = PH_FRINFC_NDEFMAP_MFUL_VAL4; + } + else + { + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] = 0x00; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL1] = 0x00; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL2] = SectorNo; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL3] = 0; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL4] = 0; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL5] = 0; + NdefMap->SendLength = PH_FRINFC_NDEFMAP_MFUL_VAL5 + 1; + } + + /* Calculate CRC */ + + phFriNfc_MfUL_H_ComputeCrc(CRC_A, &NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL2], + NdefMap->SendLength - 2, + &NdefMap->SendRecvBuf[NdefMap->SendLength], + &NdefMap->SendRecvBuf[NdefMap->SendLength + 1]); + + NdefMap->SendLength += PH_FRINFC_NDEFMAP_MFUL_VAL2; + + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + NdefMap->Cmd.MfCmd = phHal_eMifareRaw; + + /* 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_MfUL_H_RdCardfindNdefTLV( phFriNfc_NdefMap_t *NdefMap, + uint8_t BlockNo) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_FND_NDEF_COMP; + /* set the data for additional data exchange */ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] = + BlockNo; + NdefMap->SendLength = PH_FRINFC_NDEFMAP_MFUL_VAL1; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + /* + * Changed + * Description: phHal_eMifareCmdListMifareRead replace with phHal_eMifareRead + */ + NdefMap->Cmd.MfCmd = phHal_eMifareRead; + + /* 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_MfUL_H_ChkRemainTLV(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t TempLength = PH_FRINFC_NDEFMAP_MFUL_VAL0, + ShiftLength = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + switch(NdefMap->TLVStruct.NoLbytesinTLV) + { + case PH_FRINFC_NDEFMAP_MFUL_VAL1: + case PH_FRINFC_NDEFMAP_MFUL_VAL2: + ShiftLength = ((NdefMap->TLVStruct.NoLbytesinTLV == + PH_FRINFC_NDEFMAP_MFUL_VAL1)? + NdefMap->TLVStruct.prevLenByteValue: + NdefMap->SendRecvBuf[TempLength]); + ShiftLength = ((NdefMap->TLVStruct.NoLbytesinTLV == + PH_FRINFC_NDEFMAP_MFUL_VAL1)? + (((uint16_t)(NdefMap->SendRecvBuf[TempLength]) << + PH_FRINFC_NDEFMAP_MFUL_SHIFT8) | + ShiftLength): + (((uint16_t)(NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_NDEFMAP_MFUL_VAL1)]) << + PH_FRINFC_NDEFMAP_MFUL_SHIFT8) | + ShiftLength)); + + NdefMap->MifareULContainer.RemainingSize -= + PH_FRINFC_NDEFMAP_MFUL_VAL1; + + NdefMap->TLVStruct.ActualSize = + NdefMap->TLVStruct.BytesRemainLinTLV = ShiftLength; + + /* Check for remaining free space in the card with the + length (L) of TLV OR length(L) of TLV is less than + 255 bytes (The length (L) of TLV for 3 byte should not + be less than 255) */ + Result = ((((NdefMap->MifareULContainer.RemainingSize)<= + ShiftLength) || (ShiftLength < + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_LFF))? + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER)): + Result); + + + Result = ((Result == NFCSTATUS_SUCCESS)? + phFriNfc_MapTool_SetCardState( NdefMap, ShiftLength): + Result); + + *CRFlag = (uint8_t)((Result == (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER)))? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + + + if(Result == NFCSTATUS_SUCCESS) + { + + NdefMap->MifareULContainer.RemainingSize= NdefMap->MifareULContainer.RemainingSize- + NdefMap->TLVStruct.NoLbytesinTLV; +/* + NdefMap->TLVStruct.NdefTLVByte = ((ShiftLength% + PH_FRINFC_NDEFMAP_MFUL_VAL4) + + PH_FRINFC_NDEFMAP_MFUL_VAL1); + + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(NdefMap->MifareULContainer.CurrentBlock + + (ShiftLength/PH_FRINFC_NDEFMAP_MFUL_VAL4)); + NdefMap->MifareULContainer.CurrentBlock = + NdefMap->TLVStruct.NdefTLVBlock; + + Result = phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->TLVStruct.NdefTLVBlock); + */ + } + break; + + default: + if((NdefMap->SendRecvBuf[TempLength] == + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_LFF) || + ((NdefMap->SendRecvBuf[TempLength] == + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L) && + (NdefMap->TLVStruct.NdefTLVFoundFlag != + PH_FRINFC_NDEFMAP_MFUL_FLAG1))) + { + /* In the present case, the card space is not greater + than 0xFF */ +/* + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + + *CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + +*/ + + ShiftLength = NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_NDEFMAP_MFUL_VAL1)]; + ShiftLength = (((uint16_t)(NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_NDEFMAP_MFUL_VAL2)]) + << PH_FRINFC_NDEFMAP_MFUL_SHIFT8) | + ShiftLength); + Result = ((ShiftLength > (NdefMap->MifareULContainer.RemainingSize))? + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER)): + Result); + + + Result = ((Result == NFCSTATUS_SUCCESS)? + phFriNfc_MapTool_SetCardState( NdefMap, ShiftLength): + Result); + + NdefMap->TLVStruct.ActualSize = + NdefMap->TLVStruct.BytesRemainLinTLV = ShiftLength; + + if(Result == NFCSTATUS_SUCCESS) + { + + NdefMap->MifareULContainer.RemainingSize= NdefMap->MifareULContainer.RemainingSize- + NdefMap->TLVStruct.NoLbytesinTLV; +/* + NdefMap->TLVStruct.NdefTLVByte = ((ShiftLength% + PH_FRINFC_NDEFMAP_MFUL_VAL4) + + PH_FRINFC_NDEFMAP_MFUL_VAL1); + + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(NdefMap->MifareULContainer.CurrentBlock + + (ShiftLength/PH_FRINFC_NDEFMAP_MFUL_VAL4)); + + NdefMap->MifareULContainer.CurrentBlock = + NdefMap->TLVStruct.NdefTLVBlock; + + Result = phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->TLVStruct.NdefTLVBlock); +*/ + } + } + else + { + /* length (L) value in TLV shall not be greater than + remaining free space in the card */ + Result = ((NdefMap->SendRecvBuf[TempLength] > + NdefMap->MifareULContainer.RemainingSize)? + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER)): + Result); + + NdefMap->TLVStruct.ActualSize = + NdefMap->TLVStruct.BytesRemainLinTLV = + NdefMap->SendRecvBuf[TempLength]; + NdefMap->MifareULContainer.RemainingSize--; + + if((Result == NFCSTATUS_SUCCESS) && + (NdefMap->TLVStruct.NdefTLVFoundFlag != + PH_FRINFC_NDEFMAP_MFUL_FLAG1)) + { + phFriNfc_MfUL_H_UpdateLen(NdefMap, + (uint16_t)NdefMap->SendRecvBuf[TempLength]); + + NdefMap->MifareULContainer.CurrentBlock = + NdefMap->TLVStruct.NdefTLVBlock; + TempLength=TempLength+(NdefMap->SendRecvBuf[TempLength]); + Result =((TempLength < PH_FRINFC_NDEFMAP_MFUL_RDBYTES_16)? + phFriNfc_MfUL_H_findNDEFTLV(NdefMap, CRFlag): + phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->TLVStruct.NdefTLVBlock)); + } + } + break; + } + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + Result = phFriNfc_MapTool_SetCardState( NdefMap, NdefMap->TLVStruct.ActualSize); + + return Result; +} + +static void phFriNfc_MfUL_H_UpdateLen(phFriNfc_NdefMap_t *NdefMap, + uint16_t DataLen) +{ + NdefMap->MifareULContainer.RemainingSize= NdefMap->MifareULContainer.RemainingSize-DataLen; + NdefMap->TLVStruct.NdefTLVByte = ((DataLen % + PH_FRINFC_NDEFMAP_MFUL_VAL4) + + PH_FRINFC_NDEFMAP_MFUL_VAL1); + NdefMap->TLVStruct.NdefTLVBlock = + (uint8_t)(NdefMap->MifareULContainer.CurrentBlock + + (DataLen/PH_FRINFC_NDEFMAP_MFUL_VAL4)); +} + + static NFCSTATUS phFriNfc_MfUL_H_NxtOp(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + switch(NdefMap->PrevOperation) + { + case PH_FRINFC_NDEFMAP_CHECK_OPE: + *CRFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + break; + + case PH_FRINFC_NDEFMAP_READ_OPE: + if (NdefMap->TLVStruct.NdefTLVSector == 1) + { + /* Goto sector 1 */ + NdefMap->MifareULContainer.CurrentSector = 1; + NdefMap->MifareULContainer.CurrentBlock = 0; + + Result = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_READ_1); + } + else + { + NdefMap->MifareULContainer.CurrentBlock = (NdefMap->TLVStruct.NdefTLVBlock / 4) * 4; + Result = phFriNfc_MfUL_H_Rd16Bytes(NdefMap); + } +#if 0 + NdefMap->MifareULContainer.CurrentBlock = + PH_FRINFC_NDEFMAP_MFUL_VAL4; + + Result = phFriNfc_MfUL_H_Rd16Bytes(NdefMap); +#endif + + + *CRFlag = (uint8_t)((Result != NFCSTATUS_PENDING)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_WRITE_OPE: + break; + + default: + break; + } + return Result; +} + + + +static NFCSTATUS phFriNfc_MfUL_H_CopyRdBytes(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t localCurrentBlock; + + (void)memcpy(&(NdefMap->MifareULContainer.ReadBuf[ + NdefMap->MifareULContainer.ReadBufIndex]), + NdefMap->SendRecvBuf, + *NdefMap->SendRecvLength); + NdefMap->MifareULContainer.ReadBufIndex=NdefMap->MifareULContainer.ReadBufIndex +*NdefMap->SendRecvLength; + + localCurrentBlock = NdefMap->MifareULContainer.CurrentBlock+ + (uint8_t)((NdefMap->MifareULContainer.ReadBufIndex != + NdefMap->CardMemSize)? + PH_FRINFC_NDEFMAP_MFUL_BLOCK4: + PH_FRINFC_NDEFMAP_MFUL_VAL0); + if (localCurrentBlock < 256) + { + NdefMap->MifareULContainer.CurrentBlock = NdefMap->MifareULContainer.CurrentBlock+ + (uint8_t)((NdefMap->MifareULContainer.ReadBufIndex != + NdefMap->CardMemSize)? + PH_FRINFC_NDEFMAP_MFUL_BLOCK4: + PH_FRINFC_NDEFMAP_MFUL_VAL0); + } + else + { + /* Go to next sector */ + if (NdefMap->MifareULContainer.CurrentSector == 0) + { + NdefMap->MifareULContainer.CurrentSector++; + NdefMap->MifareULContainer.CurrentBlock = 0xff; + + Result = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_READ_1); + } + } + + return Result; +} + +static NFCSTATUS phFriNfc_MfUL_H_CpDataToUserBuf(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Check the user buffer size with the + L value of TLV */ + if(NdefMap->ApduBufferSize >= + NdefMap->TLVStruct.BytesRemainLinTLV) + { + (void)memcpy(NdefMap->ApduBuffer, + &(NdefMap->MifareULContainer.ReadBuf[ + NdefMap->MifareULContainer.ByteNumber]), + NdefMap->TLVStruct.BytesRemainLinTLV); + + *(NdefMap->NumOfBytesRead) = + NdefMap->TLVStruct.BytesRemainLinTLV; + NdefMap->MifareULContainer.ByteNumber = + PH_FRINFC_NDEFMAP_MFUL_VAL0; + NdefMap->MifareULContainer.ReadWriteCompleteFlag = + PH_FRINFC_NDEFMAP_MFUL_FLAG1; + NdefMap->MifareULContainer.RemainingSize = NdefMap->MifareULContainer.RemainingSize- + NdefMap->TLVStruct.BytesRemainLinTLV; + NdefMap->TLVStruct.BytesRemainLinTLV = + PH_FRINFC_NDEFMAP_MFUL_VAL0; + } + else + { + (void)memcpy(NdefMap->ApduBuffer, + &(NdefMap->MifareULContainer.ReadBuf[ + NdefMap->MifareULContainer.ByteNumber]), + NdefMap->ApduBufferSize); + + *(NdefMap->NumOfBytesRead) = + NdefMap->ApduBufferSize; + NdefMap->MifareULContainer.ByteNumber = NdefMap->MifareULContainer.ByteNumber+ + (uint16_t)NdefMap->ApduBufferSize; + NdefMap->MifareULContainer.RemainingSize=NdefMap->MifareULContainer.RemainingSize- + (uint16_t)NdefMap->ApduBufferSize; + NdefMap->TLVStruct.BytesRemainLinTLV = NdefMap->TLVStruct.BytesRemainLinTLV- + (uint16_t)NdefMap->ApduBufferSize; + } + return Result; +} + +static NFCSTATUS phFriNfc_MfUL_H_RdBeforeWrite(phFriNfc_NdefMap_t *NdefMap) +{ + uint16_t localCurrentBlock = NdefMap->TLVStruct.NdefTLVBlock; + + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t index = PH_FRINFC_NDEFMAP_MFUL_VAL0, + i = PH_FRINFC_NDEFMAP_MFUL_VAL0; + /* BytesToWrite = PH_FRINFC_NDEFMAP_MFUL_VAL0;*/ + uint16_t TemLength = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + switch((NdefMap->TLVStruct.NdefTLVByte - PH_FRINFC_NDEFMAP_MFUL_VAL1)) + { + case PH_FRINFC_NDEFMAP_MFUL_VAL0: + /* go the NDEF TLV block to start write */ + NdefMap->MifareULContainer.CurrentBlock = + NdefMap->TLVStruct.NdefTLVBlock; + /* fill send buffer for write */ + NdefMap->SendRecvBuf[index] = + NdefMap->MifareULContainer.CurrentBlock; + index++; + NdefMap->SendRecvBuf[index] = + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_T; + index++; + if (NdefMap->ApduBufferSize > 254) + { + NdefMap->SendRecvBuf[index] = 0xFF; + index++; + NdefMap->SendRecvBuf[index] = + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L; + index++; + NdefMap->SendRecvBuf[index] = + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L; + index++; + } + else + { + NdefMap->SendRecvBuf[index] = + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L; + index++; + } + + + break; + + case PH_FRINFC_NDEFMAP_MFUL_VAL1: + case PH_FRINFC_NDEFMAP_MFUL_VAL2: + /* read to get the previous bytes */ + Result = phFriNfc_MfUL_H_RdCardfindNdefTLV(NdefMap, + NdefMap->TLVStruct.NdefTLVBlock); + break; + + case PH_FRINFC_NDEFMAP_MFUL_VAL3: + + localCurrentBlock = (NdefMap->MifareULContainer.CurrentBlock + + PH_FRINFC_NDEFMAP_MFUL_VAL1); + + if (localCurrentBlock < 256) + { + + NdefMap->MifareULContainer.CurrentBlock = + (NdefMap->MifareULContainer.CurrentBlock + + PH_FRINFC_NDEFMAP_MFUL_VAL1); + NdefMap->SendRecvBuf[index] = + NdefMap->MifareULContainer.CurrentBlock; + index++; + + if (NdefMap->ApduBufferSize > 254) + { + NdefMap->SendRecvBuf[index] = 0xFF; + index++; + NdefMap->SendRecvBuf[index] = + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L; + index++; + NdefMap->SendRecvBuf[index] = + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L; + index++; + } + else + { + NdefMap->SendRecvBuf[index] = + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L; + index++; + } + } + else + { + /* Go to next sector */ + NdefMap->MifareULContainer.CurrentSector++; + + Result = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RW_1); + } + break; + + default: + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_REMOTE_DEVICE); + break; + } + + if((((NdefMap->TLVStruct.NdefTLVByte - + PH_FRINFC_NDEFMAP_MFUL_VAL1) == PH_FRINFC_NDEFMAP_MFUL_VAL0) || + ((NdefMap->TLVStruct.NdefTLVByte - PH_FRINFC_NDEFMAP_MFUL_VAL1) + == PH_FRINFC_NDEFMAP_MFUL_VAL3)) && localCurrentBlock < 256) + { + /* Length to know how many bytes has to be written to the card */ + TemLength = (((NdefMap->TLVStruct.NdefTLVByte - PH_FRINFC_NDEFMAP_MFUL_VAL1) == + PH_FRINFC_NDEFMAP_MFUL_VAL0)? + PH_FRINFC_NDEFMAP_MFUL_VAL2: + PH_FRINFC_NDEFMAP_MFUL_VAL3); + + if (NdefMap->ApduBufferSize > 254) + { + TemLength -= 2; + } + + if(NdefMap->ApduBufferSize >= TemLength) + { + /* Prepare the receive buffer */ + (void)memcpy(&(NdefMap->SendRecvBuf[ + index]), + &(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + TemLength); + + /* Number of bytes written to the card from user buffer */ + NdefMap->NumOfBytesWritten = TemLength; + + index = index+(uint8_t)TemLength; + /* Exact number of bytes written in the card including TLV */ + if (index >= 1) + { + *NdefMap->DataCount = (index - PH_FRINFC_NDEFMAP_MFUL_VAL1); + } + else + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_REMOTE_DEVICE); + } + } + else + { + /* Prepare the receive buffer */ + (void)memcpy(&(NdefMap->SendRecvBuf[ + index]), + &(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + (uint16_t)NdefMap->ApduBufferSize); + + /* Number of bytes written to the card from user buffer */ + NdefMap->NumOfBytesWritten = (uint16_t)NdefMap->ApduBufferSize; + + index= index +(uint8_t)NdefMap->ApduBufferSize; + /* Exact number of bytes written in the card including TLV */ + *NdefMap->DataCount = (index - PH_FRINFC_NDEFMAP_MFUL_VAL1); + + for(i = index; i < PH_FRINFC_NDEFMAP_MFUL_WR_A_BLK; i++) + { + NdefMap->SendRecvBuf[i] = (uint8_t)((i == index)? + PH_FRINFC_NDEFMAP_MFUL_TERMTLV: + PH_FRINFC_NDEFMAP_MFUL_NULLTLV); + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + + /* store the bytes in buffer till the bytes are + written in a block */ + (void)memcpy(NdefMap->MifareULContainer.Buffer, + &(NdefMap->SendRecvBuf[ + PH_FRINFC_NDEFMAP_MFUL_VAL1]), + (PH_FRINFC_NDEFMAP_MFUL_WR_A_BLK - + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + (void)memcpy(NdefMap->TLVStruct.NdefTLVBuffer, + NdefMap->MifareULContainer.Buffer, + (PH_FRINFC_NDEFMAP_MFUL_WR_A_BLK - + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + /* Change the state to check ndef compliancy */ + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_WRITE; + + Result = phFriNfc_MfUL_H_Wr4bytes(NdefMap); + } + return Result; +} + +static NFCSTATUS phFriNfc_MfUL_H_CallWrOp(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + /* uint8_t index = PH_FRINFC_NDEFMAP_MFUL_VAL1;*/ + + + NdefMap->MifareULContainer.CurrentBlock = + NdefMap->TLVStruct.NdefTLVBlock; + + (void)memcpy(&(NdefMap->SendRecvBuf[ + PH_FRINFC_NDEFMAP_MFUL_VAL1]), + NdefMap->SendRecvBuf, + PH_FRINFC_NDEFMAP_MFUL_VAL4); + + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] = + NdefMap->MifareULContainer.CurrentBlock; + + if (NdefMap->ApduBufferSize > 254) + { + NdefMap->SendRecvBuf[(NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_NDEFMAP_MFUL_VAL1)] = 0xFF; + + + if((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_NDEFMAP_MFUL_VAL1) < + PH_FRINFC_NDEFMAP_MFUL_VAL4) + { + NdefMap->SendRecvBuf[(NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_NDEFMAP_MFUL_VAL2 )] = 0x00; + + NdefMap->NumOfLReminWrite = 1; + + } + else + { + NdefMap->NumOfLReminWrite = 2; + } + NdefMap->NumOfBytesWritten = 0; + } + else + { + /* Write the length value = 0 */ + NdefMap->SendRecvBuf[(NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_NDEFMAP_MFUL_VAL1)] = + PH_FRINFC_NDEFMAP_MFUL_NDEFTLV_L; + + if((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_NDEFMAP_MFUL_VAL1) < + PH_FRINFC_NDEFMAP_MFUL_VAL4) + { + /* Only one byte */ + (void)memcpy(&(NdefMap->SendRecvBuf[ + PH_FRINFC_NDEFMAP_MFUL_VAL4]), + &(NdefMap->ApduBuffer[ + NdefMap->ApduBuffIndex]), + PH_FRINFC_NDEFMAP_MFUL_VAL1); + /* Number of bytes written to the card from user buffer */ + NdefMap->NumOfBytesWritten = PH_FRINFC_NDEFMAP_MFUL_VAL1; + } + } + + (void)memcpy(NdefMap->MifareULContainer.Buffer, + &(NdefMap->SendRecvBuf[ + PH_FRINFC_NDEFMAP_MFUL_VAL1]), + PH_FRINFC_NDEFMAP_MFUL_VAL4); + + /* Copy the Ndef TLV buffer to send buffer */ + (void)memcpy(NdefMap->TLVStruct.NdefTLVBuffer, + NdefMap->MifareULContainer.Buffer, + PH_FRINFC_NDEFMAP_MFUL_BYTE4); + + /* Exact number of bytes written in the card including TLV */ + *NdefMap->DataCount = PH_FRINFC_NDEFMAP_MFUL_VAL4; + + /* Change the state to check ndef compliancy */ + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_WRITE; + + Result = phFriNfc_MfUL_H_Wr4bytes(NdefMap); + + return Result; +} + +static NFCSTATUS phFriNfc_MfUL_H_ProWrittenBytes(phFriNfc_NdefMap_t *NdefMap) +{ + uint16_t localCurrentBlock; + NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_REMOTE_DEVICE); + + if(NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize) + { + NdefMap->ApduBuffIndex = NdefMap->ApduBuffIndex+NdefMap->NumOfBytesWritten; + if(*NdefMap->DataCount < + PH_FRINFC_NDEFMAP_MFUL_VAL4) + { + (void)memcpy(NdefMap->MifareULContainer.InternalBuf, + NdefMap->MifareULContainer.Buffer, + *NdefMap->DataCount); + + NdefMap->MifareULContainer.InternalLength = *NdefMap->DataCount; + } + else + { + NdefMap->MifareULContainer.InternalLength = + PH_FRINFC_NDEFMAP_MFUL_VAL0; + } + + NdefMap->MifareULContainer.RemainingSize= NdefMap->MifareULContainer.RemainingSize- + NdefMap->NumOfBytesWritten; + if((NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize) || + (NdefMap->MifareULContainer.RemainingSize == + PH_FRINFC_NDEFMAP_MFUL_VAL0)) + { + Result = NFCSTATUS_SUCCESS; + NdefMap->MifareULContainer.ReadWriteCompleteFlag = + (uint8_t)((NdefMap->MifareULContainer.RemainingSize == + PH_FRINFC_NDEFMAP_MFUL_VAL0)? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + + NdefMap->TLVStruct.SetTermTLVFlag = + (uint8_t)(((NdefMap->MifareULContainer.RemainingSize == + PH_FRINFC_NDEFMAP_MFUL_VAL0) || + (NdefMap->TLVStruct.SetTermTLVFlag == + PH_FRINFC_NDEFMAP_MFUL_FLAG1))? + PH_FRINFC_NDEFMAP_MFUL_FLAG1: + PH_FRINFC_NDEFMAP_MFUL_FLAG0); + + NdefMap->MifareULContainer.CurrentBlock = NdefMap->MifareULContainer.CurrentBlock+ + (uint8_t)((NdefMap->MifareULContainer.InternalLength != + PH_FRINFC_NDEFMAP_MFUL_VAL0)? + PH_FRINFC_NDEFMAP_MFUL_VAL0: + PH_FRINFC_NDEFMAP_MFUL_VAL1); + + *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; + } + else + { + localCurrentBlock = NdefMap->MifareULContainer.CurrentBlock + 1; + if (localCurrentBlock < 256) + { + NdefMap->MifareULContainer.CurrentBlock++; + Result = phFriNfc_MfUL_H_fillSendBufToWr(NdefMap); + } + else + { + /* Go to next sector */ + NdefMap->MifareULContainer.CurrentSector++; + + Result = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_WRITE_1); + } + } + } + + if((Result == NFCSTATUS_SUCCESS) && + (NdefMap->TLVStruct.SetTermTLVFlag != + PH_FRINFC_NDEFMAP_MFUL_FLAG1) && + (NdefMap->MifareULContainer.RemainingSize > + PH_FRINFC_NDEFMAP_MFUL_VAL0)) + { + Result = phFriNfc_MfUL_H_WrTermTLV(NdefMap); + } + else + { + if((Result == NFCSTATUS_SUCCESS) && + (NdefMap->TLVStruct.SetTermTLVFlag == + PH_FRINFC_NDEFMAP_MFUL_FLAG1)) + { + Result = phFriNfc_MfUL_H_UpdateWrLen(NdefMap); + } + } + return Result; +} +static NFCSTATUS phFriNfc_MfUL_H_fillSendBufToWr(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t RemainingBytes = PH_FRINFC_NDEFMAP_MFUL_VAL0, + BytesToWrite = PH_FRINFC_NDEFMAP_MFUL_VAL0; + uint8_t index = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + RemainingBytes = (uint16_t)(( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <= + NdefMap->MifareULContainer.RemainingSize)? + (uint16_t)(NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex): + NdefMap->MifareULContainer.RemainingSize); + + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] = + NdefMap->MifareULContainer.CurrentBlock; + + /* Get the number of bytes that can be written after copying + the internal buffer */ + BytesToWrite = ((RemainingBytes < + (PH_FRINFC_NDEFMAP_MFUL_BYTE4 - + NdefMap->MifareULContainer.InternalLength))? + RemainingBytes: + (PH_FRINFC_NDEFMAP_MFUL_BYTE4 - + NdefMap->MifareULContainer.InternalLength)); + + if (NdefMap->NumOfBytesWritten == 0 && NdefMap->NumOfLReminWrite > 0) + { + BytesToWrite = BytesToWrite - NdefMap->NumOfLReminWrite; + + if (NdefMap->NumOfLReminWrite == 1) + { + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL1] = 0x00; + } + else + { + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL1] = 0x00; + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL2] = 0x00; + } + } + + if(NdefMap->MifareULContainer.InternalLength > + PH_FRINFC_NDEFMAP_MFUL_VAL0) + { + /* copy the internal buffer to the send buffer */ + (void)memcpy(&(NdefMap->SendRecvBuf[ + PH_FRINFC_NDEFMAP_MFUL_VAL1]), + NdefMap->MifareULContainer.InternalBuf, + NdefMap->MifareULContainer.InternalLength); + + } + + /* Copy Bytes to write in the send buffer */ + (void)memcpy(&(NdefMap->SendRecvBuf[ + (PH_FRINFC_NDEFMAP_MFUL_VAL1 + + NdefMap->MifareULContainer.InternalLength) + + NdefMap->NumOfLReminWrite]), + &(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->MifareULContainer.InternalLength + + NdefMap->NumOfLReminWrite); + + + /* if total bytes to write in the card is less than 4 bytes then + pad zeroes till 4 bytes */ + if((BytesToWrite + NdefMap->MifareULContainer.InternalLength + + NdefMap->NumOfLReminWrite) + < PH_FRINFC_NDEFMAP_MFUL_BYTE4) + { + for(index = (uint8_t)((BytesToWrite + NdefMap->MifareULContainer.InternalLength + NdefMap->NumOfLReminWrite) + + PH_FRINFC_NDEFMAP_MFUL_VAL1); + index < PH_FRINFC_NDEFMAP_MFUL_WR_A_BLK; + index++) + { + NdefMap->SendRecvBuf[index] = (uint8_t)((index == + ((BytesToWrite + + NdefMap->MifareULContainer.InternalLength + NdefMap->NumOfLReminWrite) + + PH_FRINFC_NDEFMAP_MFUL_VAL1))? + PH_FRINFC_NDEFMAP_MFUL_TERMTLV: + PH_FRINFC_NDEFMAP_MFUL_NULLTLV); + + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_NDEFMAP_MFUL_FLAG1; + } + } + + /* A temporary buffer to hold four bytes of data that is + written to the card */ + (void)memcpy(NdefMap->MifareULContainer.Buffer, + &(NdefMap->SendRecvBuf[ + PH_FRINFC_NDEFMAP_MFUL_VAL1]), + PH_FRINFC_NDEFMAP_MFUL_BYTE4); + + + + if((NdefMap->TLVStruct.NdefTLVByte - PH_FRINFC_NDEFMAP_MFUL_VAL1) < + PH_FRINFC_NDEFMAP_MFUL_VAL3) + { + if ((NdefMap->TLVStruct.NdefTLVSector == + NdefMap->MifareULContainer.CurrentSector)) + { + if(NdefMap->MifareULContainer.CurrentBlock == + NdefMap->TLVStruct.NdefTLVBlock) + { + (void)memcpy(NdefMap->TLVStruct.NdefTLVBuffer, + NdefMap->MifareULContainer.Buffer, + PH_FRINFC_NDEFMAP_MFUL_BYTE4); + } + } + + if ((NdefMap->TLVStruct.NdefTLVSector == + NdefMap->MifareULContainer.CurrentSector) || + (NdefMap->TLVStruct.NdefTLVBlock == 0xFF)) + { + if(NdefMap->MifareULContainer.CurrentBlock == + (NdefMap->TLVStruct.NdefTLVBlock + PH_FRINFC_NDEFMAP_MFUL_VAL1)) + { + (void)memcpy(NdefMap->TLVStruct.NdefTLVBuffer1, + NdefMap->MifareULContainer.Buffer, + PH_FRINFC_NDEFMAP_MFUL_BYTE4); + } + } + } + else + { + if ((NdefMap->TLVStruct.NdefTLVSector == + NdefMap->MifareULContainer.CurrentSector)) + { + if(NdefMap->MifareULContainer.CurrentBlock == + (NdefMap->TLVStruct.NdefTLVBlock + + PH_FRINFC_NDEFMAP_MFUL_VAL1)) + { + (void)memcpy(NdefMap->TLVStruct.NdefTLVBuffer, + NdefMap->MifareULContainer.Buffer, + PH_FRINFC_NDEFMAP_MFUL_BYTE4); + } + } + + if ((NdefMap->TLVStruct.NdefTLVSector == + NdefMap->MifareULContainer.CurrentSector)|| + (NdefMap->TLVStruct.NdefTLVBlock == 0xFF)) + { + if(NdefMap->MifareULContainer.CurrentBlock == + (NdefMap->TLVStruct.NdefTLVBlock + PH_FRINFC_NDEFMAP_MFUL_VAL2)) + { + (void)memcpy(NdefMap->TLVStruct.NdefTLVBuffer1, + NdefMap->MifareULContainer.Buffer, + PH_FRINFC_NDEFMAP_MFUL_BYTE4); + } + } + } + + + /* Change the state to check ndef compliancy */ + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_WRITE; + + NdefMap->NumOfLReminWrite = 0; + + /* Start writing to the current block */ + Result = phFriNfc_MfUL_H_Wr4bytes(NdefMap); + + return Result; +} +static NFCSTATUS phFriNfc_MfUL_H_WrTermTLV(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t index = PH_FRINFC_NDEFMAP_MFUL_VAL0, + i = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + /* Change the state to check ndef compliancy */ + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_TERM_TLV; + + NdefMap->SendRecvBuf[index] = + (NdefMap->MifareULContainer.CurrentBlock + + PH_FRINFC_NDEFMAP_MFUL_VAL0); + index++; + NdefMap->SendRecvBuf[index] = PH_FRINFC_NDEFMAP_MFUL_TERMTLV; + index++; + + for(i = index; i < PH_FRINFC_NDEFMAP_MFUL_VAL4; i++) + { + NdefMap->SendRecvBuf[i] = PH_FRINFC_NDEFMAP_MFUL_NULLTLV; + } + + Result = phFriNfc_MfUL_H_Wr4bytes(NdefMap); + return Result; +} + +static NFCSTATUS phFriNfc_MfUL_H_UpdateWrLen(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t BlockNo = PH_FRINFC_NDEFMAP_MFUL_VAL0, + ByteNo = PH_FRINFC_NDEFMAP_MFUL_VAL0; + + if ((NdefMap->TLVStruct.NdefTLVSector == + NdefMap->MifareULContainer.CurrentSector) || + ((NdefMap->TLVStruct.NdefTLVBlock == 0xFF) && + (NdefMap->TLVStruct.NdefTLVByte == 4) && + (NdefMap->TLVStruct.NdefTLVSector == 0))) + { + BlockNo = (((NdefMap->TLVStruct.NdefTLVByte - + PH_FRINFC_NDEFMAP_MFUL_VAL1) != + PH_FRINFC_NDEFMAP_MFUL_VAL3)? + NdefMap->TLVStruct.NdefTLVBlock: + (NdefMap->TLVStruct.NdefTLVBlock + + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + ByteNo = (((NdefMap->TLVStruct.NdefTLVByte - + PH_FRINFC_NDEFMAP_MFUL_VAL1) == + PH_FRINFC_NDEFMAP_MFUL_VAL3)? + PH_FRINFC_NDEFMAP_MFUL_VAL1: + (NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_NDEFMAP_MFUL_VAL1)); + + if (NdefMap->NumOfLReminWrite > 0) + { + BlockNo++; + + /* Copy the Ndef TLV buffer to send buffer */ + (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL1]), + NdefMap->TLVStruct.NdefTLVBuffer1, + PH_FRINFC_NDEFMAP_MFUL_BYTE4); + + if (NdefMap->NumOfLReminWrite == 1) + { + NdefMap->SendRecvBuf[1] = (uint8_t) ((NdefMap->ApduBuffIndex & 0xFF00) >> 8); + + } + else if (NdefMap->NumOfLReminWrite == 2) + { + NdefMap->SendRecvBuf[1]= (uint8_t) (NdefMap->ApduBuffIndex); + NdefMap->SendRecvBuf[2] = (uint8_t) ((NdefMap->ApduBuffIndex & 0xFF00) >> 8); + } + else + { + + } + NdefMap->NumOfLReminWrite = 0; + } + else + { + /* Copy the Ndef TLV buffer to send buffer */ + (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL1]), + NdefMap->TLVStruct.NdefTLVBuffer, + PH_FRINFC_NDEFMAP_MFUL_BYTE4); + + + if (NdefMap->ApduBuffIndex > 254) + { + ByteNo++; + if ((ByteNo == 3) || (ByteNo == 2)) + { + NdefMap->SendRecvBuf[ByteNo]= (uint8_t) (NdefMap->ApduBuffIndex); + ByteNo++; + NdefMap->SendRecvBuf[ByteNo] = (uint8_t) ((NdefMap->ApduBuffIndex & 0xFF00) >> 8); + ByteNo++; + NdefMap->NumOfLReminWrite = 0; + } + else if (ByteNo == 4) + { + NdefMap->SendRecvBuf[ByteNo]= (uint8_t) (NdefMap->ApduBuffIndex); + ByteNo++; + NdefMap->NumOfLReminWrite = 1; + } + else + { + NdefMap->NumOfLReminWrite = 2; + } + } + else + { + NdefMap->SendRecvBuf[ByteNo]= + (uint8_t)((NdefMap->Offset == + PH_FRINFC_NDEFMAP_SEEK_BEGIN)? + (uint8_t)NdefMap->ApduBuffIndex: + (NdefMap->ApduBuffIndex + + NdefMap->SendRecvBuf[ByteNo])); + } + } + + (void)memcpy(NdefMap->MifareULContainer.Buffer, + &(NdefMap->SendRecvBuf[ + PH_FRINFC_NDEFMAP_MFUL_VAL1]), + PH_FRINFC_NDEFMAP_MFUL_BYTE4); + + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_MFUL_VAL0] = (uint8_t)BlockNo; + Result = phFriNfc_MfUL_H_Wr4bytes(NdefMap); + + if (NdefMap->NumOfLReminWrite == 0) + { + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_WR_LEN_TLV; + } + else + { + NdefMap->State = PH_FRINFC_NDEFMAP_MFUL_STATE_TERM_TLV; + } + } + else if (NdefMap->TLVStruct.NdefTLVSector == 0) + { + /* Reset sector */ + NdefMap->MifareULContainer.CurrentSector = 0; + NdefMap->PrevState = PH_FRINFC_NDEFMAP_MFUL_STATE_WRITE; + + Result = phFriNfc_MfUL_H_SelectSector(NdefMap, + NdefMap->MifareULContainer.CurrentSector, 1, + PH_FRINFC_NDEFMAP_MFUL_STATE_SELECT_SECTOR_RESET_1); + + } + else + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST); + } + + + return Result; +} +#ifdef UNIT_TEST +extern void phFriNfc_MifareUL_UnitTest(void *Context,uint32_t Length) +{ + uint8_t value=10; + uint8_t* CrFlag=&value; + phFriNfc_NdefMap_t *pNdefMap=(phFriNfc_NdefMap_t*)Context; + phFriNfc_MfUL_H_UpdateLen(pNdefMap,(uint16_t) Length); + phFriNfc_MfUL_H_WrTermTLV(pNdefMap); + phFriNfc_MfUL_H_CallWrOp(pNdefMap); + phFriNfc_MfUL_H_UpdateWrLen(pNdefMap); + phFriNfc_MfUL_H_ChkRemainTLV(pNdefMap,CrFlag); + phFriNfc_MfUL_H_ProWrittenBytes(pNdefMap); + + pNdefMap->PrevOperation=PH_FRINFC_NDEFMAP_READ_OPE; + phFriNfc_MfUL_H_NxtOp(pNdefMap,CrFlag); + + pNdefMap->PrevOperation=PH_FRINFC_NDEFMAP_WRITE_OPE; + phFriNfc_MfUL_H_NxtOp(pNdefMap,CrFlag); + + pNdefMap->TLVStruct.NoLbytesinTLV=PH_FRINFC_NDEFMAP_MFUL_VAL1; + phFriNfc_MfUL_H_ChkRemainTLV(pNdefMap,CrFlag); + + pNdefMap->SendRecvBuf[0x00]= PH_FRINFC_NDEFMAP_MFUL_NULLTLV; + phFriNfc_MfUL_H_findNDEFTLV(pNdefMap,CrFlag); + + + pNdefMap->SendRecvBuf[0x00]= PH_FRINFC_NDEFMAP_MFUL_NULLTLV; + phFriNfc_MfUL_H_findNDEFTLV(pNdefMap,CrFlag); + + + phFriNfc_MfUL_H_RdBeforeWrite(pNdefMap); + pNdefMap->TLVStruct.NdefTLVByte=1; + phFriNfc_MfUL_H_RdBeforeWrite(pNdefMap); + + pNdefMap->TLVStruct.NdefTLVByte=3; + phFriNfc_MfUL_H_RdBeforeWrite(pNdefMap); + + pNdefMap->TLVStruct.NdefTLVByte=4; + phFriNfc_MfUL_H_RdBeforeWrite(pNdefMap); + + + phFriNfc_MifareUL_H_Complete(pNdefMap,NFCSTATUS_SUCCESS); + phFriNfc_MifareUL_H_Complete(NULL,NFCSTATUS_SUCCESS); + phFriNfc_MifareUL_H_Complete(pNdefMap,NFCSTATUS_SUCCESS); + pNdefMap->State=PH_FRINFC_NDEFMAP_MFUL_STATE_WRITE; + phFriNfc_MifareUL_H_Complete(pNdefMap,NFCSTATUS_SUCCESS); + + phFriNfc_MifareUL_H_Complete(pNdefMap,NFCSTATUS_FAILED); + phFriNfc_MifareUL_H_Complete(NULL,NFCSTATUS_SUCCESS); + phFriNfc_MifareUL_H_Complete(pNdefMap,NFCSTATUS_FAILED); + + *pNdefMap->DataCount=0x3; + phFriNfc_MfUL_H_ProWrittenBytes(pNdefMap); + + pNdefMap->ApduBuffIndex=0x31; + phFriNfc_MfUL_H_ProWrittenBytes(pNdefMap); + + + +} + +#endif +#endif /* PH_FRINFC_MAP_MIFAREUL_DISABLED */ + |