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