2 * Copyright (C) 2010 NXP Semiconductors
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * \file phFriNfc_FelicaMap.c
19 * \brief This component encapsulates read/write/check ndef/process functionalities,
20 * for the Felica Smart Card.
24 * $Date: Thu May 6 14:01:35 2010 $
27 * $Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $
31 #ifndef PH_FRINFC_MAP_FELICA_DISABLED
33 #include <phNfcTypes.h>
34 #include <phFriNfc_OvrHal.h>
35 #include <phFriNfc_FelicaMap.h>
36 #include <phFriNfc_MapTools.h>
39 /*! \ingroup grp_file_attributes
42 * File: \ref phFriNfc_FelicaMap.c
47 #define PHFRINFCNDEFMAP_FILEREVISION "$Revision: 1.10 $"
48 #define PHFRINFCNDEFMAP_FILEALIASES "$Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $"
52 /* Helpers for Read and updating the attribute informations*/
53 static NFCSTATUS phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap);
54 static NFCSTATUS phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap);
55 static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer,
60 /* Helpers for Poll Related Operations*/
61 static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap,
62 const uint8_t sysCode[],
65 static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap);
67 /*Helpers for Reading Operations*/
68 static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset);
69 static uint16_t phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap,uint8_t NbcOrNmaxb );
70 static void phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap);
71 static NFCSTATUS phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset);
72 static uint16_t phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc);
73 static NFCSTATUS phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap);
75 /* Helpers for Writing Operations*/
76 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap);
77 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap,
79 static NFCSTATUS phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted);
80 static NFCSTATUS phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap);
81 static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap);
83 /* Write Empty NDEF Message*/
84 static NFCSTATUS phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap);
86 /*Helpers for common checks*/
87 static NFCSTATUS phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap);
88 static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t *NdefMap,
92 static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer);
94 static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n );
97 * \brief returns maximum number of blocks can be read from the Felica Smart Card.
99 * The function is useful in reading of NDEF information from a felica tag.
102 static uint16_t phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap, uint8_t NbcOrNmaxb )
104 uint16_t BlksToRead=0;
105 uint32_t DataLen = 0;
106 /* This part of the code is useful if we take account of Nbc blks reading*/
107 if ( NbcOrNmaxb == PH_NFCFRI_NDEFMAP_FELI_NBC )
109 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
110 NdefMap->FelicaAttrInfo.LenBytes[1],
111 NdefMap->FelicaAttrInfo.LenBytes[2],
114 BlksToRead = (uint16_t) ( ((DataLen % 16) == 0) ? (DataLen >> 4) : ((DataLen >> 4) +1) );
118 else if ( NbcOrNmaxb == PH_NFCFRI_NDEFMAP_FELI_NMAXB)
120 BlksToRead = NdefMap->FelicaAttrInfo.Nmaxb;
124 /* WARNING !!! code should not reach this point*/
131 * \brief Initiates Reading of NDEF information from the Felica Card.
133 * The function initiates the reading of NDEF information from a Remote Device.
134 * It performs a reset of the state and starts the action (state machine).
135 * A periodic call of the \ref phFriNfcNdefMap_Process has to be
136 * done once the action has been triggered.
139 NFCSTATUS phFriNfc_Felica_RdNdef( phFriNfc_NdefMap_t *NdefMap,
141 uint32_t *PacketDataLength,
145 NFCSTATUS status = NFCSTATUS_PENDING;
148 NdefMap->ApduBufferSize = *PacketDataLength;
149 /*Store the packet data buffer*/
150 NdefMap->ApduBuffer = PacketData;
152 NdefMap->NumOfBytesRead = PacketDataLength ;
153 *NdefMap->NumOfBytesRead = 0;
154 NdefMap->ApduBuffIndex = 0;
156 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
157 NdefMap->Felica.Offset = Offset;
159 if( ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )||( NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE))
161 NdefMap->Felica.CurBlockNo = 0;
162 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_RD_ATTR_RD_OP;
163 NdefMap->Felica.IntermediateCpyFlag = FALSE;
164 NdefMap->Felica.IntermediateCpyLen = 0;
165 NdefMap->Felica.Rd_NoBytesToCopy = 0;
166 NdefMap->Felica.EofCardReachedFlag= FALSE ;
167 NdefMap->Felica.LastBlkReachedFlag = FALSE;
168 NdefMap->Felica.CurrBytesRead = 0;
170 phFriNfc_Felica_HInitInternalBuf(NdefMap->Felica.Rd_BytesToCopyBuff);
172 /* send request to read attribute information*/
173 status = phFriNfc_Felica_HRdAttrInfo(NdefMap);
174 /* handle the error in Transc function*/
175 if ( (status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
177 /* call respective CR */
178 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status);
183 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
185 /* Offset = Current, but the read has reached the End of NBC Blocks */
186 if(( ( Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && (NdefMap->Felica.CurBlockNo == Nbc)) &&
187 (NdefMap->Felica.EofCardReachedFlag == FELICA_RD_WR_EOF_CARD_REACHED ))
189 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
194 NdefMap->Felica.CurrBytesRead = ((NdefMap->Felica.CurBlockNo * 16)- NdefMap->Felica.Rd_NoBytesToCopy);
195 status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset);
202 /*Read Operation Related Helper Routines*/
205 * \brief Used in Read Opearation.Sets the Trx Buffer Len calls Transc Cmd.
206 * After a successful read operation, function does checks the user buffer size
207 * sets the status flags.
210 static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset)
212 NFCSTATUS status = NFCSTATUS_PENDING;
213 uint16_t Nbc=0,TranscLen=0;
215 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
216 if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > 0) && (NdefMap->Felica.CurBlockNo < Nbc ))
218 /* if data is present in the internal buffer*/
219 if (NdefMap->Felica.Rd_NoBytesToCopy > 0 )
221 /* copy data to external buffer*/
222 phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap);
223 /*Check the size of user buffer*/
224 status = phFriNfc_Felica_HChkApduBuff_Size(NdefMap);
225 if ( (status != NFCSTATUS_SUCCESS) && (NdefMap->Felica.IntermediateRdFlag == TRUE ))
227 /* set the transc len and call transc cmd*/
228 TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
229 status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset);
233 /* Nothing to be done , if IntermediateRdFlag is set to zero*/
239 /* set the transc len and call transc cmd*/
240 TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
241 status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset);
246 /* Chk the Buffer size*/
247 status = phFriNfc_Felica_HChkApduBuff_Size(NdefMap);
248 if ( (status != NFCSTATUS_SUCCESS) && (NdefMap->Felica.IntermediateRdFlag == TRUE ))
250 TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
251 status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset);
258 * \brief Used in Read Opearation.Sets the Trx Buffer Len.
261 static uint16_t phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc)
263 uint16_t TranscLen = 0,BlocksToRead=0;
265 if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)% 16) == 0)
267 BlocksToRead = (uint16_t)( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16 );
271 BlocksToRead = (uint16_t)(((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16) +1);
273 if ( (BlocksToRead > Nbc) ||( (BlocksToRead) > ( Nbc - NdefMap->Felica.CurBlockNo)) )
275 BlocksToRead = Nbc - NdefMap->Felica.CurBlockNo;
279 if ( BlocksToRead >= NdefMap->FelicaAttrInfo.Nbr)
281 if( NdefMap->FelicaAttrInfo.Nbr < Nbc )
283 TranscLen = NdefMap->FelicaAttrInfo.Nbr*16;
288 NdefMap->Felica.LastBlkReachedFlag =1;
293 if (BlocksToRead <= Nbc )
295 if ( ( BlocksToRead * 16) == ((Nbc *16) - (NdefMap->Felica.CurBlockNo * 16)))
297 NdefMap->Felica.LastBlkReachedFlag =1;
300 TranscLen = BlocksToRead*16;
308 /* As Cur Blk changes, to remember the exact len what we had set
309 in the begining of each read operation*/
310 NdefMap->Felica.TrxLen = TranscLen;
315 * \brief Used in Read Opearation.After a successful read operation,
316 * Copies the data to user buffer.
319 static void phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap)
321 uint8_t ResetFlag = FALSE, ExtrBytesToCpy = FALSE;
325 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC );
327 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
328 NdefMap->FelicaAttrInfo.LenBytes[1],
329 NdefMap->FelicaAttrInfo.LenBytes[2],
331 /* Internal Buffer has some old read bytes to cpy to user buffer*/
332 if( NdefMap->Felica.Rd_NoBytesToCopy > 0 )
334 if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.Rd_NoBytesToCopy )
336 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
338 if (NdefMap->Felica.IntermediateCpyFlag == TRUE )
340 /*Copy data from the internal buffer to user buffer*/
341 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
342 (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])),
343 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
347 /* Store number of bytes copied frm internal buffer to User Buffer */
348 NdefMap->Felica.IntermediateCpyLen += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
349 NdefMap->Felica.IntermediateCpyFlag = 1;
351 /* check do we reach len bytes any chance*/
352 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
353 NdefMap->FelicaAttrInfo.LenBytes[1],
354 NdefMap->FelicaAttrInfo.LenBytes[2],
356 /* Internal buffer has zero bytes for copy operation*/
357 if ( NdefMap->Felica.Rd_NoBytesToCopy == 0)
359 NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED;
364 /*Copy data from the internal buffer to apdu buffer*/
365 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
366 NdefMap->Felica.Rd_BytesToCopyBuff,
367 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
369 NdefMap->ApduBuffIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
372 else if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.Rd_NoBytesToCopy )
374 if ( NdefMap->Felica.IntermediateCpyFlag == TRUE )
376 /*Copy data internal buff to apdubuffer*/
377 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
378 (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])),
379 NdefMap->Felica.Rd_NoBytesToCopy);
383 /*Copy data internal buff to apdubuffer*/
384 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
385 NdefMap->Felica.Rd_BytesToCopyBuff,
386 NdefMap->Felica.Rd_NoBytesToCopy);
389 /*increment the index,internal buffer len*/
390 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
391 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBuffIndex);
393 /* To reset the parameters*/
398 /* Extra Bytes to Copy from internal buffer to external buffer*/
399 if ( NdefMap->Felica.IntermediateCpyFlag == TRUE )
401 /*Copy data internal buff to apdubuffer*/
402 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
403 (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])),
404 NdefMap->Felica.Rd_NoBytesToCopy);
408 /*Copy data internal buff to apdubuffer*/
409 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
410 NdefMap->Felica.Rd_BytesToCopyBuff,
411 NdefMap->Felica.Rd_NoBytesToCopy);
413 /*increment the index*/
414 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
416 /* To reset the parameters*/
419 }/*End of Internal Buffer has some old read bytes to cpy to user buffer*/
422 /* check if last block is reached*/
423 if ( ((NdefMap->Felica.LastBlkReachedFlag == 1) && (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= 16)) )
425 /* greater than 16 but less than the data len size*/
426 if (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= DataLen)
428 NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen) - (NdefMap->Felica.CurrBytesRead +
429 NdefMap->ApduBuffIndex));
431 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
432 (&(NdefMap->SendRecvBuf[13])),
433 NdefMap->Felica.CurrBytesRead);
435 NdefMap->ApduBuffIndex += NdefMap->Felica.CurrBytesRead;
436 if ( NdefMap->ApduBuffIndex == DataLen)
443 /* need to check exact no. of bytes to copy to buffer*/
444 if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <= NdefMap->Felica.TrxLen )||
445 ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <= DataLen ))
448 ExtrBytesToCpy = TRUE;
452 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - (DataLen)));
454 if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))
456 /*Reduce already copied bytes from the internal buffer*/
457 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
458 ExtrBytesToCpy = TRUE;
462 ExtrBytesToCpy = FALSE;
465 if ( ExtrBytesToCpy == TRUE )
467 NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen)- (NdefMap->Felica.CurrBytesRead +
468 NdefMap->ApduBuffIndex));
470 if(NdefMap->Felica.CurrBytesRead <
471 (uint16_t)(NdefMap->ApduBufferSize -
472 NdefMap->ApduBuffIndex))
474 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
475 (&(NdefMap->SendRecvBuf[13])),
476 NdefMap->Felica.CurrBytesRead);
480 (void)memcpy( (&( NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
481 (&( NdefMap->SendRecvBuf[13])),
482 (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
485 if ( NdefMap->Felica.LastBlkReachedFlag == 1 )
487 NdefMap->Felica.Rd_NoBytesToCopy =
488 (uint8_t)((NdefMap->Felica.CurrBytesRead >
489 (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))?
490 (NdefMap->Felica.CurrBytesRead -
491 (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)):
494 ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy == 0)?TRUE:FALSE);
499 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)( NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
502 /* Copy remained bytes back into internal buffer*/
503 (void)memcpy( NdefMap->Felica.Rd_BytesToCopyBuff,
504 (&(NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_RESP_HEADER_LEN+(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)])),
505 NdefMap->Felica.Rd_NoBytesToCopy);
507 /* set the intermediate flag : This flag remembers that there are still X no. bytes remained in
508 Internal Buffer Ex: User has given only one byte buffer,needs to cpy one byte at a time*/
509 NdefMap->Felica.IntermediateCpyFlag = TRUE;
511 NdefMap->ApduBuffIndex += ((NdefMap->Felica.CurrBytesRead <
512 (uint16_t)(NdefMap->ApduBufferSize -
513 NdefMap->ApduBuffIndex))?
514 NdefMap->Felica.CurrBytesRead:
515 (uint16_t)(NdefMap->ApduBufferSize -
516 NdefMap->ApduBuffIndex));
520 /*Copy data from the internal buffer to user buffer*/
521 (void)memcpy( (&( NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
522 (&( NdefMap->SendRecvBuf[13])),
523 NdefMap->Felica.Rd_NoBytesToCopy);
525 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
534 if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.TrxLen )
536 /* Calculate exactly remained bytes to copy to internal buffer and set it*/
537 if ( NdefMap->Felica.LastBlkReachedFlag == 1)
539 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - DataLen));
541 if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))
543 /*Reduce already copied bytes from the internal buffer*/
544 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
545 ExtrBytesToCpy = TRUE;
550 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
551 ExtrBytesToCpy = TRUE;
553 if ( ExtrBytesToCpy == TRUE )
555 /*Copy the read data from trx buffer to apdu of size apdu*/
556 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
557 (&(NdefMap->SendRecvBuf[13])),
558 NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
560 /*copy bytesToCopy to internal buffer*/
561 (void)memcpy( NdefMap->Felica.Rd_BytesToCopyBuff,
562 (&(NdefMap->SendRecvBuf[13+(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)])),
563 NdefMap->Felica.Rd_NoBytesToCopy);
565 NdefMap->Felica.IntermediateCpyFlag = TRUE;
566 NdefMap->ApduBuffIndex += (uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex;
570 /*Copy data from the internal buffer to user buffer*/
571 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
572 (&(NdefMap->SendRecvBuf[13])),
573 NdefMap->Felica.Rd_NoBytesToCopy);
575 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
579 if ( DataLen <= (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) )
581 NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED;
588 else if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.TrxLen )
590 /*Copy exactly remained last bytes to user buffer and increment the index*/
591 /*13 : 1+12 : 1st byte entire pkt length + 12 bytes to skip manuf details*/
592 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
593 (&(NdefMap->SendRecvBuf[13])),
594 (NdefMap->Felica.TrxLen ));
596 NdefMap->ApduBuffIndex += NdefMap->Felica.TrxLen;
600 if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > NdefMap->Felica.TrxLen )
602 /*Copy the data to apdu buffer and increment the index */
603 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
604 (&(NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_RESP_HEADER_LEN])),
605 NdefMap->Felica.TrxLen);
607 NdefMap->ApduBuffIndex += (uint16_t)NdefMap->Felica.TrxLen;
612 if ( ResetFlag == TRUE )
614 /* reset the internal buffer variables*/
615 NdefMap->Felica.Rd_NoBytesToCopy =0;
616 NdefMap->Felica.IntermediateCpyLen =0;
617 NdefMap->Felica.IntermediateCpyFlag =FALSE;
624 * \brief Used in Read Opearation.After a successful read operation,
625 Checks the relavent buffer sizes and set the status.Following function is used
626 when we read the Nmaxb blocks. Retained for future purpose.
629 static NFCSTATUS phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap)
631 NFCSTATUS status = NFCSTATUS_PENDING;
632 uint8_t ResetFlag = FALSE;
635 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
637 /* set status to Success : User Buffer is full and Curblk < nmaxb*/
638 if ( (( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) &&
639 (NdefMap->Felica.CurBlockNo < Nbc ))
641 status = PHNFCSTVAL(CID_NFC_NONE,
643 /*Reset the index, internal buffer counters back to zero*/
644 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
645 NdefMap->ApduBuffIndex = 0;
647 }/*if( (NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb )*/
650 if (( ( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) &&
651 (NdefMap->Felica.CurBlockNo == Nbc ))
653 status = PHNFCSTVAL(CID_NFC_NONE,
656 ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy > 0 )?
659 if( ResetFlag== FALSE)
661 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
662 /*Reset the index, internal buffer counters back to zero*/
663 NdefMap->ApduBuffIndex = 0;
665 }/*if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb )*/
668 /* reached reading all the blks available in the card: set EOF flag*/
669 if ( NdefMap->ApduBuffIndex == (Nbc*16))
671 status = PHNFCSTVAL(CID_NFC_NONE,
677 if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )> 0 )
679 if ( NdefMap->Felica.CurBlockNo == Nbc )
681 /* bytes pending in internal buffer , No Space in User Buffer*/
682 if ( NdefMap->Felica.Rd_NoBytesToCopy > 0)
684 if ( NdefMap->Felica.EofCardReachedFlag == TRUE )
686 status = PHNFCSTVAL(CID_NFC_NONE,
688 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
689 NdefMap->ApduBuffIndex=0;
693 phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap);
694 if( NdefMap->Felica.Rd_NoBytesToCopy > 0 )
696 status = PHNFCSTVAL(CID_NFC_NONE,
698 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
699 NdefMap->ApduBuffIndex=0;
703 /* EOF Card Reached set the internal EOF Flag*/
704 status = PHNFCSTVAL(CID_NFC_NONE,
711 /* All bytes from internal buffer are copied and set eof flag*/
714 status = PHNFCSTVAL(CID_NFC_NONE,
721 /* This flag is set to ensure that, need of Read Opearation
722 we completed coying the data from internal buffer to external buffer
723 left some more bytes,in User bufer so initiate the read operation */
724 NdefMap->Felica.IntermediateRdFlag = TRUE;
729 status = PHNFCSTVAL(CID_NFC_NONE,
734 if ( ResetFlag == TRUE)
736 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
737 /*Reset the index, internal buffer counters back to zero*/
738 NdefMap->ApduBuffIndex = 0;
739 NdefMap->Felica.Rd_NoBytesToCopy=0;
740 NdefMap->Felica.EofCardReachedFlag=FELICA_RD_WR_EOF_CARD_REACHED;
749 * \brief Used in Read Opearation.Sets the transceive Command for read.
751 static NFCSTATUS phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset)
753 NFCSTATUS TrxStatus = NFCSTATUS_PENDING;
754 uint16_t BufIndex=0,i=0;
756 /* set the felica cmd */
757 #ifdef PH_HAL4_ENABLE
758 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
760 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
761 #endif /* #ifdef PH_HAL4_ENABLE */
763 /*Change the state to Read */
764 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK;
766 /* set the complition routines for the mifare operations */
767 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process;
768 NdefMap->MapCompletionInfo.Context = NdefMap;
770 /*set the additional informations for the data exchange*/
771 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
772 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
774 /* pkt len : updated at the end*/
775 NdefMap->SendRecvBuf[BufIndex] = 0x00;
778 NdefMap->SendRecvBuf[BufIndex] = 0x06;
781 /* IDm - Manufacturer Id : 8bytes*/
782 #ifdef PH_HAL4_ENABLE
783 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
784 (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
787 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
788 (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
790 #endif /* #ifdef PH_HAL4_ENABLE */
794 /*Number of Services (n=1 ==> 0x80)*/
795 NdefMap->SendRecvBuf[BufIndex] = 0x01;
798 /*Service Code List*/
799 NdefMap->SendRecvBuf[BufIndex] = 0x0B;
802 NdefMap->SendRecvBuf[BufIndex] = 0x00;
805 /*Number of Blocks to read*/
806 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(TrxLen/16);
808 /* Set the Blk numbers as per the offset set by the user : Block List*/
809 if ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )
811 for ( i=0;i<(TrxLen/16);i++)
813 /*1st Service Code list : byte 1*/
814 NdefMap->SendRecvBuf[BufIndex] = 0x80;
818 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(i + 1);
824 for ( i= 1;i<=(TrxLen/16);i++)
826 /*1st Service Code list : byte 1*/
827 NdefMap->SendRecvBuf[BufIndex] = 0x80;
831 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(NdefMap->Felica.CurBlockNo + i);
836 /* len of entire pkt*/
837 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = (uint8_t) BufIndex;
840 NdefMap->SendLength = BufIndex;
842 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
844 TrxStatus = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice,
845 &NdefMap->MapCompletionInfo,
846 NdefMap->psRemoteDevInfo,
848 &NdefMap->psDepAdditionalInfo,
849 NdefMap->SendRecvBuf,
851 NdefMap->SendRecvBuf,
852 NdefMap->SendRecvLength);
857 * \brief Initiates Writing of NDEF information to the Remote Device.
859 * The function initiates the writing of NDEF information to a Remote Device.
860 * It performs a reset of the state and starts the action (state machine).
861 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
862 * has been triggered.
865 NFCSTATUS phFriNfc_Felica_WrNdef( phFriNfc_NdefMap_t *NdefMap,
867 uint32_t *PacketDataLength,
871 NFCSTATUS status = NFCSTATUS_PENDING;
873 NdefMap->ApduBufferSize = *PacketDataLength;
874 /*Store the packet data buffer*/
875 NdefMap->ApduBuffer = PacketData;
877 /* To Update the Acutal written bytes to context*/
878 NdefMap->WrNdefPacketLength = PacketDataLength;
879 *NdefMap->WrNdefPacketLength = 0;
882 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
883 NdefMap->Felica.Offset = Offset;
885 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_WR_ATTR_RD_OP;
886 status = phFriNfc_Felica_HRdAttrInfo(NdefMap);
887 /* handle the error in Transc function*/
888 if ( (status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
890 /* call respective CR */
891 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status);
897 * \brief Initiates Writing of Empty NDEF information to the Remote Device.
899 * The function initiates the writing empty of NDEF information to a Remote Device.
900 * It performs a reset of the state and starts the action (state machine).
901 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
902 * has been triggered.
905 NFCSTATUS phFriNfc_Felica_EraseNdef( phFriNfc_NdefMap_t *NdefMap)
908 NFCSTATUS status = NFCSTATUS_PENDING;
909 static uint32_t PktDtLength =0;
911 if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID )
913 /* Card is in invalid state, cannot have any read/write
915 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
916 NFCSTATUS_INVALID_FORMAT);
918 else if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY )
920 /*Can't write to the card :No Grants */
921 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
922 NFCSTATUS_WRITE_FAILED);
923 /* set the no. bytes written is zero*/
924 NdefMap->WrNdefPacketLength = &PktDtLength;
925 *NdefMap->WrNdefPacketLength = 0;
930 /* set the Operation*/
931 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP;
933 status = phFriNfc_Felica_HRdAttrInfo(NdefMap);
940 * \brief Used in Write Opearation.
941 * check the value set for the Write Flag, in first write operation(begin), sets the
942 * WR flag in attribute blck.
943 * After a successful write operation, This function sets the WR flag off and updates
944 * the LEN bytes in attribute Block.
947 static NFCSTATUS phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted)
949 NFCSTATUS status = NFCSTATUS_PENDING;
951 uint16_t ChkSum=0,index=0;
952 uint8_t BufIndex=0, ErrFlag = FALSE;
953 uint32_t TotNoWrittenBytes=0;
955 /* Write Operation : Begin/End Check*/
958 (( isStarted == FELICA_WRITE_STARTED )?
959 PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN:
960 PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END);
962 if( ( NdefMap->State == PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN)||
963 ( NdefMap->State == PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END) )
966 /* Set the Felica Cmd*/
967 #ifdef PH_HAL4_ENABLE
968 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
970 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
971 #endif /* #ifdef PH_HAL4_ENABLE */
973 /* 1st byte represents the length of the cmd packet*/
974 NdefMap->SendRecvBuf[BufIndex] = 0x00;
977 /* Write/Update command code*/
978 NdefMap->SendRecvBuf[BufIndex] = 0x08;
981 /* IDm - Manufacturer Id : 8bytes*/
982 #ifdef PH_HAL4_ENABLE
983 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
984 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
987 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
988 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
990 #endif /* #ifdef PH_HAL4_ENABLE */
994 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/
997 NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/
1000 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/
1003 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to Write*/
1006 NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/
1009 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/
1012 /* Fill Attribute Blk Information*/
1013 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Version;
1016 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbr;
1019 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw;
1022 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8);
1025 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff));
1028 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1031 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1034 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1037 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1040 if (isStarted == FELICA_WRITE_STARTED )
1042 NdefMap->SendRecvBuf[BufIndex] = 0x0F; /* Write Flag Made On*/
1045 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/
1049 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[0];
1052 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[1];
1055 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[2];
1060 /* Case: Previous Write Operation failed and integration context continues with write
1061 operation with offset set to Current. In this case, if we find Internal Bytes remained in the
1062 felica context is true(>0) and current block number is Zero. Then we shouldn't allow the module
1063 to write the data to card, as this is a invalid case*/
1064 if ( (NdefMap->Felica.Wr_BytesRemained > 0) && (NdefMap->Felica.CurBlockNo == 0))
1066 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1067 NFCSTATUS_INVALID_PARAMETER);
1073 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Write Flag Made Off*/
1076 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/
1079 if ( NdefMap->Felica.Wr_BytesRemained > 0 )
1081 TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained)));
1085 TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16);
1089 /* Update Len Bytes*/
1090 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(( TotNoWrittenBytes & 0x00ff0000) >> 16);
1093 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((TotNoWrittenBytes & 0x0000ff00) >> 8);
1096 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(TotNoWrittenBytes & 0x000000ff);
1101 if ( ErrFlag != TRUE )
1103 /* check sum update*/
1104 for ( index = 16 ; index < 30 ; index ++)
1106 ChkSum += NdefMap->SendRecvBuf[index];
1109 /* fill check sum in command pkt*/
1110 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8);
1113 NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff);
1116 /* update length of the cmd pkt*/
1117 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1119 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1121 /* Update the Send Len*/
1122 NdefMap->SendLength = BufIndex;
1124 /*set the completion routines for the desfire card operations*/
1125 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process;
1126 NdefMap->MapCompletionInfo.Context = NdefMap;
1128 /*set the additional informations for the data exchange*/
1129 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
1130 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
1132 /*Call the Overlapped HAL Transceive function */
1133 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1134 &NdefMap->MapCompletionInfo,
1135 NdefMap->psRemoteDevInfo,
1137 &NdefMap->psDepAdditionalInfo,
1138 NdefMap->SendRecvBuf,
1139 NdefMap->SendLength,
1140 NdefMap->SendRecvBuf,
1141 NdefMap->SendRecvLength);
1146 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1147 NFCSTATUS_INVALID_PARAMETER);
1153 static NFCSTATUS phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap)
1155 NFCSTATUS status = NFCSTATUS_PENDING;
1157 uint16_t ChkSum=0,index=0;
1160 /* Write Operation : To Erase the present NDEF Data*/
1162 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG;
1164 /* Set the Felica Cmd*/
1165 #ifdef PH_HAL4_ENABLE
1166 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
1168 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
1169 #endif /* #ifdef PH_HAL4_ENABLE */
1171 /* 1st byte represents the length of the cmd packet*/
1172 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1175 /* Write/Update command code*/
1176 NdefMap->SendRecvBuf[BufIndex] = 0x08;
1179 /* IDm - Manufacturer Id : 8bytes*/
1180 #ifdef PH_HAL4_ENABLE
1181 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1182 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
1185 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1186 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
1188 #endif /* #ifdef PH_HAL4_ENABLE */
1193 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/
1196 NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/
1199 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/
1202 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to Write*/
1205 NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/
1208 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/
1211 /* Fill Attribute Blk Information*/
1212 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Version;
1215 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbr;
1218 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw;
1221 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8);
1224 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff));
1227 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1230 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1233 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1236 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1239 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.WriteFlag;
1242 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/
1245 /* Len Bytes are set to 0 : Empty Msg*/
1246 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1249 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1252 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1255 /* check sum update*/
1256 for ( index = 16 ; index < 30 ; index ++)
1258 ChkSum += NdefMap->SendRecvBuf[index];
1261 /* fill check sum in command pkt*/
1262 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8);
1265 NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff);
1268 /* update length of the cmd pkt*/
1269 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1271 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1273 /* Update the Send Len*/
1274 NdefMap->SendLength = BufIndex;
1276 /*set the completion routines for the desfire card operations*/
1277 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process;
1278 NdefMap->MapCompletionInfo.Context = NdefMap;
1280 /*set the additional informations for the data exchange*/
1281 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
1282 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
1284 /*Call the Overlapped HAL Transceive function */
1285 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1286 &NdefMap->MapCompletionInfo,
1287 NdefMap->psRemoteDevInfo,
1289 &NdefMap->psDepAdditionalInfo,
1290 NdefMap->SendRecvBuf,
1291 NdefMap->SendLength,
1292 NdefMap->SendRecvBuf,
1293 NdefMap->SendRecvLength);
1302 * \brief Used in Write Opearation.
1303 * This Function is called after a successful validation and storing of attribution block
1304 * content in to context.
1305 * If the write operation is initiated with begin,function initiates the write operation with
1307 * If the Offset is set to Current, Checks for the EOF card reached status and writes data to
1311 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap)
1313 NFCSTATUS status = NFCSTATUS_PENDING;
1316 /*check RW Flag Access Rights*/
1317 /* set to read only cannot write*/
1318 if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00)
1321 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1322 NFCSTATUS_INVALID_DEVICE_REQUEST);
1326 if ( ( NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) ||
1327 ( ( NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE) &&
1328 (NdefMap->Felica.Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN ) ))
1330 /* check allready written number of bytes and apdu buffer size*/
1331 if (NdefMap->ApduBufferSize > (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16))
1333 NdefMap->Felica.EofCardReachedFlag = FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET;
1337 NdefMap->Felica.EofCardReachedFlag = FALSE;
1341 /* reset the internal variables initiate toupdate the attribute blk*/
1342 NdefMap->Felica.Wr_BytesRemained = 0;
1343 NdefMap->Felica.CurBlockNo = 0;
1344 NdefMap->Felica.NoBlocksWritten = 0;
1345 phFriNfc_Felica_HInitInternalBuf(NdefMap->Felica.Wr_RemainedBytesBuff);
1346 status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED);
1351 if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR )
1353 /* Calculate the Allready Written No. Of Blocks*/
1354 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
1355 NdefMap->FelicaAttrInfo.LenBytes[1],
1356 NdefMap->FelicaAttrInfo.LenBytes[2],
1359 if (( NdefMap->ApduBufferSize + (DataLen )) >
1360 (uint32_t)( NdefMap->FelicaAttrInfo.Nmaxb *16))
1362 if(( DataLen ) == (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16) )
1364 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1365 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
1370 NdefMap->Felica.EofCardReachedFlag =FELICA_EOF_REACHED_WR_WITH_CURR_OFFSET;
1371 NdefMap->ApduBuffIndex =0;
1372 NdefMap->Felica.NoBlocksWritten = 0;
1373 status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED);
1378 NdefMap->ApduBuffIndex =0;
1379 NdefMap->Felica.NoBlocksWritten = 0;
1380 status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED);
1382 }/*if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR )*/
1389 * \brief Used in Read Opearation.
1390 * This Function is called after a successful validation and storing of attribution block
1391 * content in to context.
1392 * While Offset is set to Current, Checks for the EOF card reached status and reads data from
1396 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap,
1399 NFCSTATUS status = NFCSTATUS_PENDING;
1401 /*check WR Flag Access Rights*/
1402 /* set to still writing data state only cannot Read*/
1403 if ( NdefMap->FelicaAttrInfo.WriteFlag == 0x0F )
1405 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_READ_FAILED);
1406 /* As we are not able to continue with reading data
1407 bytes read set to zero*/
1408 *NdefMap->NumOfBytesRead = 0;
1412 status = phFriNfc_MapTool_SetCardState( NdefMap,NdefLen);
1413 if ( status == NFCSTATUS_SUCCESS)
1415 /* Read data From the card*/
1416 status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset);
1424 * \brief Used in Write Opearation.
1425 * This function writes the data in terms of blocks.
1426 * Each write operation supports,minimum Nbw blocks of bytes.
1427 * Also checks for the EOF,>=NBW,<NBW etc
1429 static NFCSTATUS phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap)
1431 NFCSTATUS status = NFCSTATUS_PENDING;
1442 uint32_t BytesRemainedInCard=0,
1444 TotNoWrittenBytes=0;
1446 if( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > 0 )
1448 /* Prepare the write cmd pkt for felica*/
1449 /* 1st byte represents the length of the cmd packet*/
1450 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1453 /* Write/Update command code*/
1454 NdefMap->SendRecvBuf[BufIndex] = 0x08;
1457 /* IDm - Manufacturer Id : 8bytes*/
1458 #ifdef PH_HAL4_ENABLE
1459 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1460 (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
1463 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1464 (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
1466 #endif /* #ifdef PH_HAL4_ENABLE */
1470 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/
1473 NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/
1476 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/
1479 if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET)
1481 /* check for the eof card reached flag.Need to write only mamximum bytes(memory)to card.
1482 Used when, offset set to begin case*/
1483 BytesRemainedInCard= ( (NdefMap->FelicaAttrInfo.Nmaxb*16) - (NdefMap->Felica.CurBlockNo * 16));
1487 /* Offset : Cuurent*/
1488 if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_CURR_OFFSET )
1490 /* caculate previously written Ndef blks*/
1491 (void)phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
1493 if ( NdefMap->Felica.Wr_BytesRemained )
1495 TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained)));
1499 TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16);
1501 /* Determine exactly, how many bytes we can write*/
1502 BytesRemainedInCard = (NdefMap->FelicaAttrInfo.Nmaxb*16 - (TotNoWrittenBytes));
1506 /* Write Data Pending in the Internal Buffer*/
1507 if(NdefMap->Felica.Wr_BytesRemained > 0)
1509 /* update the number of blocks to write with the block list elements*/
1510 /* Total Number of blocks to write*/
1511 NdefMap->SendRecvBuf[BufIndex] = 0;
1514 /* Update this Total no. Bloks later*/
1515 NoOfBlks = BufIndex;
1517 /* As we are writing atleast one block*/
1520 /* check do we have some extra bytes to write? in User Buffer*/
1521 if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained))
1523 /* Have we reached EOF?*/
1524 if ( NdefMap->Felica.EofCardReachedFlag )
1526 BytesRemained = BytesRemainedInCard;
1530 /* This value tells how many extra bytes we can write other than internal buffer bytes*/
1531 BytesRemained = (uint8_t)NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained);
1534 if ( BytesRemained )
1536 /* Not reached EOF*/
1537 if (!NdefMap->Felica.EofCardReachedFlag)
1539 /* Calculate How many blks we need to write*/
1540 BlkNo =((uint8_t)( BytesRemained )/16);
1542 /* check blocks to write exceeds nbw*/
1543 if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw )
1545 BlkNo = NdefMap->FelicaAttrInfo.Nbw;
1546 /* No. Blks to write are more than Nbw*/
1551 if ((( BytesRemained %16) == 0)&& (BlkNo == 0 ))
1556 /* check do we need pad bytes?*/
1557 if( (!NbwCheck && (uint8_t)( BytesRemained)%16) != 0)
1560 PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained);
1561 NdefMap->Felica.PadByteFlag = TRUE;
1562 NdefMap->Felica.NoBlocksWritten = BlkNo;
1570 /* as we have to write only 8 blocks and already we have pad bytes so we have
1571 to strat from previous block*/
1572 TotNoBlks += BlkNo - 1;
1573 NdefMap->Felica.NoBlocksWritten = TotNoBlks-1;
1577 if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 ))
1585 if ( NdefMap->Felica.PadByteFlag )
1587 NdefMap->Felica.NoBlocksWritten = TotNoBlks-1;
1595 /* we have reached the eof card & hv bytes to write*/
1596 BlkNo =(uint8_t)(( BytesRemained - ((16 -NdefMap->Felica.Wr_BytesRemained)) )/16);
1598 /* check are we exceeding the NBW limit, while a write?*/
1599 if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw )
1601 BlkNo = NdefMap->FelicaAttrInfo.Nbw;
1603 /* No. Blks to write are more than Nbw*/
1609 if ((( BytesRemained %16) == 0)&& (BlkNo == 0 ))
1615 /*check Total how many blocks to write*/
1616 if(((!NbwCheck) &&( BytesRemained- (16 - NdefMap->Felica.Wr_BytesRemained))%16) != 0)
1619 PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained);
1620 NdefMap->Felica.PadByteFlag = TRUE;
1621 NdefMap->Felica.NoBlocksWritten = BlkNo;
1629 /* as we have to write only 8 blocks and already we have pad bytes so we have
1630 to strat from previous last block*/
1631 TotNoBlks += BlkNo - 1;
1632 NdefMap->Felica.NoBlocksWritten = TotNoBlks-1;
1636 /* we need to write only one block ( bytesremanind + internal buffer size = 16)*/
1637 if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 ))
1643 ;/* we are not incrementing the Total no. of blocks to write*/
1646 if ( NdefMap->Felica.PadByteFlag )
1648 NdefMap->Felica.NoBlocksWritten = TotNoBlks -1;
1654 }/*if ( BytesRemained )*/
1657 ; /*Nothing to process here*/
1659 }/*if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained))*/
1662 /* No new blks to write*/
1663 NdefMap->Felica.NoBlocksWritten = 0;
1665 /* Prepare the Blk List for Write Operation*/
1666 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/
1667 for ( i=0; i< TotNoBlks; i++)
1669 NdefMap->SendRecvBuf[BufIndex] = 0x80;
1671 /* remember the previous Blk no and continue from there*/
1672 if ( NdefMap->Felica.PadByteFlag == TRUE )
1674 NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i;
1679 CurBlk = NdefMap->Felica.CurBlockNo +1;
1680 NdefMap->SendRecvBuf[BufIndex] = CurBlk + i;
1684 /* Copy relevant data to Transc buffer*/
1685 if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16 - NdefMap->Felica.Wr_BytesRemained))
1688 /*Copy the Remained bytes from the internal buffer to trxbuffer */
1689 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1690 NdefMap->Felica.Wr_RemainedBytesBuff,
1691 NdefMap->Felica.Wr_BytesRemained);
1693 /*Increment the buff index*/
1694 BufIndex += NdefMap->Felica.Wr_BytesRemained;
1697 /*append copy 16-bytesToPad to trxBuffer*/
1698 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1699 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1700 (16 - NdefMap->Felica.Wr_BytesRemained));
1702 /* Update Number Of Bytes Writtened*/
1703 NdefMap->NumOfBytesWritten = 16 - NdefMap->Felica.Wr_BytesRemained;
1705 /* increment the index*/
1706 BufIndex += 16 - NdefMap->Felica.Wr_BytesRemained;
1708 if ( BytesRemained )
1710 if (!NdefMap->Felica.EofCardReachedFlag)
1712 /* check nbw limit*/
1713 if ( NbwCheck != 1 )
1715 /* Copy Extra Bytes other than the internal buffer bytes*/
1716 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1717 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])),
1718 (NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained)));
1721 /* Update Number Of Bytes Writtened*/
1722 NdefMap->NumOfBytesWritten += (uint16_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained));
1724 BufIndex += (uint8_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained));
1728 for(i= 0; i< PadBytes; i++)
1730 NdefMap->SendRecvBuf[BufIndex] =0x00;
1733 /* no of bytes remained copy*/
1734 NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes);
1736 /*copy the data to internal buffer : Bytes remained*/
1737 (void)memcpy( NdefMap->Felica.Wr_RemainedBytesBuff,
1738 (&( NdefMap->ApduBuffer[(NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained)])),
1739 ( NdefMap->Felica.Wr_BytesRemained));
1743 /* No Bytes in Internal buffer*/
1744 NdefMap->Felica.Wr_BytesRemained = 0;
1751 /*Copy Nbw*16 bytes of data to the trx buffer*/
1752 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1753 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])),
1754 (NdefMap->FelicaAttrInfo.Nbw - 1) * 16);
1756 /* increment the Buffindex*/
1757 BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16);
1759 NdefMap->Felica.Wr_BytesRemained = 0;
1760 NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16);
1761 NdefMap->Felica.PadByteFlag =FALSE;
1763 }/*if (!NdefMap->Felica.EofCardReachedFlag)*/
1766 /* check nbw limit*/
1767 if ( NbwCheck != 1 )
1769 /* handle EOF card reached case*/
1770 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1771 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])),
1772 ( BytesRemained - ((16 -NdefMap->Felica.Wr_BytesRemained) )));
1774 /* Update Number Of Bytes Writtened*/
1775 NdefMap->NumOfBytesWritten += (uint16_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained));
1777 BufIndex += (uint8_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained));
1781 for(i= 0; i< PadBytes; i++)
1783 NdefMap->SendRecvBuf[BufIndex] =0x00;
1787 /*no of bytes remained copy*/
1788 NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes);
1790 /*copy the data to internal buffer : Bytes remained*/
1791 (void)memcpy(NdefMap->Felica.Wr_RemainedBytesBuff,
1792 (&(NdefMap->ApduBuffer[(NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained)])),
1793 (NdefMap->Felica.Wr_BytesRemained));
1798 NdefMap->Felica.Wr_BytesRemained = 0;
1804 /*Copy Nbw*16 bytes of data to the trx buffer*/
1805 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1806 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])),
1807 (NdefMap->FelicaAttrInfo.Nbw - 1) * 16);
1809 /* increment the Buffindex*/
1810 BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16);
1812 NdefMap->Felica.Wr_BytesRemained = 0;
1813 NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16);
1815 NdefMap->Felica.PadByteFlag =FALSE;
1818 }/*if ( BytesRemained )*/
1821 NdefMap->Felica.Wr_BytesRemained = 0;
1823 /* Update Total No. of blocks writtened*/
1824 NdefMap->SendRecvBuf[NoOfBlks -1 ]=TotNoBlks;
1825 }/*if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16 - NdefMap->Felica.Wr_BytesRemained))*/
1828 /*copy the internal buffer data to trx buffer*/
1829 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1830 NdefMap->Felica.Wr_RemainedBytesBuff,
1831 (NdefMap->Felica.Wr_BytesRemained));
1833 /* increment the index*/
1834 BufIndex+=NdefMap->Felica.Wr_BytesRemained;
1836 /*append the apdusize data to the trx buffer*/
1837 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1838 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1839 NdefMap->ApduBufferSize);
1841 /* Index increment*/
1842 BufIndex+= (uint8_t)NdefMap->ApduBufferSize;
1844 /* Tells how many bytes present in the internal buffer*/
1845 BytesRemained = NdefMap->Felica.Wr_BytesRemained + NdefMap->ApduBufferSize;
1847 PadBytes = (uint8_t)(16-BytesRemained);
1849 /* Pad empty bytes with Zeroes to complete 16 bytes*/
1850 for(i= 0; i< PadBytes; i++)
1852 NdefMap->SendRecvBuf[BufIndex] =0x00;
1856 /* Update Number Of Bytes Writtened*/
1857 NdefMap->NumOfBytesWritten = (uint16_t)NdefMap->ApduBufferSize;
1859 /* Flag set to understand that , we have received less no. of bytes than
1860 present in the internal buffer*/
1861 NdefMap->Felica.IntermediateWrFlag = TRUE;
1863 if ( NdefMap->Felica.PadByteFlag )
1865 NdefMap->Felica.NoBlocksWritten = 0;
1869 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1870 NdefMap->SendLength = BufIndex;
1871 /* Update Total No. of blocks writtened*/
1872 NdefMap->SendRecvBuf[NoOfBlks -1 ]=TotNoBlks;
1876 /*Fresh write, starting from a new block*/
1877 if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw ))
1879 /* check for the card size and write Nbw Blks*/
1880 if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw)
1882 /* update the number of blocks to write with the block list elements*/
1883 /* Total Number of blocks to write*/
1884 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw;
1887 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/
1888 for ( i=1; i<= NdefMap->FelicaAttrInfo.Nbw; i++)
1890 NdefMap->SendRecvBuf[BufIndex] = 0x80;
1893 NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i;
1896 /*Copy Nbw*16 bytes of data to the trx buffer*/
1898 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1899 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1900 NdefMap->FelicaAttrInfo.Nbw * 16);
1902 /* increment the Buffindex*/
1903 BufIndex += (NdefMap->FelicaAttrInfo.Nbw*16);
1905 /* update the length*/
1906 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1908 NdefMap->Felica.Wr_BytesRemained = 0;
1909 NdefMap->NumOfBytesWritten = (NdefMap->FelicaAttrInfo.Nbw*16);
1910 NdefMap->Felica.NoBlocksWritten = NdefMap->FelicaAttrInfo.Nbw;
1912 /* update the Send length*/
1913 NdefMap->SendLength = BufIndex;
1915 NdefMap->Felica.PadByteFlag = FALSE;
1916 }/*if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw)*/
1919 /* we need to write less than nbw blks*/
1920 /* update the number of blocks to write with the block list elements*/
1921 /* Total Number of blocks to write*/
1922 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo);
1925 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/
1926 for ( i=1; i<= (NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo); i++)
1928 NdefMap->SendRecvBuf[BufIndex] = 0x80;
1930 NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i;
1934 /*Copy Nbw*16 bytes of data to the trx buffer*/
1935 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1936 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1937 (NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo)*16);
1939 /* increment the Buffindex*/
1940 BufIndex += (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo )*16);
1942 /* update the length*/
1943 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1945 NdefMap->NumOfBytesWritten = ((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo)*16);
1946 NdefMap->Felica.NoBlocksWritten = (uint8_t)(NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo);
1948 /* update the Send length*/
1949 NdefMap->SendLength = BufIndex;
1951 NdefMap->Felica.PadByteFlag =FALSE;
1952 NdefMap->Felica.Wr_BytesRemained = 0;
1954 }/* if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */
1958 if ( NdefMap->Felica.EofCardReachedFlag)
1960 BlkNo =((uint8_t)(BytesRemainedInCard )/16);
1961 if(((uint8_t)( BytesRemainedInCard )%16) != 0)
1964 PadBytes = ((BlkNo * 16) - (uint8_t)(BytesRemainedInCard ));
1965 NdefMap->Felica.PadByteFlag = TRUE;
1971 BlkNo =((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16);
1972 if(((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)%16) != 0)
1975 PadBytes = (BlkNo * 16) - (uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
1976 NdefMap->Felica.PadByteFlag = TRUE;
1983 /* update the number of blocks to write with the block list elements*/
1984 /* Total Number of blocks to write*/
1985 NdefMap->SendRecvBuf[BufIndex] = BlkNo;
1988 NdefMap->Felica.NoBlocksWritten = BlkNo;
1990 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/
1991 for ( i=0; i< BlkNo; i++)
1993 NdefMap->SendRecvBuf[BufIndex] = 0x80;
1996 CurBlk = NdefMap->Felica.CurBlockNo +1;
1997 NdefMap->SendRecvBuf[BufIndex] = CurBlk + i;
2001 if ( NdefMap->Felica.EofCardReachedFlag )
2003 /*Copy last data to the trx buffer*/
2004 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2005 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
2006 BytesRemainedInCard );
2008 /* increment the bufindex and bytes written*/
2009 BufIndex += (uint8_t )BytesRemainedInCard ;
2010 NdefMap->NumOfBytesWritten = (uint16_t)BytesRemainedInCard ;
2014 /*Copy data to the trx buffer*/
2015 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2016 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
2017 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
2019 /* increment the bufindex and bytes written*/
2020 BufIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
2021 NdefMap->NumOfBytesWritten = (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
2025 for(i= 0; i< PadBytes; i++)
2027 NdefMap->SendRecvBuf[BufIndex] =0x00;
2030 /*no of bytes remained copy*/
2031 NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes);
2033 if ( NdefMap->Felica.EofCardReachedFlag )
2035 /*copy the data to internal buffer : Bytes remained*/
2036 (void)memcpy(NdefMap->Felica.Wr_RemainedBytesBuff,
2037 (&(NdefMap->ApduBuffer[((BytesRemainedInCard - (BytesRemainedInCard % 16)))])),
2038 ( NdefMap->Felica.Wr_BytesRemained));
2043 /*copy the data to internal buffer : Bytes remained*/
2044 (void)memcpy( NdefMap->Felica.Wr_RemainedBytesBuff,
2045 (&(NdefMap->ApduBuffer[((NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained))])),
2046 ( NdefMap->Felica.Wr_BytesRemained));
2049 }/*if ( PadBytes )*/
2052 NdefMap->Felica.Wr_BytesRemained = 0;
2053 NdefMap->Felica.PadByteFlag = FALSE;
2055 /* update the pkt len*/
2056 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
2057 NdefMap->SendLength = BufIndex;
2059 }/* else of if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */
2060 status = phFriNfc_Felica_HWriteDataBlk(NdefMap);
2064 /*0 represents the write operation ended*/
2065 status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED);
2072 * \brief Used in Write Opearation.
2073 * This function prepares and sends transcc Cmd Pkt.
2076 static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap)
2078 NFCSTATUS status = NFCSTATUS_PENDING;
2080 /*set the additional informations for the data exchange*/
2081 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
2082 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
2084 /*Set the ISO14434 command*/
2085 #ifdef PH_HAL4_ENABLE
2086 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
2088 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
2089 #endif /* #ifdef PH_HAL4_ENABLE */
2092 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK;
2094 /* set send receive length*/
2095 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
2097 /*Call the Overlapped HAL Transceive function */
2098 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
2099 &NdefMap->MapCompletionInfo,
2100 NdefMap->psRemoteDevInfo,
2102 &NdefMap->psDepAdditionalInfo,
2103 NdefMap->SendRecvBuf,
2104 NdefMap->SendLength,
2105 NdefMap->SendRecvBuf,
2106 NdefMap->SendRecvLength);
2111 * \brief Check whether a particular Remote Device is NDEF compliant.
2112 * The function checks whether the peer device is NDEF compliant.
2115 NFCSTATUS phFriNfc_Felica_ChkNdef( phFriNfc_NdefMap_t *NdefMap)
2117 NFCSTATUS status = NFCSTATUS_PENDING;
2120 /* set the system code for selecting the wild card*/
2124 status = phFriNfc_Felica_HPollCard( NdefMap,sysCode,PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP);
2130 * \brief Check whether a particular Remote Device is NDEF compliant.
2131 * selects the sysCode and then NFC Forum Reference Applications
2133 #ifdef PH_HAL4_ENABLE
2134 static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap,
2135 const uint8_t sysCode[],
2138 NFCSTATUS status = NFCSTATUS_PENDING;
2140 /*Format the Poll Packet for selecting the system code passed as parameter */
2141 NdefMap->SendRecvBuf[0] = 0x06;
2142 NdefMap->SendRecvBuf[1] = 0x00;
2143 NdefMap->SendRecvBuf[2] = sysCode[0];
2144 NdefMap->SendRecvBuf[3] = sysCode[1];
2145 NdefMap->SendRecvBuf[4] = 0x01;
2146 NdefMap->SendRecvBuf[5] = 0x03;
2148 NdefMap->SendLength = 6;
2150 /*set the completion routines for the felica card operations*/
2151 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process;
2152 NdefMap->MapCompletionInfo.Context = NdefMap;
2155 NdefMap->State = state;
2157 /* set the felica cmd */
2158 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
2160 /*set the additional informations for the data exchange*/
2161 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
2162 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
2164 status = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice,
2165 &NdefMap->MapCompletionInfo,
2166 NdefMap->psRemoteDevInfo,
2168 &NdefMap->psDepAdditionalInfo,
2169 NdefMap->SendRecvBuf,
2170 NdefMap->SendLength,
2171 NdefMap->SendRecvBuf,
2172 NdefMap->SendRecvLength);
2178 #ifndef PH_HAL4_ENABLE
2179 static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap,
2180 const uint8_t sysCode[],
2183 NFCSTATUS status = NFCSTATUS_PENDING;
2185 /*Format the Poll Packet for selecting the wild card "0xff 0xff as system code*/
2186 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[0] = 0x00;
2187 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[1] = sysCode[0];
2188 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[2] = sysCode[1];
2189 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[3] = 0x01;
2190 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[4] = 0x03;
2192 /* set the length to zero*/
2193 NdefMap->FelicaPollDetails.DevInputParam->GeneralByteLength =0x00;
2195 NdefMap->NoOfDevices = PH_FRINFC_NDEFMAP_FELI_NUM_DEVICE_TO_DETECT;
2197 /*set the completion routines for the felica card operations*/
2198 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process;
2199 NdefMap->MapCompletionInfo.Context = NdefMap;
2202 NdefMap->State = state;
2204 /* Harsha: This is a special case for felica.
2205 Make a copy of the remote device information and send it for
2206 polling. Return the original remote device information to the
2207 caller. The user does not need the updated results of the poll
2208 that we are going to call now. This is only used for checking
2209 whether the felica card is NDEF compliant or not. */
2210 (void) memcpy( &NdefMap->FelicaPollDetails.psTempRemoteDevInfo,
2211 NdefMap->psRemoteDevInfo,
2212 sizeof(phHal_sRemoteDevInformation_t));
2214 /* Reset the session opened flag */
2215 NdefMap->FelicaPollDetails.psTempRemoteDevInfo.SessionOpened = 0x00;
2217 /*Call the Overlapped HAL POLL function */
2218 status = phFriNfc_OvrHal_Poll( NdefMap->LowerDevice,
2219 &NdefMap->MapCompletionInfo,
2220 NdefMap->OpModeType,
2221 &NdefMap->FelicaPollDetails.psTempRemoteDevInfo,
2222 &NdefMap->NoOfDevices,
2223 NdefMap->FelicaPollDetails.DevInputParam);
2227 #endif /* #ifndef PH_HAL4_ENABLE */
2229 * \brief Checks validity of system code sent from the lower device, during poll operation.
2232 static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap)
2234 NFCSTATUS status = NFCSTATUS_PENDING;
2236 /* Get the details from Poll Response packet */
2237 if (NdefMap->SendRecvLength >= 20)
2239 (void)memcpy( (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm,
2240 (uint8_t *)&NdefMap->SendRecvBuf[2], 8);
2241 (void)memcpy( (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm,
2242 (uint8_t *)&NdefMap->SendRecvBuf[10], 8);
2243 NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[1] = NdefMap->SendRecvBuf[18];
2244 NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[0] = NdefMap->SendRecvBuf[19];
2245 NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDmLength = 8;
2247 /* copy the IDm and PMm in Manufacture Details Structure*/
2248 (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufID),
2249 (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm,
2251 (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter),
2252 (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm,
2254 if((NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[1] == 0x12)
2255 && (NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[0] == 0xFC))
2257 status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS);
2261 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2262 NFCSTATUS_NO_NDEF_SUPPORT);
2267 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2268 NFCSTATUS_NO_NDEF_SUPPORT);
2276 * \brief Completion Routine, Processing function, needed to avoid long blocking.
2277 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
2278 * Routine in order to be able to notify the component that an I/O has finished and data are
2279 * ready to be processed.
2282 void phFriNfc_Felica_Process(void *Context,
2285 uint8_t CRFlag = FALSE;
2286 uint16_t RecvTxLen = 0,
2289 uint32_t TotNoWrittenBytes = 0,
2292 /*Set the context to Map Module*/
2293 phFriNfc_NdefMap_t *NdefMap = (phFriNfc_NdefMap_t *)Context;
2295 if ( Status == NFCSTATUS_SUCCESS )
2297 switch (NdefMap->State)
2299 case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP:
2301 /* check the ndef compliency with the system code reecived in the RemoteDevInfo*/
2302 Status = phFriNfc_Felica_HUpdateManufIdDetails(NdefMap);
2304 if (Status == NFCSTATUS_SUCCESS)
2306 /* Mantis ID : 645*/
2307 /* set the operation type to Check ndef type*/
2308 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP;
2309 Status = phFriNfc_Felica_HRdAttrInfo(NdefMap);
2310 /* handle the error in Transc function*/
2311 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2320 if ( CRFlag == TRUE )
2322 /* call respective CR */
2323 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,Status);
2328 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR:
2329 /* check for the status flag1 and status flag2for the successful read operation*/
2330 if ( NdefMap->SendRecvBuf[10] == 0x00)
2332 /* check the Manuf Id in the receive buffer*/
2333 Status = phFriNfc_Felica_HCheckManufId(NdefMap);
2334 if ( Status == NFCSTATUS_SUCCESS)
2336 /* Update the Attribute Information in to the context structure*/
2337 Status = phFriNfc_Felica_HUpdateAttrInfo(NdefMap);
2338 if ( Status == NFCSTATUS_SUCCESS )
2340 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
2341 NdefMap->FelicaAttrInfo.LenBytes[1],
2342 NdefMap->FelicaAttrInfo.LenBytes[2],
2345 if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_ATTR_RD_OP )
2347 /* Proceed With Write Functinality*/
2348 Status = phFriNfc_Felica_HChkAttrBlkForWrOp(NdefMap);
2349 /* handle the error in Transc function*/
2350 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2352 /* call respective CR */
2353 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2356 else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_RD_ATTR_RD_OP )
2358 /* Proceed With Read Functinality*/
2359 Status = phFriNfc_Felica_HChkAttrBlkForRdOp(NdefMap,NDEFLen);
2360 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2362 /* call respective CR */
2363 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status);
2366 else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP )
2369 Status = phFriNfc_MapTool_SetCardState( NdefMap,
2371 /* check status value*/
2372 NdefMap->CardType = PH_FRINFC_NDEFMAP_FELICA_SMART_CARD;
2373 /*reset the buffer index*/
2374 NdefMap->ApduBuffIndex = 0;
2375 /* set the Next operation Flag to indicate need of reading attribute information*/
2376 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_OP_NONE;
2377 /* call respective CR */
2378 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,Status);
2380 else if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP )
2382 /* Proceed With Write Functinality*/
2383 Status = phFriNfc_Felica_HWrEmptyMsg(NdefMap);
2384 /* handle the error in Transc function*/
2385 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2387 /* call respective CR */
2388 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_ERASE_NDEF,Status);
2394 /* invalid operation occured*/
2395 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2396 NFCSTATUS_INVALID_DEVICE_REQUEST);
2413 /*handle the Error case*/
2414 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2415 NFCSTATUS_READ_FAILED);
2417 if ( CRFlag == TRUE )
2419 /* call respective CR */
2420 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status);
2424 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN:
2425 /* chk the status flags 1 and 2*/
2426 if ( NdefMap->SendRecvBuf[10] == 0x00 )
2428 /* Update Data Call*/
2429 Status =phFriNfc_Felica_HUpdateData(NdefMap);
2430 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2432 /* call respective CR */
2433 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2438 /*handle the Error case*/
2439 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2440 NFCSTATUS_WRITE_FAILED);
2441 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2445 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END:
2447 /* chk the status flags 1 and 2*/
2448 if ( NdefMap->SendRecvBuf[10] == 0x00)
2450 /* Entire Write Operation is complete*/
2451 Status = PHNFCSTVAL(CID_NFC_NONE,\
2456 /*handle the Error case*/
2457 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2458 NFCSTATUS_WRITE_FAILED);
2460 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2463 case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG :
2465 /* chk the status flags 1 and 2*/
2466 if ( NdefMap->SendRecvBuf[10] == 0x00)
2468 /* Entire Write Operation is complete*/
2469 Status = PHNFCSTVAL(CID_NFC_NONE,\
2474 /*handle the Error case*/
2475 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2476 NFCSTATUS_WRITE_FAILED);
2478 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2481 case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK :
2482 if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE )
2484 /* chk the status flags 1 and 2*/
2485 if ( NdefMap->SendRecvBuf[10] == 0x00 )
2487 /* This is used when we have bytes less than 16 bytes*/
2488 if ( NdefMap->Felica.IntermediateWrFlag == TRUE )
2490 /* after Successful write copy the last writtened bytes back to the
2492 (void)memcpy( (&(NdefMap->Felica.Wr_RemainedBytesBuff[NdefMap->Felica.Wr_BytesRemained])),
2493 NdefMap->ApduBuffer,
2494 NdefMap->NumOfBytesWritten);
2496 NdefMap->Felica.Wr_BytesRemained +=
2497 (uint8_t)( NdefMap->NumOfBytesWritten);
2499 /* Increment the Send Buffer index */
2500 NdefMap->ApduBuffIndex +=
2501 NdefMap->NumOfBytesWritten;
2503 *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
2504 NdefMap->Felica.IntermediateWrFlag = FALSE;
2505 /* Call Update Data()*/
2506 Status = phFriNfc_Felica_HUpdateData(NdefMap);
2510 /* update the index and bytes writtened*/
2511 NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten;
2512 *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
2513 if ( NdefMap->Felica.EofCardReachedFlag )
2515 if ( NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb)
2517 NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten;
2519 if (( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) &&
2520 ( NdefMap->ApduBuffIndex == (NdefMap->FelicaAttrInfo.Nmaxb*16)))
2522 NdefMap->Felica.EofCardReachedFlag = FELICA_RD_WR_EOF_CARD_REACHED ;
2523 /*0 represents the write ended*/
2524 Status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED);
2525 if( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2527 /* call respective CR */
2528 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2533 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
2534 NdefMap->FelicaAttrInfo.LenBytes[1],
2535 NdefMap->FelicaAttrInfo.LenBytes[2],
2537 if ( ( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) &&
2538 ((TotNoWrittenBytes + NdefMap->ApduBuffIndex) == (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb*16)))
2540 NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED;
2541 /*0 represents the write ended*/
2542 Status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED);
2543 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2545 /* call respective CR */
2546 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2551 /* Call Update Data()*/
2552 Status = phFriNfc_Felica_HUpdateData(NdefMap);
2553 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2555 /* call respective CR */
2556 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2560 }/*if ( NdefMap->Felica.EofCardReachedFlag )*/
2563 NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten;
2564 /* Call Update Data()*/
2565 Status = phFriNfc_Felica_HUpdateData(NdefMap);
2566 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2568 /* call respective CR */
2569 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2573 }/*if ( NdefMap->SendRecvBuf[10] == 0x00 )*/
2576 /*handle the Error case*/
2577 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2578 NFCSTATUS_WRITE_FAILED);
2582 }/*if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE )*/
2585 /*return Error "Invalid Write Response Code"*/
2586 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2587 NFCSTATUS_WRITE_FAILED);
2591 if ( CRFlag == TRUE )
2593 /* Reset following parameters*/
2594 NdefMap->ApduBuffIndex=0;
2595 NdefMap->Felica.Wr_BytesRemained = 0;
2596 NdefMap->ApduBufferSize = 0;
2597 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2602 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK :
2604 /* check the Manuf Id in the receive buffer*/
2605 Status = phFriNfc_Felica_HCheckManufId(NdefMap);
2606 if ( Status == NFCSTATUS_SUCCESS )
2608 if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_RD_RESP_BYTE )
2610 /* calculate the Nmaxb*/
2611 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
2612 /*get Receive length from the card for corss verifications*/
2613 RecvTxLen= phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
2614 BytesToRecv = NdefMap->SendRecvBuf[12]*16;
2616 /* chk the status flags 1 */
2617 if ( NdefMap->SendRecvBuf[10] == 0x00)
2619 if ( RecvTxLen == BytesToRecv)
2621 NdefMap->Felica.CurBlockNo += (uint8_t)(RecvTxLen/16);
2622 phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap);
2623 Status = phFriNfc_Felica_HReadData(NdefMap,PH_FRINFC_NDEFMAP_SEEK_CUR);
2624 /* handle the error in Transc function*/
2625 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2633 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2634 NFCSTATUS_INVALID_RECEIVE_LENGTH);
2635 /*set the buffer index back to zero*/
2636 NdefMap->ApduBuffIndex = 0;
2637 NdefMap->Felica.Rd_NoBytesToCopy = 0;
2642 NdefMap->ApduBuffIndex=0;
2643 /*handle the Error case*/
2644 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2645 NFCSTATUS_READ_FAILED);
2652 NdefMap->ApduBuffIndex=0;
2653 /*return Error "Invalid Read Response Code"*/
2654 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2655 NFCSTATUS_READ_FAILED);
2662 if ( CRFlag ==TRUE )
2664 /* call respective CR */
2665 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status);
2670 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2671 NFCSTATUS_INVALID_DEVICE_REQUEST);
2672 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_INVALID_OPE, Status);
2680 /* Call CR for unknown Error's*/
2681 switch ( NdefMap->State)
2683 case PH_FRINFC_NDEFMAP_FELI_STATE_CHK_NDEF :
2684 case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_WILD_CARD :
2685 case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP :
2686 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR :
2687 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_CHK_NDEF,
2690 case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK :
2691 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN :
2692 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END :
2693 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_WR_NDEF,
2696 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK :
2697 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_RD_NDEF,
2701 /*set the invalid state*/
2702 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST);
2703 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_INVALID_OPE, Status);
2711 * \brief Prepares Cmd Pkt for reading attribute Blk information.
2713 static NFCSTATUS phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap)
2716 NFCSTATUS status = NFCSTATUS_PENDING;
2717 uint8_t BufIndex = 0;
2719 /* Set the Felica Cmd*/
2720 #ifdef PH_HAL4_ENABLE
2721 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
2723 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
2724 #endif /* #ifdef PH_HAL4_ENABLE */
2726 /*set the additional informations for the data exchange*/
2727 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
2728 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
2730 /* 1st byte represents the length of the cmd packet*/
2731 NdefMap->SendRecvBuf[BufIndex] = 0x00;
2734 /* Read/check command code*/
2735 NdefMap->SendRecvBuf[BufIndex] = 0x06;
2738 /* IDm - Manufacturer Id : 8bytes*/
2739 #ifdef PH_HAL4_ENABLE
2740 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2741 (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm,
2744 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2745 (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t,
2748 #endif /* #ifdef PH_HAL4_ENABLE */
2752 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/
2755 NdefMap->SendRecvBuf[BufIndex] = 0x0B; /* Service Code List*/
2758 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/
2761 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to read)*/
2764 NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/
2767 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/
2770 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
2772 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
2774 /* Update the Send Len*/
2775 NdefMap->SendLength = BufIndex;
2777 /* Change the state to PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR */
2778 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR;
2780 /*set the completion routines for the desfire card operations*/
2781 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process;
2782 NdefMap->MapCompletionInfo.Context = NdefMap;
2784 /*Call the Overlapped HAL Transceive function */
2785 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
2786 &NdefMap->MapCompletionInfo,
2787 NdefMap->psRemoteDevInfo,
2789 &NdefMap->psDepAdditionalInfo,
2790 NdefMap->SendRecvBuf,
2791 NdefMap->SendLength,
2792 NdefMap->SendRecvBuf,
2793 NdefMap->SendRecvLength);
2799 * \brief Validated manufacturer Details, during the read/write operations.
2802 static NFCSTATUS phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap)
2804 NFCSTATUS status = NFCSTATUS_PENDING;
2808 /* check the stored manufacture id with the received manufacture id*/
2809 result = (uint8_t)(phFriNfc_Felica_MemCompare( (void *)(&(NdefMap->SendRecvBuf[2])),
2810 (void *)NdefMap->FelicaManufDetails.ManufID,
2815 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE);
2820 status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
2826 static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer,
2829 uint16_t RecvChkSum)
2831 NFCSTATUS Result = NFCSTATUS_SUCCESS;
2832 uint16_t CheckSum=0,
2835 for(BufIndex = StartIndex;BufIndex <=EndIndex;BufIndex++)
2837 CheckSum += TempBuffer[BufIndex];
2839 if( RecvChkSum != CheckSum )
2841 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2842 NFCSTATUS_INVALID_FORMAT);
2858 * \brief On successful read attribute blk information, this function validates and stores the
2859 * Attribute informations in to the context.
2861 static NFCSTATUS phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap)
2863 NFCSTATUS status = NFCSTATUS_PENDING;
2864 uint8_t CRFlag = FALSE,
2866 ChkSum1 = 0, ChkSum2=0;
2868 uint16_t Nmaxblk = 0,
2871 uint32_t DataLen =0;
2874 /* Validate T3VNo and NFCDevVNo */
2875 status = phFriNfc_MapTool_ChkSpcVer(NdefMap,
2876 PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX);
2877 if ( status != NFCSTATUS_SUCCESS )
2883 /* get the Nmaxb from the receive buffer*/
2884 Nmaxb1 = NdefMap->SendRecvBuf[16];
2885 Nmaxb2 = NdefMap->SendRecvBuf[17];
2887 Nmaxblk = (((uint16_t)Nmaxb1 << 8) | (Nmaxb2 & 0x00ff));
2891 /* check the Nbr against the Nmaxb*/
2892 if ( NdefMap->SendRecvBuf[14] > Nmaxblk )
2898 /*check Nbw > Nmaxb*/
2899 /*check the write flag validity*/
2900 /*check for the RFU bytes validity*/
2901 if ( (NdefMap->SendRecvBuf[15] > Nmaxblk) ||
2902 ((NdefMap->SendRecvBuf[22] != 0x00) && (NdefMap->SendRecvBuf[22] !=0x0f ))||
2903 ( (NdefMap->SendRecvBuf[23] != 0x00) && (NdefMap->SendRecvBuf[23] !=0x01 ))||
2904 ( NdefMap->SendRecvBuf[18] != 0x00) ||
2905 ( NdefMap->SendRecvBuf[19] != 0x00) ||
2906 ( NdefMap->SendRecvBuf[20] != 0x00) ||
2907 ( NdefMap->SendRecvBuf[21] != 0x00))
2914 /* check the validity of the actual ndef data len*/
2915 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES( NdefMap->SendRecvBuf[24],
2916 NdefMap->SendRecvBuf[25],
2917 NdefMap->SendRecvBuf[26],
2922 NdefBlk = (uint16_t )((( DataLen % 16) == 0 ) ? (DataLen >> 4) : ((DataLen >> 4) +1));
2924 /* check Nbc against Nmaxb*/
2925 if ((NdefBlk > Nmaxblk))
2931 /*Store the attribute information in phFriNfc_Felica_AttrInfo*/
2932 NdefMap->FelicaAttrInfo.Version = NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX];
2933 NdefMap->FelicaAttrInfo.Nbr = NdefMap->SendRecvBuf[14];
2934 NdefMap->FelicaAttrInfo.Nbw = NdefMap->SendRecvBuf[15];
2936 NdefMap->FelicaAttrInfo.Nmaxb = Nmaxblk;
2938 NdefMap->FelicaAttrInfo.WriteFlag = NdefMap->SendRecvBuf[22];
2939 NdefMap->FelicaAttrInfo.RdWrFlag = NdefMap->SendRecvBuf[23];
2942 ChkSum1 = NdefMap->SendRecvBuf[27];
2943 ChkSum2 = NdefMap->SendRecvBuf[28];
2945 RecvChkSum = (((uint16_t)ChkSum1 << 8) | (ChkSum2 & 0x00ff));
2947 /* Check the check sum validity?*/
2948 status = phFriNfc_Felica_HCalCheckSum(NdefMap->SendRecvBuf,
2949 PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX,
2952 if ( status != NFCSTATUS_SUCCESS )
2958 /*check RW Flag Access Rights*/
2959 /* set to read only cannot write*/
2960 if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00 )
2962 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
2964 else if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x01 ) // additional check for R/W access
2966 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
2968 else // otherwise invalid
2970 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2973 NdefMap->FelicaAttrInfo.LenBytes[0] = NdefMap->SendRecvBuf[24];
2974 NdefMap->FelicaAttrInfo.LenBytes[1] = NdefMap->SendRecvBuf[25];
2975 NdefMap->FelicaAttrInfo.LenBytes[2] = NdefMap->SendRecvBuf[26];
2976 status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
2987 if ( (status == NFCSTATUS_INVALID_FORMAT ) && (CRFlag == TRUE ))
2989 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2991 if ( CRFlag == TRUE )
2993 /*Return Status Error
\93 Invalid Format
\94*/
2994 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);
3001 * \brief this shall notify the integration software with respective
3002 * success/error status along with the completion routines.
3004 static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t *NdefMap,
3008 /* set the state back to the Reset_Init state*/
3009 NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
3011 /* set the completion routine*/
3012 NdefMap->CompletionRoutine[CrIndex].
3013 CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);
3017 * \brief this shall initialise the internal buffer data to zero.
3019 static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer)
3023 for( index = 0; index< 16 ; index++)
3029 static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n )
3032 int8_t *char_1 =(int8_t *)s1;
3033 int8_t *char_2 =(int8_t *)s2;
3034 if(NULL == s1 || NULL == s2)
3036 PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare");
3040 for(;((n>0)&&(diff==0));n--,char_1++,char_2++)
3042 diff = *char_1 - *char_2;
3050 #include <phUnitTestNfc_Felica_static.c>
3053 #endif /* PH_FRINFC_MAP_FELICA_DISABLED */