2 * Copyright (C) 2010 NXP Semiconductors
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * \file phFriNfc_MifStdFormat.c
19 * \brief NFC Ndef Formatting For Mifare standard card.
23 * $Date: Tue Oct 20 20:13:03 2009 $
26 * $Aliases: NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $
30 #include <phFriNfc_MifStdFormat.h>
31 #include <phFriNfc_OvrHal.h>
33 /*! \ingroup grp_file_attributes
36 * File: \ref phFriNfc_MifStdFormat.c
40 #define PHFRINFCMIFSTDFMT_FILEREVISION "$Revision: 1.9 $"
41 #define PHFRINFCMIFSTDFMT_FILEALIASES "$Aliases: NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $"
45 * \brief \copydoc page_ovr Helper function for Mifare standard. This function fills the
46 * send buffer for transceive function
48 static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
52 * \brief \copydoc page_ovr Helper function for Mifare standard. This function authenticates
53 * a block or a sector from the card.
55 static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
58 * \brief \copydoc page_ovr Helper function for Mifare standard. This function calls
61 static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
65 * \brief \copydoc page_ovr Helper function for Mifare standard. This function calls
68 static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
70 #ifndef PH_HAL4_ENABLE
72 * \brief \copydoc page_ovr Helper function for Mifare standard. This function calls
75 static NFCSTATUS phFriNfc_MfStd_H_CallPoll(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
76 #endif /* #ifndef PH_HAL4_ENABLE */
79 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
82 static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
85 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
88 static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
91 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
92 * read access bit call.
94 static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
97 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
98 * write access bit call.
100 static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
103 * \brief \copydoc page_ovr Helper function for Mifare standard. This function writes the
104 * sector trailer using the block number.
106 static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
109 * \brief \copydoc page_ovr Helper function for Mifare standard. This function checks the
110 * access bits of each sector trailer.
112 static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t BlockNo,
113 const uint8_t *RecvBuf,
114 const uint8_t AcsBits1[],
115 const uint8_t AcsBits2[]);
118 * \brief \copydoc page_ovr Helper function for Mifare standard. This function change the
119 * authentication state and change the block number if required
121 static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
124 * \brief \copydoc page_ovr Helper function for Mifare standard. This function finds the
125 * contiguous ndef compliant blocks.
127 static void phFriNfc_MfStd_H_NdefComplSect(uint8_t CardTypes,
131 * \brief \copydoc page_ovr Helper function for Mifare standard. This function writes the
134 static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
137 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
138 * the error status of the authentication
140 static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
143 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
144 * the error status of the writing sector trailer
146 static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
149 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
150 * the error status of the reading sector trailer
152 static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
155 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
156 * the error status of the writing sector trailer
158 static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
161 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall store the
162 * ndef compliant in the MAD array which will be later used for updating the MAD sector
164 static void phFriNfc_MfStd_H_StrNdefData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
167 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall find the ndef compliant
168 * and calculate the block number to write the NDEF TLV
170 static void phFriNfc_MfStd_H_BlkNoToWrTLV(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
172 static int phFriNfc_MfStd_MemCompare ( void *s1, void *s2, unsigned int n );
175 void phFriNfc_MfStd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
177 uint8_t NfcForSectArray[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT,
178 MADSectArray[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K;
180 /* Authentication state */
181 NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_VAL_1;
183 /* Set default key for A or B */
184 (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.Default_KeyA_OR_B,
185 PH_FRINFC_MFSTD_FMT_DEFAULT_KEY, /* 0xFF */
186 PH_FRINFC_MFSTD_FMT_VAL_6);
188 /* MAD sector key A */
189 (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_KeyA,
190 MADSectArray, //PH_FRINFC_MFSTD_FMT_VAL_0,
191 PH_FRINFC_MFSTD_FMT_VAL_6);
193 /* Copy access bits for MAD sectors */
194 (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits,
195 &MADSectArray[PH_FRINFC_MFSTD_FMT_VAL_6],
196 PH_FRINFC_MFSTD_FMT_VAL_3);
198 /* NFC forum sector key A */
199 (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_KeyA,
200 NfcForSectArray, //PH_FRINFC_MFSTD_FMT_VAL_0,
201 PH_FRINFC_MFSTD_FMT_VAL_6);
203 /* Copy access bits for NFC forum sectors */
204 (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits,
205 &NfcForSectArray[PH_FRINFC_MFSTD_FMT_VAL_6],
206 PH_FRINFC_MFSTD_FMT_VAL_3);
208 /* Sector compliant array initialised to 0 */
209 (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl,
210 PH_FRINFC_MFSTD_FMT_VAL_0, /* 0x00 */
211 PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
213 NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_0;
214 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
218 NFCSTATUS phFriNfc_MfStd_Format( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB )
220 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
221 NFCSTATUS_INVALID_PARAMETER);
222 uint8_t index = PH_FRINFC_MFSTD_FMT_VAL_0;
226 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
227 PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
228 /* Store Key B in the context */
229 while(index < PH_FRINFC_MFSTD_FMT_VAL_6)
231 NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB[index] = ScrtKeyB[index];
235 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
236 /* Initialise current block to the first sector trailer */
237 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = PH_FRINFC_MFSTD_FMT_VAL_3;
238 /* Set the authenticate state */
239 NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
240 /* Start authentication */
241 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
246 void phFriNfc_MfStd_Process(void *Context,
249 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context;
250 /* Copy the formatting status */
251 NdefSmtCrdFmt->FmtProcStatus = Status;
252 if(Status == NFCSTATUS_SUCCESS)
254 switch(NdefSmtCrdFmt->State)
256 case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
257 Status = phFriNfc_MfStd_H_ProAuth(NdefSmtCrdFmt);
260 case PH_FRINFC_MFSTD_FMT_DIS_CON:
261 #ifndef PH_HAL4_ENABLE
262 Status = phFriNfc_MfStd_H_CallPoll(NdefSmtCrdFmt);
265 case PH_FRINFC_MFSTD_FMT_POLL:
266 #endif /* #ifndef PH_HAL4_ENABLE */
267 Status = phFriNfc_MfStd_H_CallCon(NdefSmtCrdFmt);
270 case PH_FRINFC_MFSTD_FMT_CON:
271 Status = phFriNfc_MfStd_H_ProCon(NdefSmtCrdFmt);
274 case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
275 Status = phFriNfc_MfStd_H_ProRdSectTr(NdefSmtCrdFmt);
278 case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
279 Status = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt);
282 case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK:
283 Status = phFriNfc_MfStd_H_ProWrMADBlk(NdefSmtCrdFmt);
286 case PH_FRINFC_MFSTD_FMT_WR_TLV:
289 case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK:
290 Status = phFriNfc_MfStd_H_ProUpdMADBlk(NdefSmtCrdFmt);
294 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
295 NFCSTATUS_INVALID_DEVICE_REQUEST);
301 switch(NdefSmtCrdFmt->State)
303 case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
304 Status = phFriNfc_MfStd_H_ProErrAuth(NdefSmtCrdFmt);
307 case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
308 Status = phFriNfc_MfStd_H_ErrWrSectTr(NdefSmtCrdFmt);
311 case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
312 Status = phFriNfc_MfStd_H_ErrRdSectTr(NdefSmtCrdFmt);
316 Status = NdefSmtCrdFmt->FmtProcStatus;
321 /* Status is not success then call completion routine */
322 if(Status != NFCSTATUS_PENDING)
324 phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, Status);
328 static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
332 uint8_t MADSectTr1k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K, /* MAD key A,
333 Access bits and GPB of MAD sector */
334 MADSectTr4k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_4K, /* MAD key A,
335 Access bits and GPB of MAD sector */
336 NFCSectTr[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT, /* NFC forum key A,
337 Access bits and GPB of NFC sector */
338 NDEFMsgTLV[16] = {0x03, 0x00, 0xFE, 0x00, 0x00, 0x00, /* NDEF message TLV (INITIALISED state) */
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00},
341 MADBlk[16] = {0x0F, 0x00, 0x03, 0xE1, 0x03, 0xE1,
342 0x03, 0xE1, 0x03, 0xE1,
343 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
344 /* Block number in send buffer */
345 NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_0] = (uint8_t)BlockNo;
346 /* Initialise send receive length */
347 *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_MFSTD_FMT_MAX_RECV_LENGTH;
349 /* Depending on the different state, fill the send buffer */
350 switch(NdefSmtCrdFmt->State)
352 case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
353 /* Depending on the authentication state, fill the send buffer */
354 switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)
356 case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:
357 case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:
358 /* Fill send buffer with the default key */
359 PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_DEF(mem);
362 case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:
363 /* Fill send buffer with NFC forum sector key */
364 PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_NFCSECT_KEYA(mem);
367 case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:
368 /* Fill send buffer with NFC forum sector key */
369 PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_SCRT_KEY(mem);
372 case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:
374 /* Fill send buffer with MAD sector key */
375 PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_MADSECT_KEYA(mem);
380 case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
381 #ifdef PH_HAL4_ENABLE
382 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead;
384 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead;
385 #endif /* #ifdef PH_HAL4_ENABLE */
387 /* Send length is always one for read operation */
388 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_1;
391 case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
392 /* Fill send buffer for writing sector trailer */
393 #ifdef PH_HAL4_ENABLE
394 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
396 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
397 #endif /* #ifdef PH_HAL4_ENABLE */
398 /* Copy the relevant sector trailer value in the buffer */
399 switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock)
401 case PH_FRINFC_MFSTD_FMT_VAL_3:
402 if (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)
404 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
406 sizeof(MADSectTr1k));
410 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
412 sizeof(MADSectTr4k));
416 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
418 sizeof(MADSectTr4k));
421 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
426 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_11],
427 NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB,
428 sizeof(NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB));
430 /* Send length is always 17 for write operation */
431 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
434 case PH_FRINFC_MFSTD_FMT_WR_TLV:
435 /* Fill send buffer for writing TLV */
436 #ifdef PH_HAL4_ENABLE
437 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
439 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
440 #endif /* #ifdef PH_HAL4_ENABLE */
441 /* Copy the NDEF message TLV */
442 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
443 NDEFMsgTLV, sizeof(NDEFMsgTLV));
444 /* Send length is always 17 for write operation */
445 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
448 case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK:
449 /* Fill send buffer for writing MAD block */
450 #ifdef PH_HAL4_ENABLE
451 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
453 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
454 #endif /* #ifdef PH_HAL4_ENABLE */
456 if((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_2) ||
457 (BlockNo == 65) || (BlockNo == 66))
459 /* MAD block number 2, 65 and 66 has 0x03, 0xE1 in the
461 MADBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x03;
462 MADBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0xE1;
464 /* Copy the MAD Block values */
465 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
466 MADBlk, sizeof(MADBlk));
467 /* Send length is always 17 for write operation */
468 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
471 case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK:
473 /* Fill send buffer for writing MAD block */
474 #ifdef PH_HAL4_ENABLE
475 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
477 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
478 #endif /* #ifdef PH_HAL4_ENABLE */
479 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
480 switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk)
482 case PH_FRINFC_MFSTD_FMT_MAD_BLK_1:
483 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
484 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk,
485 (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
488 case PH_FRINFC_MFSTD_FMT_MAD_BLK_2:
489 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
490 &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[16],
491 (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
494 case PH_FRINFC_MFSTD_FMT_MAD_BLK_64:
495 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
496 &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32],
497 (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
500 case PH_FRINFC_MFSTD_FMT_MAD_BLK_65:
501 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
502 &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[48],
503 (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
506 case PH_FRINFC_MFSTD_FMT_MAD_BLK_66:
508 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
509 &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[64],
510 (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
515 PHNFC_UNUSED_VARIABLE(mem);
518 static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
520 NFCSTATUS Result = NFCSTATUS_SUCCESS;
522 /* set the data for additional data exchange*/
523 NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
524 NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0;
525 NdefSmtCrdFmt->psDepAdditionalInfo.NAD = 0;
527 /*set the completion routines for the card operations*/
528 NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process;
529 NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt;
531 *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE;
533 /* Call the Overlapped HAL Transceive function */
534 Result = phFriNfc_OvrHal_Transceive( NdefSmtCrdFmt->LowerDevice,
535 &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
536 NdefSmtCrdFmt->psRemoteDevInfo,
538 &NdefSmtCrdFmt->psDepAdditionalInfo,
539 NdefSmtCrdFmt->SendRecvBuf,
540 NdefSmtCrdFmt->SendLength,
541 NdefSmtCrdFmt->SendRecvBuf,
542 NdefSmtCrdFmt->SendRecvLength);
546 static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
549 NFCSTATUS Result = Status;
552 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_DIS_CON;
554 #ifdef PH_HAL4_ENABLE
556 /*Call the Overlapped HAL POLL function */
557 Result = phFriNfc_OvrHal_Reconnect( NdefSmtCrdFmt->LowerDevice,
558 &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
559 NdefSmtCrdFmt->psRemoteDevInfo);
561 /*Call the Overlapped HAL POLL function */
562 Result = phFriNfc_OvrHal_Disconnect( NdefSmtCrdFmt->LowerDevice,
563 &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
564 NdefSmtCrdFmt->psRemoteDevInfo);
565 #endif /* #ifdef PH_HAL4_ENABLE */
570 static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
572 NFCSTATUS Result = NFCSTATUS_SUCCESS;
574 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_CON;
576 /*Call the Overlapped HAL POLL function */
577 #ifdef PH_HAL4_ENABLE
578 Result = phFriNfc_OvrHal_Connect( NdefSmtCrdFmt->LowerDevice,
579 &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
580 NdefSmtCrdFmt->psRemoteDevInfo,
581 NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam);
583 Result = phFriNfc_OvrHal_Connect( NdefSmtCrdFmt->LowerDevice,
584 &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
585 phHal_eOpModesMifare,
586 NdefSmtCrdFmt->psRemoteDevInfo,
587 NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam);
588 #endif /* #ifdef PH_HAL4_ENABLE */
593 #ifndef PH_HAL4_ENABLE
595 static NFCSTATUS phFriNfc_MfStd_H_CallPoll(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
597 NFCSTATUS Result = NFCSTATUS_SUCCESS;
599 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_POLL;
601 NdefSmtCrdFmt->OpModeType[PH_FRINFC_MFSTD_FMT_VAL_0] = phHal_eOpModesMifare;
602 NdefSmtCrdFmt->OpModeType[PH_FRINFC_MFSTD_FMT_VAL_1] = phHal_eOpModesArrayTerminator;
604 /* Number of devices to poll */
605 NdefSmtCrdFmt->AddInfo.MfStdInfo.NoOfDevices = PH_FRINFC_MFSTD_FMT_VAL_1;
607 /*Call the Overlapped HAL POLL function */
608 Result = phFriNfc_OvrHal_Poll( NdefSmtCrdFmt->LowerDevice,
609 &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
610 NdefSmtCrdFmt->OpModeType,
611 NdefSmtCrdFmt->psRemoteDevInfo,
612 &NdefSmtCrdFmt->AddInfo.MfStdInfo.NoOfDevices,
613 NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam);
617 #endif /* #ifndef PH_HAL4_ENABLE */
619 static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
621 NFCSTATUS Result = NFCSTATUS_SUCCESS;
622 uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
623 index = PH_FRINFC_MFSTD_FMT_VAL_1;
624 uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
626 phFriNfc_MfStd_H_ChangeAuthSt(NdefSmtCrdFmt);
627 if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
629 PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
634 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
635 /* Start authentication */
636 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
641 static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
643 NFCSTATUS Result = NFCSTATUS_SUCCESS;
645 /* Depending on the authentication key check the */
646 switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)
648 case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:
649 if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
650 PH_FRINFC_MFSTD_FMT_VAL_3) &&
651 (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag ==
652 PH_FRINFC_MFSTD_FMT_VAL_0))
654 /* Authenticate with default key for block 3 is successful,
655 so fill the MAD block of sector 0 */
656 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
657 PH_FRINFC_MFSTD_FMT_VAL_1;
658 /* Write the MAD block */
659 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
661 else if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67)
662 && (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag ==
663 PH_FRINFC_MFSTD_FMT_VAL_0))
665 /* Authenticate with default key for block 3 is successful,
666 so fill the MAD block of sector 64 */
667 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 64;
668 /* Write the MAD block */
669 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
673 /* Not a MAD sector */
674 NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
675 PH_FRINFC_MFSTD_FMT_VAL_0;
676 /* Write the MAD block */
677 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
681 case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:
682 if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
683 PH_FRINFC_MFSTD_FMT_MAD_BLK_1) ||
684 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
685 PH_FRINFC_MFSTD_FMT_MAD_BLK_2) ||
686 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
687 PH_FRINFC_MFSTD_FMT_MAD_BLK_64) ||
688 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
689 PH_FRINFC_MFSTD_FMT_MAD_BLK_65) ||
690 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
691 PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
693 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
694 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk;
695 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK;
699 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
700 PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
701 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
706 case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:
707 if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
708 PH_FRINFC_MFSTD_FMT_MAD_BLK_1) ||
709 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
710 PH_FRINFC_MFSTD_FMT_MAD_BLK_2) ||
711 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
712 PH_FRINFC_MFSTD_FMT_MAD_BLK_64) ||
713 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
714 PH_FRINFC_MFSTD_FMT_MAD_BLK_65) ||
715 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
716 PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
718 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
719 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk;
720 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK;
724 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
725 PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
726 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
730 case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:
731 case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:
733 if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
734 PH_FRINFC_MFSTD_FMT_MAD_BLK_66) ||
735 (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
736 PH_FRINFC_MFSTD_FMT_MAD_BLK_2))
738 /* Updating the MAD block is complete */
739 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
740 PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
741 /* If Mifare 4k card, write the TLV */
742 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_TLV;
746 /* Depending on the sector trailer, check the access bit */
747 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_RD_SECT_TR;
751 /* Call read, write or authenticate */
752 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
756 static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
758 NFCSTATUS Result = NdefSmtCrdFmt->FmtProcStatus;
759 /* If default key A is used for authentication and if write fails, then try to
760 authenticate using key B*/
761 if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
762 PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)
764 /* Change the state to authentication */
765 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
766 /* internal authenticate state = key B */
767 NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB;
768 /* Now call authenticate */
769 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
773 Result = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt);
777 static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
779 NFCSTATUS Result = NFCSTATUS_SUCCESS;
780 uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
781 index = PH_FRINFC_MFSTD_FMT_VAL_1,
782 SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
783 uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
785 /* Calculate sector index */
786 SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
788 /* Depending on the sector trailer, check the access bit */
789 memcompare = phFriNfc_MfStd_H_ChkAcsBit(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock,
790 NdefSmtCrdFmt->SendRecvBuf,
791 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits,
792 NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits);
794 /* Check the sector for ndef compliance */
795 NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
796 ((memcompare != PH_FRINFC_MFSTD_FMT_VAL_0)?
797 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
798 PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
800 /* Increment the current block */
801 PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
803 if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
805 PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
810 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
811 /* Set the authenticate state */
812 NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
813 PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
814 /* Start authentication */
815 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
820 static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
822 NFCSTATUS Result = NFCSTATUS_SUCCESS;
823 uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
824 index = PH_FRINFC_MFSTD_FMT_VAL_1,
825 SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
826 uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
828 /* Calculate sector index */
829 SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
831 /* Sector is ndef compliance */
832 NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
833 ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)?
834 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
835 PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
837 /* Increment the current block */
838 PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
840 if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
842 PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
847 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
848 /* Set the authenticate state */
849 NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
850 PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
851 /* Start authentication */
852 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
857 static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t BlockNo,
858 const uint8_t *RecvBuf,
859 const uint8_t AcsBits1[],
860 const uint8_t AcsBits2[])
862 uint32_t mem = PH_FRINFC_MFSTD_FMT_VAL_0;
864 /* Compare the access bits read from the sector trailer */
865 mem = (uint32_t)(((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_3) ||
867 phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6],
869 PH_FRINFC_MFSTD_FMT_VAL_3):
870 phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6],
872 PH_FRINFC_MFSTD_FMT_VAL_3));
877 static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
879 NFCSTATUS Result = NFCSTATUS_SUCCESS;
880 /* Fill send buffer and send length */
881 phFriNfc_MfStd_H_FillSendBuf(NdefSmtCrdFmt,
882 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock);
883 /* Call ovrhal transceive */
884 Result = phFriNfc_MfStd_H_Transceive(NdefSmtCrdFmt);
889 static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
891 uint8_t SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
893 if( NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
894 PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)
896 /* Calculate sector index */
897 SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
899 /* Check the sector for ndef compliance */
900 NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] =
901 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL;
903 PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
905 PH_FRINFC_MFSTD_FMT_NXT_AUTH_STATE();
908 static void phFriNfc_MfStd_H_NdefComplSect(uint8_t CardTypes,
911 uint8_t count = PH_FRINFC_MFSTD_FMT_VAL_0,
912 NdefComplSectMax = PH_FRINFC_MFSTD_FMT_VAL_0,
913 NdefComplSectTemp = PH_FRINFC_MFSTD_FMT_VAL_1,
914 SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0,
915 MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0,
916 MaxSect = PH_FRINFC_MFSTD_FMT_VAL_0;
918 /* Get the maximum sector depending on the sector */
919 MaxSect = ((CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)?
920 PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K:
921 PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
923 NdefComplSectTemp = SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1;
924 /* Check the sector index depending on the card type */
925 while(((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
926 (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
927 ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
928 (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)))
930 if (Sector[SectIndex] ==
931 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL)
935 /* Store the maximum contiguous */
936 NdefComplSectMax = NdefComplSectTemp;
939 MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0;
940 /* Increment the sector index */
941 PH_FRINFC_MFSTD_FMT_INCR_SECT;
942 /* Get the next compliant sector */
943 NdefComplSectTemp = SectIndex;
947 /* Increment the sector index */
948 PH_FRINFC_MFSTD_FMT_INCR_SECT;
955 /* Store the maximum contiguous */
956 NdefComplSectMax = NdefComplSectTemp;
959 /* Set the sector value has non ndef compliant which are not present with
960 contiguous ndef compliant sectors */
961 if((((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_1)) && (CardTypes
962 == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)) ||
963 ((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2)) && (CardTypes
964 == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD))) &&
965 ((NdefComplSectMax > PH_FRINFC_MFSTD_FMT_VAL_0) &&
966 (NdefComplSectMax < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2))))
968 (void)memset(&Sector[PH_FRINFC_MFSTD_FMT_VAL_1],
969 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
970 (NdefComplSectMax - PH_FRINFC_MFSTD_FMT_VAL_1));
972 (void)memset(&Sector[(NdefComplSectMax + count)],
973 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
974 (MaxSect - (NdefComplSectMax + count)));
979 static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
981 NFCSTATUS Result = NFCSTATUS_SUCCESS;
983 switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock)
985 case PH_FRINFC_MFSTD_FMT_VAL_1:
986 /* MAD blocks, still not completed */
987 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
988 /* MAD block number 2 */
989 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
990 PH_FRINFC_MFSTD_FMT_VAL_2;
993 case PH_FRINFC_MFSTD_FMT_VAL_2:
994 /* Now write to MAD block is completed */
995 NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
996 PH_FRINFC_MFSTD_FMT_VAL_1;
997 /* Now write the sector trailer, so change the state */
998 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
999 /* MAD block number 3 = Sector trailer */
1000 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1001 PH_FRINFC_MFSTD_FMT_VAL_3;
1005 /* MAD blocks, still not completed */
1006 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
1007 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 65;
1011 /* MAD blocks, still not completed */
1012 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
1013 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 66;
1018 /* Now write to MAD block is completed */
1019 NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
1020 PH_FRINFC_MFSTD_FMT_VAL_1;
1021 /* Now write the sector trailer, so change the state */
1022 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
1023 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 67;
1027 /* Write the block */
1028 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
1033 static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
1035 NFCSTATUS Result = NdefSmtCrdFmt->FmtProcStatus;
1036 uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
1037 index = PH_FRINFC_MFSTD_FMT_VAL_1;
1038 uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
1040 if ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67) &&
1041 (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
1042 PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB))
1044 /* Error in the MAD sector 16, so the remaining sector
1045 information cant be updated */
1046 (void)memset(&NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[16],
1047 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
1048 (PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K - 16));
1049 PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
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)))
1060 /* Authenticate failed, so disconnect, poll and connect */
1061 Result = phFriNfc_MfStd_H_CallDisCon(NdefSmtCrdFmt,
1066 if (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
1067 PH_FRINFC_MFSTD_FMT_VAL_3)
1069 (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl,
1070 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
1071 PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
1078 static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
1080 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1081 switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk)
1083 case PH_FRINFC_MFSTD_FMT_MAD_BLK_1:
1084 /* Write the next MAD Block */
1085 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
1086 PH_FRINFC_MFSTD_FMT_MAD_BLK_2;
1087 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1088 PH_FRINFC_MFSTD_FMT_MAD_BLK_2;
1091 case PH_FRINFC_MFSTD_FMT_MAD_BLK_2:
1092 case PH_FRINFC_MFSTD_FMT_MAD_BLK_66:
1093 if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) ||
1094 (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
1095 PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
1097 /* Get the block from where the TLV has to be written */
1098 phFriNfc_MfStd_H_BlkNoToWrTLV(NdefSmtCrdFmt);
1100 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
1101 NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
1102 PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY;
1106 /* Write the next MAD Block */
1107 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
1108 PH_FRINFC_MFSTD_FMT_MAD_BLK_64;
1109 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1110 PH_FRINFC_MFSTD_FMT_MAD_BLK_64;
1111 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
1112 NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
1113 PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB;
1117 case PH_FRINFC_MFSTD_FMT_MAD_BLK_64:
1118 /* Write the next MAD Block */
1119 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
1120 PH_FRINFC_MFSTD_FMT_MAD_BLK_65;
1121 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1122 PH_FRINFC_MFSTD_FMT_MAD_BLK_65;
1125 case PH_FRINFC_MFSTD_FMT_MAD_BLK_65:
1127 /* Write the next MAD Block */
1128 NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
1129 PH_FRINFC_MFSTD_FMT_MAD_BLK_66;
1130 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1131 PH_FRINFC_MFSTD_FMT_MAD_BLK_66;
1134 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
1138 static void phFriNfc_MfStd_H_StrNdefData( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
1140 uint8_t SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1,
1141 index = PH_FRINFC_MFSTD_FMT_VAL_0;
1143 (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk,
1145 PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
1147 /* Zeroth sector of the Mifare card is MAD sector, CRC is 0x14 */
1148 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x14;
1149 /* Info byte is 0x01, because the NDEF application is written and as per the MAD spec,
1150 the value for miscellaneous application is 0x01 */
1151 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0x01;
1153 if(NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)
1155 /* If 4k card then sector number 16 is MAD sector, CRC is 0xE8 */
1156 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32] = 0xE8;
1157 /* Info byte is 0x01, because the NDEF application is written and
1158 as per the MAD spec,
1159 the value for miscellaneous application is 0x01 */
1160 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[33] = 0x01;
1162 /* NDEF information has to be updated from */
1163 index = PH_FRINFC_MFSTD_FMT_VAL_2;
1164 /* Depending on the card type, check the sector index */
1165 while (((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
1166 (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
1167 ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
1168 (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)))
1170 /* Is the sector ndef compliant? */
1171 if(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] ==
1172 PH_FRINFC_MFSTD_FMT_NDEF_COMPL)
1174 /* Ndef compliant sector, update the MAD sector array
1175 in the context with values 0x03 and 0xE1
1176 0x03 and 0xE1 is NDEF information in MAD sector */
1177 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] =
1178 PH_FRINFC_MFSTD_FMT_NDEF_INFO1;
1180 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] =
1181 PH_FRINFC_MFSTD_FMT_NDEF_INFO2;
1186 /* Not a Ndef compliant sector, update the MAD sector array
1187 in the context with values 0x00 and 0x00
1188 0x00 and 0x00 is NDEF information in MAD sector */
1189 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00;
1191 NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00;
1194 /* Go to next sector */
1196 /* is the sector, a MAD sector 16? */
1197 if(SectIndex == PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K)
1199 /* MAD sector number 16, so skip this sector */
1200 SectIndex = SectIndex + PH_FRINFC_MFSTD_FMT_VAL_1;
1201 index = index + PH_FRINFC_MFSTD_FMT_VAL_2;
1206 static void phFriNfc_MfStd_H_BlkNoToWrTLV( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
1208 uint8_t SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_1;
1209 while (((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
1210 (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
1211 ((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
1212 (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)))
1214 if (NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] ==
1215 (uint8_t)PH_FRINFC_MFSTD_FMT_NDEF_COMPL)
1217 /* Get the first NFC forum sector's block */
1218 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = (uint16_t)
1219 (((SectIndex & 0xE0) >= 32)?
1220 (128 + ((SectIndex % 32) * 16)):
1221 (SectIndex * (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_4));
1222 /* Break out of the loop */
1223 SectIndex += (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K;
1229 static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
1231 NFCSTATUS Result = NdefSmtCrdFmt->FmtProcStatus;
1232 uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
1233 index = PH_FRINFC_MFSTD_FMT_VAL_1,
1234 SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
1235 uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
1236 /* If default key A is used for authentication and if write fails, then try to
1237 authenticate using key B*/
1238 if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
1239 PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)
1241 /* Change the state to authentication */
1242 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
1243 /* internal authenticate state = key B */
1244 NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB;
1245 /* Now call authenticate */
1246 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
1250 /* Calculate sector index */
1251 SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
1253 /* Sector is ndef compliance */
1254 NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
1255 ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)?
1256 PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
1257 PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
1259 /* Increment the current block */
1260 PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
1262 if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
1264 PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
1269 NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
1270 /* Set the authenticate state */
1271 NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
1272 PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
1273 /* Start authentication */
1274 Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
1280 static int phFriNfc_MfStd_MemCompare( void *s1, void *s2, unsigned int n )
1283 int8_t *char_1 =(int8_t *)s1;
1284 int8_t *char_2 =(int8_t *)s2;
1285 if(NULL == s1 || NULL == s2)
1287 PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare");
1291 for(;((n>0)&&(diff==0));n--,char_1++,char_2++)
1293 diff = *char_1 - *char_2;
1302 #include <phUnitTestNfc_MifStdFormat_static.c>