1/*
2 * Copyright (C) 2010 NXP Semiconductors
3 *
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
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17/*!
18 * \file  phFriNfc_FelicaMap.c
19 * \brief This component encapsulates read/write/check ndef/process functionalities,
20 *        for the Felica Smart Card.
21 *
22 * Project: NFC-FRI
23 *
24 * $Date: Thu May  6 14:01:35 2010 $
25 * $Author: ing07385 $
26 * $Revision: 1.10 $
27 * $Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $
28 *
29 */
30
31#ifndef PH_FRINFC_MAP_FELICA_DISABLED
32
33#include <phNfcTypes.h>
34#include <phFriNfc_OvrHal.h>
35#include <phFriNfc_FelicaMap.h>
36#include <phFriNfc_MapTools.h>
37
38
39/*! \ingroup grp_file_attributes
40 *  \name NDEF Mapping
41 *
42 * File: \ref phFriNfc_FelicaMap.c
43 *
44 */
45/*@{*/
46
47#define PHFRINFCNDEFMAP_FILEREVISION "$Revision: 1.10 $"
48#define PHFRINFCNDEFMAP_FILEALIASES  "$Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $"
49
50/*@}*/
51
52/* Helpers for Read and updating the attribute informations*/
53static NFCSTATUS   phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap);
54static NFCSTATUS   phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap);
55static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer,
56                                              uint8_t StartIndex,
57                                              uint8_t EndIndex,
58                                              uint16_t RecvChkSum);
59
60/* Helpers for Poll Related Operations*/
61static NFCSTATUS   phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t   *NdefMap,
62                                              const uint8_t sysCode[],
63                                              uint8_t state);
64
65static NFCSTATUS   phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap);
66
67/*Helpers for Reading Operations*/
68static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset);
69static uint16_t    phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap,uint8_t NbcOrNmaxb );
70static void        phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap);
71static NFCSTATUS   phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset);
72static uint16_t    phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc);
73static NFCSTATUS   phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap);
74
75/* Helpers for Writing Operations*/
76static NFCSTATUS   phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap);
77static NFCSTATUS   phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap,
78                                                      uint32_t NdefLen);
79static NFCSTATUS  phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted);
80static NFCSTATUS   phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap);
81static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap);
82
83/* Write Empty NDEF Message*/
84static NFCSTATUS phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap);
85
86/*Helpers for common checks*/
87static NFCSTATUS   phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap);
88static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t  *NdefMap,
89                                 uint8_t              CrIndex,
90                                 NFCSTATUS            Status);
91
92static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer);
93
94static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n );
95
96/*!
97 * \brief returns maximum number of blocks can be read from the Felica Smart Card.
98 *
99 * The function is useful in reading of NDEF information from a felica tag.
100 */
101
102static uint16_t    phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap, uint8_t NbcOrNmaxb )
103{
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 )
108    {
109        PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
110                                                                NdefMap->FelicaAttrInfo.LenBytes[1],
111                                                                NdefMap->FelicaAttrInfo.LenBytes[2],
112                                                                DataLen);
113        /* Calculate Nbc*/
114        BlksToRead = (uint16_t) ( ((DataLen % 16) == 0) ? (DataLen >> 4) : ((DataLen >> 4) +1) );
115
116
117    }
118    else if ( NbcOrNmaxb == PH_NFCFRI_NDEFMAP_FELI_NMAXB)
119    {
120        BlksToRead = NdefMap->FelicaAttrInfo.Nmaxb;
121    }
122    else
123    {
124        /* WARNING !!! code should not reach this point*/
125        ;
126    }
127    return (BlksToRead);
128}
129
130/*!
131 * \brief Initiates Reading of NDEF information from the Felica Card.
132 *
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.
137 */
138
139NFCSTATUS phFriNfc_Felica_RdNdef(  phFriNfc_NdefMap_t  *NdefMap,
140                                    uint8_t             *PacketData,
141                                    uint32_t            *PacketDataLength,
142                                    uint8_t             Offset)
143{
144
145    NFCSTATUS status = NFCSTATUS_PENDING;
146    uint32_t  Nbc = 0;
147
148    NdefMap->ApduBufferSize = *PacketDataLength;
149    /*Store the packet data buffer*/
150    NdefMap->ApduBuffer = PacketData;
151
152    NdefMap->NumOfBytesRead = PacketDataLength ;
153    *NdefMap->NumOfBytesRead = 0;
154    NdefMap->ApduBuffIndex = 0;
155
156    NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
157    NdefMap->Felica.Offset = Offset;
158
159    if( ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )||( NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE))
160    {
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;
169
170        phFriNfc_Felica_HInitInternalBuf(NdefMap->Felica.Rd_BytesToCopyBuff);
171
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))
176        {
177            /* call respective CR */
178            phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status);
179        }
180    }
181    else
182    {
183         Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
184
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 ))
188        {
189            status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,  NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
190        }
191        else
192        {
193
194            NdefMap->Felica.CurrBytesRead = ((NdefMap->Felica.CurBlockNo * 16)- NdefMap->Felica.Rd_NoBytesToCopy);
195            status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset);
196
197        }
198    }
199    return (status);
200}
201
202/*Read Operation Related Helper Routines*/
203
204/*!
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.
208*/
209
210static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset)
211{
212    NFCSTATUS status = NFCSTATUS_PENDING;
213    uint16_t Nbc=0,TranscLen=0;
214
215    Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
216    if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > 0) && (NdefMap->Felica.CurBlockNo < Nbc ))
217    {
218        /* if data is present in the internal buffer*/
219        if (NdefMap->Felica.Rd_NoBytesToCopy > 0 )
220        {
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 ))
226            {
227                /* set the transc len and call transc cmd*/
228                TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
229                status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset);
230            }
231            else
232            {
233                /* Nothing to be done , if IntermediateRdFlag is set to zero*/
234                ;
235            }
236        }
237        else
238        {
239            /* set the transc len and call transc cmd*/
240            TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
241            status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset);
242        }
243    }
244    else
245    {
246        /* Chk the Buffer size*/
247        status = phFriNfc_Felica_HChkApduBuff_Size(NdefMap);
248        if ( (status != NFCSTATUS_SUCCESS) && (NdefMap->Felica.IntermediateRdFlag == TRUE ))
249        {
250            TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
251            status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset);
252        }
253    }
254    return (status);
255}
256
257/*!
258 * \brief Used in Read Opearation.Sets the Trx Buffer Len.
259 */
260
261static uint16_t    phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc)
262{
263    uint16_t TranscLen = 0,BlocksToRead=0;
264
265    if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)% 16) == 0)
266    {
267        BlocksToRead = (uint16_t)( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16 );
268    }
269    else
270    {
271        BlocksToRead = (uint16_t)(((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16) +1);
272    }
273    if ( (BlocksToRead > Nbc) ||( (BlocksToRead) > ( Nbc - NdefMap->Felica.CurBlockNo)) )
274    {
275        BlocksToRead = Nbc - NdefMap->Felica.CurBlockNo;
276    }
277
278
279    if ( BlocksToRead >= NdefMap->FelicaAttrInfo.Nbr)
280    {
281        if( NdefMap->FelicaAttrInfo.Nbr < Nbc )
282        {
283            TranscLen =  NdefMap->FelicaAttrInfo.Nbr*16;
284        }
285        else
286        {
287            TranscLen = Nbc*16;
288            NdefMap->Felica.LastBlkReachedFlag =1;
289        }
290    }
291    else
292    {
293        if (BlocksToRead <= Nbc )
294        {
295            if ( ( BlocksToRead * 16) == ((Nbc *16) -  (NdefMap->Felica.CurBlockNo * 16)))
296            {
297                NdefMap->Felica.LastBlkReachedFlag =1;
298
299            }
300            TranscLen = BlocksToRead*16;
301
302        }
303        else
304        {
305            TranscLen = Nbc*16;
306        }
307    }
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;
311    return (TranscLen);
312}
313
314/*!
315 * \brief Used in Read Opearation.After a successful read operation,
316 *   Copies the data to user buffer.
317 */
318
319static void    phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap)
320{
321    uint8_t ResetFlag = FALSE, ExtrBytesToCpy = FALSE;
322    uint16_t Nbc=0;
323    uint32_t DataLen=0;
324
325    Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC );
326
327    PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
328                                                                NdefMap->FelicaAttrInfo.LenBytes[1],
329                                                                NdefMap->FelicaAttrInfo.LenBytes[2],
330                                                                DataLen);
331    /* Internal Buffer has some old read bytes to cpy to user buffer*/
332    if( NdefMap->Felica.Rd_NoBytesToCopy > 0 )
333    {
334        if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.Rd_NoBytesToCopy )
335        {
336                NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
337
338                if (NdefMap->Felica.IntermediateCpyFlag == TRUE )
339                {
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));
344
345
346
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;
350
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],
355                                                                    DataLen);
356                    /* Internal buffer has zero bytes for copy operation*/
357                    if ( NdefMap->Felica.Rd_NoBytesToCopy == 0)
358                    {
359                        NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED;
360                    }
361                }
362                else
363                {
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));
368                }
369                NdefMap->ApduBuffIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
370
371        }
372        else if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.Rd_NoBytesToCopy )
373        {
374            if ( NdefMap->Felica.IntermediateCpyFlag == TRUE )
375            {
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);
380            }
381            else
382            {
383                /*Copy data internal buff to apdubuffer*/
384                 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
385                                NdefMap->Felica.Rd_BytesToCopyBuff,
386                                NdefMap->Felica.Rd_NoBytesToCopy);
387            }
388
389            /*increment the index,internal buffer len*/
390            NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
391            NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBuffIndex);
392
393            /* To reset the parameters*/
394            ResetFlag = TRUE;
395        }
396        else
397        {
398            /* Extra Bytes to Copy from internal buffer to external buffer*/
399            if ( NdefMap->Felica.IntermediateCpyFlag == TRUE )
400            {
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);
405            }
406            else
407            {
408                /*Copy data internal buff to apdubuffer*/
409                 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
410                                NdefMap->Felica.Rd_BytesToCopyBuff,
411                                NdefMap->Felica.Rd_NoBytesToCopy);
412            }
413            /*increment the index*/
414            NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
415
416            /* To reset the parameters*/
417            ResetFlag = TRUE;
418        }
419    }/*End of Internal Buffer has some old read bytes to cpy to user buffer*/
420    else
421    {
422        /* check if last block is reached*/
423        if ( ((NdefMap->Felica.LastBlkReachedFlag == 1) && (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= 16)) )
424        {
425            /* greater than 16 but less than the data len size*/
426            if (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= DataLen)
427            {
428                NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen) - (NdefMap->Felica.CurrBytesRead +
429                                                    NdefMap->ApduBuffIndex));
430
431                 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
432                               (&(NdefMap->SendRecvBuf[13])),
433                                NdefMap->Felica.CurrBytesRead);
434
435                NdefMap->ApduBuffIndex += NdefMap->Felica.CurrBytesRead;
436                if ( NdefMap->ApduBuffIndex == DataLen)
437                {
438                    ResetFlag = TRUE;
439                }
440            }
441            else
442            {
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 ))
446                {
447
448                    ExtrBytesToCpy = TRUE;
449                }
450                else
451                {
452                    NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - (DataLen)));
453
454                    if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))
455                    {
456                        /*Reduce already copied bytes from the internal buffer*/
457                        NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
458                        ExtrBytesToCpy = TRUE;
459                    }
460                    else
461                    {
462                        ExtrBytesToCpy = FALSE;
463                    }
464                }
465                if ( ExtrBytesToCpy == TRUE )
466                {
467                    NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen)- (NdefMap->Felica.CurrBytesRead +
468                                                    NdefMap->ApduBuffIndex));
469
470                    if(NdefMap->Felica.CurrBytesRead <
471                        (uint16_t)(NdefMap->ApduBufferSize -
472                        NdefMap->ApduBuffIndex))
473                    {
474                         (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
475                                       (&(NdefMap->SendRecvBuf[13])),
476                                       NdefMap->Felica.CurrBytesRead);
477                    }
478                    else
479                    {
480                         (void)memcpy( (&( NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
481                                       (&( NdefMap->SendRecvBuf[13])),
482                                        (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
483                    }
484
485                    if ( NdefMap->Felica.LastBlkReachedFlag == 1 )
486                    {
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)):
492                                    0);
493
494                        ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy == 0)?TRUE:FALSE);
495
496                    }
497                    else
498                    {
499                        NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)( NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
500                    }
501
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);
506
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;
510
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));
517                }
518                else
519                {
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);
524
525                    NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
526                    ResetFlag = TRUE;
527
528                }
529            }
530
531        }
532        else
533        {
534            if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.TrxLen )
535            {
536                /* Calculate exactly remained bytes to copy to internal buffer and set it*/
537                if ( NdefMap->Felica.LastBlkReachedFlag == 1)
538                {
539                    NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - DataLen));
540
541                    if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))
542                    {
543                        /*Reduce already copied bytes from the internal buffer*/
544                        NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
545                        ExtrBytesToCpy = TRUE;
546                    }
547                }
548                else
549                {
550                    NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
551                    ExtrBytesToCpy = TRUE;
552                }
553                if ( ExtrBytesToCpy == TRUE )
554                {
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);
559
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);
564
565                    NdefMap->Felica.IntermediateCpyFlag = TRUE;
566                    NdefMap->ApduBuffIndex += (uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex;
567                }
568                else
569                {
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);
574
575                    NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
576                    ResetFlag = TRUE;
577
578                }
579                if ( DataLen <= (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) )
580                {
581                        NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED;
582                }
583                else
584                {
585                ;
586                }
587            }
588            else if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.TrxLen )
589            {
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 ));
595
596                NdefMap->ApduBuffIndex += NdefMap->Felica.TrxLen;
597            }
598            else
599            {
600                if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > NdefMap->Felica.TrxLen )
601                {
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);
606
607                        NdefMap->ApduBuffIndex += (uint16_t)NdefMap->Felica.TrxLen;
608                }
609            }
610        }
611    }
612    if ( ResetFlag == TRUE )
613    {
614        /* reset the internal buffer variables*/
615        NdefMap->Felica.Rd_NoBytesToCopy =0;
616        NdefMap->Felica.IntermediateCpyLen =0;
617        NdefMap->Felica.IntermediateCpyFlag =FALSE;
618    }
619    return;
620}
621
622
623/*!
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.
627 */
628
629static NFCSTATUS phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap)
630{
631    NFCSTATUS status = NFCSTATUS_PENDING;
632    uint8_t ResetFlag = FALSE;
633    uint32_t Nbc = 0;
634
635    Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
636
637    /* set status to Success : User Buffer is full and Curblk < nmaxb*/
638    if ( (( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) &&
639         (NdefMap->Felica.CurBlockNo < Nbc ))
640    {
641        status = PHNFCSTVAL(CID_NFC_NONE,
642                                       NFCSTATUS_SUCCESS);
643        /*Reset the index, internal buffer counters back to zero*/
644        *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
645        NdefMap->ApduBuffIndex = 0;
646
647    }/*if( (NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb )*/
648    else
649    {
650        if (( ( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) &&
651             (NdefMap->Felica.CurBlockNo == Nbc ))
652        {
653            status = PHNFCSTVAL(CID_NFC_NONE,
654                                       NFCSTATUS_SUCCESS);
655
656            ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy > 0 )?
657                            FALSE:
658                            TRUE);
659            if( ResetFlag== FALSE)
660            {
661                *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
662                /*Reset the index, internal buffer counters back to zero*/
663                NdefMap->ApduBuffIndex = 0;
664            }
665        }/*if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb )*/
666        else
667        {
668            /* reached reading all the blks available in the card: set EOF flag*/
669            if ( NdefMap->ApduBuffIndex == (Nbc*16))
670            {
671                status = PHNFCSTVAL(CID_NFC_NONE,
672                                    NFCSTATUS_SUCCESS);
673                ResetFlag = TRUE;
674            }
675            else
676            {
677                if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )> 0 )
678                {
679                    if ( NdefMap->Felica.CurBlockNo == Nbc )
680                    {
681                        /* bytes pending in internal buffer , No Space in User Buffer*/
682                        if ( NdefMap->Felica.Rd_NoBytesToCopy > 0)
683                        {
684                            if ( NdefMap->Felica.EofCardReachedFlag == TRUE )
685                            {
686                                status = PHNFCSTVAL(CID_NFC_NONE,
687                                NFCSTATUS_SUCCESS);
688                                *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
689                                NdefMap->ApduBuffIndex=0;
690                            }
691                            else
692                            {
693                                phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap);
694                                if( NdefMap->Felica.Rd_NoBytesToCopy > 0 )
695                                {
696                                    status = PHNFCSTVAL(CID_NFC_NONE,
697                                        NFCSTATUS_SUCCESS);
698                                    *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
699                                    NdefMap->ApduBuffIndex=0;
700                                }
701                                else
702                                {
703                                    /* EOF Card Reached set the internal EOF Flag*/
704                                    status = PHNFCSTVAL(CID_NFC_NONE,
705                                       NFCSTATUS_SUCCESS);
706
707                                    ResetFlag = TRUE;
708                                }
709                            }
710                        }
711                        /* All bytes from internal buffer are copied and set eof flag*/
712                        else
713                        {
714                               status = PHNFCSTVAL(CID_NFC_NONE,
715                                      NFCSTATUS_SUCCESS);
716                               ResetFlag = TRUE;
717                         }
718                    }
719                    else
720                    {
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;
725                    }
726                }
727                else
728                {
729                    status = PHNFCSTVAL(CID_NFC_NONE,
730                                       NFCSTATUS_SUCCESS);
731                }
732            }
733        }
734        if ( ResetFlag == TRUE)
735        {
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;
741
742        }
743
744    }
745    return( status);
746}
747
748/*!
749 * \brief Used in Read Opearation.Sets the transceive Command for read.
750 */
751static NFCSTATUS   phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset)
752{
753    NFCSTATUS TrxStatus =  NFCSTATUS_PENDING;
754    uint16_t BufIndex=0,i=0;
755
756    /* set the felica cmd */
757#ifdef PH_HAL4_ENABLE
758    NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
759#else
760    NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
761#endif /* #ifdef PH_HAL4_ENABLE */
762
763    /*Change the state to Read */
764    NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK;
765
766    /* set the complition routines for the mifare operations */
767    NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process;
768    NdefMap->MapCompletionInfo.Context = NdefMap;
769
770    /*set the additional informations for the data exchange*/
771    NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
772    NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
773
774    /* pkt len : updated at the end*/
775    NdefMap->SendRecvBuf[BufIndex]    =   0x00;
776    BufIndex ++;
777
778    NdefMap->SendRecvBuf[BufIndex]    =   0x06;
779    BufIndex++;
780
781    /* IDm - Manufacturer Id : 8bytes*/
782#ifdef PH_HAL4_ENABLE
783    (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
784                  (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
785                   8);
786#else
787     (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
788                  (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
789                   8);
790#endif  /* #ifdef PH_HAL4_ENABLE */
791
792    BufIndex+=8;
793
794    /*Number of Services (n=1 ==> 0x80)*/
795    NdefMap->SendRecvBuf[BufIndex]    =   0x01;
796    BufIndex++;
797
798    /*Service Code List*/
799    NdefMap->SendRecvBuf[BufIndex]    =   0x0B;
800    BufIndex++;
801
802    NdefMap->SendRecvBuf[BufIndex]    =   0x00;
803    BufIndex++;
804
805    /*Number of Blocks to read*/
806    NdefMap->SendRecvBuf[BufIndex]    =  (uint8_t)(TrxLen/16);
807    BufIndex++;
808    /* Set the Blk numbers as per the offset set by the user : Block List*/
809    if ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )
810    {
811        for ( i=0;i<(TrxLen/16);i++)
812        {
813            /*1st Service Code list : byte 1*/
814            NdefMap->SendRecvBuf[BufIndex]    =   0x80;
815            BufIndex++;
816
817            /* No. Of Blocks*/
818            NdefMap->SendRecvBuf[BufIndex]    =   (uint8_t)(i + 1);
819            BufIndex++;
820        }
821    }
822    else
823    {
824        for ( i= 1;i<=(TrxLen/16);i++)
825        {
826            /*1st Service Code list : byte 1*/
827            NdefMap->SendRecvBuf[BufIndex]    =   0x80;
828            BufIndex++;
829
830            /* No. Of Blocks*/
831            NdefMap->SendRecvBuf[BufIndex]    =   (uint8_t)(NdefMap->Felica.CurBlockNo + i);
832            BufIndex++;
833        }
834    }
835
836    /* len of entire pkt*/
837    NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX]          =  (uint8_t) BufIndex;
838
839    /* Set the Pkt Len*/
840    NdefMap->SendLength = BufIndex;
841
842    *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
843
844    TrxStatus = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice,
845                                        &NdefMap->MapCompletionInfo,
846                                        NdefMap->psRemoteDevInfo,
847                                        NdefMap->Cmd,
848                                        &NdefMap->psDepAdditionalInfo,
849                                        NdefMap->SendRecvBuf,
850                                        NdefMap->SendLength,
851                                        NdefMap->SendRecvBuf,
852                                        NdefMap->SendRecvLength);
853    return (TrxStatus);
854}
855
856/*!
857 * \brief Initiates Writing of NDEF information to the Remote Device.
858 *
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.
863 */
864
865NFCSTATUS phFriNfc_Felica_WrNdef(  phFriNfc_NdefMap_t  *NdefMap,
866                                    uint8_t             *PacketData,
867                                    uint32_t            *PacketDataLength,
868                                    uint8_t             Offset)
869{
870
871    NFCSTATUS status = NFCSTATUS_PENDING;
872
873    NdefMap->ApduBufferSize = *PacketDataLength;
874    /*Store the packet data buffer*/
875    NdefMap->ApduBuffer = PacketData;
876
877    /* To Update the Acutal written bytes to context*/
878    NdefMap->WrNdefPacketLength = PacketDataLength;
879    *NdefMap->WrNdefPacketLength = 0;
880
881
882    NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
883    NdefMap->Felica.Offset = Offset;
884
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))
889    {
890        /* call respective CR */
891        phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status);
892    }
893    return (status);
894}
895
896/*!
897 * \brief Initiates Writing of Empty NDEF information to the Remote Device.
898 *
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.
903 */
904
905NFCSTATUS phFriNfc_Felica_EraseNdef(  phFriNfc_NdefMap_t  *NdefMap)
906{
907
908    NFCSTATUS status = NFCSTATUS_PENDING;
909    static uint32_t PktDtLength =0;
910
911    if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID )
912    {
913        /*  Card is in invalid state, cannot have any read/write
914        operations*/
915        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
916            NFCSTATUS_INVALID_FORMAT);
917    }
918    else if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY )
919    {
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;
926    }
927    else
928    {
929
930        /* set the Operation*/
931        NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP;
932
933        status = phFriNfc_Felica_HRdAttrInfo(NdefMap);
934    }
935    return (status);
936}
937
938
939/*!
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.
945 */
946
947static NFCSTATUS  phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted)
948{
949    NFCSTATUS   status = NFCSTATUS_PENDING;
950
951    uint16_t ChkSum=0,index=0;
952    uint8_t BufIndex=0, ErrFlag = FALSE;
953    uint32_t TotNoWrittenBytes=0;
954
955    /* Write Operation : Begin/End Check*/
956
957    NdefMap->State =
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);
961
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) )
964    {
965
966        /* Set the Felica Cmd*/
967#ifdef PH_HAL4_ENABLE
968        NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
969#else
970        NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
971#endif  /* #ifdef PH_HAL4_ENABLE */
972
973        /* 1st byte represents the length of the cmd packet*/
974        NdefMap->SendRecvBuf[BufIndex] = 0x00;
975        BufIndex++;
976
977        /* Write/Update command code*/
978        NdefMap->SendRecvBuf[BufIndex] = 0x08;
979        BufIndex++;
980
981        /* IDm - Manufacturer Id : 8bytes*/
982#ifdef PH_HAL4_ENABLE
983        (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
984                    (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
985                        8);
986#else
987        (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
988                    (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
989                        8);
990#endif /* #ifdef PH_HAL4_ENABLE */
991
992        BufIndex+=8;
993
994        NdefMap->SendRecvBuf[BufIndex]    =   0x01;  /*  Number of Services (n=1 ==> 0x80)*/
995        BufIndex++;
996
997        NdefMap->SendRecvBuf[BufIndex]    =   0x09;  /*  Service Code List*/
998        BufIndex++;
999
1000        NdefMap->SendRecvBuf[BufIndex]    =   0x00;  /*  Service Code List*/
1001        BufIndex++;
1002
1003        NdefMap->SendRecvBuf[BufIndex]    =   0x01;  /*  Number of Blocks to Write*/
1004        BufIndex++;
1005
1006        NdefMap->SendRecvBuf[BufIndex]    =   0x80;  /*  1st Block Element : byte 1*/
1007        BufIndex++;
1008
1009        NdefMap->SendRecvBuf[BufIndex]    =   0x00;  /*  1st Block Element : byte 2, block 1*/
1010        BufIndex++;
1011
1012        /* Fill Attribute Blk Information*/
1013        NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.Version;
1014        BufIndex++;
1015
1016        NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.Nbr;
1017        BufIndex++;
1018
1019        NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.Nbw;
1020        BufIndex++;
1021
1022        NdefMap->SendRecvBuf[BufIndex]  = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8);
1023        BufIndex++;
1024
1025        NdefMap->SendRecvBuf[BufIndex]  = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff));
1026        BufIndex++;
1027
1028        NdefMap->SendRecvBuf[BufIndex]  = 0x00; /*RFU*/
1029        BufIndex++;
1030
1031        NdefMap->SendRecvBuf[BufIndex]  = 0x00; /*RFU*/
1032        BufIndex++;
1033
1034        NdefMap->SendRecvBuf[BufIndex]  = 0x00; /*RFU*/
1035        BufIndex++;
1036
1037        NdefMap->SendRecvBuf[BufIndex]  = 0x00; /*RFU*/
1038        BufIndex++;
1039
1040        if (isStarted == FELICA_WRITE_STARTED )
1041        {
1042            NdefMap->SendRecvBuf[BufIndex]  = 0x0F; /* Write Flag Made On*/
1043            BufIndex++;
1044
1045            NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/
1046            BufIndex++;
1047
1048            /* Len Bytes*/
1049            NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.LenBytes[0];
1050            BufIndex++;
1051
1052            NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.LenBytes[1];
1053            BufIndex++;
1054
1055            NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.LenBytes[2];
1056            BufIndex++;
1057        }
1058        else
1059        {
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))
1065            {
1066                status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1067                                        NFCSTATUS_INVALID_PARAMETER);
1068                ErrFlag = TRUE;
1069            }
1070            else
1071            {
1072
1073                NdefMap->SendRecvBuf[BufIndex]  = 0x00; /* Write Flag Made Off*/
1074                BufIndex++;
1075
1076                NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/
1077                BufIndex++;
1078
1079                if ( NdefMap->Felica.Wr_BytesRemained > 0 )
1080                {
1081                    TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained)));
1082                }
1083                else
1084                {
1085                    TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16);
1086
1087                }
1088
1089                /* Update Len Bytes*/
1090                NdefMap->SendRecvBuf[BufIndex]  = (uint8_t)(( TotNoWrittenBytes & 0x00ff0000) >> 16);
1091                BufIndex++;
1092
1093                NdefMap->SendRecvBuf[BufIndex]  = (uint8_t)((TotNoWrittenBytes & 0x0000ff00) >> 8);
1094                BufIndex++;
1095
1096                NdefMap->SendRecvBuf[BufIndex]  = (uint8_t)(TotNoWrittenBytes & 0x000000ff);
1097                BufIndex++;
1098            }
1099        }
1100
1101        if ( ErrFlag != TRUE )
1102        {
1103            /* check sum update*/
1104            for ( index = 16 ; index < 30 ; index ++)
1105            {
1106                ChkSum += NdefMap->SendRecvBuf[index];
1107            }
1108
1109            /* fill check sum in command pkt*/
1110            NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8);
1111            BufIndex++;
1112
1113            NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff);
1114            BufIndex++;
1115
1116            /* update length of the cmd pkt*/
1117            NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1118
1119            *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1120
1121            /* Update the Send Len*/
1122            NdefMap->SendLength = BufIndex;
1123
1124            /*set the completion routines for the desfire card operations*/
1125            NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process;
1126            NdefMap->MapCompletionInfo.Context = NdefMap;
1127
1128            /*set the additional informations for the data exchange*/
1129            NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
1130            NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
1131
1132            /*Call the Overlapped HAL Transceive function */
1133            status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1134                                                &NdefMap->MapCompletionInfo,
1135                                                NdefMap->psRemoteDevInfo,
1136                                                NdefMap->Cmd,
1137                                                &NdefMap->psDepAdditionalInfo,
1138                                                NdefMap->SendRecvBuf,
1139                                                NdefMap->SendLength,
1140                                                NdefMap->SendRecvBuf,
1141                                                NdefMap->SendRecvLength);
1142        }
1143    }
1144    else
1145    {
1146        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1147                                      NFCSTATUS_INVALID_PARAMETER);
1148
1149    }
1150    return (status);
1151}
1152
1153static NFCSTATUS  phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap)
1154{
1155    NFCSTATUS   status = NFCSTATUS_PENDING;
1156
1157    uint16_t ChkSum=0,index=0;
1158    uint8_t BufIndex=0;
1159
1160    /* Write Operation : To Erase the present NDEF Data*/
1161
1162    NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG;
1163
1164    /* Set the Felica Cmd*/
1165#ifdef PH_HAL4_ENABLE
1166    NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
1167#else
1168    NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
1169#endif  /* #ifdef PH_HAL4_ENABLE */
1170
1171    /* 1st byte represents the length of the cmd packet*/
1172    NdefMap->SendRecvBuf[BufIndex] = 0x00;
1173    BufIndex++;
1174
1175    /* Write/Update command code*/
1176    NdefMap->SendRecvBuf[BufIndex] = 0x08;
1177    BufIndex++;
1178
1179    /* IDm - Manufacturer Id : 8bytes*/
1180#ifdef PH_HAL4_ENABLE
1181    (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1182                (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
1183                    8);
1184#else
1185    (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1186                (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
1187                    8);
1188#endif  /* #ifdef PH_HAL4_ENABLE */
1189
1190
1191    BufIndex+=8;
1192
1193    NdefMap->SendRecvBuf[BufIndex]    =   0x01;  /*  Number of Services (n=1 ==> 0x80)*/
1194    BufIndex++;
1195
1196    NdefMap->SendRecvBuf[BufIndex]    =   0x09;  /*  Service Code List*/
1197    BufIndex++;
1198
1199    NdefMap->SendRecvBuf[BufIndex]    =   0x00;  /*  Service Code List*/
1200    BufIndex++;
1201
1202    NdefMap->SendRecvBuf[BufIndex]    =   0x01;  /*  Number of Blocks to Write*/
1203    BufIndex++;
1204
1205    NdefMap->SendRecvBuf[BufIndex]    =   0x80;  /*  1st Block Element : byte 1*/
1206    BufIndex++;
1207
1208    NdefMap->SendRecvBuf[BufIndex]    =   0x00;  /*  1st Block Element : byte 2, block 1*/
1209    BufIndex++;
1210
1211    /* Fill Attribute Blk Information*/
1212    NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.Version;
1213    BufIndex++;
1214
1215    NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.Nbr;
1216    BufIndex++;
1217
1218    NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.Nbw;
1219    BufIndex++;
1220
1221    NdefMap->SendRecvBuf[BufIndex]  = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8);
1222    BufIndex++;
1223
1224    NdefMap->SendRecvBuf[BufIndex]  = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff));
1225    BufIndex++;
1226
1227    NdefMap->SendRecvBuf[BufIndex]  = 0x00; /*RFU*/
1228    BufIndex++;
1229
1230    NdefMap->SendRecvBuf[BufIndex]  = 0x00; /*RFU*/
1231    BufIndex++;
1232
1233    NdefMap->SendRecvBuf[BufIndex]  = 0x00; /*RFU*/
1234    BufIndex++;
1235
1236    NdefMap->SendRecvBuf[BufIndex]  = 0x00; /*RFU*/
1237    BufIndex++;
1238
1239    NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.WriteFlag;
1240    BufIndex++;
1241
1242    NdefMap->SendRecvBuf[BufIndex]  = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/
1243    BufIndex++;
1244
1245    /* Len Bytes are set to 0 : Empty Msg*/
1246    NdefMap->SendRecvBuf[BufIndex]  = 0x00;
1247    BufIndex++;
1248
1249    NdefMap->SendRecvBuf[BufIndex]  = 0x00;
1250    BufIndex++;
1251
1252    NdefMap->SendRecvBuf[BufIndex]  = 0x00;
1253    BufIndex++;
1254
1255    /* check sum update*/
1256    for ( index = 16 ; index < 30 ; index ++)
1257    {
1258        ChkSum += NdefMap->SendRecvBuf[index];
1259    }
1260
1261    /* fill check sum in command pkt*/
1262    NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8);
1263    BufIndex++;
1264
1265    NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff);
1266    BufIndex++;
1267
1268    /* update length of the cmd pkt*/
1269    NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1270
1271    *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1272
1273    /* Update the Send Len*/
1274    NdefMap->SendLength = BufIndex;
1275
1276    /*set the completion routines for the desfire card operations*/
1277    NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process;
1278    NdefMap->MapCompletionInfo.Context = NdefMap;
1279
1280    /*set the additional informations for the data exchange*/
1281    NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
1282    NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
1283
1284    /*Call the Overlapped HAL Transceive function */
1285    status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1286                                        &NdefMap->MapCompletionInfo,
1287                                        NdefMap->psRemoteDevInfo,
1288                                        NdefMap->Cmd,
1289                                        &NdefMap->psDepAdditionalInfo,
1290                                        NdefMap->SendRecvBuf,
1291                                        NdefMap->SendLength,
1292                                        NdefMap->SendRecvBuf,
1293                                        NdefMap->SendRecvLength);
1294
1295    return (status);
1296}
1297
1298
1299
1300
1301/*!
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
1306 *  RdWr flag.
1307 *  If the Offset is set to Current, Checks for the EOF card reached status and writes data to
1308 *  The Card
1309 */
1310
1311static NFCSTATUS   phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t  *NdefMap)
1312{
1313    NFCSTATUS   status = NFCSTATUS_PENDING;
1314    uint32_t DataLen=0;
1315
1316    /*check RW Flag Access Rights*/
1317    /* set to read only cannot write*/
1318    if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00)
1319
1320    {
1321        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1322                                       NFCSTATUS_INVALID_DEVICE_REQUEST);
1323    }
1324    else
1325    {
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 ) ))
1329        {
1330            /* check allready written number of bytes and apdu buffer size*/
1331            if (NdefMap->ApduBufferSize > (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16))
1332            {
1333                NdefMap->Felica.EofCardReachedFlag = FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET;
1334            }
1335            else
1336            {
1337                NdefMap->Felica.EofCardReachedFlag = FALSE;
1338            }
1339
1340
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);
1347
1348        }
1349        else
1350        {
1351            if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR )
1352            {
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],
1357                                                                DataLen);
1358
1359                if (( NdefMap->ApduBufferSize + (DataLen )) >
1360                        (uint32_t)( NdefMap->FelicaAttrInfo.Nmaxb *16))
1361                {
1362                    if(( DataLen ) ==  (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16) )
1363                    {
1364                        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1365                                     NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
1366                    }
1367                    else
1368                    {
1369
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);
1374                    }
1375                }
1376                else
1377                {
1378                    NdefMap->ApduBuffIndex =0;
1379                    NdefMap->Felica.NoBlocksWritten = 0;
1380                    status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED);
1381                }
1382            }/*if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR )*/
1383        }
1384    }
1385    return (status);
1386}
1387
1388/*!
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
1393 *  The Card
1394 */
1395
1396static NFCSTATUS   phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap,
1397                                                      uint32_t NdefLen)
1398{
1399    NFCSTATUS   status = NFCSTATUS_PENDING;
1400
1401    /*check WR Flag Access Rights*/
1402    /* set to still writing data state only cannot Read*/
1403    if ( NdefMap->FelicaAttrInfo.WriteFlag == 0x0F )
1404    {
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;
1409    }
1410    else
1411    {
1412        status = phFriNfc_MapTool_SetCardState( NdefMap,NdefLen);
1413        if ( status == NFCSTATUS_SUCCESS)
1414        {
1415            /* Read data From the card*/
1416            status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset);
1417        }
1418    }
1419
1420    return (status);
1421}
1422
1423/*!
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
1428 */
1429static NFCSTATUS   phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap)
1430{
1431    NFCSTATUS status = NFCSTATUS_PENDING;
1432
1433    uint8_t BufIndex=0,
1434            i=0,
1435            BlkNo=0,
1436            PadBytes=0,
1437            CurBlk=1,
1438            NoOfBlks=0,
1439            NbwCheck=0,
1440            TotNoBlks=0;
1441
1442    uint32_t BytesRemainedInCard=0,
1443             BytesRemained=0,
1444             TotNoWrittenBytes=0;
1445
1446    if( (NdefMap->ApduBufferSize -  NdefMap->ApduBuffIndex) > 0 )
1447    {
1448        /* Prepare the write cmd pkt for felica*/
1449        /* 1st byte represents the length of the cmd packet*/
1450        NdefMap->SendRecvBuf[BufIndex] = 0x00;
1451        BufIndex++;
1452
1453        /* Write/Update command code*/
1454        NdefMap->SendRecvBuf[BufIndex] = 0x08;
1455        BufIndex++;
1456
1457        /* IDm - Manufacturer Id : 8bytes*/
1458#ifdef PH_HAL4_ENABLE
1459        (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1460                     (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
1461                      8);
1462#else
1463         (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1464                     (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
1465                      8);
1466#endif  /* #ifdef PH_HAL4_ENABLE */
1467
1468        BufIndex+=8;
1469
1470        NdefMap->SendRecvBuf[BufIndex]    =   0x01;   /*  Number of Services (n=1 ==> 0x80)*/
1471        BufIndex++;
1472
1473        NdefMap->SendRecvBuf[BufIndex]    =   0x09;   /*  Service Code List*/
1474        BufIndex++;
1475
1476        NdefMap->SendRecvBuf[BufIndex]    =   0x00;   /* Service Code List*/
1477        BufIndex++;
1478
1479        if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET)
1480        {
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));
1484        }
1485        else
1486        {
1487            /* Offset : Cuurent*/
1488            if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_CURR_OFFSET )
1489            {
1490                  /* caculate previously written Ndef blks*/
1491                 (void)phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
1492
1493                 if ( NdefMap->Felica.Wr_BytesRemained  )
1494                 {
1495                    TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained)));
1496                 }
1497                 else
1498                 {
1499                    TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16);
1500                 }
1501                 /* Determine exactly, how many bytes we can write*/
1502                 BytesRemainedInCard = (NdefMap->FelicaAttrInfo.Nmaxb*16 - (TotNoWrittenBytes));
1503            }
1504
1505        }
1506        /* Write Data Pending in the Internal Buffer*/
1507        if(NdefMap->Felica.Wr_BytesRemained > 0)
1508        {
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;
1512            BufIndex++;
1513
1514            /* Update this Total no. Bloks later*/
1515            NoOfBlks = BufIndex;
1516
1517            /* As we are writing atleast one block*/
1518            TotNoBlks = 1;
1519
1520            /* check do we have some extra bytes to write? in User Buffer*/
1521            if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained))
1522            {
1523                /* Have we reached EOF?*/
1524                if ( NdefMap->Felica.EofCardReachedFlag )
1525                {
1526                    BytesRemained = BytesRemainedInCard;
1527                }
1528                else
1529                {
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);
1532                }
1533
1534                if ( BytesRemained )
1535                {
1536                    /* Not reached EOF*/
1537                    if (!NdefMap->Felica.EofCardReachedFlag)
1538                    {
1539                       /* Calculate How many blks we need to write*/
1540                        BlkNo =((uint8_t)( BytesRemained )/16);
1541
1542                        /* check blocks to write exceeds nbw*/
1543                        if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw )
1544                        {
1545                            BlkNo = NdefMap->FelicaAttrInfo.Nbw;
1546                            /* No. Blks to write are more than Nbw*/
1547                            NbwCheck = 1;
1548                        }
1549                        else
1550                        {
1551                             if  ((( BytesRemained %16) == 0)&& (BlkNo == 0 ))
1552                            {
1553                                BlkNo=1;
1554                            }
1555                        }
1556                        /* check do we need pad bytes?*/
1557                        if( (!NbwCheck && (uint8_t)( BytesRemained)%16) != 0)
1558                        {
1559                            BlkNo++;
1560                            PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained);
1561                            NdefMap->Felica.PadByteFlag = TRUE;
1562                            NdefMap->Felica.NoBlocksWritten = BlkNo;
1563                            TotNoBlks += BlkNo;
1564
1565                        }
1566                        else
1567                        {
1568                            if ( NbwCheck )
1569                            {
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;
1574                            }
1575                            else
1576                            {
1577                                if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 ))
1578                                {
1579                                    TotNoBlks += BlkNo;
1580                                }
1581                                else
1582                                {
1583
1584                                }
1585                                 if ( NdefMap->Felica.PadByteFlag )
1586                                {
1587                                    NdefMap->Felica.NoBlocksWritten = TotNoBlks-1;
1588
1589                                }
1590                            }
1591                        }
1592                    }
1593                    else
1594                    {
1595                         /* we have reached the eof card & hv bytes to write*/
1596                        BlkNo =(uint8_t)(( BytesRemained - ((16 -NdefMap->Felica.Wr_BytesRemained)) )/16);
1597
1598                        /* check are we exceeding the NBW limit, while a write?*/
1599                        if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw )
1600                        {
1601                            BlkNo = NdefMap->FelicaAttrInfo.Nbw;
1602
1603                            /* No. Blks to write are more than Nbw*/
1604                            NbwCheck = 1;
1605
1606                        }
1607                        else
1608                        {
1609                            if  ((( BytesRemained %16) == 0)&& (BlkNo == 0 ))
1610                            {
1611                                BlkNo=1;
1612                            }
1613                        }
1614
1615                        /*check Total how many blocks to write*/
1616                        if(((!NbwCheck) &&( BytesRemained- (16 - NdefMap->Felica.Wr_BytesRemained))%16) != 0)
1617                        {
1618                            BlkNo++;
1619                            PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained);
1620                            NdefMap->Felica.PadByteFlag = TRUE;
1621                            NdefMap->Felica.NoBlocksWritten = BlkNo;
1622                            TotNoBlks += BlkNo;
1623
1624                        }
1625                        else
1626                        {
1627                            if ( NbwCheck )
1628                            {
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;
1633                            }
1634                            else
1635                            {
1636                                /* we need to write only one block ( bytesremanind + internal buffer size = 16)*/
1637                                if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 ))
1638                                {
1639                                    TotNoBlks += BlkNo;
1640                                }
1641                                else
1642                                {
1643                                    ;/* we are not incrementing the Total no. of blocks to write*/
1644                                }
1645
1646                                if ( NdefMap->Felica.PadByteFlag )
1647                                {
1648                                    NdefMap->Felica.NoBlocksWritten = TotNoBlks -1;
1649
1650                                }
1651                            }
1652                        }
1653                    }
1654                }/*if ( BytesRemained )*/
1655                else
1656                {
1657                   ; /*Nothing to process here*/
1658                }
1659            }/*if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained))*/
1660            else
1661            {
1662                /* No new blks to write*/
1663                NdefMap->Felica.NoBlocksWritten = 0;
1664            }
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++)
1668            {
1669                NdefMap->SendRecvBuf[BufIndex]    =   0x80;
1670                BufIndex++;
1671                /* remember the previous Blk no and continue from there*/
1672                if ( NdefMap->Felica.PadByteFlag == TRUE )
1673                {
1674                    NdefMap->SendRecvBuf[BufIndex]    =   NdefMap->Felica.CurBlockNo + i;
1675                    BufIndex++;
1676                }
1677                else
1678                {
1679                    CurBlk = NdefMap->Felica.CurBlockNo +1;
1680                    NdefMap->SendRecvBuf[BufIndex]    =   CurBlk + i;
1681                    BufIndex++;
1682                }
1683            }
1684            /* Copy relevant data to Transc buffer*/
1685            if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16 - NdefMap->Felica.Wr_BytesRemained))
1686            {
1687
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);
1692
1693                /*Increment the buff index*/
1694                BufIndex += NdefMap->Felica.Wr_BytesRemained;
1695
1696
1697                /*append copy 16-bytesToPad to trxBuffer*/
1698                (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1699                               (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1700                                (16 - NdefMap->Felica.Wr_BytesRemained));
1701
1702                /* Update Number Of Bytes Writtened*/
1703                NdefMap->NumOfBytesWritten = 16 - NdefMap->Felica.Wr_BytesRemained;
1704
1705                /* increment the index*/
1706                BufIndex += 16 - NdefMap->Felica.Wr_BytesRemained;
1707
1708                if ( BytesRemained )
1709                {
1710                    if (!NdefMap->Felica.EofCardReachedFlag)
1711                    {
1712                        /* check nbw limit*/
1713                        if ( NbwCheck != 1 )
1714                        {
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)));
1719
1720
1721                            /* Update Number Of Bytes Writtened*/
1722                            NdefMap->NumOfBytesWritten += (uint16_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained));
1723
1724                            BufIndex += (uint8_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained));
1725
1726                            if ( PadBytes )
1727                            {
1728                                for(i= 0; i< PadBytes; i++)
1729                                {
1730                                    NdefMap->SendRecvBuf[BufIndex] =0x00;
1731                                    BufIndex++;
1732                                }
1733                                /* no of bytes remained copy*/
1734                                NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes);
1735
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));
1740                            }
1741                            else
1742                            {
1743                                /* No Bytes in Internal buffer*/
1744                                NdefMap->Felica.Wr_BytesRemained = 0;
1745                            }
1746
1747                        }
1748                        else
1749                        {
1750
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);
1755
1756                            /* increment the Buffindex*/
1757                            BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16);
1758
1759                            NdefMap->Felica.Wr_BytesRemained = 0;
1760                            NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16);
1761                            NdefMap->Felica.PadByteFlag =FALSE;
1762                        }
1763                    }/*if (!NdefMap->Felica.EofCardReachedFlag)*/
1764                    else
1765                    {
1766                         /* check nbw limit*/
1767                        if ( NbwCheck != 1 )
1768                        {
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) )));
1773
1774                            /* Update Number Of Bytes Writtened*/
1775                            NdefMap->NumOfBytesWritten += (uint16_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained));
1776
1777                            BufIndex += (uint8_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained));
1778
1779                            if ( PadBytes )
1780                            {
1781                                for(i= 0; i< PadBytes; i++)
1782                                {
1783                                    NdefMap->SendRecvBuf[BufIndex] =0x00;
1784                                    BufIndex++;
1785                                }
1786
1787                                /*no of bytes remained copy*/
1788                                NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes);
1789
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));
1794
1795                            }
1796                            else
1797                            {
1798                                NdefMap->Felica.Wr_BytesRemained = 0;
1799                            }
1800                        }
1801                        else
1802                        {
1803
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);
1808
1809                            /* increment the Buffindex*/
1810                            BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16);
1811
1812                            NdefMap->Felica.Wr_BytesRemained = 0;
1813                            NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16);
1814
1815                            NdefMap->Felica.PadByteFlag =FALSE;
1816                        }
1817                    }
1818                }/*if ( BytesRemained )*/
1819                else
1820                {
1821                    NdefMap->Felica.Wr_BytesRemained = 0;
1822                }
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))*/
1826            else
1827            {
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));
1832
1833                /* increment the index*/
1834                BufIndex+=NdefMap->Felica.Wr_BytesRemained;
1835
1836                /*append the apdusize data to the trx buffer*/
1837                (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1838                            (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1839                            NdefMap->ApduBufferSize);
1840
1841                 /* Index increment*/
1842                BufIndex+= (uint8_t)NdefMap->ApduBufferSize;
1843
1844                /* Tells how many bytes present in the internal buffer*/
1845                BytesRemained = NdefMap->Felica.Wr_BytesRemained + NdefMap->ApduBufferSize;
1846
1847                PadBytes = (uint8_t)(16-BytesRemained);
1848
1849                /* Pad empty bytes with Zeroes to complete 16 bytes*/
1850                for(i= 0; i< PadBytes; i++)
1851                {
1852                    NdefMap->SendRecvBuf[BufIndex] =0x00;
1853                    BufIndex++;
1854                }
1855
1856                /* Update Number Of Bytes Writtened*/
1857                NdefMap->NumOfBytesWritten = (uint16_t)NdefMap->ApduBufferSize;
1858
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;
1862
1863                if ( NdefMap->Felica.PadByteFlag )
1864                {
1865                    NdefMap->Felica.NoBlocksWritten = 0;
1866                }
1867            }
1868
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;
1873        }
1874        else
1875        {
1876            /*Fresh write, starting from a new block*/
1877            if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw ))
1878            {
1879                /* check for the card size and write Nbw Blks*/
1880                if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw)
1881                {
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;
1885                    BufIndex++;
1886
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++)
1889                    {
1890                        NdefMap->SendRecvBuf[BufIndex]    =   0x80;
1891                        BufIndex++;
1892
1893                        NdefMap->SendRecvBuf[BufIndex]    =   NdefMap->Felica.CurBlockNo + i;
1894                        BufIndex++;
1895                    }
1896                    /*Copy Nbw*16 bytes of data to the trx buffer*/
1897
1898                    (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1899                                 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1900                                 NdefMap->FelicaAttrInfo.Nbw * 16);
1901
1902                    /* increment the Buffindex*/
1903                    BufIndex += (NdefMap->FelicaAttrInfo.Nbw*16);
1904
1905                    /* update the length*/
1906                    NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1907
1908                    NdefMap->Felica.Wr_BytesRemained = 0;
1909                    NdefMap->NumOfBytesWritten = (NdefMap->FelicaAttrInfo.Nbw*16);
1910                    NdefMap->Felica.NoBlocksWritten = NdefMap->FelicaAttrInfo.Nbw;
1911
1912                    /* update the Send length*/
1913                    NdefMap->SendLength = BufIndex;
1914
1915                    NdefMap->Felica.PadByteFlag = FALSE;
1916                }/*if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw)*/
1917                else
1918                {
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);
1923                    BufIndex++;
1924
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++)
1927                    {
1928                        NdefMap->SendRecvBuf[BufIndex]    =   0x80;
1929                        BufIndex++;
1930                        NdefMap->SendRecvBuf[BufIndex]    =   NdefMap->Felica.CurBlockNo + i;
1931                        BufIndex++;
1932                    }
1933
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);
1938
1939                    /* increment the Buffindex*/
1940                    BufIndex += (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo )*16);
1941
1942                    /* update the length*/
1943                    NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1944
1945                    NdefMap->NumOfBytesWritten = ((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo)*16);
1946                    NdefMap->Felica.NoBlocksWritten = (uint8_t)(NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo);
1947
1948                    /* update the Send length*/
1949                    NdefMap->SendLength = BufIndex;
1950
1951                    NdefMap->Felica.PadByteFlag =FALSE;
1952                    NdefMap->Felica.Wr_BytesRemained = 0;
1953                }
1954            }/* if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */
1955            else
1956            {
1957                /*chk eof reached*/
1958                if ( NdefMap->Felica.EofCardReachedFlag)
1959                {
1960                    BlkNo =((uint8_t)(BytesRemainedInCard )/16);
1961                    if(((uint8_t)( BytesRemainedInCard )%16) != 0)
1962                    {
1963                        BlkNo++;
1964                        PadBytes = ((BlkNo * 16) - (uint8_t)(BytesRemainedInCard ));
1965                        NdefMap->Felica.PadByteFlag = TRUE;
1966                    }
1967                }
1968                else
1969                {
1970
1971                    BlkNo =((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16);
1972                    if(((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)%16) != 0)
1973                    {
1974                        BlkNo++;
1975                        PadBytes = (BlkNo * 16) - (uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
1976                        NdefMap->Felica.PadByteFlag = TRUE;
1977
1978                    }
1979
1980
1981                }
1982
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;
1986                BufIndex++;
1987
1988                NdefMap->Felica.NoBlocksWritten = BlkNo;
1989
1990                /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/
1991                for ( i=0; i< BlkNo; i++)
1992                {
1993                    NdefMap->SendRecvBuf[BufIndex]    =   0x80;
1994                    BufIndex++;
1995                    {
1996                        CurBlk = NdefMap->Felica.CurBlockNo +1;
1997                        NdefMap->SendRecvBuf[BufIndex]    =   CurBlk + i;
1998                        BufIndex++;
1999                    }
2000                }
2001                if ( NdefMap->Felica.EofCardReachedFlag )
2002                {
2003                    /*Copy last data to the trx buffer*/
2004                    (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2005                                 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
2006                                 BytesRemainedInCard );
2007
2008                    /* increment the bufindex and bytes written*/
2009                    BufIndex += (uint8_t )BytesRemainedInCard ;
2010                    NdefMap->NumOfBytesWritten = (uint16_t)BytesRemainedInCard ;
2011                }
2012                else
2013                {
2014                    /*Copy data to the trx buffer*/
2015                    (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2016                                 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
2017                                 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
2018
2019                    /* increment the bufindex and bytes written*/
2020                    BufIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
2021                    NdefMap->NumOfBytesWritten = (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
2022                }
2023                if ( PadBytes )
2024                {
2025                    for(i= 0; i< PadBytes; i++)
2026                    {
2027                        NdefMap->SendRecvBuf[BufIndex] =0x00;
2028                        BufIndex++;
2029                    }
2030                    /*no of bytes remained copy*/
2031                    NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes);
2032
2033                    if ( NdefMap->Felica.EofCardReachedFlag )
2034                    {
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));
2039
2040                    }
2041                    else
2042                    {
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));
2047
2048                    }
2049                }/*if ( PadBytes )*/
2050                else
2051                {
2052                    NdefMap->Felica.Wr_BytesRemained = 0;
2053                    NdefMap->Felica.PadByteFlag = FALSE;
2054                }
2055                /* update the pkt len*/
2056                NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
2057                NdefMap->SendLength = BufIndex;
2058            }
2059        }/* else of if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */
2060        status = phFriNfc_Felica_HWriteDataBlk(NdefMap);
2061    }
2062    else
2063    {
2064        /*0 represents the write operation ended*/
2065        status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED);
2066    }
2067    return (status);
2068}
2069
2070
2071/*!
2072 * \brief Used in Write Opearation.
2073 * This function prepares and sends transcc Cmd Pkt.
2074 */
2075
2076static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap)
2077{
2078    NFCSTATUS status = NFCSTATUS_PENDING;
2079
2080    /*set the additional informations for the data exchange*/
2081    NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
2082    NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
2083
2084    /*Set the ISO14434 command*/
2085#ifdef PH_HAL4_ENABLE
2086    NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
2087#else
2088    NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
2089#endif  /* #ifdef PH_HAL4_ENABLE */
2090
2091    /* set the state*/
2092    NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK;
2093
2094    /* set send receive length*/
2095    *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
2096
2097     /*Call the Overlapped HAL Transceive function */
2098    status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
2099                                         &NdefMap->MapCompletionInfo,
2100                                         NdefMap->psRemoteDevInfo,
2101                                         NdefMap->Cmd,
2102                                         &NdefMap->psDepAdditionalInfo,
2103                                         NdefMap->SendRecvBuf,
2104                                         NdefMap->SendLength,
2105                                         NdefMap->SendRecvBuf,
2106                                         NdefMap->SendRecvLength);
2107    return (status);
2108}
2109
2110/*!
2111 * \brief Check whether a particular Remote Device is NDEF compliant.
2112 * The function checks whether the peer device is NDEF compliant.
2113 */
2114
2115NFCSTATUS phFriNfc_Felica_ChkNdef( phFriNfc_NdefMap_t     *NdefMap)
2116{
2117    NFCSTATUS status = NFCSTATUS_PENDING;
2118    uint8_t sysCode[2];
2119
2120    /* set the system code for selecting the wild card*/
2121    sysCode[0] = 0x12;
2122    sysCode[1] = 0xFC;
2123
2124    status = phFriNfc_Felica_HPollCard( NdefMap,sysCode,PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP);
2125
2126    return (status);
2127
2128}
2129/*!
2130 * \brief Check whether a particular Remote Device is NDEF compliant.
2131 * selects the sysCode and then NFC Forum Reference Applications
2132 */
2133#ifdef PH_HAL4_ENABLE
2134static NFCSTATUS   phFriNfc_Felica_HPollCard(  phFriNfc_NdefMap_t     *NdefMap,
2135                                        const uint8_t sysCode[],
2136                                        uint8_t state)
2137{
2138    NFCSTATUS status = NFCSTATUS_PENDING;
2139
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;
2147
2148    NdefMap->SendLength = 6;
2149
2150     /*set the completion routines for the felica card operations*/
2151    NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process;
2152    NdefMap->MapCompletionInfo.Context = NdefMap;
2153
2154    /*Set Ndef State*/
2155    NdefMap->State = state;
2156
2157    /* set the felica cmd */
2158    NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
2159
2160    /*set the additional informations for the data exchange*/
2161    NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
2162    NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
2163
2164    status = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice,
2165                                        &NdefMap->MapCompletionInfo,
2166                                        NdefMap->psRemoteDevInfo,
2167                                        NdefMap->Cmd,
2168                                        &NdefMap->psDepAdditionalInfo,
2169                                        NdefMap->SendRecvBuf,
2170                                        NdefMap->SendLength,
2171                                        NdefMap->SendRecvBuf,
2172                                        NdefMap->SendRecvLength);
2173    return (status);
2174}
2175#endif
2176
2177
2178#ifndef PH_HAL4_ENABLE
2179static NFCSTATUS   phFriNfc_Felica_HPollCard(  phFriNfc_NdefMap_t     *NdefMap,
2180                                        const uint8_t                 sysCode[],
2181                                        uint8_t                 state)
2182{
2183    NFCSTATUS status = NFCSTATUS_PENDING;
2184
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;
2191
2192    /* set the length to zero*/
2193    NdefMap->FelicaPollDetails.DevInputParam->GeneralByteLength =0x00;
2194
2195    NdefMap->NoOfDevices = PH_FRINFC_NDEFMAP_FELI_NUM_DEVICE_TO_DETECT;
2196
2197     /*set the completion routines for the felica card operations*/
2198    NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process;
2199    NdefMap->MapCompletionInfo.Context = NdefMap;
2200
2201    /*Set Ndef State*/
2202    NdefMap->State = state;
2203
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));
2213
2214    /*  Reset the session opened flag */
2215    NdefMap->FelicaPollDetails.psTempRemoteDevInfo.SessionOpened = 0x00;
2216
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);
2224
2225    return (status);
2226}
2227#endif /* #ifndef PH_HAL4_ENABLE */
2228/*!
2229 * \brief Checks validity of system code sent from the lower device, during poll operation.
2230 */
2231
2232static NFCSTATUS   phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap)
2233{
2234    NFCSTATUS status = NFCSTATUS_PENDING;
2235
2236    /* Get the details from Poll Response packet */
2237    if (NdefMap->SendRecvLength >= 20)
2238    {
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;
2246
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,
2250                      8);
2251        (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter),
2252                      (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm,
2253                      8);
2254        if((NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[1] == 0x12)
2255            && (NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[0] == 0xFC))
2256        {
2257            status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS);
2258        }
2259        else
2260        {
2261            status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2262                                NFCSTATUS_NO_NDEF_SUPPORT);
2263        }
2264    }
2265    else
2266    {
2267        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2268                            NFCSTATUS_NO_NDEF_SUPPORT);
2269    }
2270
2271    return (status);
2272}
2273
2274
2275/*!
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.
2280 */
2281
2282void phFriNfc_Felica_Process(void       *Context,
2283                             NFCSTATUS   Status)
2284{
2285    uint8_t  CRFlag = FALSE;
2286    uint16_t RecvTxLen = 0,
2287             BytesToRecv = 0,
2288             Nbc = 0;
2289    uint32_t TotNoWrittenBytes = 0,
2290             NDEFLen=0;
2291
2292    /*Set the context to Map Module*/
2293    phFriNfc_NdefMap_t      *NdefMap = (phFriNfc_NdefMap_t *)Context;
2294
2295    if ( Status == NFCSTATUS_SUCCESS )
2296    {
2297        switch (NdefMap->State)
2298        {
2299            case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP:
2300
2301                    /* check the ndef compliency with the system code reecived in the RemoteDevInfo*/
2302                    Status = phFriNfc_Felica_HUpdateManufIdDetails(NdefMap);
2303
2304                    if (Status == NFCSTATUS_SUCCESS)
2305                    {
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))
2312                        {
2313                            CRFlag = TRUE;
2314                        }
2315                    }
2316                    else
2317                    {
2318                        CRFlag = TRUE;
2319                    }
2320                    if ( CRFlag == TRUE )
2321                    {
2322                        /* call respective CR */
2323                        phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,Status);
2324
2325                    }
2326                break;
2327
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)
2331                {
2332                    /* check the Manuf Id in the receive buffer*/
2333                    Status = phFriNfc_Felica_HCheckManufId(NdefMap);
2334                    if ( Status == NFCSTATUS_SUCCESS)
2335                    {
2336                        /* Update the Attribute Information in to the context structure*/
2337                        Status = phFriNfc_Felica_HUpdateAttrInfo(NdefMap);
2338                        if ( Status == NFCSTATUS_SUCCESS )
2339                        {
2340                            PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
2341                                                                NdefMap->FelicaAttrInfo.LenBytes[1],
2342                                                                NdefMap->FelicaAttrInfo.LenBytes[2],
2343                                                                NDEFLen);
2344
2345                            if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_ATTR_RD_OP )
2346                            {
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))
2351                                {
2352                                    /* call respective CR */
2353                                    phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2354                                }
2355                            }
2356                            else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_RD_ATTR_RD_OP )
2357                            {
2358                                /* Proceed With Read Functinality*/
2359                                Status = phFriNfc_Felica_HChkAttrBlkForRdOp(NdefMap,NDEFLen);
2360                                if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2361                                {
2362                                    /* call respective CR */
2363                                    phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status);
2364                                }
2365                            }
2366                            else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP )
2367                            {
2368
2369                                Status = phFriNfc_MapTool_SetCardState( NdefMap,
2370                                                                        NDEFLen);
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);
2379                            }
2380                            else if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP )
2381                            {
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))
2386                                {
2387                                    /* call respective CR */
2388                                    phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_ERASE_NDEF,Status);
2389                                }
2390                            }
2391                            else
2392                            {
2393
2394                                /* invalid operation occured*/
2395                                Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2396                                        NFCSTATUS_INVALID_DEVICE_REQUEST);
2397                                CRFlag =TRUE ;
2398                            }
2399                        }
2400                        else
2401                        {
2402                            CRFlag =TRUE ;
2403                        }
2404                    }
2405                    else
2406                    {
2407                        CRFlag =TRUE ;
2408                    }
2409                }
2410                else
2411                {
2412                    CRFlag =TRUE;
2413                    /*handle the  Error case*/
2414                    Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2415                                        NFCSTATUS_READ_FAILED);
2416                }
2417                if ( CRFlag == TRUE )
2418                {
2419                    /* call respective CR */
2420                    phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status);
2421                }
2422                break;
2423
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 )
2427                    {
2428                        /* Update Data Call*/
2429                        Status =phFriNfc_Felica_HUpdateData(NdefMap);
2430                        if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2431                        {
2432                            /* call respective CR */
2433                            phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2434                        }
2435                    }
2436                    else
2437                    {
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);
2442
2443                    }
2444                break;
2445            case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END:
2446
2447                    /* chk the status flags 1 and 2*/
2448                    if ( NdefMap->SendRecvBuf[10] == 0x00)
2449                    {
2450                        /* Entire Write Operation is complete*/
2451                        Status = PHNFCSTVAL(CID_NFC_NONE,\
2452                                            NFCSTATUS_SUCCESS);
2453                    }
2454                    else
2455                    {
2456                         /*handle the  Error case*/
2457                        Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2458                                            NFCSTATUS_WRITE_FAILED);
2459                    }
2460                    phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2461                break;
2462
2463            case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG :
2464
2465                    /* chk the status flags 1 and 2*/
2466                    if ( NdefMap->SendRecvBuf[10] == 0x00)
2467                    {
2468                        /* Entire Write Operation is complete*/
2469                        Status = PHNFCSTVAL(CID_NFC_NONE,\
2470                                            NFCSTATUS_SUCCESS);
2471                    }
2472                    else
2473                    {
2474                         /*handle the  Error case*/
2475                        Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2476                                            NFCSTATUS_WRITE_FAILED);
2477                    }
2478                    phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2479                break;
2480
2481            case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK :
2482                if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE )
2483                {
2484                    /* chk the status flags 1 and 2*/
2485                    if ( NdefMap->SendRecvBuf[10] == 0x00 )
2486                    {
2487                        /* This is used when we have bytes less than 16 bytes*/
2488                        if ( NdefMap->Felica.IntermediateWrFlag == TRUE )
2489                        {
2490                            /* after Successful write copy the last writtened bytes back to the
2491                            internal buffer*/
2492                            (void)memcpy( (&(NdefMap->Felica.Wr_RemainedBytesBuff[NdefMap->Felica.Wr_BytesRemained])),
2493                                            NdefMap->ApduBuffer,
2494                                            NdefMap->NumOfBytesWritten);
2495
2496                            NdefMap->Felica.Wr_BytesRemained +=
2497                           (uint8_t)( NdefMap->NumOfBytesWritten);
2498
2499                            /* Increment the Send Buffer index */
2500                            NdefMap->ApduBuffIndex +=
2501                                NdefMap->NumOfBytesWritten;
2502
2503                            *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
2504                            NdefMap->Felica.IntermediateWrFlag = FALSE;
2505                            /* Call Update Data()*/
2506                            Status = phFriNfc_Felica_HUpdateData(NdefMap);
2507                        }
2508                        else
2509                        {
2510                            /* update the index and bytes writtened*/
2511                            NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten;
2512                            *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
2513                            if ( NdefMap->Felica.EofCardReachedFlag )
2514                            {
2515                                if ( NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb)
2516                                {
2517                                    NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten;
2518                                }
2519                                if (( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) &&
2520                                 ( NdefMap->ApduBuffIndex == (NdefMap->FelicaAttrInfo.Nmaxb*16)))
2521                                {
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))
2526                                    {
2527                                        /* call respective CR */
2528                                        phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2529                                    }
2530                                }
2531                                else
2532                                {
2533                                    PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
2534                                                                NdefMap->FelicaAttrInfo.LenBytes[1],
2535                                                                NdefMap->FelicaAttrInfo.LenBytes[2],
2536                                                                TotNoWrittenBytes);
2537                                    if ( ( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) &&
2538                                        ((TotNoWrittenBytes + NdefMap->ApduBuffIndex) == (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb*16)))
2539                                    {
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))
2544                                        {
2545                                            /* call respective CR */
2546                                            phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2547                                        }
2548                                    }
2549                                    else
2550                                    {
2551                                        /* Call Update Data()*/
2552                                        Status = phFriNfc_Felica_HUpdateData(NdefMap);
2553                                        if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2554                                        {
2555                                            /* call respective CR */
2556                                            phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2557                                        }
2558                                    }
2559                                }
2560                            }/*if ( NdefMap->Felica.EofCardReachedFlag )*/
2561                            else
2562                            {
2563                                NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten;
2564                                /* Call Update Data()*/
2565                                Status = phFriNfc_Felica_HUpdateData(NdefMap);
2566                                if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2567                                {
2568                                    /* call respective CR */
2569                                    phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2570                                }
2571                            }
2572                        }
2573                    }/*if ( NdefMap->SendRecvBuf[10] == 0x00 )*/
2574                    else
2575                    {
2576                        /*handle the  Error case*/
2577                        Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2578                                            NFCSTATUS_WRITE_FAILED);
2579                        CRFlag = TRUE;
2580
2581                    }
2582                }/*if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE )*/
2583                else
2584                {
2585                   /*return Error "Invalid Write Response Code"*/
2586                    Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2587                                       NFCSTATUS_WRITE_FAILED);
2588                    CRFlag = TRUE;
2589
2590                }
2591                if ( CRFlag == TRUE )
2592                {
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);
2598                }
2599
2600                break;
2601
2602            case    PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK :
2603
2604            /* check the Manuf Id in the receive buffer*/
2605            Status = phFriNfc_Felica_HCheckManufId(NdefMap);
2606            if ( Status == NFCSTATUS_SUCCESS )
2607            {
2608                if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_RD_RESP_BYTE )
2609                {
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;
2615
2616                    /* chk the status flags 1 */
2617                    if ( NdefMap->SendRecvBuf[10] == 0x00)
2618                    {
2619                        if ( RecvTxLen == BytesToRecv)
2620                        {
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))
2626                            {
2627                                CRFlag =TRUE;
2628                            }
2629                        }
2630                        else
2631                        {
2632                            CRFlag =TRUE;
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;
2638                        }
2639                    }
2640                    else
2641                    {
2642                        NdefMap->ApduBuffIndex=0;
2643                        /*handle the  Error case*/
2644                        Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2645                                            NFCSTATUS_READ_FAILED);
2646                        CRFlag =TRUE;
2647                    }
2648                }
2649                else
2650                {
2651                    CRFlag =TRUE;
2652                    NdefMap->ApduBuffIndex=0;
2653                    /*return Error "Invalid Read Response Code"*/
2654                    Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2655                                NFCSTATUS_READ_FAILED);
2656                }
2657            }
2658            else
2659            {
2660                CRFlag =TRUE;
2661            }
2662            if ( CRFlag ==TRUE )
2663            {
2664                /* call respective CR */
2665                phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status);
2666            }
2667            break;
2668
2669        default:
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);
2673            break;
2674
2675
2676        }
2677    }
2678    else
2679    {
2680        /* Call CR for unknown Error's*/
2681        switch ( NdefMap->State)
2682        {
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,
2688                                            Status);
2689                break;
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,
2694                                            Status);
2695                break;
2696            case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK :
2697                phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_RD_NDEF,
2698                                            Status);
2699                break;
2700            default :
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);
2704                break;
2705        }
2706    }
2707
2708}
2709
2710/*!
2711 * \brief Prepares Cmd Pkt for reading attribute Blk information.
2712 */
2713static NFCSTATUS   phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap)
2714{
2715
2716    NFCSTATUS   status = NFCSTATUS_PENDING;
2717    uint8_t BufIndex = 0;
2718
2719    /* Set the Felica Cmd*/
2720#ifdef PH_HAL4_ENABLE
2721    NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
2722#else
2723    NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
2724#endif  /* #ifdef PH_HAL4_ENABLE */
2725
2726    /*set the additional informations for the data exchange*/
2727    NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
2728    NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
2729
2730    /* 1st byte represents the length of the cmd packet*/
2731    NdefMap->SendRecvBuf[BufIndex] = 0x00;
2732    BufIndex++;
2733
2734    /* Read/check command code*/
2735    NdefMap->SendRecvBuf[BufIndex] = 0x06;
2736    BufIndex++;
2737
2738    /* IDm - Manufacturer Id : 8bytes*/
2739#ifdef PH_HAL4_ENABLE
2740    (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2741                (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm,
2742                8);
2743#else
2744    (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2745                (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t,
2746                8);
2747
2748#endif  /* #ifdef PH_HAL4_ENABLE */
2749
2750    BufIndex+=8;
2751
2752    NdefMap->SendRecvBuf[BufIndex]    =   0x01;  /*  Number of Services (n=1 ==> 0x80)*/
2753    BufIndex++;
2754
2755    NdefMap->SendRecvBuf[BufIndex]    =   0x0B;  /*  Service Code List*/
2756    BufIndex++;
2757
2758    NdefMap->SendRecvBuf[BufIndex]    =   0x00;  /*  Service Code List*/
2759    BufIndex++;
2760
2761    NdefMap->SendRecvBuf[BufIndex]    =   0x01;  /*  Number of Blocks to read)*/
2762    BufIndex++;
2763
2764    NdefMap->SendRecvBuf[BufIndex]    =   0x80;  /*  1st Block Element : byte 1*/
2765    BufIndex++;
2766
2767    NdefMap->SendRecvBuf[BufIndex]    =   0x00;  /*  1st Block Element : byte 2, block 1*/
2768    BufIndex++;
2769
2770    NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX]             =   BufIndex;
2771
2772    *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
2773
2774    /* Update the Send Len*/
2775    NdefMap->SendLength = BufIndex;
2776
2777    /* Change the state to  PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR */
2778    NdefMap->State =  PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR;
2779
2780    /*set the completion routines for the desfire card operations*/
2781    NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process;
2782    NdefMap->MapCompletionInfo.Context = NdefMap;
2783
2784    /*Call the Overlapped HAL Transceive function */
2785    status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
2786                                         &NdefMap->MapCompletionInfo,
2787                                         NdefMap->psRemoteDevInfo,
2788                                         NdefMap->Cmd,
2789                                         &NdefMap->psDepAdditionalInfo,
2790                                         NdefMap->SendRecvBuf,
2791                                         NdefMap->SendLength,
2792                                         NdefMap->SendRecvBuf,
2793                                         NdefMap->SendRecvLength);
2794      return (status);
2795
2796}
2797
2798/*!
2799 * \brief Validated manufacturer Details, during the read/write operations.
2800 */
2801
2802static NFCSTATUS   phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap)
2803{
2804    NFCSTATUS status = NFCSTATUS_PENDING;
2805
2806    uint8_t result = 0;
2807
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,
2811                               8));
2812
2813    if ( result != 0)
2814    {
2815        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE);
2816
2817    }
2818    else
2819    {
2820        status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
2821
2822    }
2823    return (status);
2824}
2825
2826static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer,
2827                                              uint8_t StartIndex,
2828                                              uint8_t EndIndex,
2829                                              uint16_t RecvChkSum)
2830{
2831    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
2832    uint16_t CheckSum=0,
2833             BufIndex=0;
2834
2835    for(BufIndex = StartIndex;BufIndex <=EndIndex;BufIndex++)
2836    {
2837        CheckSum += TempBuffer[BufIndex];
2838    }
2839    if( RecvChkSum != CheckSum )
2840    {
2841           Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2842                            NFCSTATUS_INVALID_FORMAT);
2843    }
2844    return (Result);
2845}
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857/*!
2858 * \brief On successful read attribute blk information, this function validates and stores the
2859 * Attribute informations in to the context.
2860 */
2861static NFCSTATUS   phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap)
2862{
2863    NFCSTATUS status = NFCSTATUS_PENDING;
2864    uint8_t   CRFlag = FALSE,
2865              Nmaxb1, Nmaxb2 = 0,
2866              ChkSum1 = 0, ChkSum2=0;
2867
2868    uint16_t  Nmaxblk = 0,
2869              RecvChkSum=0,
2870              NdefBlk = 0;
2871    uint32_t  DataLen =0;
2872
2873
2874    /* Validate T3VNo and NFCDevVNo */
2875    status = phFriNfc_MapTool_ChkSpcVer(NdefMap,
2876                                        PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX);
2877    if ( status != NFCSTATUS_SUCCESS )
2878    {
2879        CRFlag = TRUE;
2880    }
2881    else
2882    {
2883        /* get the Nmaxb from the receive buffer*/
2884        Nmaxb1 = NdefMap->SendRecvBuf[16];
2885        Nmaxb2 = NdefMap->SendRecvBuf[17];
2886
2887        Nmaxblk = (((uint16_t)Nmaxb1 << 8) | (Nmaxb2 & 0x00ff));
2888
2889        if ( Nmaxblk != 0 )
2890        {
2891            /* check the Nbr against the Nmaxb*/
2892            if ( NdefMap->SendRecvBuf[14] > Nmaxblk )
2893            {
2894                CRFlag = TRUE;
2895            }
2896            else
2897            {
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))
2908
2909                {
2910                    CRFlag = TRUE;
2911                }
2912                else
2913                {
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],
2918                                                          DataLen);
2919
2920
2921                    /* Calculate Nbc*/
2922                    NdefBlk = (uint16_t )((( DataLen % 16) == 0 ) ? (DataLen >> 4) : ((DataLen >> 4) +1));
2923
2924                    /* check Nbc against Nmaxb*/
2925                    if ((NdefBlk > Nmaxblk))
2926                    {
2927                        CRFlag = TRUE;
2928                    }
2929                    else
2930                    {
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];
2935
2936                        NdefMap->FelicaAttrInfo.Nmaxb = Nmaxblk;
2937
2938                        NdefMap->FelicaAttrInfo.WriteFlag = NdefMap->SendRecvBuf[22];
2939                        NdefMap->FelicaAttrInfo.RdWrFlag = NdefMap->SendRecvBuf[23];
2940
2941                        /* Get CheckSum*/
2942                        ChkSum1 = NdefMap->SendRecvBuf[27];
2943                        ChkSum2 = NdefMap->SendRecvBuf[28];
2944
2945                        RecvChkSum = (((uint16_t)ChkSum1 << 8) | (ChkSum2 & 0x00ff));
2946
2947                        /* Check the check sum validity?*/
2948                        status = phFriNfc_Felica_HCalCheckSum(NdefMap->SendRecvBuf,
2949                                                              PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX,
2950                                                              26,
2951                                                              RecvChkSum);
2952                        if ( status != NFCSTATUS_SUCCESS )
2953                        {
2954                            CRFlag = TRUE;
2955                        }
2956                        else
2957                        {
2958                            /*check RW Flag Access Rights*/
2959                            /* set to read only cannot write*/
2960                            if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00 )
2961                            {
2962                                NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
2963                            }
2964                            else if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x01 ) // additional check for R/W access
2965                            {
2966                                NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
2967                            }
2968                            else // otherwise invalid
2969                            {
2970                                NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2971                            }
2972
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);
2977                        }
2978                    }
2979                }
2980            }
2981        }
2982        else
2983        {
2984            CRFlag = TRUE;
2985        }
2986    }
2987    if ( (status == NFCSTATUS_INVALID_FORMAT ) && (CRFlag == TRUE ))
2988    {
2989        NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2990    }
2991    if ( CRFlag == TRUE )
2992    {
2993        /*Return Status Error  Invalid Format*/
2994        status =  PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);
2995    }
2996
2997    return (status);
2998}
2999
3000/*!
3001 * \brief this shall notify the integration software with respective
3002 *  success/error status along with the completion routines.
3003 */
3004static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t  *NdefMap,
3005                                 uint8_t              CrIndex,
3006                                 NFCSTATUS            Status)
3007{
3008    /* set the state back to the Reset_Init state*/
3009    NdefMap->State =  PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
3010
3011    /* set the completion routine*/
3012    NdefMap->CompletionRoutine[CrIndex].
3013        CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);
3014}
3015
3016/*!
3017 * \brief this shall initialise the internal buffer data to zero.
3018 */
3019static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer)
3020{
3021    uint8_t index=0;
3022
3023    for( index = 0; index< 16 ; index++)
3024    {
3025        Buffer[index] = 0;
3026    }
3027}
3028
3029static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n )
3030{
3031    int8_t   diff = 0;
3032    int8_t *char_1  =(int8_t *)s1;
3033    int8_t *char_2  =(int8_t *)s2;
3034    if(NULL == s1 || NULL == s2)
3035    {
3036        PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare");
3037    }
3038    else
3039    {
3040        for(;((n>0)&&(diff==0));n--,char_1++,char_2++)
3041        {
3042            diff = *char_1 - *char_2;
3043        }
3044    }
3045    return (int)diff;
3046}
3047
3048
3049#ifdef UNIT_TEST
3050#include <phUnitTestNfc_Felica_static.c>
3051#endif
3052
3053#endif  /* PH_FRINFC_MAP_FELICA_DISABLED */
3054