blob: 8d1df810ba3078f85b9e6c791db957c85d7b95cc [file] [log] [blame]
/*
* 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 */