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