summaryrefslogtreecommitdiffstats
path: root/src/phFriNfc_FelicaMap.c
diff options
context:
space:
mode:
authorNick Pelly <npelly@google.com>2010-09-23 12:47:58 -0700
committerNick Pelly <npelly@google.com>2010-09-23 13:53:18 -0700
commit5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a (patch)
tree190f9251c6db03d3550ec7f30b51a2561c01d9cf /src/phFriNfc_FelicaMap.c
parent4ff7c86a2c706b150078274455406f1b04966e1a (diff)
downloadexternal_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.c3040
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 */