Home | History | Annotate | Download | only in mifare
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      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  * Mifare Standard Format implementation
     19  */
     20 
     21 #include <phFriNfc_MifStdFormat.h>
     22 #include <phNxpExtns_MifareStd.h>
     23 #include <phNfcCompId.h>
     24 #include <phNxpLog.h>
     25 
     26 /* Function prototype declarations */
     27 static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, uint16_t BlockNo);
     28 static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     29 static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, NFCSTATUS Status);
     30 static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     31 static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     32 static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     33 static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     34 static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     35 static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     36 static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t BlockNo, const uint8_t *RecvBuf, const uint8_t AcsBits1[], const uint8_t AcsBits2[]);
     37 static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     38 static void phFriNfc_MfStd_H_NdefComplSect(uint8_t CardTypes, uint8_t Sector[]);
     39 static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     40 static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     41 static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     42 static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     43 static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     44 static void phFriNfc_MfStd_H_StrNdefData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     45 static void phFriNfc_MfStd_H_BlkNoToWrTLV(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
     46 static int phFriNfc_MfStd_MemCompare(void *s1, void *s2, unsigned int n );
     47 
     48 /*
     49  * Enum definition contains format states
     50  */
     51 typedef enum Mfc_format_state{
     52     MFC_FORMAT_INIT = 0x00,
     53     MFC_FORMAT_NFC_KEY,
     54     MFC_FORMAT_DEF_KEY,
     55     MFC_FORMAT_INVALID
     56 }MFC_FORMAT_STATE;
     57 
     58 /* format key status */
     59 static MFC_FORMAT_STATE  FormatKeyState = MFC_FORMAT_INIT;
     60 
     61 /*******************************************************************************
     62 **
     63 ** Function         phFriNfc_MfStd_Reset
     64 **
     65 ** Description      Resets the component instance to the initial state and initializes the
     66 **                  internal variables.
     67 **
     68 ** Returns          none
     69 **
     70 *******************************************************************************/
     71 void phFriNfc_MfStd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
     72 {
     73     uint8_t NfcForSectArray[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT,
     74     MADSectArray[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K;
     75 
     76     /* Authentication state */
     77     NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_VAL_1;
     78 
     79     /* Set default key for A or B */
     80     memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.Default_KeyA_OR_B,
     81                 PH_FRINFC_MFSTD_FMT_DEFAULT_KEY, /* 0xFF */
     82                 PH_FRINFC_MFSTD_FMT_VAL_6);
     83 
     84     /* MAD sector key A */
     85     memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_KeyA,
     86                 MADSectArray, /*PH_FRINFC_MFSTD_FMT_VAL_0, */
     87                 PH_FRINFC_MFSTD_FMT_VAL_6);
     88 
     89     /* Copy access bits for MAD sectors */
     90     memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits,
     91                 &MADSectArray[PH_FRINFC_MFSTD_FMT_VAL_6],
     92                 PH_FRINFC_MFSTD_FMT_VAL_3);
     93 
     94     /* NFC forum sector key A */
     95     (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_KeyA,
     96                 NfcForSectArray, /*PH_FRINFC_MFSTD_FMT_VAL_0, */
     97                 PH_FRINFC_MFSTD_FMT_VAL_6);
     98 
     99     /* Copy access bits for NFC forum sectors */
    100     (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits,
    101                 &NfcForSectArray[PH_FRINFC_MFSTD_FMT_VAL_6],
    102                 PH_FRINFC_MFSTD_FMT_VAL_3);
    103 
    104     /* Sector compliant array initialised to 0 */
    105     memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl,
    106                 PH_FRINFC_MFSTD_FMT_VAL_0, /* 0x00 */
    107                 PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
    108 
    109     NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_0;
    110     NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
    111 
    112     return;
    113 }
    114 
    115 /*******************************************************************************
    116 **
    117 ** Function         phFriNfc_MfStd_Format
    118 **
    119 ** Description      The function initiates and formats the Smart Card.After this formation, remote
    120 **                  card would be properly initialized and Ndef Compliant.
    121 **
    122 ** Returns          NFCSTATUS_PENDING if successful
    123 **                  Other values if an error has occurred
    124 **
    125 *******************************************************************************/
    126 NFCSTATUS phFriNfc_MfStd_Format( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB )
    127 {
    128     NFCSTATUS    Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    129                                                 NFCSTATUS_INVALID_PARAMETER);
    130     uint8_t      index = PH_FRINFC_MFSTD_FMT_VAL_0;
    131 
    132     if(ScrtKeyB != NULL)
    133     {
    134         NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
    135             PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
    136         /* Store Key B in the context */
    137         while(index < PH_FRINFC_MFSTD_FMT_VAL_6)
    138         {
    139             NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB[index] = ScrtKeyB[index];
    140             index++;
    141         }
    142         /* Set the state */
    143         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
    144         /* Initialize current block to the first sector trailer */
    145         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = PH_FRINFC_MFSTD_FMT_VAL_3;
    146         /* Set the authenticate state */
    147         if( MFC_FORMAT_DEF_KEY == FormatKeyState)
    148         {
    149             FormatKeyState = MFC_FORMAT_INIT;
    150             NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
    151         }
    152         else
    153         {
    154             FormatKeyState = MFC_FORMAT_NFC_KEY;
    155             NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY; /* Key Chnage for some cards */
    156         }
    157         /* Start authentication */
    158         Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
    159     }
    160     return Result;
    161 }
    162 
    163 /*******************************************************************************
    164 **
    165 ** Function         phFriNfc_MfStd_Process
    166 **
    167 ** Description      Completion Routine: This function is called by the lower layer (OVR HAL)
    168 **                  when an I/O operation has finished. The internal state machine decides
    169 **                  whether to call into the lower device again or to complete the process
    170 **                  by calling into the upper layer's completion routine, stored within this
    171 **                  component's context (phFriNfc_sNdefSmtCrdFmt_t).
    172 **
    173 ** Returns          none
    174 **
    175 *******************************************************************************/
    176 void phFriNfc_MfStd_Process(void *Context, NFCSTATUS Status)
    177 {
    178     phFriNfc_sNdefSmtCrdFmt_t  *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context;
    179     /* Copy the formatting status */
    180     NdefSmtCrdFmt->FmtProcStatus = Status;
    181 
    182     if(Status == NFCSTATUS_SUCCESS)
    183     {
    184         switch(NdefSmtCrdFmt->State)
    185         {
    186         case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
    187             Status = phFriNfc_MfStd_H_ProAuth(NdefSmtCrdFmt);
    188             break;
    189 
    190         case PH_FRINFC_MFSTD_FMT_DIS_CON:
    191             Status = phFriNfc_MfStd_H_CallCon(NdefSmtCrdFmt);
    192             break;
    193 
    194         case PH_FRINFC_MFSTD_FMT_CON:
    195             if( MFC_FORMAT_DEF_KEY == FormatKeyState)
    196             {
    197                 /* retry the format with other key */
    198                 Mfc_FormatNdef(current_key,6);
    199                 return;
    200             }
    201             Status = phFriNfc_MfStd_H_ProCon(NdefSmtCrdFmt);
    202             break;
    203 
    204         case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
    205             Status = phFriNfc_MfStd_H_ProRdSectTr(NdefSmtCrdFmt);
    206             break;
    207 
    208         case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
    209             Status = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt);
    210             break;
    211 
    212         case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK:
    213             Status = phFriNfc_MfStd_H_ProWrMADBlk(NdefSmtCrdFmt);
    214             break;
    215 
    216         case PH_FRINFC_MFSTD_FMT_WR_TLV:
    217             break;
    218 
    219         case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK:
    220             Status = phFriNfc_MfStd_H_ProUpdMADBlk(NdefSmtCrdFmt);
    221             break;
    222 
    223         default:
    224             Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    225                                 NFCSTATUS_INVALID_DEVICE_REQUEST);
    226             break;
    227         }
    228     }
    229     else
    230     {
    231         switch(NdefSmtCrdFmt->State)
    232         {
    233         case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
    234             if(MFC_FORMAT_NFC_KEY == FormatKeyState)
    235             {
    236                 FormatKeyState = MFC_FORMAT_DEF_KEY;
    237             }
    238             Status = phFriNfc_MfStd_H_ProErrAuth(NdefSmtCrdFmt);
    239             break;
    240 
    241         case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
    242             Status = phFriNfc_MfStd_H_ErrWrSectTr(NdefSmtCrdFmt);
    243             break;
    244 
    245         case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
    246             Status = phFriNfc_MfStd_H_ErrRdSectTr(NdefSmtCrdFmt);
    247             break;
    248 
    249         default:
    250             Status = NdefSmtCrdFmt->FmtProcStatus;
    251             break;
    252         }
    253     }
    254 
    255     /* Status is not success then call completion routine */
    256     if(Status != NFCSTATUS_PENDING)
    257     {
    258         phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, Status);
    259     }
    260 
    261     return;
    262 }
    263 
    264 /*******************************************************************************
    265 **
    266 ** Function         phFriNfc_MfStd_H_FillSendBuf
    267 **
    268 ** Description      This function fills the send buffer for transceive function
    269 **
    270 ** Returns          none
    271 **
    272 *******************************************************************************/
    273 static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, uint16_t BlockNo)
    274 {
    275 //    void        *mem = NULL;                                                    /*commented to eliminate unused variable warning*/
    276     uint8_t     MADSectTr1k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K, /* MAD key A,
    277                                                                             Access bits and GPB of MAD sector */
    278                 MADSectTr2k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_2K, /* MAD key A,
    279                                                                             Access bits and GPB of MAD sector */
    280                 MADSectTr4k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_4K, /* MAD key A,
    281                                                                                     Access bits and GPB of MAD sector */
    282                 NFCSectTr[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT, /* NFC forum key A,
    283                                                                              Access bits and GPB of NFC sector */
    284                 NDEFMsgTLV[16] = {0x03, 0x00, 0xFE, 0x00, 0x00, 0x00, /* NDEF message TLV (INITIALISED state) */
    285                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    286                                   0x00, 0x00, 0x00, 0x00},
    287                 MADBlk[16] = {0x0F, 0x00, 0x03, 0xE1, 0x03, 0xE1,
    288                               0x03, 0xE1, 0x03, 0xE1,
    289                               0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
    290     /* Block number in send buffer */
    291     NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_0] = (uint8_t)BlockNo;
    292     /* Initialize send receive length */
    293     *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_MFSTD_FMT_MAX_RECV_LENGTH;
    294 
    295     /* Depending on the different state, fill the send buffer */
    296     switch(NdefSmtCrdFmt->State)
    297     {
    298         case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
    299             /* Depending on the authentication state, fill the send buffer */
    300             switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)
    301             {
    302                 case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:
    303                 case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:
    304                     /* Fill send buffer with the default key */
    305                     PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_DEF(mem);
    306                 break;
    307 
    308                 case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:
    309                     /* Fill send buffer with NFC forum sector key */
    310                     PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_NFCSECT_KEYA(mem);
    311                 break;
    312 
    313                 case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:
    314                     /* Fill send buffer with NFC forum sector key */
    315                     PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_SCRT_KEY(mem);
    316                     break;
    317 
    318                 case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:
    319                 default:
    320                     /* Fill send buffer with MAD sector key */
    321                     PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_MADSECT_KEYA(mem);
    322                 break;
    323             }
    324         break;
    325 
    326         case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
    327             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead;
    328 
    329             /* Send length is always one for read operation */
    330             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_1;
    331         break;
    332 
    333         case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
    334             /* Fill send buffer for writing sector trailer */
    335             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
    336             /* Copy the relevant sector trailer value in the buffer */
    337             switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock)
    338             {
    339             case PH_FRINFC_MFSTD_FMT_VAL_3:
    340                 if (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)
    341                 {
    342                     memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    343                                 MADSectTr1k,
    344                                 sizeof(MADSectTr1k));
    345                 }
    346                 else if (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)
    347                 {
    348                     memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    349                                  MADSectTr2k,
    350                                  sizeof(MADSectTr2k));
    351                 }
    352                 else
    353                 {
    354                     memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    355                                 MADSectTr4k,
    356                                 sizeof(MADSectTr4k));
    357                 }
    358                 break;
    359             case 67:
    360                 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    361                             MADSectTr4k,
    362                             sizeof(MADSectTr4k));
    363                 break;
    364             default:
    365                 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    366                             NFCSectTr,
    367                             sizeof(NFCSectTr));
    368                 break;
    369             }
    370             memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_11],
    371                 NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB,
    372                 sizeof(NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB));
    373 
    374             /* Send length is always 17 for write operation */
    375             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
    376         break;
    377 
    378         case PH_FRINFC_MFSTD_FMT_WR_TLV:
    379             /* Fill send buffer for writing TLV */
    380             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
    381             /* Copy the NDEF message TLV */
    382             memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    383                         NDEFMsgTLV, sizeof(NDEFMsgTLV));
    384             /* Send length is always 17 for write operation */
    385             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
    386         break;
    387 
    388         case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK:
    389             /* Fill send buffer for writing MAD block */
    390             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
    391             if((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_2) ||
    392                 (BlockNo == 65) || (BlockNo == 66))
    393             {
    394                 /* MAD block number 2, 65 and 66 has 0x03, 0xE1 in the
    395                  * first two bytes
    396                  */
    397                 MADBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x03;
    398                 MADBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0xE1;
    399             }
    400             /* Copy the MAD Block values */
    401             memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    402                             MADBlk, sizeof(MADBlk));
    403             /* Send length is always 17 for write operation */
    404             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
    405         break;
    406 
    407         case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK:
    408         default:
    409             /* Fill send buffer for writing MAD block */
    410             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
    411             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
    412             switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk)
    413             {
    414             case PH_FRINFC_MFSTD_FMT_MAD_BLK_1:
    415                 memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    416                             NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk,
    417                             (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
    418                 break;
    419 
    420             case PH_FRINFC_MFSTD_FMT_MAD_BLK_2:
    421                 memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    422                     &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[16],
    423                     (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
    424                 break;
    425 
    426             case PH_FRINFC_MFSTD_FMT_MAD_BLK_64:
    427                 memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    428                     &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32],
    429                     (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
    430                 break;
    431 
    432             case PH_FRINFC_MFSTD_FMT_MAD_BLK_65:
    433                 memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    434                     &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[48],
    435                     (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
    436                 break;
    437 
    438             case PH_FRINFC_MFSTD_FMT_MAD_BLK_66:
    439             default:
    440                 memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
    441                     &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[64],
    442                     (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
    443                 break;
    444             }
    445             break;
    446     }
    447 
    448     return;
    449 }
    450 
    451 /*******************************************************************************
    452 **
    453 ** Function         phFriNfc_MfStd_H_Transceive
    454 **
    455 ** Description      This function authenticates a block or a sector from the card.
    456 **
    457 ** Returns          NFCSTATUS_PENDING if successful
    458 **                  Other values if an error has occurred
    459 **
    460 *******************************************************************************/
    461 static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    462 {
    463     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
    464 
    465     /*set the completion routines for the card operations*/
    466     NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process;
    467     NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt;
    468 
    469     *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE;
    470 
    471     /* Call the Overlapped HAL Transceive function */
    472     Result = phFriNfc_ExtnsTransceive(NdefSmtCrdFmt->pTransceiveInfo,
    473                           NdefSmtCrdFmt->Cmd,
    474                           NdefSmtCrdFmt->SendRecvBuf,
    475                           NdefSmtCrdFmt->SendLength,
    476                           NdefSmtCrdFmt->SendRecvLength);
    477     return Result;
    478 }
    479 
    480 /*******************************************************************************
    481 **
    482 ** Function         phFriNfc_MfStd_H_CallDisCon
    483 **
    484 ** Description      This function calls disconnect.
    485 **
    486 ** Returns          NFCSTATUS_PENDING if successful
    487 **                  Other values if an error has occurred
    488 **
    489 *******************************************************************************/
    490 static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, NFCSTATUS Status)
    491 {
    492     NFCSTATUS   Result = Status;
    493 
    494     /*Set Ndef State*/
    495     NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_DIS_CON;
    496 
    497     Result = phNxNciExtns_MifareStd_Reconnect();
    498     return Result;
    499 }
    500 
    501 /*******************************************************************************
    502 **
    503 ** Function         phFriNfc_MfStd_H_CallCon
    504 **
    505 ** Description      This function calls reconnect.
    506 **
    507 ** Returns          NFCSTATUS_PENDING if successful
    508 **                  Other values if an error has occurred
    509 **
    510 *******************************************************************************/
    511 static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    512 {
    513     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
    514     /*Set Ndef State*/
    515     NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_CON;
    516 
    517     Result = phNxNciExtns_MifareStd_Reconnect();
    518     return Result;
    519 }
    520 
    521 /*******************************************************************************
    522 **
    523 ** Function         phFriNfc_MfStd_H_ProCon
    524 **
    525 ** Description      This function shall process the poll call.
    526 **
    527 ** Returns          NFCSTATUS_PENDING if successful
    528 **                  Other values if an error has occurred
    529 **
    530 *******************************************************************************/
    531 static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    532 {
    533     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
    534     uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL};
    535     uint8_t     index = PH_FRINFC_MFSTD_FMT_VAL_1;
    536     uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
    537 
    538     phFriNfc_MfStd_H_ChangeAuthSt(NdefSmtCrdFmt);
    539     if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
    540     {
    541         PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
    542     }
    543     else
    544     {
    545         /* Set the state */
    546         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
    547         /* Start authentication */
    548         Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
    549     }
    550     return Result;
    551 }
    552 
    553 /*******************************************************************************
    554 **
    555 ** Function         phFriNfc_MfStd_H_ProAuth
    556 **
    557 ** Description      This function shall process the authenticate call.
    558 **
    559 ** Returns          NFCSTATUS_PENDING if successful
    560 **                  Other values if an error has occurred
    561 **
    562 *******************************************************************************/
    563 static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    564 {
    565     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
    566 
    567     /* Depending on the authentication key check the  */
    568     switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)
    569     {
    570         case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:
    571             if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
    572                 PH_FRINFC_MFSTD_FMT_VAL_3) &&
    573                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag ==
    574                 PH_FRINFC_MFSTD_FMT_VAL_0))
    575             {
    576                 /* Authenticate with default key for block 3 is successful,
    577                  * so fill the MAD block of sector 0
    578                  */
    579                 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
    580                                     PH_FRINFC_MFSTD_FMT_VAL_1;
    581                 /* Write the MAD block */
    582                 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
    583             }
    584             else if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67)
    585                 && (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag ==
    586                 PH_FRINFC_MFSTD_FMT_VAL_0))
    587             {
    588                 /* Authenticate with default key for block 3 is successful,
    589                  * so fill the MAD block of sector 64
    590                  */
    591                 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 64;
    592                 /* Write the MAD block */
    593                 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
    594             }
    595             else
    596             {
    597                 /* Not a MAD sector */
    598                 NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
    599                                         PH_FRINFC_MFSTD_FMT_VAL_0;
    600                 /* Write the MAD block */
    601                 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
    602             }
    603         break;
    604 
    605         case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:
    606             if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    607                 PH_FRINFC_MFSTD_FMT_MAD_BLK_1) ||
    608                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    609                 PH_FRINFC_MFSTD_FMT_MAD_BLK_2) ||
    610                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    611                 PH_FRINFC_MFSTD_FMT_MAD_BLK_64) ||
    612                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    613                 PH_FRINFC_MFSTD_FMT_MAD_BLK_65) ||
    614                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    615                 PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
    616             {
    617                 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
    618                             NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk;
    619                 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK;
    620             }
    621             else
    622             {
    623                 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
    624                                 PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
    625                 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
    626             }
    627 
    628         break;
    629 
    630         case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:
    631             if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    632                 PH_FRINFC_MFSTD_FMT_MAD_BLK_1) ||
    633                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    634                 PH_FRINFC_MFSTD_FMT_MAD_BLK_2) ||
    635                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    636                 PH_FRINFC_MFSTD_FMT_MAD_BLK_64) ||
    637                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    638                 PH_FRINFC_MFSTD_FMT_MAD_BLK_65) ||
    639                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    640                 PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
    641             {
    642                 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
    643                     NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk;
    644                 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK;
    645             }
    646             else
    647             {
    648                 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
    649                     PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
    650                 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
    651             }
    652             break;
    653 
    654         case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:
    655         case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:
    656         default:
    657             if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    658                 PH_FRINFC_MFSTD_FMT_MAD_BLK_66) ||
    659                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
    660                 PH_FRINFC_MFSTD_FMT_MAD_BLK_2))
    661             {
    662                 /* Updating the MAD block is complete */
    663                 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
    664                                 PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
    665                 /* If Mifare 4k card, write the TLV */
    666                 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_TLV;
    667             }
    668             else
    669             {
    670                 /* Depending on the sector trailer, check the access bit */
    671                 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_RD_SECT_TR;
    672             }
    673         break;
    674     }
    675     /* Call read, write or authenticate */
    676     Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
    677     return Result;
    678 }
    679 
    680 /*******************************************************************************
    681 **
    682 ** Function         phFriNfc_MfStd_H_ErrWrSectTr
    683 **
    684 ** Description      This function shall process the error status of the writing sector trailer.
    685 **
    686 ** Returns          NFCSTATUS_PENDING if successful
    687 **                  Other values if an error has occurred
    688 **
    689 *******************************************************************************/
    690 static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
    691 {
    692     NFCSTATUS   Result = NdefSmtCrdFmt->FmtProcStatus;
    693     /* If default key A is used for authentication and if write fails, then try to
    694      * authenticate using key B
    695      */
    696     if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
    697         PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)
    698     {
    699         /* Change the state to authentication */
    700         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
    701         /* internal authenticate state = key B */
    702         NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB;
    703         /* Now call authenticate */
    704         Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
    705     }
    706     else
    707     {
    708         Result = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt);
    709     }
    710     return Result;
    711 }
    712 
    713 /*******************************************************************************
    714 **
    715 ** Function         phFriNfc_MfStd_H_ProRdSectTr
    716 **
    717 ** Description      This function shall process the read access bit call.
    718 **
    719 ** Returns          NFCSTATUS_PENDING if successful
    720 **                  Other values if an error has occurred
    721 **
    722 *******************************************************************************/
    723 static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    724 {
    725     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
    726     uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
    727                 index = PH_FRINFC_MFSTD_FMT_VAL_1,
    728                 SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
    729     uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
    730 
    731     /* Calculate sector index */
    732     SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
    733 
    734     /* Depending on the sector trailer, check the access bit */
    735     memcompare = phFriNfc_MfStd_H_ChkAcsBit(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock,
    736                                             NdefSmtCrdFmt->SendRecvBuf,
    737                                             NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits,
    738                                             NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits);
    739 
    740     /* Check the sector for ndef compliance */
    741     NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
    742                 ((memcompare != PH_FRINFC_MFSTD_FMT_VAL_0)?
    743                 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
    744                 PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
    745 
    746     /* Increment the current block */
    747     PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
    748     SectIndex++;
    749     if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
    750     {
    751        PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
    752     }
    753     else
    754     {
    755         /* Set the state */
    756         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
    757         /* Set the authenticate state */
    758         NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
    759                             PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
    760         /* Start authentication */
    761         Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
    762     }
    763     return Result;
    764 }
    765 
    766 /*******************************************************************************
    767 **
    768 ** Function         phFriNfc_MfStd_H_ProWrSectTr
    769 **
    770 ** Description      This function shall process the write access bit call.
    771 **
    772 ** Returns          NFCSTATUS_PENDING if successful
    773 **                  Other values if an error has occurred
    774 **
    775 *******************************************************************************/
    776 static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    777 {
    778     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
    779     uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
    780                 index = PH_FRINFC_MFSTD_FMT_VAL_1,
    781                 SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
    782     uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
    783 
    784     /* Calculate sector index */
    785     SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
    786 
    787     /* Sector is ndef compliance */
    788     NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
    789                     ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)?
    790                         PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
    791                         PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
    792 
    793     /* Increment the current block */
    794     PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
    795     SectIndex++;
    796     if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
    797     {
    798         PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
    799     }
    800     else
    801     {
    802         /* Set the state */
    803         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
    804         /* Set the authenticate state */
    805         NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
    806                             PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
    807         /* Start authentication */
    808         Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
    809     }
    810     return Result;
    811 }
    812 
    813 /*******************************************************************************
    814 **
    815 ** Function         phFriNfc_MfStd_H_ChkAcsBit
    816 **
    817 ** Description      This function checks access bits of each sector trailer.
    818 **
    819 ** Returns          compare value
    820 **
    821 *******************************************************************************/
    822 static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t                 BlockNo,
    823                                            const uint8_t            *RecvBuf,
    824                                            const uint8_t            AcsBits1[],
    825                                            const uint8_t            AcsBits2[])
    826 {
    827     uint32_t    mem = PH_FRINFC_MFSTD_FMT_VAL_0;
    828 
    829     /* Compare the access bits read from the sector trailer */
    830     mem = (uint32_t)(((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_3) ||
    831                     (BlockNo == 67))?
    832                     phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6],
    833                             (void*)AcsBits1,
    834                             PH_FRINFC_MFSTD_FMT_VAL_3):
    835                     phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6],
    836                             (void*)AcsBits2,
    837                             PH_FRINFC_MFSTD_FMT_VAL_3));
    838 
    839     return mem;
    840 }
    841 
    842 /*******************************************************************************
    843 **
    844 ** Function         phFriNfc_MfStd_H_WrRdAuth
    845 **
    846 ** Description      This function writes sector trailer using the block number.
    847 **
    848 ** Returns          NFCSTATUS_PENDING if successful
    849 **                  Other values if an error has occurred
    850 **
    851 *******************************************************************************/
    852 static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    853 {
    854     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
    855     /* Fill send buffer and send length */
    856     phFriNfc_MfStd_H_FillSendBuf(NdefSmtCrdFmt,
    857                                  NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock);
    858     /* Call ovrhal transceive */
    859     Result = phFriNfc_MfStd_H_Transceive(NdefSmtCrdFmt);
    860 
    861     return Result;
    862 }
    863 
    864 /*******************************************************************************
    865 **
    866 ** Function         phFriNfc_MfStd_H_ChangeAuthSt
    867 **
    868 ** Description      This function changes authentication state and change the block number if required.
    869 **
    870 ** Returns          none
    871 **
    872 *******************************************************************************/
    873 static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    874 {
    875     uint8_t     SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
    876 
    877     if( NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
    878         PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)
    879     {
    880         /* Calculate sector index */
    881         SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
    882 
    883         /* Check the sector for ndef compliance */
    884         NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] =
    885                     PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL;
    886 
    887         PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
    888     }
    889     PH_FRINFC_MFSTD_FMT_NXT_AUTH_STATE();
    890 
    891     return;
    892 }
    893 
    894 /*******************************************************************************
    895 **
    896 ** Function         phFriNfc_MfStd_H_NdefComplSect
    897 **
    898 ** Description      This function finds contiguous ndef compliant blocks.
    899 **
    900 ** Returns          none
    901 **
    902 *******************************************************************************/
    903  static void phFriNfc_MfStd_H_NdefComplSect(uint8_t CardTypes, uint8_t Sector[])
    904 {
    905     uint8_t     count = PH_FRINFC_MFSTD_FMT_VAL_0,
    906                 NdefComplSectMax = PH_FRINFC_MFSTD_FMT_VAL_0,
    907                 NdefComplSectTemp = PH_FRINFC_MFSTD_FMT_VAL_1,
    908                 SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0,
    909                 MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0,
    910                 MaxSect = PH_FRINFC_MFSTD_FMT_VAL_0;
    911 
    912     /* Get the maximum sector depending on the sector */
    913     MaxSect = ((CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)?
    914                 PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K:
    915                 ((CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)?
    916                   PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K:
    917                   PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K));
    918     /* Sector index */
    919     NdefComplSectTemp = SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1;
    920     /* Check the sector index depending on the card type */
    921     while(((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
    922         (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
    923         ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
    924         (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD))||
    925         ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K) &&
    926         (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)))
    927     {
    928         if (Sector[SectIndex] ==
    929             PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL)
    930         {
    931             if (MaxCont > count)
    932             {
    933                 /* Store the maximum contiguous */
    934                 NdefComplSectMax = NdefComplSectTemp;
    935                 count = MaxCont;
    936             }
    937             MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0;
    938             /* Increment the sector index */
    939             PH_FRINFC_MFSTD_FMT_INCR_SECT;
    940             /* Get the next compliant sector */
    941             NdefComplSectTemp = SectIndex;
    942         }
    943         else
    944         {
    945             /* Increment the sector index */
    946             PH_FRINFC_MFSTD_FMT_INCR_SECT;
    947         }
    948         MaxCont ++;
    949 
    950     }
    951     if (MaxCont > count)
    952     {
    953         /* Store the maximum contiguous */
    954         NdefComplSectMax = NdefComplSectTemp;
    955         count = MaxCont;
    956     }
    957     /* Set the sector value has non ndef compliant which are not present with
    958      * contiguous ndef compliant sectors
    959      */
    960     if((((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_1)) && (CardTypes
    961         == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)) ||
    962         ((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2)) && (CardTypes
    963         == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
    964         ((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2)) && (CardTypes
    965         == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)))&&
    966         ((NdefComplSectMax > PH_FRINFC_MFSTD_FMT_VAL_0) &&
    967         (NdefComplSectMax < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2))))
    968     {
    969         memset(&Sector[PH_FRINFC_MFSTD_FMT_VAL_1],
    970             PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
    971             (NdefComplSectMax - PH_FRINFC_MFSTD_FMT_VAL_1));
    972 
    973 
    974         memset(&Sector[(NdefComplSectMax + count)],
    975             PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
    976             (MaxSect - (NdefComplSectMax + count)));
    977     }
    978 
    979     return;
    980 }
    981 
    982 /*******************************************************************************
    983 **
    984 ** Function         phFriNfc_MfStd_H_ProWrMADBlk
    985 **
    986 ** Description      This function writes the finds MAD block values.
    987 **
    988 ** Returns          NFCSTATUS_PENDING if successful
    989 **                  Other values if an error has occurred
    990 **
    991 *******************************************************************************/
    992 static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
    993 {
    994     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
    995 
    996     switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock)
    997     {
    998     case PH_FRINFC_MFSTD_FMT_VAL_1:
    999         /* MAD blocks, still not completed */
   1000         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
   1001         /* MAD block number 2 */
   1002         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
   1003                             PH_FRINFC_MFSTD_FMT_VAL_2;
   1004         break;
   1005 
   1006     case PH_FRINFC_MFSTD_FMT_VAL_2:
   1007         /* Now write to MAD block is completed */
   1008         NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
   1009                                         PH_FRINFC_MFSTD_FMT_VAL_1;
   1010         /* Now write the sector trailer, so change the state */
   1011         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
   1012         /* MAD block number 3 = Sector trailer */
   1013         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
   1014                             PH_FRINFC_MFSTD_FMT_VAL_3;
   1015         break;
   1016 
   1017     case 64:
   1018         /* MAD blocks, still not completed */
   1019         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
   1020         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 65;
   1021         break;
   1022 
   1023     case 65:
   1024         /* MAD blocks, still not completed */
   1025         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
   1026         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 66;
   1027         break;
   1028 
   1029     case 66:
   1030     default:
   1031         /* Now write to MAD block is completed */
   1032         NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
   1033                                         PH_FRINFC_MFSTD_FMT_VAL_1;
   1034         /* Now write the sector trailer, so change the state */
   1035         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
   1036         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 67;
   1037         break;
   1038 
   1039     }
   1040     /* Write the block */
   1041     Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
   1042 
   1043     return Result;
   1044 }
   1045 
   1046 /*******************************************************************************
   1047 **
   1048 ** Function         phFriNfc_MfStd_H_ProErrAuth
   1049 **
   1050 ** Description      This function shall process the error status of the authentication.
   1051 **
   1052 ** Returns          NFCSTATUS_PENDING if successful
   1053 **                  Other values if an error has occurred
   1054 **
   1055 *******************************************************************************/
   1056 static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
   1057 {
   1058     NFCSTATUS   Result = NdefSmtCrdFmt->FmtProcStatus;
   1059     uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
   1060                 index = PH_FRINFC_MFSTD_FMT_VAL_1;
   1061     uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
   1062 
   1063     if ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67) &&
   1064         (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
   1065                     PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB))
   1066     {
   1067         /* Error in the MAD sector 16, so the remaining sector
   1068          * information can't be updated
   1069          */
   1070         memset(&NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[16],
   1071                     PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
   1072                     (PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K - 16));
   1073         PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
   1074     }
   1075     else if(((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >
   1076         PH_FRINFC_MFSTD_FMT_VAL_3) &&
   1077         (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState !=
   1078         PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)) ||
   1079         ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
   1080         PH_FRINFC_MFSTD_FMT_VAL_3) &&
   1081         (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState <
   1082         PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)))
   1083     {
   1084         /* Authenticate failed, so disconnect, poll and connect */
   1085         Result = phFriNfc_MfStd_H_CallDisCon(NdefSmtCrdFmt,
   1086                                              Result);
   1087     }
   1088     else
   1089     {
   1090         if (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
   1091             PH_FRINFC_MFSTD_FMT_VAL_3)
   1092         {
   1093             memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl,
   1094                         PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
   1095                         PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
   1096         }
   1097     }
   1098 
   1099     return Result;
   1100 }
   1101 
   1102 /*******************************************************************************
   1103 **
   1104 ** Function         phFriNfc_MfStd_H_ProUpdMADBlk
   1105 **
   1106 ** Description      This function shall process the error status of the writing sector trailer.
   1107 **
   1108 ** Returns          NFCSTATUS_PENDING if successful
   1109 **                  Other values if an error has occurred
   1110 **
   1111 *******************************************************************************/
   1112 static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
   1113 {
   1114     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
   1115     switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk)
   1116     {
   1117     case PH_FRINFC_MFSTD_FMT_MAD_BLK_1:
   1118         /* Write the next MAD Block */
   1119         NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
   1120                                 PH_FRINFC_MFSTD_FMT_MAD_BLK_2;
   1121         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
   1122                                 PH_FRINFC_MFSTD_FMT_MAD_BLK_2;
   1123         break;
   1124 
   1125     case PH_FRINFC_MFSTD_FMT_MAD_BLK_2:
   1126     case PH_FRINFC_MFSTD_FMT_MAD_BLK_66:
   1127         if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) ||
   1128            (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
   1129            PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
   1130         {
   1131             /* Get the block from where the TLV has to be written */
   1132             phFriNfc_MfStd_H_BlkNoToWrTLV(NdefSmtCrdFmt);
   1133 
   1134             NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
   1135             NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
   1136                                     PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY;
   1137         }
   1138         else
   1139         {
   1140             /* Write the next MAD Block */
   1141             NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
   1142                             PH_FRINFC_MFSTD_FMT_MAD_BLK_64;
   1143                 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
   1144                             PH_FRINFC_MFSTD_FMT_MAD_BLK_64;
   1145             NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
   1146             NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
   1147                                 PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB;
   1148         }
   1149         break;
   1150 
   1151     case PH_FRINFC_MFSTD_FMT_MAD_BLK_64:
   1152         /* Write the next MAD Block */
   1153         NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
   1154                                 PH_FRINFC_MFSTD_FMT_MAD_BLK_65;
   1155         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
   1156                                 PH_FRINFC_MFSTD_FMT_MAD_BLK_65;
   1157         break;
   1158 
   1159     case PH_FRINFC_MFSTD_FMT_MAD_BLK_65:
   1160     default:
   1161         /* Write the next MAD Block */
   1162         NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
   1163                                     PH_FRINFC_MFSTD_FMT_MAD_BLK_66;
   1164         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
   1165                                     PH_FRINFC_MFSTD_FMT_MAD_BLK_66;
   1166         break;
   1167     }
   1168     Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
   1169     return Result;
   1170 }
   1171 
   1172 /*******************************************************************************
   1173 **
   1174 ** Function         phFriNfc_MfStd_H_StrNdefData
   1175 **
   1176 ** Description      This function shall store ndef compliant in the MAD array
   1177 **                  which will be later used for updating the MAD sector.
   1178 **
   1179 ** Returns          none
   1180 **
   1181 *******************************************************************************/
   1182 static void phFriNfc_MfStd_H_StrNdefData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
   1183 {
   1184     uint8_t     SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1,
   1185                 index = PH_FRINFC_MFSTD_FMT_VAL_0;
   1186 
   1187     memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk,
   1188                 0x00,
   1189                 PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
   1190 
   1191     /* Zeroth sector of the Mifare card is MAD sector, CRC is 0x14 */
   1192     NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x14;
   1193     /* Info byte is 0x01, because the NDEF application is written and as per the MAD spec,
   1194      * the value for miscellaneous application is 0x01
   1195      */
   1196     NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0x01;
   1197 
   1198     if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD) ||
   1199        (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD))
   1200     {
   1201         /* If 4k card then sector number 16 is MAD sector, CRC is 0xE8 */
   1202         NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32] = 0xE8;
   1203         /* Info byte is 0x01, because the NDEF application is written and
   1204          * as per the MAD spec,
   1205          * the value for miscellaneous application is 0x01
   1206          */
   1207         NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[33] = 0x01;
   1208     }
   1209     /* NDEF information has to be updated from */
   1210     index = PH_FRINFC_MFSTD_FMT_VAL_2;
   1211     /* Depending on the card type, check the sector index */
   1212     while (((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
   1213         (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
   1214         ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
   1215         (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)) ||
   1216         ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K) &&
   1217         (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)))
   1218     {
   1219         /* Is the sector ndef compliant? */
   1220         if(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] ==
   1221             PH_FRINFC_MFSTD_FMT_NDEF_COMPL)
   1222         {
   1223             /* Ndef compliant sector, update the MAD sector array
   1224              * in the context with values 0x03 and 0xE1
   1225              * 0x03 and 0xE1 is NDEF information in MAD sector
   1226              */
   1227             NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] =
   1228                                         PH_FRINFC_MFSTD_FMT_NDEF_INFO1;
   1229             index++;
   1230             NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] =
   1231                                         PH_FRINFC_MFSTD_FMT_NDEF_INFO2;
   1232             index++;
   1233         }
   1234         else
   1235         {
   1236             /* Not a Ndef compliant sector, update the MAD sector array
   1237              * in the context with values 0x00 and 0x00
   1238              * 0x00 and 0x00 is NDEF information in MAD sector
   1239              */
   1240             NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00;
   1241             index++;
   1242             NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00;
   1243             index++;
   1244         }
   1245         /* Go to next sector */
   1246         SectIndex++;
   1247         /* is the sector, a MAD sector 16? */
   1248         if(SectIndex == PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K)
   1249         {
   1250             /* MAD sector number 16, so skip this sector */
   1251             SectIndex = SectIndex + PH_FRINFC_MFSTD_FMT_VAL_1;
   1252             index = index + PH_FRINFC_MFSTD_FMT_VAL_2;
   1253         }
   1254     }
   1255 
   1256     return;
   1257 }
   1258 
   1259 /*******************************************************************************
   1260 **
   1261 ** Function         phFriNfc_MfStd_H_BlkNoToWrTLV
   1262 **
   1263 ** Description      This function shall find the ndef compliant
   1264 **                  and calculate the block number to write the NDEF TLV.
   1265 **
   1266 ** Returns          none
   1267 **
   1268 *******************************************************************************/
   1269 static void phFriNfc_MfStd_H_BlkNoToWrTLV(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
   1270 {
   1271     uint8_t     SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_1;
   1272     while (((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
   1273         (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
   1274         ((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
   1275         (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)) ||
   1276         ((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K) &&
   1277         (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)))
   1278     {
   1279         if (NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] ==
   1280             (uint8_t)PH_FRINFC_MFSTD_FMT_NDEF_COMPL)
   1281         {
   1282             /* Get the first NFC forum sector's block */
   1283             NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = (uint16_t)
   1284                                           (((SectIndex & 0xE0) >= 32)?
   1285                                         (128 + ((SectIndex % 32) * 16)):
   1286                                         (SectIndex * (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_4));
   1287             /* Break out of the loop */
   1288             SectIndex += (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K;
   1289         }
   1290         SectIndex++;
   1291     }
   1292 
   1293     return;
   1294 }
   1295 
   1296 /*******************************************************************************
   1297 **
   1298 ** Function         phFriNfc_MfStd_H_ErrRdSectTr
   1299 **
   1300 ** Description      This function shall process the error status of the reading sector trailer.
   1301 **
   1302 ** Returns          NFCSTATUS_PENDING if successful
   1303 **                  Other values if an error has occurred
   1304 **
   1305 *******************************************************************************/
   1306 static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
   1307 {
   1308     NFCSTATUS   Result = NdefSmtCrdFmt->FmtProcStatus;
   1309     uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
   1310                 index = PH_FRINFC_MFSTD_FMT_VAL_1,
   1311                 SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
   1312     uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
   1313     /* If default key A is used for authentication and if write fails, then try to
   1314      * authenticate using key B
   1315      */
   1316     if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
   1317         PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)
   1318     {
   1319         /* Change the state to authentication */
   1320         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
   1321         /* internal authenticate state = key B */
   1322         NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB;
   1323         /* Now call authenticate */
   1324         Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
   1325     }
   1326     else
   1327     {
   1328         /* Calculate sector index */
   1329         SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
   1330 
   1331         /* Sector is ndef compliance */
   1332         NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
   1333                             ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)?
   1334                             PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
   1335                             PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
   1336 
   1337         /* Increment the current block */
   1338         PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
   1339         SectIndex++;
   1340         if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
   1341         {
   1342             PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
   1343         }
   1344         else
   1345         {
   1346             /* Set the state */
   1347             NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
   1348             /* Set the authenticate state */
   1349             NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
   1350                 PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
   1351             /* Start authentication */
   1352             Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
   1353         }
   1354     }
   1355     return Result;
   1356 }
   1357 
   1358 /*******************************************************************************
   1359 **
   1360 ** Function         phFriNfc_MfStd_MemCompare
   1361 **
   1362 ** Description      This function shall process memory comparison.
   1363 **
   1364 ** Returns          0 if memory is same
   1365 **                  Not 0 if different
   1366 **
   1367 *******************************************************************************/
   1368 static int phFriNfc_MfStd_MemCompare(void *s1, void *s2, unsigned int n )
   1369 {
   1370     int8_t   diff = 0;
   1371     int8_t *char_1  =(int8_t *)s1;
   1372     int8_t *char_2  =(int8_t *)s2;
   1373     if(NULL == s1 || NULL == s2)
   1374     {
   1375         NXPLOG_EXTNS_E("NULL pointer passed to memcompare");
   1376     }
   1377     else
   1378     {
   1379         for(;((n>0)&&(diff==0));n--,char_1++,char_2++)
   1380         {
   1381             diff = *char_1 - *char_2;
   1382         }
   1383     }
   1384     return (int)diff;
   1385 }
   1386