| /* |
| * 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->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 */ |
| |