/* * 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.36 $ * $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->SendRecvBuf[Temp16Bytes] == PH_FRINFC_NDEFMAP_MFUL_PROPRIETRY_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] | (ShiftLength << PH_FRINFC_NDEFMAP_MFUL_SHIFT8)); // 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; /* Fix to check if the actual size in the TLV is greater than card */ if (NdefMap->TLVStruct.ActualSize > (NdefMap->CardMemSize - 2)) { Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); } 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; #ifndef NDEF_READ_CHANGE uint16_t v_field_byte = 0; if (NdefMap->MifareULContainer.CurrentBlock == NdefMap->TLVStruct.NdefTLVBlock) { if (NdefMap->CardMemSize > (0x12 * PH_FRINFC_NDEFMAP_MFUL_MUL8)) { v_field_byte = NdefMap->TLVStruct.NdefTLVByte; } /* Calculate the Value field of the TLV to read */ if (NdefMap->TLVStruct.ActualSize >= 0xFF) { /* here 3 is the 3 LENGTH bytes to skip 4 is the block size 1 is to increment the byte number */ v_field_byte = (uint16_t) (((v_field_byte + 3) % 4) + 1); } else { /* less than 0xFF */ #if 0 if ((0x03 == v_field_byte) || (0x04 == v_field_byte)) { /* here 1 is the 1 LENGTH byte to skip 4 is the block size 1 is to increment the byte number */ v_field_byte = (uint16_t) (((v_field_byte + 1) % 4) + 1); } else { v_field_byte = (uint16_t) (v_field_byte + 1); } #endif /* #if 0 */ } } #endif /* #ifndef NDEF_READ_CHANGE */ #ifndef NDEF_READ_CHANGE (void)memcpy(&(NdefMap->MifareULContainer.ReadBuf[ NdefMap->MifareULContainer.ReadBufIndex]), (void *)(NdefMap->SendRecvBuf + v_field_byte), (*NdefMap->SendRecvLength - v_field_byte)); NdefMap->MifareULContainer.ReadBufIndex = (uint16_t) (NdefMap->MifareULContainer.ReadBufIndex + (*NdefMap->SendRecvLength - v_field_byte)); #else /* #ifndef NDEF_READ_CHANGE */ (void)memcpy(&(NdefMap->MifareULContainer.ReadBuf[ NdefMap->MifareULContainer.ReadBufIndex]), NdefMap->SendRecvBuf, *NdefMap->SendRecvLength); NdefMap->MifareULContainer.ReadBufIndex=NdefMap->MifareULContainer.ReadBufIndex +*NdefMap->SendRecvLength; #endif /* #ifndef NDEF_READ_CHANGE */ 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); */ NdefMap->SendRecvBuf[1] = (uint8_t) NdefMap->ApduBuffIndex; } else if (NdefMap->NumOfLReminWrite == 2) { NdefMap->SendRecvBuf[1] = (uint8_t) ((NdefMap->ApduBuffIndex & 0xFF00) >> 8); NdefMap->SendRecvBuf[2]= (uint8_t) (NdefMap->ApduBuffIndex); } 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 & 0xFF00) >> 8); ByteNo++; NdefMap->SendRecvBuf[ByteNo] = (uint8_t) (NdefMap->ApduBuffIndex); ByteNo++; NdefMap->NumOfLReminWrite = 0; } else if (ByteNo == 4) { /* NdefMap->SendRecvBuf[ByteNo]= (uint8_t) (NdefMap->ApduBuffIndex); */ NdefMap->SendRecvBuf[ByteNo]= (uint8_t) ((NdefMap->ApduBuffIndex & 0xFF00) >> 8); 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 */