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