diff options
author | Nick Pelly <npelly@google.com> | 2010-09-23 12:47:58 -0700 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2010-09-23 13:53:18 -0700 |
commit | 5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a (patch) | |
tree | 190f9251c6db03d3550ec7f30b51a2561c01d9cf /src/phFriNfc_FelicaMap.c | |
parent | 4ff7c86a2c706b150078274455406f1b04966e1a (diff) | |
download | external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.zip external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.gz external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.bz2 |
Initial libnfc checkin
Source: Trusted_NFC_Device_Host_AA03.01e02_google.zip code drop (23-Sep-2010)
Change-Id: Ie47f18423f949a8d3e0815d13f55c814312add24
Signed-off-by: Nick Pelly <npelly@google.com>
Diffstat (limited to 'src/phFriNfc_FelicaMap.c')
-rw-r--r-- | src/phFriNfc_FelicaMap.c | 3040 |
1 files changed, 3040 insertions, 0 deletions
diff --git a/src/phFriNfc_FelicaMap.c b/src/phFriNfc_FelicaMap.c new file mode 100644 index 0000000..52745da --- /dev/null +++ b/src/phFriNfc_FelicaMap.c @@ -0,0 +1,3040 @@ +/* + * 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_FelicaMap.c + * \brief This component encapsulates read/write/check ndef/process functionalities, + * for the Felica Smart Card. + * + * Project: NFC-FRI + * + * $Date: Thu May 6 14:01:35 2010 $ + * $Author: ing07385 $ + * $Revision: 1.10 $ + * $Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $ + * + */ + +#ifndef PH_FRINFC_MAP_FELICA_DISABLED + +#include <phNfcTypes.h> +#include <phFriNfc_OvrHal.h> +#include <phFriNfc_FelicaMap.h> +#include <phFriNfc_MapTools.h> + + +/*! \ingroup grp_file_attributes + * \name NDEF Mapping + * + * File: \ref phFriNfc_FelicaMap.c + * + */ +/*@{*/ + +#define PHFRINFCNDEFMAP_FILEREVISION "$Revision: 1.10 $" +#define PHFRINFCNDEFMAP_FILEALIASES "$Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $" + +/*@}*/ + +/* Helpers for Read and updating the attribute informations*/ +static NFCSTATUS phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer, + uint8_t StartIndex, + uint8_t EndIndex, + uint16_t RecvChkSum); + +#ifndef PH_HAL4_ENABLE +/* Helpers for Poll Related Operations*/ +static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap, + const uint8_t sysCode[], + uint8_t state); +#endif /* #ifndef PH_HAL4_ENABLE */ + + +static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap); + +/*Helpers for Reading Operations*/ +static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset); +static uint16_t phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap,uint8_t NbcOrNmaxb ); +static void phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset); +static uint16_t phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc); +static NFCSTATUS phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap); + +/* Helpers for Writing Operations*/ +static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap, + uint32_t NdefLen); +static NFCSTATUS phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted); +static NFCSTATUS phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap); + +/* Write Empty NDEF Message*/ +static NFCSTATUS phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap); + +/*Helpers for common checks*/ +static NFCSTATUS phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t *NdefMap, + uint8_t CrIndex, + NFCSTATUS Status); + +static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer); + +static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n ); + +/*! + * \brief returns maximum number of blocks can be read from the Felica Smart Card. + * + * The function is useful in reading of NDEF information from a felica tag. + */ + +static uint16_t phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap, uint8_t NbcOrNmaxb ) +{ + uint16_t BlksToRead=0; + uint32_t DataLen = 0; + /* This part of the code is useful if we take account of Nbc blks reading*/ + if ( NbcOrNmaxb == PH_NFCFRI_NDEFMAP_FELI_NBC ) + { + PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], + NdefMap->FelicaAttrInfo.LenBytes[1], + NdefMap->FelicaAttrInfo.LenBytes[2], + DataLen); + /* Calculate Nbc*/ + BlksToRead = (uint16_t) ( ((DataLen % 16) == 0) ? (DataLen >> 4) : ((DataLen >> 4) +1) ); + + + } + else if ( NbcOrNmaxb == PH_NFCFRI_NDEFMAP_FELI_NMAXB) + { + BlksToRead = NdefMap->FelicaAttrInfo.Nmaxb; + } + else + { + /* WARNING !!! code should not reach this point*/ + ; + } + return (BlksToRead); +} + +/*! + * \brief Initiates Reading of NDEF information from the Felica Card. + * + * The function initiates the reading of NDEF information from a Remote Device. + * It performs a reset of the state and starts the action (state machine). + * A periodic call of the \ref phFriNfcNdefMap_Process has to be + * done once the action has been triggered. + */ + +NFCSTATUS phFriNfc_Felica_RdNdef( phFriNfc_NdefMap_t *NdefMap, + uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset) +{ + + NFCSTATUS status = NFCSTATUS_PENDING; + uint32_t Nbc = 0; + + NdefMap->ApduBufferSize = *PacketDataLength; + /*Store the packet data buffer*/ + NdefMap->ApduBuffer = PacketData; + + NdefMap->NumOfBytesRead = PacketDataLength ; + *NdefMap->NumOfBytesRead = 0; + NdefMap->ApduBuffIndex = 0; + + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; + NdefMap->Felica.Offset = Offset; + + if( ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )||( NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE)) + { + NdefMap->Felica.CurBlockNo = 0; + NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_RD_ATTR_RD_OP; + NdefMap->Felica.IntermediateCpyFlag = FALSE; + NdefMap->Felica.IntermediateCpyLen = 0; + NdefMap->Felica.Rd_NoBytesToCopy = 0; + NdefMap->Felica.EofCardReachedFlag= FALSE ; + NdefMap->Felica.LastBlkReachedFlag = FALSE; + NdefMap->Felica.CurrBytesRead = 0; + + phFriNfc_Felica_HInitInternalBuf(NdefMap->Felica.Rd_BytesToCopyBuff); + + /* send request to read attribute information*/ + status = phFriNfc_Felica_HRdAttrInfo(NdefMap); + /* handle the error in Transc function*/ + if ( (status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status); + } + } + else + { + Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); + + /* Offset = Current, but the read has reached the End of NBC Blocks */ + if(( ( Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && (NdefMap->Felica.CurBlockNo == Nbc)) && + (NdefMap->Felica.EofCardReachedFlag == FELICA_RD_WR_EOF_CARD_REACHED )) + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); + } + else + { + + NdefMap->Felica.CurrBytesRead = ((NdefMap->Felica.CurBlockNo * 16)- NdefMap->Felica.Rd_NoBytesToCopy); + status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset); + + } + } + return (status); +} + +/*Read Operation Related Helper Routines*/ + +/*! + * \brief Used in Read Opearation.Sets the Trx Buffer Len calls Transc Cmd. + * After a successful read operation, function does checks the user buffer size + * sets the status flags. +*/ + +static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + uint16_t Nbc=0,TranscLen=0; + + Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); + if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > 0) && (NdefMap->Felica.CurBlockNo < Nbc )) + { + /* if data is present in the internal buffer*/ + if (NdefMap->Felica.Rd_NoBytesToCopy > 0 ) + { + /* copy data to external buffer*/ + phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap); + /*Check the size of user buffer*/ + status = phFriNfc_Felica_HChkApduBuff_Size(NdefMap); + if ( (status != NFCSTATUS_SUCCESS) && (NdefMap->Felica.IntermediateRdFlag == TRUE )) + { + /* set the transc len and call transc cmd*/ + TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc); + status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset); + } + else + { + /* Nothing to be done , if IntermediateRdFlag is set to zero*/ + ; + } + } + else + { + /* set the transc len and call transc cmd*/ + TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc); + status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset); + } + } + else + { + /* Chk the Buffer size*/ + status = phFriNfc_Felica_HChkApduBuff_Size(NdefMap); + if ( (status != NFCSTATUS_SUCCESS) && (NdefMap->Felica.IntermediateRdFlag == TRUE )) + { + TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc); + status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset); + } + } + return (status); +} + +/*! + * \brief Used in Read Opearation.Sets the Trx Buffer Len. + */ + +static uint16_t phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc) +{ + uint16_t TranscLen = 0,BlocksToRead=0; + + if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)% 16) == 0) + { + BlocksToRead = (uint16_t)( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16 ); + } + else + { + BlocksToRead = (uint16_t)(((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16) +1); + } + if ( (BlocksToRead > Nbc) ||( (BlocksToRead) > ( Nbc - NdefMap->Felica.CurBlockNo)) ) + { + BlocksToRead = Nbc - NdefMap->Felica.CurBlockNo; + } + + + if ( BlocksToRead >= NdefMap->FelicaAttrInfo.Nbr) + { + if( NdefMap->FelicaAttrInfo.Nbr < Nbc ) + { + TranscLen = NdefMap->FelicaAttrInfo.Nbr*16; + } + else + { + TranscLen = Nbc*16; + NdefMap->Felica.LastBlkReachedFlag =1; + } + } + else + { + if (BlocksToRead <= Nbc ) + { + if ( ( BlocksToRead * 16) == ((Nbc *16) - (NdefMap->Felica.CurBlockNo * 16))) + { + NdefMap->Felica.LastBlkReachedFlag =1; + + } + TranscLen = BlocksToRead*16; + + } + else + { + TranscLen = Nbc*16; + } + } + /* As Cur Blk changes, to remember the exact len what we had set + in the begining of each read operation*/ + NdefMap->Felica.TrxLen = TranscLen; + return (TranscLen); +} + +/*! + * \brief Used in Read Opearation.After a successful read operation, + * Copies the data to user buffer. + */ + +static void phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t ResetFlag = FALSE, ExtrBytesToCpy = FALSE; + uint16_t Nbc=0; + uint32_t DataLen=0; + + Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC ); + + PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], + NdefMap->FelicaAttrInfo.LenBytes[1], + NdefMap->FelicaAttrInfo.LenBytes[2], + DataLen); + /* Internal Buffer has some old read bytes to cpy to user buffer*/ + if( NdefMap->Felica.Rd_NoBytesToCopy > 0 ) + { + if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.Rd_NoBytesToCopy ) + { + NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + + if (NdefMap->Felica.IntermediateCpyFlag == TRUE ) + { + /*Copy data from the internal buffer to user buffer*/ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])), + (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); + + + + /* Store number of bytes copied frm internal buffer to User Buffer */ + NdefMap->Felica.IntermediateCpyLen += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + NdefMap->Felica.IntermediateCpyFlag = 1; + + /* check do we reach len bytes any chance*/ + PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], + NdefMap->FelicaAttrInfo.LenBytes[1], + NdefMap->FelicaAttrInfo.LenBytes[2], + DataLen); + /* Internal buffer has zero bytes for copy operation*/ + if ( NdefMap->Felica.Rd_NoBytesToCopy == 0) + { + NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED; + } + } + else + { + /*Copy data from the internal buffer to apdu buffer*/ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + NdefMap->Felica.Rd_BytesToCopyBuff, + (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); + } + NdefMap->ApduBuffIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + + } + else if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.Rd_NoBytesToCopy ) + { + if ( NdefMap->Felica.IntermediateCpyFlag == TRUE ) + { + /*Copy data internal buff to apdubuffer*/ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])), + NdefMap->Felica.Rd_NoBytesToCopy); + } + else + { + /*Copy data internal buff to apdubuffer*/ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + NdefMap->Felica.Rd_BytesToCopyBuff, + NdefMap->Felica.Rd_NoBytesToCopy); + } + + /*increment the index,internal buffer len*/ + NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy; + NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBuffIndex); + + /* To reset the parameters*/ + ResetFlag = TRUE; + } + else + { + /* Extra Bytes to Copy from internal buffer to external buffer*/ + if ( NdefMap->Felica.IntermediateCpyFlag == TRUE ) + { + /*Copy data internal buff to apdubuffer*/ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])), + NdefMap->Felica.Rd_NoBytesToCopy); + } + else + { + /*Copy data internal buff to apdubuffer*/ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + NdefMap->Felica.Rd_BytesToCopyBuff, + NdefMap->Felica.Rd_NoBytesToCopy); + } + /*increment the index*/ + NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy; + + /* To reset the parameters*/ + ResetFlag = TRUE; + } + }/*End of Internal Buffer has some old read bytes to cpy to user buffer*/ + else + { + /* check if last block is reached*/ + if ( ((NdefMap->Felica.LastBlkReachedFlag == 1) && (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= 16)) ) + { + /* greater than 16 but less than the data len size*/ + if (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= DataLen) + { + NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen) - (NdefMap->Felica.CurrBytesRead + + NdefMap->ApduBuffIndex)); + + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&(NdefMap->SendRecvBuf[13])), + NdefMap->Felica.CurrBytesRead); + + NdefMap->ApduBuffIndex += NdefMap->Felica.CurrBytesRead; + if ( NdefMap->ApduBuffIndex == DataLen) + { + ResetFlag = TRUE; + } + } + else + { + /* need to check exact no. of bytes to copy to buffer*/ + if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <= NdefMap->Felica.TrxLen )|| + ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <= DataLen )) + { + + ExtrBytesToCpy = TRUE; + } + else + { + NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - (DataLen))); + + if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)) + { + /*Reduce already copied bytes from the internal buffer*/ + NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + ExtrBytesToCpy = TRUE; + } + else + { + ExtrBytesToCpy = FALSE; + } + } + if ( ExtrBytesToCpy == TRUE ) + { + NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen)- (NdefMap->Felica.CurrBytesRead + + NdefMap->ApduBuffIndex)); + + if(NdefMap->Felica.CurrBytesRead < + (uint16_t)(NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex)) + { + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&(NdefMap->SendRecvBuf[13])), + NdefMap->Felica.CurrBytesRead); + } + else + { + (void)memcpy( (&( NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&( NdefMap->SendRecvBuf[13])), + (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); + } + + if ( NdefMap->Felica.LastBlkReachedFlag == 1 ) + { + NdefMap->Felica.Rd_NoBytesToCopy = + (uint8_t)((NdefMap->Felica.CurrBytesRead > + (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))? + (NdefMap->Felica.CurrBytesRead - + (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)): + 0); + + ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy == 0)?TRUE:FALSE); + + } + else + { + NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)( NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); + } + + /* Copy remained bytes back into internal buffer*/ + (void)memcpy( NdefMap->Felica.Rd_BytesToCopyBuff, + (&(NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_RESP_HEADER_LEN+(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)])), + NdefMap->Felica.Rd_NoBytesToCopy); + + /* set the intermediate flag : This flag remembers that there are still X no. bytes remained in + Internal Buffer Ex: User has given only one byte buffer,needs to cpy one byte at a time*/ + NdefMap->Felica.IntermediateCpyFlag = TRUE; + + NdefMap->ApduBuffIndex += ((NdefMap->Felica.CurrBytesRead < + (uint16_t)(NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex))? + NdefMap->Felica.CurrBytesRead: + (uint16_t)(NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex)); + } + else + { + /*Copy data from the internal buffer to user buffer*/ + (void)memcpy( (&( NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&( NdefMap->SendRecvBuf[13])), + NdefMap->Felica.Rd_NoBytesToCopy); + + NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy; + ResetFlag = TRUE; + + } + } + + } + else + { + if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.TrxLen ) + { + /* Calculate exactly remained bytes to copy to internal buffer and set it*/ + if ( NdefMap->Felica.LastBlkReachedFlag == 1) + { + NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - DataLen)); + + if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)) + { + /*Reduce already copied bytes from the internal buffer*/ + NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + ExtrBytesToCpy = TRUE; + } + } + else + { + NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); + ExtrBytesToCpy = TRUE; + } + if ( ExtrBytesToCpy == TRUE ) + { + /*Copy the read data from trx buffer to apdu of size apdu*/ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&(NdefMap->SendRecvBuf[13])), + NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + + /*copy bytesToCopy to internal buffer*/ + (void)memcpy( NdefMap->Felica.Rd_BytesToCopyBuff, + (&(NdefMap->SendRecvBuf[13+(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)])), + NdefMap->Felica.Rd_NoBytesToCopy); + + NdefMap->Felica.IntermediateCpyFlag = TRUE; + NdefMap->ApduBuffIndex += (uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex; + } + else + { + /*Copy data from the internal buffer to user buffer*/ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&(NdefMap->SendRecvBuf[13])), + NdefMap->Felica.Rd_NoBytesToCopy); + + NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy; + ResetFlag = TRUE; + + } + if ( DataLen <= (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) ) + { + NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED; + } + else + { + ; + } + } + else if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.TrxLen ) + { + /*Copy exactly remained last bytes to user buffer and increment the index*/ + /*13 : 1+12 : 1st byte entire pkt length + 12 bytes to skip manuf details*/ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&(NdefMap->SendRecvBuf[13])), + (NdefMap->Felica.TrxLen )); + + NdefMap->ApduBuffIndex += NdefMap->Felica.TrxLen; + } + else + { + if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > NdefMap->Felica.TrxLen ) + { + /*Copy the data to apdu buffer and increment the index */ + (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (&(NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_RESP_HEADER_LEN])), + NdefMap->Felica.TrxLen); + + NdefMap->ApduBuffIndex += (uint16_t)NdefMap->Felica.TrxLen; + } + } + } + } + if ( ResetFlag == TRUE ) + { + /* reset the internal buffer variables*/ + NdefMap->Felica.Rd_NoBytesToCopy =0; + NdefMap->Felica.IntermediateCpyLen =0; + NdefMap->Felica.IntermediateCpyFlag =FALSE; + } + return; +} + + +/*! + * \brief Used in Read Opearation.After a successful read operation, + Checks the relavent buffer sizes and set the status.Following function is used + when we read the Nmaxb blocks. Retained for future purpose. + */ + +static NFCSTATUS phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + uint8_t ResetFlag = FALSE; + uint32_t Nbc = 0; + + Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); + + /* set status to Success : User Buffer is full and Curblk < nmaxb*/ + if ( (( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) && + (NdefMap->Felica.CurBlockNo < Nbc )) + { + status = PHNFCSTVAL(CID_NFC_NONE, + NFCSTATUS_SUCCESS); + /*Reset the index, internal buffer counters back to zero*/ + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + NdefMap->ApduBuffIndex = 0; + + }/*if( (NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb )*/ + else + { + if (( ( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) && + (NdefMap->Felica.CurBlockNo == Nbc )) + { + status = PHNFCSTVAL(CID_NFC_NONE, + NFCSTATUS_SUCCESS); + + ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy > 0 )? + FALSE: + TRUE); + if( ResetFlag== FALSE) + { + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + /*Reset the index, internal buffer counters back to zero*/ + NdefMap->ApduBuffIndex = 0; + } + }/*if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb )*/ + else + { + /* reached reading all the blks available in the card: set EOF flag*/ + if ( NdefMap->ApduBuffIndex == (Nbc*16)) + { + status = PHNFCSTVAL(CID_NFC_NONE, + NFCSTATUS_SUCCESS); + ResetFlag = TRUE; + } + else + { + if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )> 0 ) + { + if ( NdefMap->Felica.CurBlockNo == Nbc ) + { + /* bytes pending in internal buffer , No Space in User Buffer*/ + if ( NdefMap->Felica.Rd_NoBytesToCopy > 0) + { + if ( NdefMap->Felica.EofCardReachedFlag == TRUE ) + { + status = PHNFCSTVAL(CID_NFC_NONE, + NFCSTATUS_SUCCESS); + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + NdefMap->ApduBuffIndex=0; + } + else + { + phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap); + if( NdefMap->Felica.Rd_NoBytesToCopy > 0 ) + { + status = PHNFCSTVAL(CID_NFC_NONE, + NFCSTATUS_SUCCESS); + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + NdefMap->ApduBuffIndex=0; + } + else + { + /* EOF Card Reached set the internal EOF Flag*/ + status = PHNFCSTVAL(CID_NFC_NONE, + NFCSTATUS_SUCCESS); + + ResetFlag = TRUE; + } + } + } + /* All bytes from internal buffer are copied and set eof flag*/ + else + { + status = PHNFCSTVAL(CID_NFC_NONE, + NFCSTATUS_SUCCESS); + ResetFlag = TRUE; + } + } + else + { + /* This flag is set to ensure that, need of Read Opearation + we completed coying the data from internal buffer to external buffer + left some more bytes,in User bufer so initiate the read operation */ + NdefMap->Felica.IntermediateRdFlag = TRUE; + } + } + else + { + status = PHNFCSTVAL(CID_NFC_NONE, + NFCSTATUS_SUCCESS); + } + } + } + if ( ResetFlag == TRUE) + { + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + /*Reset the index, internal buffer counters back to zero*/ + NdefMap->ApduBuffIndex = 0; + NdefMap->Felica.Rd_NoBytesToCopy=0; + NdefMap->Felica.EofCardReachedFlag=FELICA_RD_WR_EOF_CARD_REACHED; + + } + + } + return( status); +} + +/*! + * \brief Used in Read Opearation.Sets the transceive Command for read. + */ +static NFCSTATUS phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset) +{ + NFCSTATUS TrxStatus = NFCSTATUS_PENDING; + uint16_t BufIndex=0,i=0; + + /* set the felica cmd */ +#ifdef PH_HAL4_ENABLE + NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; +#else + NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; +#endif /* #ifdef PH_HAL4_ENABLE */ + + /*Change the state to Read */ + NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK; + + /* set the complition routines for the mifare operations */ + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + /*set the additional informations for the data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + + /* pkt len : updated at the end*/ + NdefMap->SendRecvBuf[BufIndex] = 0x00; + BufIndex ++; + + NdefMap->SendRecvBuf[BufIndex] = 0x06; + BufIndex++; + + /* IDm - Manufacturer Id : 8bytes*/ +#ifdef PH_HAL4_ENABLE + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)), + 8); +#else + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)), + 8); +#endif /* #ifdef PH_HAL4_ENABLE */ + + BufIndex+=8; + + /*Number of Services (n=1 ==> 0x80)*/ + NdefMap->SendRecvBuf[BufIndex] = 0x01; + BufIndex++; + + /*Service Code List*/ + NdefMap->SendRecvBuf[BufIndex] = 0x0B; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; + BufIndex++; + + /*Number of Blocks to read*/ + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(TrxLen/16); + BufIndex++; + /* Set the Blk numbers as per the offset set by the user : Block List*/ + if ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN ) + { + for ( i=0;i<(TrxLen/16);i++) + { + /*1st Service Code list : byte 1*/ + NdefMap->SendRecvBuf[BufIndex] = 0x80; + BufIndex++; + + /* No. Of Blocks*/ + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(i + 1); + BufIndex++; + } + } + else + { + for ( i= 1;i<=(TrxLen/16);i++) + { + /*1st Service Code list : byte 1*/ + NdefMap->SendRecvBuf[BufIndex] = 0x80; + BufIndex++; + + /* No. Of Blocks*/ + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(NdefMap->Felica.CurBlockNo + i); + BufIndex++; + } + } + + /* len of entire pkt*/ + NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = (uint8_t) BufIndex; + + /* Set the Pkt Len*/ + NdefMap->SendLength = BufIndex; + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + TrxStatus = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + return (TrxStatus); +} + +/*! + * \brief Initiates Writing of NDEF information to the Remote Device. + * + * The function initiates the writing of NDEF information to a Remote Device. + * It performs a reset of the state and starts the action (state machine). + * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action + * has been triggered. + */ + +NFCSTATUS phFriNfc_Felica_WrNdef( phFriNfc_NdefMap_t *NdefMap, + uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset) +{ + + NFCSTATUS status = NFCSTATUS_PENDING; + + NdefMap->ApduBufferSize = *PacketDataLength; + /*Store the packet data buffer*/ + NdefMap->ApduBuffer = PacketData; + + /* To Update the Acutal written bytes to context*/ + NdefMap->WrNdefPacketLength = PacketDataLength; + *NdefMap->WrNdefPacketLength = 0; + + + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; + NdefMap->Felica.Offset = Offset; + + NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_WR_ATTR_RD_OP; + status = phFriNfc_Felica_HRdAttrInfo(NdefMap); + /* handle the error in Transc function*/ + if ( (status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status); + } + return (status); +} + +/*! + * \brief Initiates Writing of Empty NDEF information to the Remote Device. + * + * The function initiates the writing empty of NDEF information to a Remote Device. + * It performs a reset of the state and starts the action (state machine). + * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action + * has been triggered. + */ + +NFCSTATUS phFriNfc_Felica_EraseNdef( phFriNfc_NdefMap_t *NdefMap) +{ + + NFCSTATUS status = NFCSTATUS_PENDING; + static uint32_t PktDtLength =0; + + if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID ) + { + /* Card is in invalid state, cannot have any read/write + operations*/ + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ + NFCSTATUS_INVALID_FORMAT); + } + else if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY ) + { + /*Can't write to the card :No Grants */ + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ + NFCSTATUS_WRITE_FAILED); + /* set the no. bytes written is zero*/ + NdefMap->WrNdefPacketLength = &PktDtLength; + *NdefMap->WrNdefPacketLength = 0; + } + else + { + + /* set the Operation*/ + NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP; + + status = phFriNfc_Felica_HRdAttrInfo(NdefMap); + } + return (status); +} + + +/*! + * \brief Used in Write Opearation. + * check the value set for the Write Flag, in first write operation(begin), sets the + * WR flag in attribute blck. + * After a successful write operation, This function sets the WR flag off and updates + * the LEN bytes in attribute Block. + */ + +static NFCSTATUS phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + uint16_t ChkSum=0,index=0; + uint8_t BufIndex=0, ErrFlag = FALSE; + uint32_t TotNoWrittenBytes=0; + + /* Write Operation : Begin/End Check*/ + + NdefMap->State = + (( isStarted == FELICA_WRITE_STARTED )? + PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN: + PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END); + + if( ( NdefMap->State == PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN)|| + ( NdefMap->State == PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END) ) + { + + /* Set the Felica Cmd*/ +#ifdef PH_HAL4_ENABLE + NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; +#else + NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; +#endif /* #ifdef PH_HAL4_ENABLE */ + + /* 1st byte represents the length of the cmd packet*/ + NdefMap->SendRecvBuf[BufIndex] = 0x00; + BufIndex++; + + /* Write/Update command code*/ + NdefMap->SendRecvBuf[BufIndex] = 0x08; + BufIndex++; + + /* IDm - Manufacturer Id : 8bytes*/ +#ifdef PH_HAL4_ENABLE + (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), + (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)), + 8); +#else + (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), + (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)), + 8); +#endif /* #ifdef PH_HAL4_ENABLE */ + + BufIndex+=8; + + NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to Write*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/ + BufIndex++; + + /* Fill Attribute Blk Information*/ + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Version; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbr; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8); + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff)); + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ + BufIndex++; + + if (isStarted == FELICA_WRITE_STARTED ) + { + NdefMap->SendRecvBuf[BufIndex] = 0x0F; /* Write Flag Made On*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/ + BufIndex++; + + /* Len Bytes*/ + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[0]; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[1]; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[2]; + BufIndex++; + } + else + { + /* Case: Previous Write Operation failed and integration context continues with write + operation with offset set to Current. In this case, if we find Internal Bytes remained in the + felica context is true(>0) and current block number is Zero. Then we shouldn't allow the module + to write the data to card, as this is a invalid case*/ + if ( (NdefMap->Felica.Wr_BytesRemained > 0) && (NdefMap->Felica.CurBlockNo == 0)) + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + ErrFlag = TRUE; + } + else + { + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Write Flag Made Off*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/ + BufIndex++; + + if ( NdefMap->Felica.Wr_BytesRemained > 0 ) + { + TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained))); + } + else + { + TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16); + + } + + /* Update Len Bytes*/ + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(( TotNoWrittenBytes & 0x00ff0000) >> 16); + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((TotNoWrittenBytes & 0x0000ff00) >> 8); + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(TotNoWrittenBytes & 0x000000ff); + BufIndex++; + } + } + + if ( ErrFlag != TRUE ) + { + /* check sum update*/ + for ( index = 16 ; index < 30 ; index ++) + { + ChkSum += NdefMap->SendRecvBuf[index]; + } + + /* fill check sum in command pkt*/ + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8); + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff); + BufIndex++; + + /* update length of the cmd pkt*/ + NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + /* Update the Send Len*/ + NdefMap->SendLength = BufIndex; + + /*set the completion routines for the desfire card operations*/ + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + /*set the additional informations for the data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + + /*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_PARAMETER); + + } + return (status); +} + +static NFCSTATUS phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + uint16_t ChkSum=0,index=0; + uint8_t BufIndex=0; + + /* Write Operation : To Erase the present NDEF Data*/ + + NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG; + + /* Set the Felica Cmd*/ +#ifdef PH_HAL4_ENABLE + NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; +#else + NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; +#endif /* #ifdef PH_HAL4_ENABLE */ + + /* 1st byte represents the length of the cmd packet*/ + NdefMap->SendRecvBuf[BufIndex] = 0x00; + BufIndex++; + + /* Write/Update command code*/ + NdefMap->SendRecvBuf[BufIndex] = 0x08; + BufIndex++; + + /* IDm - Manufacturer Id : 8bytes*/ +#ifdef PH_HAL4_ENABLE + (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), + (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)), + 8); +#else + (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), + (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)), + 8); +#endif /* #ifdef PH_HAL4_ENABLE */ + + + BufIndex+=8; + + NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to Write*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/ + BufIndex++; + + /* Fill Attribute Blk Information*/ + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Version; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbr; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8); + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff)); + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.WriteFlag; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/ + BufIndex++; + + /* Len Bytes are set to 0 : Empty Msg*/ + NdefMap->SendRecvBuf[BufIndex] = 0x00; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; + BufIndex++; + + /* check sum update*/ + for ( index = 16 ; index < 30 ; index ++) + { + ChkSum += NdefMap->SendRecvBuf[index]; + } + + /* fill check sum in command pkt*/ + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8); + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff); + BufIndex++; + + /* update length of the cmd pkt*/ + NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + /* Update the Send Len*/ + NdefMap->SendLength = BufIndex; + + /*set the completion routines for the desfire card operations*/ + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + /*set the additional informations for the data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + + /*Call the Overlapped HAL Transceive function */ + status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + + return (status); +} + + + + +/*! + * \brief Used in Write Opearation. + * This Function is called after a successful validation and storing of attribution block + * content in to context. + * If the write operation is initiated with begin,function initiates the write operation with + * RdWr flag. + * If the Offset is set to Current, Checks for the EOF card reached status and writes data to + * The Card + */ + +static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + uint32_t DataLen=0; + + /*check RW Flag Access Rights*/ + /* set to read only cannot write*/ + if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00) + + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_DEVICE_REQUEST); + } + else + { + if ( ( NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || + ( ( NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE) && + (NdefMap->Felica.Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN ) )) + { + /* check allready written number of bytes and apdu buffer size*/ + if (NdefMap->ApduBufferSize > (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16)) + { + NdefMap->Felica.EofCardReachedFlag = FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET; + } + else + { + NdefMap->Felica.EofCardReachedFlag = FALSE; + } + + + /* reset the internal variables initiate toupdate the attribute blk*/ + NdefMap->Felica.Wr_BytesRemained = 0; + NdefMap->Felica.CurBlockNo = 0; + NdefMap->Felica.NoBlocksWritten = 0; + phFriNfc_Felica_HInitInternalBuf(NdefMap->Felica.Wr_RemainedBytesBuff); + status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED); + + } + else + { + if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR ) + { + /* Calculate the Allready Written No. Of Blocks*/ + PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], + NdefMap->FelicaAttrInfo.LenBytes[1], + NdefMap->FelicaAttrInfo.LenBytes[2], + DataLen); + + if (( NdefMap->ApduBufferSize + (DataLen )) > + (uint32_t)( NdefMap->FelicaAttrInfo.Nmaxb *16)) + { + if(( DataLen ) == (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16) ) + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); + } + else + { + + NdefMap->Felica.EofCardReachedFlag =FELICA_EOF_REACHED_WR_WITH_CURR_OFFSET; + NdefMap->ApduBuffIndex =0; + NdefMap->Felica.NoBlocksWritten = 0; + status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED); + } + } + else + { + NdefMap->ApduBuffIndex =0; + NdefMap->Felica.NoBlocksWritten = 0; + status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED); + } + }/*if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR )*/ + } + } + return (status); +} + +/*! + * \brief Used in Read Opearation. + * This Function is called after a successful validation and storing of attribution block + * content in to context. + * While Offset is set to Current, Checks for the EOF card reached status and reads data from + * The Card + */ + +static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap, + uint32_t NdefLen) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + /*check WR Flag Access Rights*/ + /* set to still writing data state only cannot Read*/ + if ( NdefMap->FelicaAttrInfo.WriteFlag == 0x0F ) + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_READ_FAILED); + /* As we are not able to continue with reading data + bytes read set to zero*/ + *NdefMap->NumOfBytesRead = 0; + } + else + { + status = phFriNfc_MapTool_SetCardState( NdefMap,NdefLen); + if ( status == NFCSTATUS_SUCCESS) + { + /* Read data From the card*/ + status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset); + } + } + + return (status); +} + +/*! + * \brief Used in Write Opearation. + * This function writes the data in terms of blocks. + * Each write operation supports,minimum Nbw blocks of bytes. + * Also checks for the EOF,>=NBW,<NBW etc + */ +static NFCSTATUS phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + uint8_t BufIndex=0, + i=0, + BlkNo=0, + PadBytes=0, + CurBlk=1, + NoOfBlks=0, + NbwCheck=0, + TotNoBlks=0; + + uint32_t BytesRemainedInCard=0, + BytesRemained=0, + TotNoWrittenBytes=0; + + if( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > 0 ) + { + /* Prepare the write cmd pkt for felica*/ + /* 1st byte represents the length of the cmd packet*/ + NdefMap->SendRecvBuf[BufIndex] = 0x00; + BufIndex++; + + /* Write/Update command code*/ + NdefMap->SendRecvBuf[BufIndex] = 0x08; + BufIndex++; + + /* IDm - Manufacturer Id : 8bytes*/ +#ifdef PH_HAL4_ENABLE + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)), + 8); +#else + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)), + 8); +#endif /* #ifdef PH_HAL4_ENABLE */ + + BufIndex+=8; + + NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/ + BufIndex++; + + if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET) + { + /* check for the eof card reached flag.Need to write only mamximum bytes(memory)to card. + Used when, offset set to begin case*/ + BytesRemainedInCard= ( (NdefMap->FelicaAttrInfo.Nmaxb*16) - (NdefMap->Felica.CurBlockNo * 16)); + } + else + { + /* Offset : Cuurent*/ + if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_CURR_OFFSET ) + { + /* caculate previously written Ndef blks*/ + (void)phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); + + if ( NdefMap->Felica.Wr_BytesRemained ) + { + TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained))); + } + else + { + TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16); + } + /* Determine exactly, how many bytes we can write*/ + BytesRemainedInCard = (NdefMap->FelicaAttrInfo.Nmaxb*16 - (TotNoWrittenBytes)); + } + + } + /* Write Data Pending in the Internal Buffer*/ + if(NdefMap->Felica.Wr_BytesRemained > 0) + { + /* update the number of blocks to write with the block list elements*/ + /* Total Number of blocks to write*/ + NdefMap->SendRecvBuf[BufIndex] = 0; + BufIndex++; + + /* Update this Total no. Bloks later*/ + NoOfBlks = BufIndex; + + /* As we are writing atleast one block*/ + TotNoBlks = 1; + + /* check do we have some extra bytes to write? in User Buffer*/ + if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained)) + { + /* Have we reached EOF?*/ + if ( NdefMap->Felica.EofCardReachedFlag ) + { + BytesRemained = BytesRemainedInCard; + } + else + { + /* This value tells how many extra bytes we can write other than internal buffer bytes*/ + BytesRemained = (uint8_t)NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained); + } + + if ( BytesRemained ) + { + /* Not reached EOF*/ + if (!NdefMap->Felica.EofCardReachedFlag) + { + /* Calculate How many blks we need to write*/ + BlkNo =((uint8_t)( BytesRemained )/16); + + /* check blocks to write exceeds nbw*/ + if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw ) + { + BlkNo = NdefMap->FelicaAttrInfo.Nbw; + /* No. Blks to write are more than Nbw*/ + NbwCheck = 1; + } + else + { + if ((( BytesRemained %16) == 0)&& (BlkNo == 0 )) + { + BlkNo=1; + } + } + /* check do we need pad bytes?*/ + if( (!NbwCheck && (uint8_t)( BytesRemained)%16) != 0) + { + BlkNo++; + PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained); + NdefMap->Felica.PadByteFlag = TRUE; + NdefMap->Felica.NoBlocksWritten = BlkNo; + TotNoBlks += BlkNo; + + } + else + { + if ( NbwCheck ) + { + /* as we have to write only 8 blocks and already we have pad bytes so we have + to strat from previous block*/ + TotNoBlks += BlkNo - 1; + NdefMap->Felica.NoBlocksWritten = TotNoBlks-1; + } + else + { + if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 )) + { + TotNoBlks += BlkNo; + } + else + { + + } + if ( NdefMap->Felica.PadByteFlag ) + { + NdefMap->Felica.NoBlocksWritten = TotNoBlks-1; + + } + } + } + } + else + { + /* we have reached the eof card & hv bytes to write*/ + BlkNo =(uint8_t)(( BytesRemained - ((16 -NdefMap->Felica.Wr_BytesRemained)) )/16); + + /* check are we exceeding the NBW limit, while a write?*/ + if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw ) + { + BlkNo = NdefMap->FelicaAttrInfo.Nbw; + + /* No. Blks to write are more than Nbw*/ + NbwCheck = 1; + + } + else + { + if ((( BytesRemained %16) == 0)&& (BlkNo == 0 )) + { + BlkNo=1; + } + } + + /*check Total how many blocks to write*/ + if(((!NbwCheck) &&( BytesRemained- (16 - NdefMap->Felica.Wr_BytesRemained))%16) != 0) + { + BlkNo++; + PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained); + NdefMap->Felica.PadByteFlag = TRUE; + NdefMap->Felica.NoBlocksWritten = BlkNo; + TotNoBlks += BlkNo; + + } + else + { + if ( NbwCheck ) + { + /* as we have to write only 8 blocks and already we have pad bytes so we have + to strat from previous last block*/ + TotNoBlks += BlkNo - 1; + NdefMap->Felica.NoBlocksWritten = TotNoBlks-1; + } + else + { + /* we need to write only one block ( bytesremanind + internal buffer size = 16)*/ + if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 )) + { + TotNoBlks += BlkNo; + } + else + { + ;/* we are not incrementing the Total no. of blocks to write*/ + } + + if ( NdefMap->Felica.PadByteFlag ) + { + NdefMap->Felica.NoBlocksWritten = TotNoBlks -1; + + } + } + } + } + }/*if ( BytesRemained )*/ + else + { + ; /*Nothing to process here*/ + } + }/*if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained))*/ + else + { + /* No new blks to write*/ + NdefMap->Felica.NoBlocksWritten = 0; + } + /* Prepare the Blk List for Write Operation*/ + /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/ + for ( i=0; i< TotNoBlks; i++) + { + NdefMap->SendRecvBuf[BufIndex] = 0x80; + BufIndex++; + /* remember the previous Blk no and continue from there*/ + if ( NdefMap->Felica.PadByteFlag == TRUE ) + { + NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i; + BufIndex++; + } + else + { + CurBlk = NdefMap->Felica.CurBlockNo +1; + NdefMap->SendRecvBuf[BufIndex] = CurBlk + i; + BufIndex++; + } + } + /* Copy relevant data to Transc buffer*/ + if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16 - NdefMap->Felica.Wr_BytesRemained)) + { + + /*Copy the Remained bytes from the internal buffer to trxbuffer */ + (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), + NdefMap->Felica.Wr_RemainedBytesBuff, + NdefMap->Felica.Wr_BytesRemained); + + /*Increment the buff index*/ + BufIndex += NdefMap->Felica.Wr_BytesRemained; + + + /*append copy 16-bytesToPad to trxBuffer*/ + (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (16 - NdefMap->Felica.Wr_BytesRemained)); + + /* Update Number Of Bytes Writtened*/ + NdefMap->NumOfBytesWritten = 16 - NdefMap->Felica.Wr_BytesRemained; + + /* increment the index*/ + BufIndex += 16 - NdefMap->Felica.Wr_BytesRemained; + + if ( BytesRemained ) + { + if (!NdefMap->Felica.EofCardReachedFlag) + { + /* check nbw limit*/ + if ( NbwCheck != 1 ) + { + /* Copy Extra Bytes other than the internal buffer bytes*/ + (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])), + (NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained))); + + + /* Update Number Of Bytes Writtened*/ + NdefMap->NumOfBytesWritten += (uint16_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained)); + + BufIndex += (uint8_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained)); + + if ( PadBytes ) + { + for(i= 0; i< PadBytes; i++) + { + NdefMap->SendRecvBuf[BufIndex] =0x00; + BufIndex++; + } + /* no of bytes remained copy*/ + NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes); + + /*copy the data to internal buffer : Bytes remained*/ + (void)memcpy( NdefMap->Felica.Wr_RemainedBytesBuff, + (&( NdefMap->ApduBuffer[(NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained)])), + ( NdefMap->Felica.Wr_BytesRemained)); + } + else + { + /* No Bytes in Internal buffer*/ + NdefMap->Felica.Wr_BytesRemained = 0; + } + + } + else + { + + /*Copy Nbw*16 bytes of data to the trx buffer*/ + (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])), + (NdefMap->FelicaAttrInfo.Nbw - 1) * 16); + + /* increment the Buffindex*/ + BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16); + + NdefMap->Felica.Wr_BytesRemained = 0; + NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16); + NdefMap->Felica.PadByteFlag =FALSE; + } + }/*if (!NdefMap->Felica.EofCardReachedFlag)*/ + else + { + /* check nbw limit*/ + if ( NbwCheck != 1 ) + { + /* handle EOF card reached case*/ + (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])), + ( BytesRemained - ((16 -NdefMap->Felica.Wr_BytesRemained) ))); + + /* Update Number Of Bytes Writtened*/ + NdefMap->NumOfBytesWritten += (uint16_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)); + + BufIndex += (uint8_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)); + + if ( PadBytes ) + { + for(i= 0; i< PadBytes; i++) + { + NdefMap->SendRecvBuf[BufIndex] =0x00; + BufIndex++; + } + + /*no of bytes remained copy*/ + NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes); + + /*copy the data to internal buffer : Bytes remained*/ + (void)memcpy(NdefMap->Felica.Wr_RemainedBytesBuff, + (&(NdefMap->ApduBuffer[(NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained)])), + (NdefMap->Felica.Wr_BytesRemained)); + + } + else + { + NdefMap->Felica.Wr_BytesRemained = 0; + } + } + else + { + + /*Copy Nbw*16 bytes of data to the trx buffer*/ + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])), + (NdefMap->FelicaAttrInfo.Nbw - 1) * 16); + + /* increment the Buffindex*/ + BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16); + + NdefMap->Felica.Wr_BytesRemained = 0; + NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16); + + NdefMap->Felica.PadByteFlag =FALSE; + } + } + }/*if ( BytesRemained )*/ + else + { + NdefMap->Felica.Wr_BytesRemained = 0; + } + /* Update Total No. of blocks writtened*/ + NdefMap->SendRecvBuf[NoOfBlks -1 ]=TotNoBlks; + }/*if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16 - NdefMap->Felica.Wr_BytesRemained))*/ + else + { + /*copy the internal buffer data to trx buffer*/ + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + NdefMap->Felica.Wr_RemainedBytesBuff, + (NdefMap->Felica.Wr_BytesRemained)); + + /* increment the index*/ + BufIndex+=NdefMap->Felica.Wr_BytesRemained; + + /*append the apdusize data to the trx buffer*/ + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + NdefMap->ApduBufferSize); + + /* Index increment*/ + BufIndex+= (uint8_t)NdefMap->ApduBufferSize; + + /* Tells how many bytes present in the internal buffer*/ + BytesRemained = NdefMap->Felica.Wr_BytesRemained + NdefMap->ApduBufferSize; + + PadBytes = (uint8_t)(16-BytesRemained); + + /* Pad empty bytes with Zeroes to complete 16 bytes*/ + for(i= 0; i< PadBytes; i++) + { + NdefMap->SendRecvBuf[BufIndex] =0x00; + BufIndex++; + } + + /* Update Number Of Bytes Writtened*/ + NdefMap->NumOfBytesWritten = (uint16_t)NdefMap->ApduBufferSize; + + /* Flag set to understand that , we have received less no. of bytes than + present in the internal buffer*/ + NdefMap->Felica.IntermediateWrFlag = TRUE; + + if ( NdefMap->Felica.PadByteFlag ) + { + NdefMap->Felica.NoBlocksWritten = 0; + } + } + + NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; + NdefMap->SendLength = BufIndex; + /* Update Total No. of blocks writtened*/ + NdefMap->SendRecvBuf[NoOfBlks -1 ]=TotNoBlks; + } + else + { + /*Fresh write, starting from a new block*/ + if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) + { + /* check for the card size and write Nbw Blks*/ + if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw) + { + /* update the number of blocks to write with the block list elements*/ + /* Total Number of blocks to write*/ + NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw; + BufIndex++; + + /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/ + for ( i=1; i<= NdefMap->FelicaAttrInfo.Nbw; i++) + { + NdefMap->SendRecvBuf[BufIndex] = 0x80; + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i; + BufIndex++; + } + /*Copy Nbw*16 bytes of data to the trx buffer*/ + + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + NdefMap->FelicaAttrInfo.Nbw * 16); + + /* increment the Buffindex*/ + BufIndex += (NdefMap->FelicaAttrInfo.Nbw*16); + + /* update the length*/ + NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; + + NdefMap->Felica.Wr_BytesRemained = 0; + NdefMap->NumOfBytesWritten = (NdefMap->FelicaAttrInfo.Nbw*16); + NdefMap->Felica.NoBlocksWritten = NdefMap->FelicaAttrInfo.Nbw; + + /* update the Send length*/ + NdefMap->SendLength = BufIndex; + + NdefMap->Felica.PadByteFlag = FALSE; + }/*if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw)*/ + else + { + /* we need to write less than nbw blks*/ + /* update the number of blocks to write with the block list elements*/ + /* Total Number of blocks to write*/ + NdefMap->SendRecvBuf[BufIndex] = (uint8_t)( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo); + BufIndex++; + + /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/ + for ( i=1; i<= (NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo); i++) + { + NdefMap->SendRecvBuf[BufIndex] = 0x80; + BufIndex++; + NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i; + BufIndex++; + } + + /*Copy Nbw*16 bytes of data to the trx buffer*/ + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo)*16); + + /* increment the Buffindex*/ + BufIndex += (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo )*16); + + /* update the length*/ + NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; + + NdefMap->NumOfBytesWritten = ((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo)*16); + NdefMap->Felica.NoBlocksWritten = (uint8_t)(NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo); + + /* update the Send length*/ + NdefMap->SendLength = BufIndex; + + NdefMap->Felica.PadByteFlag =FALSE; + NdefMap->Felica.Wr_BytesRemained = 0; + } + }/* if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */ + else + { + /*chk eof reached*/ + if ( NdefMap->Felica.EofCardReachedFlag) + { + BlkNo =((uint8_t)(BytesRemainedInCard )/16); + if(((uint8_t)( BytesRemainedInCard )%16) != 0) + { + BlkNo++; + PadBytes = ((BlkNo * 16) - (uint8_t)(BytesRemainedInCard )); + NdefMap->Felica.PadByteFlag = TRUE; + } + } + else + { + + BlkNo =((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16); + if(((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)%16) != 0) + { + BlkNo++; + PadBytes = (BlkNo * 16) - (uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + NdefMap->Felica.PadByteFlag = TRUE; + + } + + + } + + /* update the number of blocks to write with the block list elements*/ + /* Total Number of blocks to write*/ + NdefMap->SendRecvBuf[BufIndex] = BlkNo; + BufIndex++; + + NdefMap->Felica.NoBlocksWritten = BlkNo; + + /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/ + for ( i=0; i< BlkNo; i++) + { + NdefMap->SendRecvBuf[BufIndex] = 0x80; + BufIndex++; + { + CurBlk = NdefMap->Felica.CurBlockNo +1; + NdefMap->SendRecvBuf[BufIndex] = CurBlk + i; + BufIndex++; + } + } + if ( NdefMap->Felica.EofCardReachedFlag ) + { + /*Copy last data to the trx buffer*/ + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + BytesRemainedInCard ); + + /* increment the bufindex and bytes written*/ + BufIndex += (uint8_t )BytesRemainedInCard ; + NdefMap->NumOfBytesWritten = (uint16_t)BytesRemainedInCard ; + } + else + { + /*Copy data to the trx buffer*/ + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), + (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); + + /* increment the bufindex and bytes written*/ + BufIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + NdefMap->NumOfBytesWritten = (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + } + if ( PadBytes ) + { + for(i= 0; i< PadBytes; i++) + { + NdefMap->SendRecvBuf[BufIndex] =0x00; + BufIndex++; + } + /*no of bytes remained copy*/ + NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes); + + if ( NdefMap->Felica.EofCardReachedFlag ) + { + /*copy the data to internal buffer : Bytes remained*/ + (void)memcpy(NdefMap->Felica.Wr_RemainedBytesBuff, + (&(NdefMap->ApduBuffer[((BytesRemainedInCard - (BytesRemainedInCard % 16)))])), + ( NdefMap->Felica.Wr_BytesRemained)); + + } + else + { + /*copy the data to internal buffer : Bytes remained*/ + (void)memcpy( NdefMap->Felica.Wr_RemainedBytesBuff, + (&(NdefMap->ApduBuffer[((NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained))])), + ( NdefMap->Felica.Wr_BytesRemained)); + + } + }/*if ( PadBytes )*/ + else + { + NdefMap->Felica.Wr_BytesRemained = 0; + NdefMap->Felica.PadByteFlag = FALSE; + } + /* update the pkt len*/ + NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; + NdefMap->SendLength = BufIndex; + } + }/* else of if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */ + status = phFriNfc_Felica_HWriteDataBlk(NdefMap); + } + else + { + /*0 represents the write operation ended*/ + status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED); + } + return (status); +} + + +/*! + * \brief Used in Write Opearation. + * This function prepares and sends transcc Cmd Pkt. + */ + +static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + /*set the additional informations for the data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + + /*Set the ISO14434 command*/ +#ifdef PH_HAL4_ENABLE + NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; +#else + NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; +#endif /* #ifdef PH_HAL4_ENABLE */ + + /* set the state*/ + NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK; + + /* set send receive length*/ + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + /*Call the Overlapped HAL Transceive function */ + status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + return (status); +} + +/*! + * \brief Check whether a particular Remote Device is NDEF compliant. + * The function checks whether the peer device is NDEF compliant. + */ + +NFCSTATUS phFriNfc_Felica_ChkNdef( phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + +#ifndef PH_HAL4_ENABLE + uint8_t sysCode[2]; +#endif /* #ifndef PH_HAL4_ENABLE */ + +#ifdef PH_HAL4_ENABLE + + /* check the ndef compliency with the system code reecived in the RemoteDevInfo*/ + status = phFriNfc_Felica_HUpdateManufIdDetails(NdefMap); + + if (status == NFCSTATUS_SUCCESS) + { + + /* set the operation type to Check ndef type*/ + NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP; + status = phFriNfc_Felica_HRdAttrInfo(NdefMap); + } +#else + + /* set the system code for selecting the wild card*/ + sysCode[0] = 0x12; + sysCode[1] = 0xFC; + + status = phFriNfc_Felica_HPollCard( NdefMap,sysCode,PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP); +#endif /* #ifdef PH_HAL4_ENABLE */ + + return (status); + +} +/*! + * \brief Check whether a particular Remote Device is NDEF compliant. + * selects the wild card and then NFC Forum Reference Applications + */ + +#ifndef PH_HAL4_ENABLE +static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap, + const uint8_t sysCode[], + uint8_t state) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + /*Format the Poll Packet for selecting the wild card "0xff 0xff as system code*/ + NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[0] = 0x00; + NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[1] = sysCode[0]; + NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[2] = sysCode[1]; + NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[3] = 0x01; + NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[4] = 0x03; + + /* set the length to zero*/ + NdefMap->FelicaPollDetails.DevInputParam->GeneralByteLength =0x00; + + NdefMap->NoOfDevices = PH_FRINFC_NDEFMAP_FELI_NUM_DEVICE_TO_DETECT; + + /*set the completion routines for the felica card operations*/ + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + /*Set Ndef State*/ + NdefMap->State = state; + + /* Harsha: This is a special case for felica. + Make a copy of the remote device information and send it for + polling. Return the original remote device information to the + caller. The user does not need the updated results of the poll + that we are going to call now. This is only used for checking + whether the felica card is NDEF compliant or not. */ + (void) memcpy( &NdefMap->FelicaPollDetails.psTempRemoteDevInfo, + NdefMap->psRemoteDevInfo, + sizeof(phHal_sRemoteDevInformation_t)); + + /* Reset the session opened flag */ + NdefMap->FelicaPollDetails.psTempRemoteDevInfo.SessionOpened = 0x00; + + /*Call the Overlapped HAL POLL function */ + status = phFriNfc_OvrHal_Poll( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->OpModeType, + &NdefMap->FelicaPollDetails.psTempRemoteDevInfo, + &NdefMap->NoOfDevices, + NdefMap->FelicaPollDetails.DevInputParam); + + return (status); +} +#endif /* #ifndef PH_HAL4_ENABLE */ +/*! + * \brief Checks validity of system code sent from the lower device, during poll operation. + */ + +static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + +#ifdef PH_HAL4_ENABLE + /* copy the IDm and PMm in Manufacture Details Structure*/ + (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufID), + (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm, + 8); + (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter), + (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm, + 8); + if((NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[0] == 0x12) + && (NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[1] == 0xFC)) + { + status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS); + } + else + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } +#else + + + /* Check the System Code for 0x12,0xFC*/ + if( (NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.SystemCodeAvailable == 1) + && (NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.SystemCode[0] == 0x12) + && (NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.SystemCode[1] == 0xFC)) + { + + /* copy the IDm and PMm in Manufacture Details Structure*/ + (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufID), + (uint8_t *)NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t, + 8); + (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter), + (uint8_t *)NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.PMm, + 8); + + + status = PHNFCSTVAL(CID_NFC_NONE, + NFCSTATUS_SUCCESS); + + } + else + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } +#endif /* #ifdef PH_HAL4_ENABLE */ + + return (status); + +} + + + +/*! + * \brief Completion Routine, Processing function, needed to avoid long blocking. + * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion + * Routine in order to be able to notify the component that an I/O has finished and data are + * ready to be processed. + */ + +void phFriNfc_Felica_Process(void *Context, + NFCSTATUS Status) +{ + uint8_t CRFlag = FALSE; + uint16_t RecvTxLen = 0, + BytesToRecv = 0, + Nbc = 0; + uint32_t TotNoWrittenBytes = 0, + NDEFLen=0; + + /*Set the context to Map Module*/ + phFriNfc_NdefMap_t *NdefMap = (phFriNfc_NdefMap_t *)Context; + + if ( Status == NFCSTATUS_SUCCESS ) + { + switch (NdefMap->State) + { + case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP: + + /* check the ndef compliency with the system code reecived in the RemoteDevInfo*/ + Status = phFriNfc_Felica_HUpdateManufIdDetails(NdefMap); + + if (Status == NFCSTATUS_SUCCESS) + { + /* Mantis ID : 645*/ + /* set the operation type to Check ndef type*/ + NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP; + Status = phFriNfc_Felica_HRdAttrInfo(NdefMap); + /* handle the error in Transc function*/ + if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + CRFlag = TRUE; + } + } + else + { + CRFlag = TRUE; + } + if ( CRFlag == TRUE ) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,Status); + + } + break; + + case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR: + /* check for the status flag1 and status flag2for the successful read operation*/ + if ( NdefMap->SendRecvBuf[10] == 0x00) + { + /* check the Manuf Id in the receive buffer*/ + Status = phFriNfc_Felica_HCheckManufId(NdefMap); + if ( Status == NFCSTATUS_SUCCESS) + { + /* Update the Attribute Information in to the context structure*/ + Status = phFriNfc_Felica_HUpdateAttrInfo(NdefMap); + if ( Status == NFCSTATUS_SUCCESS ) + { + PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], + NdefMap->FelicaAttrInfo.LenBytes[1], + NdefMap->FelicaAttrInfo.LenBytes[2], + NDEFLen); + + if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_ATTR_RD_OP ) + { + /* Proceed With Write Functinality*/ + Status = phFriNfc_Felica_HChkAttrBlkForWrOp(NdefMap); + /* handle the error in Transc function*/ + if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + } + } + else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_RD_ATTR_RD_OP ) + { + /* Proceed With Read Functinality*/ + Status = phFriNfc_Felica_HChkAttrBlkForRdOp(NdefMap,NDEFLen); + if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status); + } + } + else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP ) + { + + Status = phFriNfc_MapTool_SetCardState( NdefMap, + NDEFLen); + /* check status value*/ + NdefMap->CardType = PH_FRINFC_NDEFMAP_FELICA_SMART_CARD; + /*reset the buffer index*/ + NdefMap->ApduBuffIndex = 0; + /* set the Next operation Flag to indicate need of reading attribute information*/ + NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_OP_NONE; + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,Status); + } + else if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP ) + { + /* Proceed With Write Functinality*/ + Status = phFriNfc_Felica_HWrEmptyMsg(NdefMap); + /* handle the error in Transc function*/ + if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_ERASE_NDEF,Status); + } + } + else + { + + /* invalid operation occured*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ + NFCSTATUS_INVALID_DEVICE_REQUEST); + CRFlag =TRUE ; + } + } + else + { + CRFlag =TRUE ; + } + } + else + { + CRFlag =TRUE ; + } + } + else + { + CRFlag =TRUE; + /*handle the Error case*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ + NFCSTATUS_READ_FAILED); + } + if ( CRFlag == TRUE ) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status); + } + break; + + case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN: + /* chk the status flags 1 and 2*/ + if ( NdefMap->SendRecvBuf[10] == 0x00 ) + { + /* Update Data Call*/ + Status =phFriNfc_Felica_HUpdateData(NdefMap); + if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + } + } + else + { + /*handle the Error case*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ + NFCSTATUS_WRITE_FAILED); + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + + } + break; + case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END: + + /* chk the status flags 1 and 2*/ + if ( NdefMap->SendRecvBuf[10] == 0x00) + { + /* Entire Write Operation is complete*/ + Status = PHNFCSTVAL(CID_NFC_NONE,\ + NFCSTATUS_SUCCESS); + } + else + { + /*handle the Error case*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ + NFCSTATUS_WRITE_FAILED); + } + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + break; + + case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG : + + /* chk the status flags 1 and 2*/ + if ( NdefMap->SendRecvBuf[10] == 0x00) + { + /* Entire Write Operation is complete*/ + Status = PHNFCSTVAL(CID_NFC_NONE,\ + NFCSTATUS_SUCCESS); + } + else + { + /*handle the Error case*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ + NFCSTATUS_WRITE_FAILED); + } + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + break; + + case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK : + if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE ) + { + /* chk the status flags 1 and 2*/ + if ( NdefMap->SendRecvBuf[10] == 0x00 ) + { + /* This is used when we have bytes less than 16 bytes*/ + if ( NdefMap->Felica.IntermediateWrFlag == TRUE ) + { + /* after Successful write copy the last writtened bytes back to the + internal buffer*/ + (void)memcpy( (&(NdefMap->Felica.Wr_RemainedBytesBuff[NdefMap->Felica.Wr_BytesRemained])), + NdefMap->ApduBuffer, + NdefMap->NumOfBytesWritten); + + NdefMap->Felica.Wr_BytesRemained += + (uint8_t)( NdefMap->NumOfBytesWritten); + + /* Increment the Send Buffer index */ + NdefMap->ApduBuffIndex += + NdefMap->NumOfBytesWritten; + + *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; + NdefMap->Felica.IntermediateWrFlag = FALSE; + /* Call Update Data()*/ + Status = phFriNfc_Felica_HUpdateData(NdefMap); + } + else + { + /* update the index and bytes writtened*/ + NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten; + *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; + if ( NdefMap->Felica.EofCardReachedFlag ) + { + if ( NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb) + { + NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten; + } + if (( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) && + ( NdefMap->ApduBuffIndex == (NdefMap->FelicaAttrInfo.Nmaxb*16))) + { + NdefMap->Felica.EofCardReachedFlag = FELICA_RD_WR_EOF_CARD_REACHED ; + /*0 represents the write ended*/ + Status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED); + if( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + } + } + else + { + PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], + NdefMap->FelicaAttrInfo.LenBytes[1], + NdefMap->FelicaAttrInfo.LenBytes[2], + TotNoWrittenBytes); + if ( ( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) && + ((TotNoWrittenBytes + NdefMap->ApduBuffIndex) == (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb*16))) + { + NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED; + /*0 represents the write ended*/ + Status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED); + if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + } + } + else + { + /* Call Update Data()*/ + Status = phFriNfc_Felica_HUpdateData(NdefMap); + if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + } + } + } + }/*if ( NdefMap->Felica.EofCardReachedFlag )*/ + else + { + NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten; + /* Call Update Data()*/ + Status = phFriNfc_Felica_HUpdateData(NdefMap); + if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + } + } + } + }/*if ( NdefMap->SendRecvBuf[10] == 0x00 )*/ + else + { + /*handle the Error case*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ + NFCSTATUS_WRITE_FAILED); + CRFlag = TRUE; + + } + }/*if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE )*/ + else + { + /*return Error "Invalid Write Response Code"*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_WRITE_FAILED); + CRFlag = TRUE; + + } + if ( CRFlag == TRUE ) + { + /* Reset following parameters*/ + NdefMap->ApduBuffIndex=0; + NdefMap->Felica.Wr_BytesRemained = 0; + NdefMap->ApduBufferSize = 0; + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); + } + + break; + + case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK : + + /* check the Manuf Id in the receive buffer*/ + Status = phFriNfc_Felica_HCheckManufId(NdefMap); + if ( Status == NFCSTATUS_SUCCESS ) + { + if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_RD_RESP_BYTE ) + { + /* calculate the Nmaxb*/ + Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); + /*get Receive length from the card for corss verifications*/ + RecvTxLen= phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc); + BytesToRecv = NdefMap->SendRecvBuf[12]*16; + + /* chk the status flags 1 */ + if ( NdefMap->SendRecvBuf[10] == 0x00) + { + if ( RecvTxLen == BytesToRecv) + { + NdefMap->Felica.CurBlockNo += (uint8_t)(RecvTxLen/16); + phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap); + Status = phFriNfc_Felica_HReadData(NdefMap,PH_FRINFC_NDEFMAP_SEEK_CUR); + /* handle the error in Transc function*/ + if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) + { + CRFlag =TRUE; + } + } + else + { + CRFlag =TRUE; + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_RECEIVE_LENGTH); + /*set the buffer index back to zero*/ + NdefMap->ApduBuffIndex = 0; + NdefMap->Felica.Rd_NoBytesToCopy = 0; + } + } + else + { + NdefMap->ApduBuffIndex=0; + /*handle the Error case*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ + NFCSTATUS_READ_FAILED); + CRFlag =TRUE; + } + } + else + { + CRFlag =TRUE; + NdefMap->ApduBuffIndex=0; + /*return Error "Invalid Read Response Code"*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_READ_FAILED); + } + } + else + { + CRFlag =TRUE; + } + if ( CRFlag ==TRUE ) + { + /* call respective CR */ + phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status); + } + break; + + default: + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_DEVICE_REQUEST); + phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_INVALID_OPE, Status); + break; + + + } + } + else + { + /* Call CR for unknown Error's*/ + switch ( NdefMap->State) + { + case PH_FRINFC_NDEFMAP_FELI_STATE_CHK_NDEF : + case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_WILD_CARD : + case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP : + case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR : + phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_CHK_NDEF, + Status); + break; + case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK : + case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN : + case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END : + phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_WR_NDEF, + Status); + break; + case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK : + phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_RD_NDEF, + Status); + break; + default : + /*set the invalid state*/ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST); + phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_INVALID_OPE, Status); + break; + } + } + +} + +/*! + * \brief Prepares Cmd Pkt for reading attribute Blk information. + */ +static NFCSTATUS phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap) +{ + + NFCSTATUS status = NFCSTATUS_PENDING; + uint8_t BufIndex = 0; + + /* Set the Felica Cmd*/ +#ifdef PH_HAL4_ENABLE + NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; +#else + NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; +#endif /* #ifdef PH_HAL4_ENABLE */ + + /*set the additional informations for the data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + + /* 1st byte represents the length of the cmd packet*/ + NdefMap->SendRecvBuf[BufIndex] = 0x00; + BufIndex++; + + /* Read/check command code*/ + NdefMap->SendRecvBuf[BufIndex] = 0x06; + BufIndex++; + + /* IDm - Manufacturer Id : 8bytes*/ +#ifdef PH_HAL4_ENABLE + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm, + 8); +#else + (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), + (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t, + 8); + +#endif /* #ifdef PH_HAL4_ENABLE */ + + BufIndex+=8; + + NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x0B; /* Service Code List*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to read)*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/ + BufIndex++; + + NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/ + BufIndex++; + + NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + /* Update the Send Len*/ + NdefMap->SendLength = BufIndex; + + /* Change the state to PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR */ + NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR; + + /*set the completion routines for the desfire card operations*/ + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + /*Call the Overlapped HAL Transceive function */ + status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + return (status); + +} + +/*! + * \brief Validated manufacturer Details, during the read/write operations. + */ + +static NFCSTATUS phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + uint8_t result = 0; + + /* check the stored manufacture id with the received manufacture id*/ + result = (uint8_t)(phFriNfc_Felica_MemCompare( (void *)(&(NdefMap->SendRecvBuf[2])), + (void *)NdefMap->FelicaManufDetails.ManufID, + 8)); + + if ( result != 0) + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE); + + } + else + { + status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS); + + } + return (status); +} + +static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer, + uint8_t StartIndex, + uint8_t EndIndex, + uint16_t RecvChkSum) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t CheckSum=0, + BufIndex=0; + + for(BufIndex = StartIndex;BufIndex <=EndIndex;BufIndex++) + { + CheckSum += TempBuffer[BufIndex]; + } + if( RecvChkSum != CheckSum ) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + } + return (Result); +} + + + + + + + + + + + +/*! + * \brief On successful read attribute blk information, this function validates and stores the + * Attribute informations in to the context. + */ +static NFCSTATUS phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + uint8_t CRFlag = FALSE, + Nmaxb1, Nmaxb2 = 0, + ChkSum1 = 0, ChkSum2=0; + + uint16_t Nmaxblk = 0, + RecvChkSum=0, + NdefBlk = 0; + uint32_t DataLen =0; + + + /* Validate T3VNo and NFCDevVNo */ + status = phFriNfc_MapTool_ChkSpcVer(NdefMap, + PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX); + if ( status != NFCSTATUS_SUCCESS ) + { + CRFlag = TRUE; + } + else + { + /* get the Nmaxb from the receive buffer*/ + Nmaxb1 = NdefMap->SendRecvBuf[16]; + Nmaxb2 = NdefMap->SendRecvBuf[17]; + + Nmaxblk = (((uint16_t)Nmaxb1 << 8) | (Nmaxb2 & 0x00ff)); + + if ( Nmaxblk != 0 ) + { + /* check the Nbr against the Nmaxb*/ + if ( NdefMap->SendRecvBuf[14] > Nmaxblk ) + { + CRFlag = TRUE; + } + else + { + /*check Nbw > Nmaxb*/ + /*check the write flag validity*/ + /*check for the RFU bytes validity*/ + if ( (NdefMap->SendRecvBuf[15] > Nmaxblk) || + ((NdefMap->SendRecvBuf[22] != 0x00) && (NdefMap->SendRecvBuf[22] !=0x0f ))|| + ( (NdefMap->SendRecvBuf[23] != 0x00) && (NdefMap->SendRecvBuf[23] !=0x01 ))|| + ( NdefMap->SendRecvBuf[18] != 0x00) || + ( NdefMap->SendRecvBuf[19] != 0x00) || + ( NdefMap->SendRecvBuf[20] != 0x00) || + ( NdefMap->SendRecvBuf[21] != 0x00)) + + { + CRFlag = TRUE; + } + else + { + /* check the validity of the actual ndef data len*/ + PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES( NdefMap->SendRecvBuf[24], + NdefMap->SendRecvBuf[25], + NdefMap->SendRecvBuf[26], + DataLen); + + + /* Calculate Nbc*/ + NdefBlk = (uint16_t )((( DataLen % 16) == 0 ) ? (DataLen >> 4) : ((DataLen >> 4) +1)); + + /* check Nbc against Nmaxb*/ + if ((NdefBlk > Nmaxblk)) + { + CRFlag = TRUE; + } + else + { + /*Store the attribute information in phFriNfc_Felica_AttrInfo*/ + NdefMap->FelicaAttrInfo.Version = NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX]; + NdefMap->FelicaAttrInfo.Nbr = NdefMap->SendRecvBuf[14]; + NdefMap->FelicaAttrInfo.Nbw = NdefMap->SendRecvBuf[15]; + + NdefMap->FelicaAttrInfo.Nmaxb = Nmaxblk; + + NdefMap->FelicaAttrInfo.WriteFlag = NdefMap->SendRecvBuf[22]; + NdefMap->FelicaAttrInfo.RdWrFlag = NdefMap->SendRecvBuf[23]; + + /* Get CheckSum*/ + ChkSum1 = NdefMap->SendRecvBuf[27]; + ChkSum2 = NdefMap->SendRecvBuf[28]; + + RecvChkSum = (((uint16_t)ChkSum1 << 8) | (ChkSum2 & 0x00ff)); + + /* Check the check sum validity?*/ + status = phFriNfc_Felica_HCalCheckSum(NdefMap->SendRecvBuf, + PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX, + 26, + RecvChkSum); + if ( status != NFCSTATUS_SUCCESS ) + { + CRFlag = TRUE; + } + else + { + /*check RW Flag Access Rights*/ + /* set to read only cannot write*/ + if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00 ) + { + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY; + } + else + { + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE; + } + + NdefMap->FelicaAttrInfo.LenBytes[0] = NdefMap->SendRecvBuf[24]; + NdefMap->FelicaAttrInfo.LenBytes[1] = NdefMap->SendRecvBuf[25]; + NdefMap->FelicaAttrInfo.LenBytes[2] = NdefMap->SendRecvBuf[26]; + status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS); + } + } + } + } + } + else + { + CRFlag = TRUE; + } + } + if ( (status == NFCSTATUS_INVALID_FORMAT ) && (CRFlag == TRUE )) + { + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; + } + if ( CRFlag == TRUE ) + { + /*Return Status Error “ Invalid Format”*/ + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT); + } + + return (status); +} + +/*! + * \brief this shall notify the integration software with respective + * success/error status along with the completion routines. + */ +static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t *NdefMap, + uint8_t CrIndex, + NFCSTATUS Status) +{ + /* set the state back to the Reset_Init state*/ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT; + + /* set the completion routine*/ + NdefMap->CompletionRoutine[CrIndex]. + CompletionRoutine(NdefMap->CompletionRoutine->Context, Status); +} + +/*! + * \brief this shall initialise the internal buffer data to zero. + */ +static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer) +{ + uint8_t index=0; + + for( index = 0; index< 16 ; index++) + { + Buffer[index] = 0; + } +} + +static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n ) +{ + int8_t diff = 0; + int8_t *char_1 =(int8_t *)s1; + int8_t *char_2 =(int8_t *)s2; + if(NULL == s1 || NULL == s2) + { + PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare"); + } + else + { + for(;((n>0)&&(diff==0));n--,char_1++,char_2++) + { + diff = *char_1 - *char_2; + } + } + return (int)diff; +} + + +#ifdef UNIT_TEST +#include <phUnitTestNfc_Felica_static.c> +#endif + +#endif /* PH_FRINFC_MAP_FELICA_DISABLED */ |