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