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_Desfire.c
19* \brief This component encapsulates read/write/check ndef/process functionalities,
20*        for the Desfire Card.
21*
22* Project: NFC-FRI
23*
24* $Date: Tue Jul 27 08:58:22 2010 $
25* $Author: ing02260 $
26* $Revision: 1.11 $
27* $Aliases:  $
28*
29*/
30
31#ifndef PH_FRINFC_MAP_DESFIRE_DISABLED
32
33#include <phFriNfc_OvrHal.h>
34#include <phFriNfc_DesfireMap.h>
35#include <phFriNfc_MapTools.h>
36
37
38/*! \ingroup grp_file_attributes
39*  \name NDEF Mapping
40*
41* File: \ref phFriNfc_Desfire.c
42*
43*/
44/*@{*/
45#define PHFRINFCNDEFMAP_FILEREVISION "$Revision: 1.11 $"
46#define PHFRINFCNDEFMAP_FILEALIASES  "$Aliases:  $"
47
48/*@}*/
49
50/***************** Start of MACROS ********************/
51#ifdef DESFIRE_EV1
52    #define DESFIRE_EV1_P2_OFFSET_VALUE                         (0x0CU)
53#endif /* #ifdef DESFIRE_EV1 */
54
55/***************** End of MACROS ********************/
56
57/*@}*/
58
59/*!
60 * \name Desfire Mapping - Helper Functions
61 *
62 */
63/*@{*/
64
65/*!
66 * \brief \copydoc page_ovr Helper function for Desfire. This function specifies
67 *  the card is a Desfire card or not.
68 */
69static NFCSTATUS phFriNfc_Desfire_SelectSmartTag(  phFriNfc_NdefMap_t  *NdefMap);
70
71/*!
72 * \brief \copydoc page_ovr Helper function for Desfire. This function is used
73 *  to selct a file in the card.
74 */
75static NFCSTATUS phFriNfc_Desfire_SelectFile ( phFriNfc_NdefMap_t  *NdefMap);
76
77/*!
78 * \brief \copydoc page_ovr Helper function for Desfire. This function is to
79 *  read the card.
80 */
81static NFCSTATUS  phFriNfc_Desfire_ReadBinary( phFriNfc_NdefMap_t  *NdefMap);
82
83/*!
84 * \brief \copydoc page_ovr Helper function for Desfire. This function is to
85 *  write to the card.
86 */
87static NFCSTATUS  phFriNfc_Desfire_UpdateBinary(   phFriNfc_NdefMap_t  *NdefMap);
88
89/*!
90 * \brief \copydoc page_ovr Helper function for Desfire. This function is to
91 *  update the capability container of the card.
92 */
93static NFCSTATUS  phFriNfc_Desfire_Update_SmartTagCapContainer( phFriNfc_NdefMap_t *NdefMap);
94
95
96/* Completion Helper*/
97static void phFriNfc_Desfire_HCrHandler(    phFriNfc_NdefMap_t  *NdefMap,
98                                        NFCSTATUS           Status);
99
100/* Calculates the Le Bytes for Read Operation*/
101static uint32_t phFriNfc_Desfire_HGetLeBytes(   phFriNfc_NdefMap_t  *NdefMap);
102
103static NFCSTATUS phFriNfc_Desf_HChkAndParseTLV( phFriNfc_NdefMap_t  *NdefMap,
104                                               uint8_t             BuffIndex);
105
106static NFCSTATUS phFriNfc_Desfire_HSetGet_NLEN( phFriNfc_NdefMap_t  *NdefMap);
107
108static void phFriNfc_Desfire_HProcReadData( phFriNfc_NdefMap_t  *NdefMap);
109
110static void phFriNfc_Desfire_HChkNDEFFileAccessRights(  phFriNfc_NdefMap_t  *NdefMap);
111static NFCSTATUS phFriNfc_Desfire_HSendTransCmd(phFriNfc_NdefMap_t *NdefMap,uint8_t SendRecvLen);
112
113#ifdef PH_HAL4_ENABLE
114
115#else
116
117/* Following are the API's are used to get the version of the desfire card*/
118static NFCSTATUS phFriNfc_Desfire_HGetHWVersion(phFriNfc_NdefMap_t    *NdefMap);
119static NFCSTATUS phFriNfc_Desfire_HGetSWVersion(phFriNfc_NdefMap_t    *NdefMap);
120static NFCSTATUS phFriNfc_Desfire_HGetUIDDetails(phFriNfc_NdefMap_t   *NdefMap);
121static NFCSTATUS phFriNfc_Desfire_HUpdateVersionDetails(const phFriNfc_NdefMap_t *NdefMap);
122
123#endif /* #ifdef PH_HAL4_ENABLE */
124
125#ifdef PH_HAL4_ENABLE
126
127#else
128
129static NFCSTATUS phFriNfc_Desfire_HGetHWVersion(phFriNfc_NdefMap_t    *NdefMap)
130{
131
132    NFCSTATUS status = NFCSTATUS_PENDING;
133
134    /*set the state*/
135    NdefMap->State = PH_FRINFC_DESF_STATE_GET_HW_VERSION;
136
137    /* Helper routine to wrap the native desfire cmds*/
138    PH_FRINFC_DESF_ISO_NATIVE_WRAPPER();
139    status =  phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE);
140
141    return (status);
142}
143
144static NFCSTATUS phFriNfc_Desfire_HGetSWVersion(phFriNfc_NdefMap_t *NdefMap)
145{
146
147    NFCSTATUS status = NFCSTATUS_PENDING;
148    if( ( NdefMap->SendRecvBuf[*(NdefMap->SendRecvLength)- 1] == PH_FRINFC_DESF_NATIVE_GETVER_RESP) )
149    {
150        /*set the state*/
151        NdefMap->State = PH_FRINFC_DESF_STATE_GET_SW_VERSION;
152
153        /* Helper routine to wrap the native desfire commands*/
154        PH_FRINFC_DESF_ISO_NATIVE_WRAPPER();
155        status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE);
156    }
157#ifdef PH_HAL4_ENABLE
158    else
159    {
160        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
161                       NFCSTATUS_INVALID_PARAMETER);
162    }
163#endif /* #ifdef PH_HAL4_ENABLE */
164    return status;
165}
166
167static NFCSTATUS phFriNfc_Desfire_HGetUIDDetails(phFriNfc_NdefMap_t *NdefMap)
168{
169
170    NFCSTATUS status = NFCSTATUS_PENDING;
171
172    if( ( NdefMap->SendRecvBuf[*(NdefMap->SendRecvLength)- 1] == PH_FRINFC_DESF_NATIVE_GETVER_RESP) )
173    {
174        /*set the state*/
175        NdefMap->State = PH_FRINFC_DESF_STATE_GET_UID;
176
177        /* Helper routine to wrap the native desfire commands*/
178        PH_FRINFC_DESF_ISO_NATIVE_WRAPPER();
179
180        status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE);
181    }
182#ifdef PH_HAL4_ENABLE
183    else
184    {
185        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
186                       NFCSTATUS_INVALID_PARAMETER);
187    }
188#endif /* #ifdef PH_HAL4_ENABLE */
189    return status;
190
191}
192
193static NFCSTATUS phFriNfc_Desfire_HUpdateVersionDetails(const phFriNfc_NdefMap_t *NdefMap)
194{
195    NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
196                       NFCSTATUS_INVALID_PARAMETER);
197
198    if( ( NdefMap->SendRecvBuf[*(NdefMap->SendRecvLength)- 1] == 0xAF) )
199    {
200
201        status = NFCSTATUS_SUCCESS;
202
203        /* We do not need the following details presently.Retained for future use*/
204        #if 0
205        NdefMap->AddInfo.Type4Info.MajorVersion = NdefSmtCrdFmt->SendRecvBuf[3];
206        NdefMap->AddInfo.Type4Info.MinorVersion = NdefSmtCrdFmt->SendRecvBuf[4];
207        if ( ( NdefMap->AddInfo.Type4Info.MajorVersion == 0x00 )&&
208            ( NdefMap->AddInfo.Type4Info.MinorVersion == 0x06 ))
209        {
210            /* card size of DESFire4 type */
211            //NdefMap->AddInfo.Type4Info.CardSize = 0xEDE;
212
213        }
214        else
215        {
216            // need to handle the Desfire8 type cards
217            // need to use get free memory
218        }
219        #endif
220    }
221    return status;
222}
223
224
225#endif /* #ifdef PH_HAL4_ENABLE */
226
227/*!
228* \brief Initiates Reading of NDEF information from the Desfire Card.
229*
230* The function initiates the reading of NDEF information from a Remote Device.
231* It performs a reset of the state and starts the action (state machine).
232* A periodic call of the \ref phFriNfcNdefMap_Process has to be
233* done once the action has been triggered.
234*/
235
236NFCSTATUS phFriNfc_Desfire_RdNdef(  phFriNfc_NdefMap_t  *NdefMap,
237                                  uint8_t             *PacketData,
238                                  uint32_t            *PacketDataLength,
239                                  uint8_t             Offset)
240{
241    NFCSTATUS   status = NFCSTATUS_PENDING;
242
243    NdefMap->ApduBufferSize = *PacketDataLength;
244    /*  To return actual number of bytes read to the caller */
245    NdefMap->NumOfBytesRead = PacketDataLength ;
246    *NdefMap->NumOfBytesRead = 0;
247
248    /* store the offset in to map context*/
249    NdefMap->Offset = Offset;
250
251    if( (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
252        (*NdefMap->DataCount == NdefMap->DesfireCapContainer.NdefDataLen))
253    {
254        /*  No space on card for Reading : we have already
255        reached the end of file !
256        Offset is set to Continue Operation */
257        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
258            NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
259    }
260    else
261    {
262
263        /* reset the inter flag*/
264        NdefMap->DesfireCapContainer.IsNlenPresentFlag = 0;
265        NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 0;
266
267        /*  Set the desfire read operation  */
268        NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_READ_OP;
269
270        /*  Save the packet data buffer address in the context  */
271        NdefMap->ApduBuffer = PacketData;
272
273        NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
274
275#ifdef DESFIRE_EV1
276        /* Select smart tag operation. First step for the read operation. */
277        if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)
278        {
279            status = phFriNfc_Desfire_SelectFile(NdefMap);
280        }
281        else
282#endif /* #ifdef DESFIRE_EV1 */
283        {
284            status = phFriNfc_Desfire_SelectSmartTag(NdefMap);
285        }
286    }
287
288    return status;
289}
290
291/*!
292* \brief Initiates Writing of NDEF information to the Remote Device.
293*
294* The function initiates the writing of NDEF information to a Remote Device.
295* It performs a reset of the state and starts the action (state machine).
296* A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
297* has been triggered.
298*/
299
300NFCSTATUS phFriNfc_Desfire_WrNdef(  phFriNfc_NdefMap_t  *NdefMap,
301                                  uint8_t             *PacketData,
302                                  uint32_t            *PacketDataLength,
303                                  uint8_t             Offset)
304{
305    NFCSTATUS   status = NFCSTATUS_PENDING;
306
307    NdefMap->ApduBufferSize = *PacketDataLength;
308    NdefMap->WrNdefPacketLength = PacketDataLength;
309
310    /*  Now, let's initialize     *NdefMap->WrNdefPacketLength    to zero.
311    In case we get an error, this will be correctly set to "no byte written".
312    In case there is no error, this will be updated later on, in the _process function.
313    */
314    *NdefMap->WrNdefPacketLength =   0;
315
316    /*  we have write access. */
317    if( *NdefMap->DataCount >= PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE)
318    {
319        /*  No space on card for writing : we have already
320        reached the end of file !
321        Offset is set to Continue Operation */
322        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
323            NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
324    }
325    else
326    {
327        /*  Adapt the nb of bytes that the user would like to write */
328
329        /*set the defire write operation*/
330        NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_WRITE_OP;
331        NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
332        NdefMap->Offset = Offset;
333
334        /*Store the packet data buffer*/
335        NdefMap->ApduBuffer = PacketData;
336
337#ifdef DESFIRE_EV1
338        if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)
339        {
340            status = phFriNfc_Desfire_SelectFile(NdefMap);
341        }
342        else
343#endif /* #ifdef DESFIRE_EV1 */
344        {
345            /* Select smart tag operation. First step for the write operation. */
346            status = phFriNfc_Desfire_SelectSmartTag (NdefMap);
347        }
348    }
349    return status;
350}
351
352/*!
353* \brief Check whether a particular Remote Device is NDEF compliant.
354*
355* The function checks whether the peer device is NDEF compliant.
356*
357*/
358
359NFCSTATUS phFriNfc_Desfire_ChkNdef( phFriNfc_NdefMap_t     *NdefMap)
360{
361    NFCSTATUS    status = NFCSTATUS_PENDING;
362
363#ifdef PH_HAL4_ENABLE
364
365#ifdef DESFIRE_EV1
366    /* Reset card type */
367    NdefMap->CardType = 0;
368#endif /* #ifdef DESFIRE_EV1 */
369	/*Set the desfire operation flag*/
370	NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP;
371
372    /*Call Select Smart tag Functinality*/
373    status = phFriNfc_Desfire_SelectSmartTag(NdefMap);
374#else
375	/* Need to get the version details of the card, to
376	   identify the the desfire4card type */
377	status = phFriNfc_Desfire_HGetHWVersion(NdefMap);
378#endif
379
380    return (status);
381}
382
383static NFCSTATUS phFriNfc_Desf_HChkAndParseTLV(phFriNfc_NdefMap_t     *NdefMap, uint8_t BuffIndex)
384{
385    NFCSTATUS    status = NFCSTATUS_SUCCESS;
386
387    if((NdefMap->SendRecvBuf[BuffIndex] <= 0x03) ||
388        (NdefMap->SendRecvBuf[BuffIndex] >= 0x06) )
389    {
390        status =  PHNFCSTVAL(   CID_FRI_NFC_NDEF_MAP,
391            NFCSTATUS_NO_NDEF_SUPPORT);
392    }
393    else
394    {
395        /* check for the type of TLV*/
396        NdefMap->TLVFoundFlag =
397            ((NdefMap->SendRecvBuf[BuffIndex] == 0x04)?
398            PH_FRINFC_NDEFMAP_DESF_NDEF_CNTRL_TLV:
399            PH_FRINFC_NDEFMAP_DESF_PROP_CNTRL_TLV);
400
401        status =  PHNFCSTVAL(   CID_FRI_NFC_NDEF_MAP,
402            NFCSTATUS_SUCCESS);
403    }
404    return status;
405}
406
407static NFCSTATUS    phFriNfc_Desfire_HSetGet_NLEN(phFriNfc_NdefMap_t *NdefMap)
408{
409
410    NFCSTATUS    status = NFCSTATUS_PENDING;
411
412    if ( PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP == NdefMap->DespOpFlag)
413    {
414
415        /*Call Select Smart tag Functinality*/
416        status = phFriNfc_Desfire_SelectSmartTag(NdefMap);
417    }
418    else
419    {
420
421        /* Get the Data Count and set it to NoOfBytesWritten
422        Update the NLEN using Transceive cmd*/
423
424        /*Form the packet for the update binary command*/
425        NdefMap->SendRecvBuf[0] = 0x00;
426        NdefMap->SendRecvBuf[1] = 0xD6;
427
428        /* As we need to set the NLEN @ first 2 bytes of NDEF File*/
429        /* set the p1/p2 offsets */
430        NdefMap->SendRecvBuf[2] = 0x00; /* p1 */
431        NdefMap->SendRecvBuf[3] = 0x00; /* p2 */
432
433        /* Set only two bytes as NLEN*/
434        NdefMap->SendRecvBuf[4] = 0x02;
435
436        /* update NLEN */
437        NdefMap->SendRecvBuf[5] = (uint8_t)(*NdefMap->DataCount >> PH_FRINFC_NDEFMAP_DESF_SHL8);
438        NdefMap->SendRecvBuf[6] = (uint8_t)(*NdefMap->DataCount & (0x00ff));
439
440        NdefMap->SendLength = 0x07 ;
441
442        /* Change the state to Write */
443        NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_END;
444
445        status =  phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET);
446    }
447    return status;
448}
449
450static void phFriNfc_Desfire_HProcReadData(phFriNfc_NdefMap_t *NdefMap)
451{
452    NFCSTATUS   Result = NFCSTATUS_PENDING;
453    uint32_t    BufferSize = 0;
454    uint8_t     BufIndex=0;
455    uint16_t    SizeToCpy=0;
456
457    /* Need to check the Actual Ndef Length before copying the data to buffer*/
458    /* Only NDEF data should be copied , rest all the data should be ignored*/
459    /* Ex : Ndef File Size 50 bytes , but only 5 bytes(NLEN) are relavent to NDEF data*/
460    /* component should only copy 5 bytes to user buffer*/
461
462    /*  Data has been read successfully in the TRX buffer. */
463    /*  copy it to the user buffer. */
464
465    /* while copying need check the offset if its begin need to skip the first 2 bytes
466    while copying. If its current no need to skip the first 2 bytes*/
467
468    if ( NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )
469    {
470        BufIndex = (uint8_t)(( NdefMap->DesfireCapContainer.IsNlenPresentFlag == 1 )?
471            0:PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES);
472
473        /* Update the latest NLEN to context*/
474        NdefMap->DesfireCapContainer.NdefDataLen = ((*NdefMap->DataCount == 0)?
475            ( (((uint16_t)NdefMap->SendRecvBuf[
476                PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_FIRST_INDEX])<<8)+ \
477                    NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_SECOND_INDEX]):
478                NdefMap->DesfireCapContainer.NdefDataLen);
479
480        /* Decide how many byes to be copied into user buffer: depending upon the actual NDEF
481           size need to copy the content*/
482        if ( (NdefMap->DesfireCapContainer.NdefDataLen) <= (*NdefMap->SendRecvLength - \
483            (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET + BufIndex)))
484        {
485            SizeToCpy = NdefMap->DesfireCapContainer.NdefDataLen;
486
487        }
488        else
489        {
490            SizeToCpy = ((*NdefMap->SendRecvLength)-(PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET+BufIndex));
491        }
492
493        /* Check do we have Ndef Data len > 0 present in the card.If No Ndef Data
494        present in the card , set the card state to Initalised and set an Error*/
495        if ( NdefMap->DesfireCapContainer.NdefDataLen == 0x00 )
496        {
497            NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
498            Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
499#ifdef PH_HAL4_ENABLE
500#else
501            NdefMap->PrevOperation = 0;
502#endif /* #ifdef PH_HAL4_ENABLE */
503            phFriNfc_Desfire_HCrHandler(NdefMap,Result);
504        }
505        else
506        {
507            (void)memcpy( (&(NdefMap->ApduBuffer[
508            NdefMap->ApduBuffIndex])),
509            (&(NdefMap->SendRecvBuf[BufIndex])),
510            (SizeToCpy));
511
512            /*  Increment the Number of Bytes Read, which will be returned to the caller. */
513            *NdefMap->NumOfBytesRead = (uint32_t)(*NdefMap->NumOfBytesRead + SizeToCpy);
514
515            /*update the data count*/
516            *NdefMap->DataCount = (uint16_t)(*NdefMap->DataCount + SizeToCpy);
517
518            /*update the buffer index of the apdu buffer*/
519            NdefMap->ApduBuffIndex = (uint16_t)(NdefMap->ApduBuffIndex + SizeToCpy);
520        }
521    }
522    else
523    {
524            (void)memcpy( (&(NdefMap->ApduBuffer[
525            NdefMap->ApduBuffIndex])),
526                (NdefMap->SendRecvBuf),/* to avoid the length of the NDEF File*/
527                (*(NdefMap->SendRecvLength)-(PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET)));
528
529            /*  Increment the Number of Bytes Read, which will be returned to the caller. */
530            *NdefMap->NumOfBytesRead +=( *NdefMap->SendRecvLength - \
531                (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET));
532
533            /*update the data count*/
534            *NdefMap->DataCount += \
535                (*NdefMap->SendRecvLength - (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET));
536
537            /*update the buffer index of the apdu buffer*/
538            NdefMap->ApduBuffIndex += \
539                *NdefMap->SendRecvLength - (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET );
540    }
541
542    /*  check whether we still have to read some more data. */
543    if (*NdefMap->DataCount < NdefMap->DesfireCapContainer.NdefDataLen )
544    {
545        /*  we have some bytes to read. */
546
547        /*  Now check, we still have bytes left in the user buffer. */
548        BufferSize = NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex;
549        if(BufferSize != 0)
550        {
551            /* Before read need to set the flag to intimate the module to
552            dont skip the first 2 bytes as we are in mode reading next
553            continues available bytes, which will not contain the NLEN
554            information in the begining part that is 2 bytes*/
555            NdefMap->DesfireCapContainer.IsNlenPresentFlag = 1;
556            /* Read Operation is not complete */
557            Result = phFriNfc_Desfire_ReadBinary( NdefMap );
558            /* handle the error in Transc function*/
559            if  ( (Result & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER) )
560            {
561                /* call respective CR */
562                phFriNfc_Desfire_HCrHandler(NdefMap,Result);
563            }
564        }
565        else
566        {
567            /*  There are some more bytes to read, but
568            no space in the user buffer */
569            Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
570            NdefMap->ApduBuffIndex =0;
571            /* call respective CR */
572            phFriNfc_Desfire_HCrHandler(NdefMap,Result);
573        }
574    }
575    else
576    {
577        if (*NdefMap->DataCount == NdefMap->DesfireCapContainer.NdefDataLen )
578        {
579            /*  we have read all the bytes available in the card. */
580            Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
581#ifdef PH_HAL4_ENABLE
582            /* Do nothing */
583#else
584            NdefMap->PrevOperation = 0;
585#endif /* #ifndef PH_HAL4_ENABLE */
586        }
587        else
588        {
589            /*  The control should not come here. */
590            /*  we have actually read more byte than available in the card. */
591            NdefMap->PrevOperation = 0;
592#ifndef PH_HAL4_ENABLE
593            Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
594                NFCSTATUS_CMD_ABORTED);
595#else
596            Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
597                NFCSTATUS_FAILED);
598#endif
599        }
600
601
602        NdefMap->ApduBuffIndex = 0;
603
604        /* call respective CR */
605        phFriNfc_Desfire_HCrHandler(NdefMap,Result);
606    }
607}
608
609
610
611/*!
612* \brief Completion Routine, Processing function, needed to avoid long blocking.
613* \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
614*       Routine in order to be able to notify the component that an I/O has finished and data are
615*       ready to be processed.
616*
617*/
618
619void phFriNfc_Desfire_Process(void       *Context,
620                              NFCSTATUS   Status)
621{
622    /*Set the context to Map Module*/
623    phFriNfc_NdefMap_t  *NdefMap = (phFriNfc_NdefMap_t *)Context;
624    uint8_t             ErrFlag = 0;
625    uint16_t            NLength = 0,
626                        SendRecLen=0;
627    uint32_t            BytesRead = 0;
628
629
630    /*  Sujatha P: Fix for 0000255/0000257:[gk] MAP:Handling HAL Errors */
631    if ( Status == NFCSTATUS_SUCCESS )
632    {
633        switch (NdefMap->State)
634        {
635
636#ifdef PH_HAL4_ENABLE
637#else
638
639            case PH_FRINFC_DESF_STATE_GET_HW_VERSION :
640
641                /* Check and store the h/w and s/w specific details.
642                Ex: Major/Minor version, memory storage info. */
643                Status = phFriNfc_Desfire_HGetSWVersion(NdefMap);
644
645                /* handle the error in Transc function*/
646                if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
647                {
648                    /* call respective CR */
649                    phFriNfc_Desfire_HCrHandler(NdefMap,Status);
650                }
651
652                break;
653
654            case PH_FRINFC_DESF_STATE_GET_SW_VERSION :
655
656                /* Check and store the h/w and s/w specific details.
657                Ex: Major/Minor version, memory storage info. */
658
659                Status = phFriNfc_Desfire_HUpdateVersionDetails(NdefMap);
660                if ( Status == NFCSTATUS_SUCCESS )
661                {
662                    Status = phFriNfc_Desfire_HGetUIDDetails(NdefMap);
663                    /* handle the error in Transc function*/
664                    if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
665                    {
666                        /* call respective CR */
667                        phFriNfc_Desfire_HCrHandler(NdefMap,Status);
668                    }
669                }
670
671                break;
672
673            case PH_FRINFC_DESF_STATE_GET_UID :
674
675                /*Set the desfire operation flag*/
676                NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP;
677
678                /*Call Select Smart tag Functinality*/
679                Status = phFriNfc_Desfire_SelectSmartTag(NdefMap);
680
681                break;
682#endif /* #ifdef PH_HAL4_ENABLE */
683
684#ifdef DESFIRE_EV1
685            case PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG_EV1:
686            {
687                if(( NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength) - 2)] ==
688                    PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&
689                    (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength) - 1)] ==
690                    PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))
691                {
692                    NdefMap->CardType = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1;
693
694                    Status = phFriNfc_Desfire_SelectFile(NdefMap);
695
696                    /* handle the error in Transc function*/
697                    if ((Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
698                    {
699                        /* call respective CR */
700                        phFriNfc_Desfire_HCrHandler(NdefMap,Status);
701                    }
702                }
703                else
704                {
705                    NdefMap->CardType = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD;
706                    /* The card is not the new desfire, so send select smart tag command
707                    of the old desfire */
708                    Status = phFriNfc_Desfire_SelectSmartTag(NdefMap);
709
710
711                }
712                break;
713            }
714#endif /* #ifdef DESFIRE_EV1 */
715
716        case PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG:
717#ifdef DESFIRE_EV1
718            if(( NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength) - 2)] ==
719                    PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&
720                    (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength) - 1)] ==
721                    PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))
722#else
723            if(( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] ==
724                PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&
725                (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] ==
726                PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))
727#endif /* #ifdef DESFIRE_EV1 */
728            {
729                Status = phFriNfc_Desfire_SelectFile(NdefMap);
730
731                /* handle the error in Transc function*/
732                if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
733                {
734                    /* call respective CR */
735                    phFriNfc_Desfire_HCrHandler(NdefMap,Status);
736                }
737            }
738            else
739            {
740                /*Error " Smart Tag Functionality Not Supported"*/
741                Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
742                    NFCSTATUS_SMART_TAG_FUNC_NOT_SUPPORTED);
743#ifdef DESFIRE_EV1
744                NdefMap->CardType = 0;
745#endif /* #ifdef DESFIRE_EV1 */
746
747                /* call respective CR */
748                phFriNfc_Desfire_HCrHandler(NdefMap,Status);
749
750            }
751
752            break;
753
754        case PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_FILE :
755
756            if(( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&
757                (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))
758            {
759                /*check for the which operation */
760                if( (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_READ_OP) ||
761                    (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP) ||
762                    (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP ))
763                {
764                    /* call for read binary operation*/
765                    Status = phFriNfc_Desfire_ReadBinary(NdefMap);
766
767                    /* handle the error in Transc function*/
768                    if  ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER) )
769                    {
770                        /* call respective CR */
771                        phFriNfc_Desfire_HCrHandler(NdefMap,Status);
772                    }
773                }
774                /*its a write Operation*/
775                else if(NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_WRITE_OP )
776                {
777                    Status = phFriNfc_Desfire_UpdateBinary (NdefMap);
778                    /* handle the error in Transc function*/
779                    if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
780                    {
781                        /* call respective CR */
782                        phFriNfc_Desfire_HCrHandler(NdefMap,Status);
783                    }
784                }
785                else
786                {
787                    /* unknown/invalid desfire operations*/
788                    Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
789                        NFCSTATUS_INVALID_REMOTE_DEVICE);
790
791                    /* call respective CR */
792                    phFriNfc_Desfire_HCrHandler(NdefMap,Status);
793                }
794            }
795            else
796            {
797                /*return Error " Select File Operation Failed"*/
798                Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
799                    NFCSTATUS_INVALID_REMOTE_DEVICE);
800
801                /* call respective CR */
802                phFriNfc_Desfire_HCrHandler(NdefMap,Status);
803            }
804            break;
805
806        case PH_FRINFC_NDEFMAP_DESF_STATE_READ_CAP_CONT:
807            if( (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength)-2)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&
808                (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength)-1)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))
809            {
810                /*  Read successful. */
811                /*Update the smart tag capability container*/
812                Status = phFriNfc_Desfire_Update_SmartTagCapContainer(NdefMap);
813
814                if ( Status == NFCSTATUS_SUCCESS)
815                {
816                    NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP;
817#ifdef DESFIRE_EV1
818                    if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)
819                    {
820                        Status = phFriNfc_Desfire_SelectFile(NdefMap);
821                    }
822                    else
823#endif /* #ifdef DESFIRE_EV1 */
824                    {
825                        Status = phFriNfc_Desfire_HSetGet_NLEN(NdefMap);
826                    }
827                    /* handle the error in Transc function*/
828                    if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
829                    {
830                        /* call respective CR */
831                        phFriNfc_Desfire_HCrHandler(NdefMap,Status);
832                    }
833                }
834                else
835                {
836                    /* call respective CR */
837                    phFriNfc_Desfire_HCrHandler(NdefMap,Status);
838
839                }
840
841            }
842            else
843            {
844                /*return Error " Capability Container Not Found"*/
845                Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
846                    NFCSTATUS_INVALID_REMOTE_DEVICE);
847                /* call respective CR */
848                phFriNfc_Desfire_HCrHandler(NdefMap,Status);
849            }
850            break;
851
852        case  PH_FRINFC_NDEFMAP_DESF_STATE_READ_BIN:
853
854            /* Check how many bytes have been read/returned from the card*/
855            BytesRead = phFriNfc_Desfire_HGetLeBytes(NdefMap);
856
857            /* set the send recev len*/
858            SendRecLen = *NdefMap->SendRecvLength - (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET );
859            if ( (NdefMap->DesfireCapContainer.SkipNlenBytesFlag  == 1) && ((BytesRead == 1) || (BytesRead == 2 )))
860            {
861                BytesRead += PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES; /* to take care of first 2 len bytes*/
862
863            }
864            else
865            {
866                /* Nothing to process*/
867                ;
868            }
869            /* Read More Number Of Bytes than Expected*/
870            if ( ( BytesRead == SendRecLen ) &&
871                ((NdefMap->SendRecvBuf[(*NdefMap->SendRecvLength-2)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&
872                (NdefMap->SendRecvBuf[(*NdefMap->SendRecvLength-1)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE)))
873
874            {
875                /* this is to check the card state in first Read Operation*/
876                if ( NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP )
877                {
878                    /* check the actual length of the ndef data : NLEN*/
879                    NLength = ( (((uint16_t)NdefMap->SendRecvBuf[0])<<PH_FRINFC_NDEFMAP_DESF_SHL8)+ \
880                        NdefMap->SendRecvBuf[1]);
881                    if (( NLength > PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE )||
882                        ( NLength == 0xFFFF))
883                    {
884                        ErrFlag = 1;
885                        Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
886                            NFCSTATUS_NO_NDEF_SUPPORT);
887                    }
888                    else
889                    {
890                        /* Store the NLEN into the context  */
891                        NdefMap->DesfireCapContainer.NdefDataLen = NLength;
892
893                        Status = phFriNfc_MapTool_SetCardState( NdefMap,
894                            NLength);
895                        if ( Status == NFCSTATUS_SUCCESS )
896                        {
897                            /*Set the card type to Desfire*/
898#ifndef DESFIRE_EV1
899                            NdefMap->CardType = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD;
900#endif /* #ifdef DESFIRE_EV1 */
901                            /*Set the state to specify True for Ndef Compliant*/
902                            NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_CHK_NDEF;
903
904                            /*set the data count back to zero*/;
905                            *NdefMap->DataCount = 0;
906                            /*set the apdu buffer index to zero*/
907                            NdefMap->ApduBuffIndex = 0;
908                            /* Set the Operationg flag to Complete check NDEF Operation*/
909                            NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP;
910
911                        }
912                         /* call respective CR */
913                        phFriNfc_Desfire_HCrHandler(NdefMap,Status);
914                    }/* End ofNdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP*/
915                }
916                else if ( NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_READ_OP )
917                {
918                    phFriNfc_Desfire_HProcReadData(NdefMap);
919                }
920                else
921                {
922                    /* Invalid Desfire Operation  */
923                    Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
924                        NFCSTATUS_INVALID_REMOTE_DEVICE);
925                    phFriNfc_Desfire_HCrHandler(NdefMap,Status);
926                }
927
928            }
929            else
930            {
931                /*handle the  Error case*/
932                Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
933                    NFCSTATUS_READ_FAILED);
934                ErrFlag =1;
935            }
936            if( ErrFlag == 1)
937            {
938                *NdefMap->DataCount = 0;
939
940                /*set the buffer index back to zero*/
941                NdefMap->ApduBuffIndex = 0;
942
943                /* call respective CR */
944                phFriNfc_Desfire_HCrHandler(NdefMap,Status);
945            }
946
947            break;
948
949        case  PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_BEGIN:
950            if( (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&
951                (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))
952            {
953                /*  Write operation was successful. */
954                /*  NdefMap->NumOfBytesWritten have been written on to the card.
955                Update the DataCount and the ApduBufferIndex */
956                *NdefMap->DataCount = (uint16_t)(*NdefMap->DataCount +
957                                                NdefMap->NumOfBytesWritten);
958                NdefMap->ApduBuffIndex = (uint16_t)(NdefMap->ApduBuffIndex +
959                                                NdefMap->NumOfBytesWritten);
960
961                /*  Update the user-provided buffer size to write */
962                *NdefMap->WrNdefPacketLength += NdefMap->NumOfBytesWritten;
963
964                /*  Call Upadte Binary function to check if some more bytes are to be written. */
965                Status = phFriNfc_Desfire_UpdateBinary( NdefMap );
966            }
967            else
968            {
969                /*handle the  Error case*/
970                Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
971                    NFCSTATUS_WRITE_FAILED);
972
973                /*set the buffer index back to zero*/
974                NdefMap->ApduBuffIndex = 0;
975
976                /* call respective CR */
977                phFriNfc_Desfire_HCrHandler(NdefMap,Status);
978            }
979            break;
980        case PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_END :
981            if((NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&
982                (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))
983            {
984                /*  Updating NLEN operation was successful. */
985                /* Entire Write Operation is complete*/
986                /*  Reset the relevant parameters. */
987                Status = PHNFCSTVAL(CID_NFC_NONE,\
988                    NFCSTATUS_SUCCESS);
989
990                /* set the state & Data len into context*/
991                NdefMap->CardState = (uint8_t)((NdefMap->CardState ==
992                                            PH_NDEFMAP_CARD_STATE_INITIALIZED)?
993                                            PH_NDEFMAP_CARD_STATE_READ_WRITE :
994                                            NdefMap->CardState);
995
996                NdefMap->DesfireCapContainer.NdefDataLen = (uint16_t)(*NdefMap->WrNdefPacketLength);
997#ifdef PH_HAL4_ENABLE
998            /* Do nothing */
999#else
1000                NdefMap->PrevOperation = 0;
1001#endif /* #ifndef PH_HAL4_ENABLE */
1002
1003            }
1004            else
1005            {
1006                NdefMap->PrevOperation = 0;
1007                /*handle the  Error case*/
1008                Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
1009                    NFCSTATUS_WRITE_FAILED);
1010            }
1011
1012            /*set the buffer index back to zero*/
1013            NdefMap->ApduBuffIndex = 0;
1014
1015            /* call respective CR */
1016            phFriNfc_Desfire_HCrHandler(NdefMap,Status);
1017            break;
1018
1019        default:
1020            /*define the invalid state*/
1021            Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
1022                NFCSTATUS_INVALID_DEVICE_REQUEST);
1023            phFriNfc_Desfire_HCrHandler(NdefMap,Status);
1024            break;
1025        }
1026    }
1027    else
1028    {
1029        /* call respective CR */
1030        phFriNfc_Desfire_HCrHandler(NdefMap,Status);
1031    }
1032}
1033
1034
1035
1036/*!
1037* \brief this shall select the smart tag functinality of the Desfire card.
1038*
1039* Only when this command returns command completed it is a Smart Tag
1040* compatible product.
1041*
1042*/
1043static
1044NFCSTATUS   phFriNfc_Desfire_SelectSmartTag(phFriNfc_NdefMap_t *NdefMap)
1045{
1046
1047    NFCSTATUS                   status = NFCSTATUS_PENDING;
1048#ifdef DESFIRE_EV1
1049    uint8_t                     card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1;
1050#endif /* #ifdef DESFIRE_EV1 */
1051
1052    /*form the packet for Select smart tag command*/
1053    NdefMap->SendRecvBuf[0]  = 0x00; /* cls */
1054    NdefMap->SendRecvBuf[1]  = 0xa4; /* ins */
1055    NdefMap->SendRecvBuf[2]  = 0x04; /* p1 */
1056    NdefMap->SendRecvBuf[3]  = 0x00; /* p2 */
1057    NdefMap->SendRecvBuf[4]  = 0x07; /* lc */
1058
1059    /* next 7 bytes specify the DF Name*/
1060    NdefMap->SendRecvBuf[5]  = 0xd2;
1061    NdefMap->SendRecvBuf[6]  = 0x76;
1062    NdefMap->SendRecvBuf[7]  = 0x00;
1063    NdefMap->SendRecvBuf[8]  = 0x00;
1064    NdefMap->SendRecvBuf[9]  = 0x85;
1065    NdefMap->SendRecvBuf[10] = 0x01;
1066
1067#ifdef DESFIRE_EV1
1068
1069    switch (NdefMap->DespOpFlag)
1070    {
1071        case PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP:
1072        {
1073            /* First select the smart tag using the new desfire EV1 and increment the
1074                "sel_index" and if it fails then try the old desfire select smart tag
1075                command */
1076            if (0 == NdefMap->CardType)
1077            {
1078                /* p2
1079                NdefMap->SendRecvBuf[3]  = DESFIRE_EV1_P2_OFFSET_VALUE; */
1080                NdefMap->SendRecvBuf[11] = 0x01;
1081                /* Le */
1082                NdefMap->SendRecvBuf[12] = 0x00;
1083                NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG_EV1;
1084                card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1;
1085            }
1086            else
1087            {
1088                NdefMap->SendRecvBuf[3]  = 0x00; /* p2 */
1089                NdefMap->SendRecvBuf[11] = 0x00;
1090                NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG;
1091                card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD;
1092            }
1093            break;
1094        }
1095
1096        case PH_FRINFC_NDEFMAP_DESF_READ_OP:
1097        default :
1098        {
1099            if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)
1100            {
1101                NdefMap->SendRecvBuf[11] = 0x01;
1102                NdefMap->SendRecvBuf[12] = 0x00;
1103                NdefMap->State = (uint8_t)PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG_EV1;
1104                card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1;
1105            }
1106            else
1107            {
1108                NdefMap->SendRecvBuf[11] = 0x00;
1109                NdefMap->State = (uint8_t)PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG;
1110                card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD;
1111            }
1112            break;
1113        }
1114    }
1115
1116#else /* #ifdef DESFIRE_EV1 */
1117
1118    NdefMap->SendRecvBuf[11] = 0x00;
1119
1120#endif /* #ifdef DESFIRE_EV1 */
1121
1122    /*Set the Send length*/
1123    NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_SMARTTAG_PKT_SIZE;
1124#ifdef DESFIRE_EV1
1125
1126    if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == card_type)
1127    {
1128        /* Send length is updated for the NEW DESFIRE EV1 */
1129        NdefMap->SendLength = (uint16_t)(NdefMap->SendLength + 1);
1130    }
1131
1132#else
1133    /* Change the state to Select Smart Tag */
1134    NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG;
1135#endif /* #ifdef DESFIRE_EV1 */
1136
1137    status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET);
1138
1139    return status;
1140}
1141
1142/*!
1143* \brief this shall select/access the capability container of the Desfire
1144* card.
1145*
1146* This shall be used to identify, if NDEF data structure do exist on
1147* the smart tag, we receive command completed status.
1148*
1149*/
1150static
1151NFCSTATUS phFriNfc_Desfire_SelectFile (phFriNfc_NdefMap_t  *NdefMap)
1152{
1153
1154    NFCSTATUS                   status = NFCSTATUS_PENDING;
1155
1156    /* check for the invalid/unknown desfire operations*/
1157    if ((NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP)&& \
1158        (NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_READ_OP)&&\
1159        ( NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_WRITE_OP) &&
1160        ( NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP))
1161    {
1162        status  =   PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE);
1163    }
1164    else
1165    {
1166
1167        /*  Set the command*/
1168        //NdefMap->Cmd.Iso144434Cmd = phHal_eIso14443_4_CmdListTClCmd;
1169
1170        /*  Form the packet for select file command either for the
1171        Check Ndef/Read/Write functionalities*/
1172        NdefMap->SendRecvBuf[0] = 0x00; /* cls */
1173        NdefMap->SendRecvBuf[1] = 0xa4; /* ins */
1174        NdefMap->SendRecvBuf[2] = 0x00; /* p1 */
1175        NdefMap->SendRecvBuf[3] = 0x00; /* p2 */
1176        NdefMap->SendRecvBuf[4] = 0x02; /* lc */
1177
1178#ifdef DESFIRE_EV1
1179        if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)
1180        {
1181            NdefMap->SendRecvBuf[3]  = DESFIRE_EV1_P2_OFFSET_VALUE; /* p2 */
1182        }
1183#endif /* #ifdef DESFIRE_EV1 */
1184
1185        if ( (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP))
1186
1187        {
1188            /* cap container file identifier*/
1189            NdefMap->SendRecvBuf[5] = 0xe1;
1190            NdefMap->SendRecvBuf[6] = 0x03;
1191        }
1192        /* Mantis entry 0394 fixed */
1193        else
1194        {
1195            NdefMap->SendRecvBuf[5] = (uint8_t)((NdefMap->DesfireCapContainer.NdefMsgFid) >> PH_FRINFC_NDEFMAP_DESF_SHL8);
1196            NdefMap->SendRecvBuf[6] = (uint8_t)((NdefMap->DesfireCapContainer.NdefMsgFid) & (0x00ff));
1197        }
1198        /*Set the Send length*/
1199        NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_SELECT_FILE_PKT_SIZE;
1200
1201        /* Change the state to Select File */
1202        NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_FILE;
1203
1204        status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET);
1205
1206    }
1207
1208    return status;
1209
1210}
1211
1212/*!
1213* \brief this shall read the data from Desfire card.
1214*
1215* This is used in two cases namely Reading the Capability container
1216* data( le == 0 ) and reading the file data.Maximum bytes to be read during
1217* a single read binary is known after the reading the data from the capability
1218* conatainer.
1219*
1220*/
1221static
1222NFCSTATUS  phFriNfc_Desfire_ReadBinary(phFriNfc_NdefMap_t    *NdefMap)
1223{
1224    NFCSTATUS    status = NFCSTATUS_PENDING;
1225    uint32_t     BytesToRead = 0;
1226    uint8_t      BufIndex=0,OperFlag=0;
1227    uint16_t     DataCnt=0;
1228
1229    /* to read the capability container data*/
1230    if (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP )
1231    {
1232        /*specifies capability container shall be read*/
1233        NdefMap->SendRecvBuf[0] = 0x00;
1234        NdefMap->SendRecvBuf[1] = 0xb0;
1235        NdefMap->SendRecvBuf[2] = 0x00; /* p1 */
1236        NdefMap->SendRecvBuf[3] = 0x00; /* p2 */
1237        NdefMap->SendRecvBuf[4] = 0x0F; /* le */
1238
1239        NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_READ_BIN_PKT_SIZE;
1240
1241        /* Change the state to Cap Container Read */
1242        NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_READ_CAP_CONT;
1243
1244        /* set the send receive buffer length*/
1245        OperFlag = 1;
1246    }
1247    /*desfire file read operation*/
1248    else
1249    {
1250        NdefMap->SendRecvBuf[0] = 0x00;
1251        NdefMap->SendRecvBuf[1] = 0xb0;
1252
1253        /*TBD the NLEN bytes*/
1254        if( *NdefMap->DataCount == 0 )
1255        {
1256            /* first read */
1257            /* set the offset p1 and p2*/
1258            NdefMap->SendRecvBuf[2] = 0;
1259            NdefMap->SendRecvBuf[3] = 0;
1260        }
1261        else
1262        {
1263            /* as the p1 of the 8bit is 0, p1 and p2 are used to store the
1264            ofset value*/
1265            DataCnt = *NdefMap->DataCount;
1266            DataCnt += PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES;
1267            NdefMap->SendRecvBuf[2] = (uint8_t)((DataCnt)>> PH_FRINFC_NDEFMAP_DESF_SHL8);
1268            NdefMap->SendRecvBuf[3] = (uint8_t)((DataCnt)& (0x00ff));
1269        }
1270        /* calculate the Le Byte*/
1271        BytesToRead = phFriNfc_Desfire_HGetLeBytes(NdefMap);
1272
1273        if ( NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )
1274        {
1275            /* BufIndex represents the 2 NLEN bytes and decides about the presence of
1276            2 bytes NLEN data*/
1277
1278            BufIndex = (uint8_t)(( NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1 ) ?
1279            PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES:0);
1280
1281            if( ((BytesToRead == 1) || (BytesToRead == 2)) && (NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1))
1282            {
1283                BytesToRead += BufIndex;
1284            }
1285        }
1286
1287        /* set the Le byte*/
1288        /* This following code is true for get nlen  and current offset set*/
1289        NdefMap->SendRecvBuf[4]=(uint8_t) BytesToRead  ;
1290
1291        /* Change the state to Read */
1292        NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_READ_BIN;
1293
1294        /*set the send length*/
1295        NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_READ_BIN_PKT_SIZE;
1296        OperFlag = 2;
1297    }
1298
1299    if (OperFlag == 1 )
1300    {
1301        status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE);
1302    }
1303    else
1304    {
1305        status = phFriNfc_Desfire_HSendTransCmd(NdefMap,(uint8_t)(BytesToRead +PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET));
1306    }
1307    return (status);
1308}
1309
1310/*!
1311* \brief this shall write the data to Desfire card.
1312* Maximum bytes to be written during a single update binary
1313* is known after the reading the data from the capability
1314* conatainer.
1315*
1316* le filed specifes , how many bytes of data to be written to the
1317* Card.
1318*
1319*/
1320static
1321NFCSTATUS  phFriNfc_Desfire_UpdateBinary(phFriNfc_NdefMap_t  *NdefMap)
1322{
1323
1324    NFCSTATUS   status = NFCSTATUS_PENDING;
1325    uint16_t    noOfBytesToWrite = 0, DataCnt=0,
1326        index=0;
1327
1328    /*  Do we have space in the file to write? */
1329    if ( (*NdefMap->DataCount < PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) &&
1330        (NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize))
1331    {
1332        /*  Yes, we have some bytes to write */
1333        /*  Check and set the card memory size , if user sent bytes are more than the
1334        card memory size*/
1335        if( (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >\
1336            (uint16_t)(PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE - *NdefMap->DataCount))
1337        {
1338            NdefMap->ApduBufferSize =( (PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) - (*NdefMap->DataCount + NdefMap->ApduBuffIndex));
1339        }
1340
1341        /*  Now, we have space in the card to write the data, */
1342        /*Form the packet for the update binary command*/
1343        NdefMap->SendRecvBuf[0] = 0x00;
1344        NdefMap->SendRecvBuf[1] = 0xD6;
1345
1346        if( *NdefMap->DataCount == 0)
1347        {
1348            /* set the p1/p2 offsets */
1349            NdefMap->SendRecvBuf[2] = 0x00; /* p1 */
1350            NdefMap->SendRecvBuf[3] = 0x00; /* p2 */
1351            NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 0;
1352        }
1353        else
1354        {
1355            /*  as the p1 of the 8bit is 0, p1 and p2 are used to store the
1356            ofset value*/
1357            /*  This sets card offset in a card for a write operation. + 2 is
1358            added as first 2 offsets represents the size of the NDEF Len present
1359            in the file*/
1360
1361            DataCnt = *NdefMap->DataCount;
1362            DataCnt += PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES;
1363            NdefMap->SendRecvBuf[2] = (uint8_t)((DataCnt)>> PH_FRINFC_NDEFMAP_DESF_SHL8);
1364            NdefMap->SendRecvBuf[3] = (uint8_t)((DataCnt)& (0x00ff));
1365            /* No need to attach 2 NLEN bytes at the begining.
1366            as we have already attached in the first write operation.*/
1367            NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 1;
1368
1369        }
1370
1371        /*  Calculate the bytes to write */
1372        if( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)( NdefMap->DesfireCapContainer.MaxCmdSize ))
1373
1374        {
1375            noOfBytesToWrite = ( ( NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1) ?
1376                NdefMap->DesfireCapContainer.MaxCmdSize :
1377            (NdefMap->DesfireCapContainer.MaxCmdSize - PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES));
1378        }
1379        else
1380        {
1381            /*  Read only till the available buffer space */
1382            noOfBytesToWrite = (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
1383        }
1384
1385        if ( NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )
1386        {
1387            if ( NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1 )
1388            {
1389                index = 5;
1390                /* To Specify the NDEF data len written : updated at the of write cycle*/
1391                NdefMap->SendRecvBuf[4] = (uint8_t)noOfBytesToWrite;
1392            }
1393            else
1394            {
1395                /* Leave space to update NLEN */
1396                NdefMap->SendRecvBuf[5] = 0x00;
1397                NdefMap->SendRecvBuf[6] = 0x00;
1398                index =7;
1399                /* To Specify the NDEF data len written : updated at the of write cycle*/
1400                NdefMap->SendRecvBuf[4] = (uint8_t)noOfBytesToWrite + PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES;
1401            }
1402
1403            /* copy the data to SendRecvBuf from the apdu buffer*/
1404            (void)memcpy( &NdefMap->SendRecvBuf[index],
1405                &NdefMap->ApduBuffer[NdefMap->ApduBuffIndex],
1406                noOfBytesToWrite);
1407            NdefMap->SendLength = (noOfBytesToWrite + index);
1408        }
1409        else
1410        {
1411            NdefMap->SendRecvBuf[4] = (uint8_t)noOfBytesToWrite;
1412
1413            /* copy the data to SendRecvBuf from the apdu buffer*/
1414            (void)memcpy( &NdefMap->SendRecvBuf[5],
1415                &NdefMap->ApduBuffer[NdefMap->ApduBuffIndex],
1416                noOfBytesToWrite);
1417            NdefMap->SendLength = (noOfBytesToWrite + 5);
1418        }
1419
1420        /*  Store the number of bytes being written in the context structure, so that
1421        the parameters can be updated, after a successful write operation. */
1422        NdefMap->NumOfBytesWritten = noOfBytesToWrite;
1423
1424        /* Change the state to Write */
1425        NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_BEGIN;
1426
1427        status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET);
1428
1429    }   /*  if(NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize) */
1430    else
1431    {
1432        if ( (*NdefMap->DataCount == PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) ||
1433            (NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize))
1434        {
1435            /* The NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_SET_LEN_OP is not
1436                required, because the DespOpFlag shall be WRITE_OP
1437                */
1438            /* Update the NLEN Bytes*/
1439#ifdef PH_HAL4_ENABLE
1440            /* Do nothing */
1441#else
1442            NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_SET_LEN_OP;
1443#endif /* #ifdef PH_HAL4_ENABLE */
1444            status = phFriNfc_Desfire_HSetGet_NLEN(NdefMap);
1445        }
1446        else
1447        {
1448            /*  The control should not come here.
1449            wrong internal calculation.
1450            we have actually written more than the space available
1451            in the card ! */
1452#ifndef PH_HAL4_ENABLE
1453            status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1454                NFCSTATUS_CMD_ABORTED);
1455#else
1456            status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1457                NFCSTATUS_FAILED);
1458#endif
1459            /*  Reset the relevant parameters. */
1460            NdefMap->ApduBuffIndex = 0;
1461            NdefMap->PrevOperation = 0;
1462
1463            /* call respective CR */
1464            phFriNfc_Desfire_HCrHandler(NdefMap,status);
1465        }
1466
1467    }
1468    /*  if(*NdefMap->DataCount < PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) */
1469
1470    return status;
1471}
1472
1473
1474static void phFriNfc_Desfire_HChkNDEFFileAccessRights(phFriNfc_NdefMap_t *NdefMap)
1475{
1476    if ( (NdefMap->DesfireCapContainer.ReadAccess  == 0x00) &&
1477        (NdefMap->DesfireCapContainer.WriteAccess == 0x00 ))
1478    {
1479        /* Set the card state to Read/write State*/
1480        /* This state can be either INITIALISED or READWRITE. but default
1481        is INITIALISED */
1482        NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
1483
1484    }
1485    else if((NdefMap->DesfireCapContainer.ReadAccess  == 0x00) &&
1486        (NdefMap->DesfireCapContainer.WriteAccess == 0xFF ))
1487    {
1488        /* Set the card state to Read Only State*/
1489        NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
1490    }
1491    else
1492    {
1493        /* Set the card state to invalid State*/
1494        NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
1495    }
1496}
1497
1498/*!
1499* \brief this shall update the Desfire capability container structure.
1500*
1501* This function shall store version,maximum Ndef data structure size,
1502* Read Access permissions, Write Access permissions , Maximum data size
1503* that can be sent using a single Update Binary, maximum data size that
1504* can be read from the Desfire using a singlr read binary.
1505* These vaues shall be stored and used during the read/update binary
1506* operations.
1507*
1508*/
1509static
1510NFCSTATUS  phFriNfc_Desfire_Update_SmartTagCapContainer(phFriNfc_NdefMap_t    *NdefMap)
1511{
1512    uint16_t    CapContSize = 0,
1513        /* this is initalised 2 because CCLEN includes the field size bytes i.e 2bytes*/
1514        CCLen= 0;
1515    uint8_t     ErrFlag = 0;
1516
1517    NFCSTATUS status= NFCSTATUS_SUCCESS;
1518
1519    /*Check the Size of Cap Container */
1520    CapContSize = ( (((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_FIRST_INDEX])<<8)+ \
1521        NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_SECOND_INDEX]);
1522
1523    CCLen += 2;
1524
1525    if ( (CapContSize < 0x0f) || (CapContSize == 0xffff))
1526    {
1527        ErrFlag =1;
1528    }
1529    else
1530    {
1531        /*Version : Smart Tag Spec version */
1532        /* check for the validity of Major and Minor Version numbers*/
1533        status = phFriNfc_MapTool_ChkSpcVer (   NdefMap,
1534            PH_FRINFC_NDEFMAP_DESF_VER_INDEX);
1535        if ( status  !=  NFCSTATUS_SUCCESS )
1536        {
1537            ErrFlag =1;
1538        }
1539        else
1540        {
1541            CCLen += 1;
1542
1543            /*Get Response APDU data size
1544            to check the integration s/w response size*/
1545#ifdef PH_HAL4_ENABLE
1546			{
1547				uint16_t	max_rsp_size =
1548					((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_FIRST_INDEX]) << 8)\
1549					+ NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_SECOND_INDEX]);
1550				NdefMap->DesfireCapContainer.MaxRespSize =
1551								((max_rsp_size > PHHAL_MAX_DATASIZE)?
1552								(PHHAL_MAX_DATASIZE) : max_rsp_size);
1553			}
1554#else
1555			NdefMap->DesfireCapContainer.MaxRespSize =
1556				((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_FIRST_INDEX]) << 8)\
1557                +NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_SECOND_INDEX]);
1558#endif /* #ifdef PH_HAL4_ENABLE */
1559
1560            /*Get Command APDU data size*/
1561#ifdef PH_HAL4_ENABLE
1562			{
1563				uint16_t	max_cmd_size =
1564					((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_FIRST_INDEX])<<8)\
1565					+ NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_SECOND_INDEX]);
1566
1567				NdefMap->DesfireCapContainer.MaxCmdSize =
1568								((max_cmd_size > PHHAL_MAX_DATASIZE)?
1569								(PHHAL_MAX_DATASIZE): max_cmd_size);
1570			}
1571#else
1572			NdefMap->DesfireCapContainer.MaxCmdSize =
1573				((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_FIRST_INDEX])<<8)\
1574                +NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_SECOND_INDEX]);
1575#endif /* #ifdef PH_HAL4_ENABLE */
1576            /* Check for the Validity of Cmd & Resp Size*/
1577            /* check the Validity of the Cmd Size*/
1578            if( (NdefMap->DesfireCapContainer.MaxRespSize < 0x0f) ||
1579                ( NdefMap->DesfireCapContainer.MaxCmdSize == 0x00))
1580            {
1581                ErrFlag=1;
1582
1583            }
1584            else
1585            {
1586                CCLen += 4;
1587
1588                /* Check and Parse the TLV structure */
1589                /* In future this chk can be extended to Propritery TLV */
1590                //status = phFriNfc_ChkAndParseTLV(NdefMap);
1591                status = phFriNfc_Desf_HChkAndParseTLV(NdefMap,PH_FRINFC_NDEFMAP_DESF_TLV_INDEX);
1592                if ( (status == NFCSTATUS_SUCCESS) && (NdefMap->TLVFoundFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CNTRL_TLV))
1593                {
1594                    CCLen += 1;
1595
1596                    /* check the TLV length*/
1597                    if ( (( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX]) > 0x00 ) &&
1598                        (( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX]) <= 0xFE )&&
1599                        (( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX]) == 0x06 ))
1600                    {
1601                        CCLen +=1;
1602                        /* store the contents in to the container structure*/
1603                        NdefMap->DesfireCapContainer.NdefMsgFid = ( (((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILEID_BYTE_FIRST_INDEX])<<PH_FRINFC_NDEFMAP_DESF_SHL8)+ \
1604                            NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILEID_BYTE_SECOND_INDEX]);
1605
1606                        CCLen +=2;
1607
1608                        /* Invalid Msg File Id : User Can't Have read/write Opeartion*/
1609                        if (    (NdefMap->DesfireCapContainer.NdefMsgFid == 0xFFFF) ||
1610                            (NdefMap->DesfireCapContainer.NdefMsgFid == 0xE102) ||
1611                            (NdefMap->DesfireCapContainer.NdefMsgFid == 0xE103) ||
1612                            (NdefMap->DesfireCapContainer.NdefMsgFid == 0x3F00) ||
1613                            (NdefMap->DesfireCapContainer.NdefMsgFid == 0x3FFF ) )
1614                        {
1615
1616                            ErrFlag=1;
1617                        }
1618                        else
1619                        {
1620                            /*Get Ndef Size*/
1621                            NdefMap->DesfireCapContainer.NdefFileSize =
1622                                ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILESZ_BYTE_FIRST_INDEX])<<8)
1623                                | (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILESZ_BYTE_SECOND_INDEX] & 0x00ff));
1624
1625
1626                            /*Check Ndef Size*/
1627                            /* TBD : Do we need to minus 2 bytes of size it self?*/
1628                            if ( ((NdefMap->DesfireCapContainer.NdefFileSize -2) <= 0x0004 ) ||
1629                                ((NdefMap->DesfireCapContainer.NdefFileSize -2) == 0xFFFD ) )
1630                            {
1631                                ErrFlag=1;
1632                            }
1633                            else
1634                            {
1635                                CCLen +=2;
1636
1637                                /*Ndef File Read Access*/
1638                                NdefMap->DesfireCapContainer.ReadAccess = NdefMap->\
1639                                    SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILERD_ACCESS_INDEX] ;
1640
1641                                /*Ndef File Write Access*/
1642                                NdefMap->DesfireCapContainer.WriteAccess = NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILEWR_ACCESS_INDEX];
1643
1644                                CCLen +=2;
1645
1646                                phFriNfc_Desfire_HChkNDEFFileAccessRights(NdefMap);
1647                            }
1648                        }
1649                    }
1650                    else
1651                    {
1652
1653                        /* TLV Lenth is of two byte value
1654                        TBD: As the length of TLV is fixed for 6 bytes. We need not
1655                        handle the 2 byte value*/
1656
1657
1658                    }
1659                }
1660                else
1661                {
1662                    if ( NdefMap->TLVFoundFlag == PH_FRINFC_NDEFMAP_DESF_PROP_CNTRL_TLV )
1663                    {
1664                        /*TBD: To Handle The Proprietery TLV*/
1665                    }
1666                    else
1667                    {
1668                        /*Invalid T found case*/
1669                        ErrFlag =1;
1670                    }
1671                }
1672                /* check for the entire LENGTH Validity
1673                CCLEN + TLV L value == CCLEN*/
1674                if ( CapContSize < CCLen )
1675                {
1676                    ErrFlag=1;
1677                }
1678
1679            }/* if NdefMap->DesfireCapContainer.MaxRespSize < 0x0f */
1680        }/* Chkeck Map Version*/
1681    }/* CC size invalid*/
1682    if( ErrFlag == 1 )
1683    {
1684        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1685            NFCSTATUS_NO_NDEF_SUPPORT);
1686    }
1687    return ( status );
1688}
1689
1690static uint32_t phFriNfc_Desfire_HGetLeBytes(phFriNfc_NdefMap_t *NdefMap)
1691{
1692    /*Represents the LE byte*/
1693    uint16_t BytesToRead =0;
1694
1695    if ( NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP )
1696    {
1697        BytesToRead = PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES;
1698         NdefMap->DesfireCapContainer.SkipNlenBytesFlag =0;
1699    }
1700    else
1701    {
1702
1703        /* Calculate Le bytes : No of bytes to read*/
1704        /* Check for User Apdu Buffer Size and Msg Size of Desfire Capability container */
1705        if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= NdefMap->DesfireCapContainer.MaxRespSize)
1706        {
1707            /*  We have enough buffer space to read the whole capability container
1708            size bytes
1709            Now, check do we have NdefMap->DesfireCapContainer.MaxRespSize to read ? */
1710
1711            BytesToRead = (((NdefMap->DesfireCapContainer.NdefDataLen - *NdefMap->DataCount) >=
1712                NdefMap->DesfireCapContainer.MaxRespSize) ?
1713                NdefMap->DesfireCapContainer.MaxRespSize :
1714            (NdefMap->DesfireCapContainer.NdefDataLen -
1715                *NdefMap->DataCount));
1716        }
1717        else
1718        {
1719            /*  Read only till the available buffer space */
1720            BytesToRead = (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
1721            if(BytesToRead >= (uint16_t)(NdefMap->DesfireCapContainer.NdefDataLen - *NdefMap->DataCount))
1722            {
1723                BytesToRead = (NdefMap->DesfireCapContainer.NdefDataLen - *NdefMap->DataCount);
1724            }
1725        }
1726
1727        NdefMap->DesfireCapContainer.SkipNlenBytesFlag =
1728            (uint8_t)(((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )&&( *NdefMap->DataCount == 0 )) ?
1729            1 : 0);
1730
1731    }
1732    return (BytesToRead);
1733}
1734
1735
1736
1737/*!
1738* \brief this shall notify the integration software with respective
1739*  success/error status along with the completion routines.
1740*
1741*  This routine is called from the desfire process function.
1742*
1743*/
1744
1745static void phFriNfc_Desfire_HCrHandler(    phFriNfc_NdefMap_t  *NdefMap,
1746                                        NFCSTATUS           Status)
1747{
1748    /* set the state back to the Reset_Init state*/
1749    NdefMap->State =  PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
1750
1751    switch(NdefMap->DespOpFlag)
1752    {
1753        /* check which routine has the problem and set the CR*/
1754    case PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP :
1755        /* set the completion routine*/
1756        NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_CHK_NDEF].\
1757            CompletionRoutine(NdefMap->CompletionRoutine->Context,\
1758            Status);
1759        break;
1760
1761    case PH_FRINFC_NDEFMAP_DESF_READ_OP :
1762        /* set the completion routine*/
1763        NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_RD_NDEF].\
1764            CompletionRoutine(NdefMap->CompletionRoutine->Context,\
1765            Status);
1766        break;
1767
1768    case PH_FRINFC_NDEFMAP_DESF_WRITE_OP :
1769        /* set the completion routine*/
1770        NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_WR_NDEF].\
1771            CompletionRoutine(NdefMap->CompletionRoutine->Context,\
1772            Status);
1773        break;
1774
1775    default :
1776        /* set the completion routine*/
1777        NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_INVALID_OPE].\
1778            CompletionRoutine(NdefMap->CompletionRoutine->Context,\
1779            Status);
1780        break;
1781
1782    }
1783}
1784
1785static NFCSTATUS phFriNfc_Desfire_HSendTransCmd(phFriNfc_NdefMap_t *NdefMap,uint8_t SendRecvLen)
1786{
1787
1788    NFCSTATUS status =  NFCSTATUS_SUCCESS;
1789
1790    /* set the command type*/
1791#ifndef PH_HAL4_ENABLE
1792    NdefMap->Cmd.Iso144434Cmd = phHal_eIso14443_4_CmdListTClCmd;
1793#else
1794    NdefMap->Cmd.Iso144434Cmd = phHal_eIso14443_4_Raw;
1795#endif
1796
1797    /* set the Additional Info*/
1798    NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
1799    NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
1800
1801    /*set the completion routines for the desfire card operations*/
1802    NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Desfire_Process;
1803    NdefMap->MapCompletionInfo.Context = NdefMap;
1804
1805    /* set the receive length */
1806    *NdefMap->SendRecvLength = ((uint16_t)(SendRecvLen));
1807
1808
1809    /*Call the Overlapped HAL Transceive function */
1810    status = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice,
1811        &NdefMap->MapCompletionInfo,
1812        NdefMap->psRemoteDevInfo,
1813        NdefMap->Cmd,
1814        &NdefMap->psDepAdditionalInfo,
1815        NdefMap->SendRecvBuf,
1816        NdefMap->SendLength,
1817        NdefMap->SendRecvBuf,
1818        NdefMap->SendRecvLength);
1819
1820    return (status);
1821
1822
1823}
1824
1825
1826#ifdef UNIT_TEST
1827#include <phUnitTestNfc_Desfire_static.c>
1828#endif
1829
1830#endif  /* PH_FRINFC_MAP_DESFIRE_DISABLED */
1831