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