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