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