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