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