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_DesfireFormat.c
     19 * \brief This component encapsulates different format functinalities ,
     20 *        for the Type4/Desfire card.
     21 *
     22 * Project: NFC-FRI
     23 *
     24 * $Date: Fri Feb 20 14:38:17 2009 $
     25 * $Author: ing07385 $
     26 * $Revision: 1.4 $
     27 * $Aliases: NFC_FRI1.1_WK908_R19_1,NFC_FRI1.1_WK910_PREP1,NFC_FRI1.1_WK910_R20_1,NFC_FRI1.1_WK912_PREP1,NFC_FRI1.1_WK912_R21_1,NFC_FRI1.1_WK914_PREP1,NFC_FRI1.1_WK914_R22_1,NFC_FRI1.1_WK914_R22_2,NFC_FRI1.1_WK916_R23_1,NFC_FRI1.1_WK918_R24_1,NFC_FRI1.1_WK920_PREP1,NFC_FRI1.1_WK920_R25_1,NFC_FRI1.1_WK922_PREP1,NFC_FRI1.1_WK922_R26_1,NFC_FRI1.1_WK924_PREP1,NFC_FRI1.1_WK924_R27_1,NFC_FRI1.1_WK926_R28_1,NFC_FRI1.1_WK928_R29_1,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 #include <phNfcTypes.h>
     31 #include <phFriNfc_OvrHal.h>
     32 #include <phFriNfc_SmtCrdFmt.h>
     33 #include <phFriNfc_DesfireFormat.h>
     34 
     35 
     36 /* Following section details, how to wrap the native DESFire commands in to ISO commands
     37 Following are different native commands are wrapped under the ISO commands :
     38 1. Crate Application
     39 2. Select File
     40 3. Get version
     41 4. Create CC/NDEF File
     42 5. Write data to STD File
     43 In this File above commands are sent using the ISO Wrapper.
     44 
     45 Wrapping the native DESFire APDU's procedure
     46 --------------------------------------------------------------------------------
     47 CLA         INS     P1      P2      Lc          Data            Le
     48 0x90        Cmd     0x00    0x00    Data Len    Cmd. Par's      0x00
     49 -----------------------------------------------------------------------------------*/
     50 
     51 /* Helper functions to create app/select app/create data file/read /write from the
     52 CC file and NDEF files */
     53 static void phFriNfc_Desf_HWrapISONativeCmds(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt,uint8_t CmdType);
     54 
     55 /* Gets H/W version details*/
     56 static NFCSTATUS phFriNfc_Desf_HGetHWVersion(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
     57 
     58 /* Gets S/W version details*/
     59 static NFCSTATUS phFriNfc_Desf_HGetSWVersion(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     60 
     61 /* Updates the version details to context structure*/
     62 static NFCSTATUS phFriNfc_Desf_HUpdateVersionDetails(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     63 
     64 /*Gets UID details*/
     65 static NFCSTATUS phFriNfc_Desf_HGetUIDDetails(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt);
     66 
     67 /*Creates Application*/
     68 static NFCSTATUS phFriNfc_Desf_HCreateApp(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
     69 
     70 /* Selects Application*/
     71 static NFCSTATUS phFriNfc_Desf_HSelectApp(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
     72 
     73 /*Creates Capability Container File*/
     74 static NFCSTATUS phFriNfc_Desf_HCreatCCFile(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
     75 
     76 /* Create NDEF File*/
     77 static NFCSTATUS phFriNfc_Desf_HCreatNDEFFile(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
     78 
     79 /* Writes CC Bytes to CC File*/
     80 static NFCSTATUS phFriNfc_Desf_HWrCCBytes(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
     81 
     82 /* Writes NDEF data into NDEF File*/
     83 static NFCSTATUS phFriNfc_Desf_HWrNDEFData(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
     84 
     85 /* Transceive Cmd initiation*/
     86 static NFCSTATUS phFriNfc_Desf_HSendTransCmd(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
     87 
     88 
     89 void phFriNfc_Desfire_Reset( phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
     90 {
     91     /* This piece of code may not be useful for the current supported DESFire formatting feature*/
     92     /* Currently, s/w doesn't support authenticating either PICC Master key nor NFC Forum
     93     Application Master key*/
     94 
     95     /*NdefSmtCrdFmt->AddInfo.Type4Info.PICCMasterKey[] = PH_FRINFC_SMTCRDFMT_DESF_PICC_MASTER_KEY;
     96     NdefSmtCrdFmt->AddInfo.Type4Info.NFCForumMasterkey[]  = PH_FRINFC_SMTCRDFMT_DESF_NFCFORUM_APP_KEY;*/
     97 
     98     /* reset to zero PICC and NFC FORUM master keys*/
     99     (void)memset((void *)NdefSmtCrdFmt->AddInfo.Type4Info.PICCMasterKey,
    100         0x00,
    101         16);
    102 
    103     (void)memset((void *)NdefSmtCrdFmt->AddInfo.Type4Info.NFCForumMasterkey,
    104         0x00,
    105         16);
    106     NdefSmtCrdFmt->AddInfo.Type4Info.PrevState = 0;
    107 
    108 }
    109 
    110 
    111 static void phFriNfc_Desf_HWrapISONativeCmds(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt,uint8_t CmdType)
    112 {
    113 
    114     uint16_t i=0, CmdByte=1;
    115     uint8_t NdefFileBytes[] = PH_FRINFC_DESF_NDEFFILE_BYTES;
    116     uint8_t CCFileBytes[]  = PH_FRINFC_DESF_CCFILE_BYTES;
    117 
    118 
    119     /* common elements for all the native commands*/
    120 
    121     /* Class Byte */
    122     NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CLASS_BYTE;
    123 
    124     /* let the place to store the cmd byte type, point to next index*/
    125     i += 2;
    126 
    127 
    128     /* P1/P2 offsets always set to zero */
    129     NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P1;
    130     i++;
    131     NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P2;
    132     i++;
    133 
    134     switch(CmdType)
    135     {
    136 
    137     case PH_FRINFC_DESF_GET_HW_VERSION_CMD :
    138     case PH_FRINFC_DESF_GET_SW_VERSION_CMD :
    139     case PH_FRINFC_DESF_GET_UID_CMD :
    140 
    141         if (CmdType == PH_FRINFC_DESF_GET_HW_VERSION_CMD )
    142         {
    143             /* Instruction Cmd code */
    144             NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_GET_VER_CMD;
    145         }
    146         else
    147         {
    148             /* Instruction Cmd code */
    149             NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_PICC_ADDI_FRAME_RESP;
    150         }
    151 
    152         /*  Lc: Length of wrapped data */
    153         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    154         i++;
    155 
    156         /* NO Data to send in this cmd*/
    157         /* we are not suppose to set Le*/
    158         /* set the length of the buffer*/
    159         NdefSmtCrdFmt->SendLength = i;
    160 
    161         break;
    162 
    163     case PH_FRINFC_DESF_CREATEAPP_CMD:
    164 
    165         /* Instruction Cmd code */
    166         NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_CREATE_AID_CMD;
    167 
    168         /*  Lc: Length of wrapped data */
    169         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CRAPP_WRDT_LEN;
    170         i++;
    171 
    172         /* NFC FORUM APPLICATION ID*/
    173         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_FIRST_AID_BYTE;
    174         i++;
    175         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_SEC_AID_BYTE;
    176         i++;
    177         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_THIRD_AID_BYTE;
    178         i++;
    179 
    180         /* set key settings and number of keys*/
    181         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_PICC_NFC_KEY_SETTING;
    182         i++;
    183 
    184         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NFCFORUM_APP_NO_OF_KEYS;
    185         i++;
    186 
    187         /* Le bytes*/
    188         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE;
    189         i++;
    190 
    191         /* set the length of the buffer*/
    192         NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_CREATEAPP_CMD_SNLEN;
    193 
    194         break;
    195 
    196     case PH_FRINFC_DESF_SELECTAPP_CMD :
    197 
    198         /* Instruction Cmd code */
    199         NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_SLECT_APP_CMD;
    200 
    201         /*  Lc: Length of wrapped data */
    202         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_SLAPP_WRDT_LEN;
    203         i++;
    204 
    205         /* Data*/
    206         /* set the send buffer to create the application identifier*/
    207         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_FIRST_AID_BYTE;
    208         i++;
    209 
    210         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_SEC_AID_BYTE;
    211         i++;
    212 
    213         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_THIRD_AID_BYTE;
    214         i++;
    215 
    216         /* Le bytes*/
    217         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE;
    218         i++;
    219 
    220         /* set the length of the buffer*/
    221         NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_SELECTAPP_CMD_SNLEN;
    222 
    223         break;
    224 
    225     case PH_FRINFC_DESF_CREATECC_CMD :
    226 
    227         /* Instruction Cmd code */
    228         NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_CREATE_DATA_FILE_CMD;
    229 
    230         /*  Lc: Length of wrapped data */
    231         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CRCCNDEF_WRDT_LEN;
    232         i++;
    233 
    234         /* set cc file id*/
    235         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_ID;
    236         i++;
    237         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_COMM_SETTINGS;
    238         i++;
    239 
    240         /* set the Access Rights are set to full read/write, full cntrl*/
    241         NdefSmtCrdFmt->SendRecvBuf[i] = 0xEE;
    242         i++;
    243         NdefSmtCrdFmt->SendRecvBuf[i] = 0xEE;
    244         i++;
    245 
    246         /* set the file size*/
    247         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_SIZE;
    248         i++;
    249         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    250         i++;
    251         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    252         i++;
    253 
    254         /* Le bytes*/
    255         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE;
    256         i++;
    257 
    258         /* set the length of the buffer*/
    259         NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_CREATECCNDEF_CMD_SNLEN ;
    260         break;
    261 
    262     case PH_FRINFC_DESF_CREATENDEF_CMD :
    263 
    264         /* Instruction Cmd code */
    265         NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_CREATE_DATA_FILE_CMD;
    266 
    267         /*  Lc: Length of wrapped data */
    268         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CRCCNDEF_WRDT_LEN;
    269         i++;
    270 
    271         /* set cc file id*/
    272         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NDEF_FILE_ID;
    273         i++;
    274         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_COMM_SETTINGS;
    275         i++;
    276 
    277         /* set the r/w access rights.Once Authentication part is fixed,
    278            we will use the constants*/
    279         NdefSmtCrdFmt->SendRecvBuf[i] = 0xEE;
    280         i++;
    281         NdefSmtCrdFmt->SendRecvBuf[i] = 0xEE;
    282         i++;
    283 
    284         NdefSmtCrdFmt->SendRecvBuf[i]= (uint8_t)NdefSmtCrdFmt->AddInfo.Type4Info.CardSize ;
    285         i++;
    286         NdefSmtCrdFmt->SendRecvBuf[i]= (uint8_t)(NdefSmtCrdFmt->AddInfo.Type4Info.CardSize >> 8) ;
    287         i++;
    288         NdefSmtCrdFmt->SendRecvBuf[i]= (uint8_t)(NdefSmtCrdFmt->AddInfo.Type4Info.CardSize >> 16);
    289         i++;
    290 
    291         /* Le bytes*/
    292         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE;
    293         i++;
    294 
    295         /* set the length of the buffer*/
    296         NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_CREATECCNDEF_CMD_SNLEN ;
    297 
    298         break;
    299 
    300     case  PH_FRINFC_DESF_WRITECC_CMD:
    301 
    302         /* Instruction Cmd code */
    303         NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_WRITE_CMD;
    304 
    305         /*  Lc: Length of wrapped data */
    306         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_WRCC_WRDT_LEN;
    307         i++;
    308 
    309         /* set the file id*/
    310         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_ID;
    311         i++;
    312 
    313         /* set the offset to zero*/
    314         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    315         i++;
    316         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    317         i++;
    318         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    319         i++;
    320 
    321         /* Set the length of data available to write*/
    322         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_SIZE;
    323         i++;
    324         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    325         i++;
    326         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    327         i++;
    328 
    329         /*set the data to be written to the CC file*/
    330         (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[i],
    331             CCFileBytes,
    332             PH_FRINFC_DESF_CC_FILE_SIZE);
    333         i++;
    334 
    335         i += PH_FRINFC_DESF_CC_FILE_SIZE;
    336 
    337         /* Le bytes*/
    338         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE;
    339         i++;
    340 
    341         NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_WRITECC_CMD_SNLEN;
    342         break;
    343 
    344     case  PH_FRINFC_DESF_WRITENDEF_CMD:
    345 
    346         /* Instruction Cmd code */
    347         NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_WRITE_CMD;
    348 
    349         /*  Lc: Length of wrapped data */
    350         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_WRNDEF_WRDT_LEN;
    351         i++;
    352 
    353         /* set the file id*/
    354         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NDEF_FILE_ID;
    355         i++;
    356 
    357         /* set the offset to zero*/
    358         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    359         i++;
    360         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    361         i++;
    362         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    363         i++;
    364 
    365         /* Set the length of data available to write*/
    366         NdefSmtCrdFmt->SendRecvBuf[i] = 0x02;
    367         i++;
    368         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    369         i++;
    370         NdefSmtCrdFmt->SendRecvBuf[i] = 0x00;
    371         i++;
    372 
    373         /*set the data to be written to the CC file*/
    374 
    375         (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[i],
    376             NdefFileBytes,
    377             2);
    378         i += 2;
    379 
    380         /* Le bytes*/
    381         NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE;
    382         i++;
    383 
    384         NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_WRITENDEF_CMD_SNLEN;
    385         break;
    386 
    387     default :
    388         break;
    389     }
    390 }
    391 
    392 static NFCSTATUS phFriNfc_Desf_HGetHWVersion(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
    393 {
    394     NFCSTATUS status = NFCSTATUS_SUCCESS;
    395 #ifdef PH_HAL4_ENABLE
    396     /* Removed uint8_t i=0; */
    397 #else
    398     uint8_t i=0;
    399 #endif /* #ifdef PH_HAL4_ENABLE */
    400 
    401     /*set the state*/
    402     NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_GET_HW_VERSION;
    403 
    404     /* Helper routine to wrap the native DESFire cmds*/
    405     phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_GET_HW_VERSION_CMD);
    406 
    407     status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt);
    408 
    409     return ( status);
    410 }
    411 
    412 static NFCSTATUS phFriNfc_Desf_HGetSWVersion(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    413 {
    414 
    415     NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    416         NFCSTATUS_FORMAT_ERROR);
    417 
    418     if( ( NdefSmtCrdFmt->SendRecvBuf[*(NdefSmtCrdFmt->SendRecvLength)- 1] ==
    419                 PH_FRINFC_DESF_PICC_ADDI_FRAME_RESP) )
    420     {
    421         /*set the state*/
    422         NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_GET_SW_VERSION;
    423 
    424         /* Helper routine to wrap the native DESFire cmds*/
    425         phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_GET_SW_VERSION_CMD);
    426 
    427         status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt);
    428     }
    429     return status;
    430 }
    431 
    432 static NFCSTATUS phFriNfc_Desf_HUpdateVersionDetails(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    433 {
    434     NFCSTATUS status = PHNFCSTVAL(CID_NFC_NONE,
    435         NFCSTATUS_SUCCESS);
    436 
    437     if( ( NdefSmtCrdFmt->SendRecvBuf[*(NdefSmtCrdFmt->SendRecvLength)-
    438         PH_SMTCRDFMT_DESF_VAL1] ==  PH_FRINFC_DESF_PICC_ADDI_FRAME_RESP ) )
    439     {
    440         NdefSmtCrdFmt->AddInfo.Type4Info.MajorVersion = NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL3];
    441         NdefSmtCrdFmt->AddInfo.Type4Info.MinorVersion = NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL4];
    442         if ( ( NdefSmtCrdFmt->AddInfo.Type4Info.MajorVersion == PH_FRINFC_DESF4_MAJOR_VERSION )&&
    443              ( NdefSmtCrdFmt->AddInfo.Type4Info.MinorVersion == PH_FRINFC_DESF4_MINOR_VERSION ))
    444         {
    445             /* card size of DESFire4 type */
    446             NdefSmtCrdFmt->AddInfo.Type4Info.CardSize = PH_FRINFC_DESF4_MEMORY_SIZE;
    447 
    448         }
    449         else
    450         {
    451             // need to handle the Desfire8 type cards
    452             // need to use get free memory
    453             status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    454                 NFCSTATUS_INVALID_REMOTE_DEVICE);
    455 
    456         }
    457     }
    458     return status;
    459 
    460 }
    461 
    462 static NFCSTATUS phFriNfc_Desf_HGetUIDDetails(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)
    463 {
    464 
    465     NFCSTATUS status = NFCSTATUS_PENDING;
    466     if( ( NdefSmtCrdFmt->SendRecvBuf[*(NdefSmtCrdFmt->SendRecvLength)-
    467         PH_SMTCRDFMT_DESF_VAL1] ==  PH_FRINFC_DESF_PICC_ADDI_FRAME_RESP) )
    468     {
    469         /*set the state*/
    470         NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_GET_UID;
    471 
    472         /* Helper routine to wrap the native desfire cmds*/
    473         phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_GET_UID_CMD);
    474 
    475         status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt);
    476     }
    477 
    478     return status;
    479 
    480 }
    481 
    482 
    483 static NFCSTATUS phFriNfc_Desf_HCreateApp(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    484 {
    485     NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    486         NFCSTATUS_FORMAT_ERROR);
    487 
    488     if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL14] == PH_FRINFC_DESF_NAT_WRAP_FIRST_RESP_BYTE)
    489          && (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL15] == PH_FRINFC_DESF_NAT_WRAP_SEC_RESP_BYTE ))
    490     {
    491         /*set the state*/
    492         NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_CREATE_AID;
    493 
    494         /* Helper routine to wrap the native DESFire cmds*/
    495         phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_CREATEAPP_CMD);
    496 
    497         status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt);
    498     }
    499     return ( status);
    500 }
    501 
    502 
    503 static NFCSTATUS phFriNfc_Desf_HSelectApp(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    504 {
    505 
    506     NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    507         NFCSTATUS_FORMAT_ERROR);
    508 
    509     /* check for the response of previous operation, before
    510     issuing the next command*/
    511 
    512     if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NAT_WRAP_FIRST_RESP_BYTE) &&
    513         (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NAT_WRAP_SEC_RESP_BYTE ))
    514     {
    515         /*set the state*/
    516         NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_SELECT_APP;
    517 
    518         /* Helper routine to wrap the native DESFire cmds*/
    519         phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_SELECTAPP_CMD);
    520 
    521         status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt);
    522     }
    523     return ( status);
    524 
    525 }
    526 
    527 static NFCSTATUS phFriNfc_Desf_HCreatCCFile(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
    528 {
    529     NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    530         NFCSTATUS_FORMAT_ERROR);
    531 
    532     if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1) &&
    533             (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 ))
    534     {
    535         /*set the state*/
    536         NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_CREATE_CCFILE;
    537 
    538         /* Helper routine to wrap the native DESFire cmds*/
    539         phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_CREATECC_CMD);
    540 
    541         status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt);
    542     }
    543     return ( status);
    544 }
    545 
    546 static NFCSTATUS phFriNfc_Desf_HCreatNDEFFile(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    547 {
    548 
    549     NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    550         NFCSTATUS_FORMAT_ERROR);
    551 
    552     if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1) &&
    553             (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 ))
    554     {
    555         /*set the state*/
    556         NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_CREATE_NDEFFILE;
    557 
    558         /* Helper routine to wrap the native desfire cmds*/
    559         phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_CREATENDEF_CMD);
    560 
    561         status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt);
    562 
    563     }
    564 
    565     return ( status);
    566 
    567 }
    568 
    569 static NFCSTATUS phFriNfc_Desf_HWrCCBytes(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    570 {
    571 
    572     NFCSTATUS result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    573         NFCSTATUS_FORMAT_ERROR);
    574     if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1) &&
    575             (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 ))
    576     {
    577 
    578         /*set the state*/
    579         NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_WRITE_CC_FILE;
    580 
    581         /* Helper routine to wrap the native DESFire cmds*/
    582         phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_WRITECC_CMD);
    583 
    584         result = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt);
    585     }
    586     return (result);
    587 }
    588 
    589 static NFCSTATUS phFriNfc_Desf_HWrNDEFData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    590 {
    591 
    592     NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    593         NFCSTATUS_FORMAT_ERROR);
    594 
    595 
    596     if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1) &&
    597             (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 ))
    598     {
    599         /*set the state*/
    600         NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_WRITE_NDEF_FILE;
    601 
    602         /* Helper routine to wrap the native DESFire cmds*/
    603         phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_WRITENDEF_CMD);
    604 
    605         Result = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt);
    606     }
    607     return (Result);
    608 }
    609 
    610 static NFCSTATUS phFriNfc_Desf_HSendTransCmd(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    611 {
    612 
    613     NFCSTATUS status =  NFCSTATUS_SUCCESS;
    614 
    615     /* set the command type*/
    616 #ifdef PH_HAL4_ENABLE
    617     NdefSmtCrdFmt->Cmd.Iso144434Cmd = phHal_eIso14443_4_Raw;
    618 #else
    619     NdefSmtCrdFmt->Cmd.Iso144434Cmd = phHal_eIso14443_4_CmdListTClCmd;
    620 #endif /* #ifdef PH_HAL4_ENABLE */
    621 
    622     /* set the Additional Info*/
    623     NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
    624     NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0;
    625 
    626     /*set the completion routines for the desfire card operations*/
    627     NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process;
    628     NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt;
    629 
    630     /* set the receive length */
    631     *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE;
    632 
    633 
    634     /*Call the Overlapped HAL Transceive function */
    635     status = phFriNfc_OvrHal_Transceive(NdefSmtCrdFmt->LowerDevice,
    636         &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
    637         NdefSmtCrdFmt->psRemoteDevInfo,
    638         NdefSmtCrdFmt->Cmd,
    639         &NdefSmtCrdFmt->psDepAdditionalInfo,
    640         NdefSmtCrdFmt->SendRecvBuf,
    641         NdefSmtCrdFmt->SendLength,
    642         NdefSmtCrdFmt->SendRecvBuf,
    643         NdefSmtCrdFmt->SendRecvLength);
    644 
    645     return (status);
    646 
    647 
    648 }
    649 
    650 NFCSTATUS phFriNfc_Desfire_Format(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
    651 {
    652 
    653     NFCSTATUS status =  NFCSTATUS_SUCCESS;
    654     status =  phFriNfc_Desf_HGetHWVersion(NdefSmtCrdFmt);
    655     return (status);
    656 }
    657 
    658 void phFriNfc_Desf_Process( void       *Context,
    659                            NFCSTATUS   Status)
    660 {
    661 
    662     phFriNfc_sNdefSmtCrdFmt_t      *NdefSmtCrdFmt;
    663 
    664     NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context;
    665 
    666 
    667     if((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER))
    668     {
    669         switch(NdefSmtCrdFmt->State)
    670         {
    671 
    672         case PH_FRINFC_DESF_STATE_GET_HW_VERSION :
    673 
    674             /* Check and store the h/w and s/w specific details.
    675             Ex: Major/Minor version, memory storage info. */
    676 
    677             Status = phFriNfc_Desf_HGetSWVersion(NdefSmtCrdFmt);
    678 
    679             break;
    680 
    681         case PH_FRINFC_DESF_STATE_GET_SW_VERSION :
    682 
    683             /* Check and store the h/w and s/w specific details.
    684             Ex: Major/Minor version, memory storage info. */
    685 
    686             Status = phFriNfc_Desf_HUpdateVersionDetails(NdefSmtCrdFmt);
    687             if ( Status == NFCSTATUS_SUCCESS )
    688             {
    689                 Status = phFriNfc_Desf_HGetUIDDetails(NdefSmtCrdFmt);
    690             }
    691             break;
    692         case PH_FRINFC_DESF_STATE_GET_UID :
    693 
    694             Status = phFriNfc_Desf_HCreateApp(NdefSmtCrdFmt);
    695             break;
    696 
    697         case PH_FRINFC_DESF_STATE_CREATE_AID :
    698 
    699             Status = phFriNfc_Desf_HSelectApp(NdefSmtCrdFmt);
    700             break;
    701 
    702         case PH_FRINFC_DESF_STATE_SELECT_APP :
    703 
    704             Status = phFriNfc_Desf_HCreatCCFile(NdefSmtCrdFmt);
    705             break;
    706 
    707         case PH_FRINFC_DESF_STATE_CREATE_CCFILE :
    708 
    709             Status = phFriNfc_Desf_HCreatNDEFFile(NdefSmtCrdFmt);
    710             break;
    711 
    712         case PH_FRINFC_DESF_STATE_CREATE_NDEFFILE :
    713 
    714             Status = phFriNfc_Desf_HWrCCBytes(NdefSmtCrdFmt);
    715             break;
    716 
    717         case  PH_FRINFC_DESF_STATE_WRITE_CC_FILE :
    718 
    719             Status = phFriNfc_Desf_HWrNDEFData(NdefSmtCrdFmt);
    720             break;
    721 
    722         case  PH_FRINFC_DESF_STATE_WRITE_NDEF_FILE :
    723 
    724             if (( NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1 )&&
    725                     ( NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 ))
    726             {
    727                 Status = PHNFCSTVAL(CID_NFC_NONE,
    728                     NFCSTATUS_SUCCESS);
    729                 NdefSmtCrdFmt->CardState = 0;
    730             }
    731             break;
    732 
    733         default :
    734             /*set the invalid state*/
    735             Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    736                 NFCSTATUS_INVALID_DEVICE_REQUEST);
    737             break;
    738         }
    739     }
    740     /* Handle the all the error cases*/
    741     if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
    742     {
    743         /* call respective CR */
    744         phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt,Status);
    745     }
    746 
    747 }
    748 
    749