summaryrefslogtreecommitdiffstats
path: root/src/phFriNfc_MifStdFormat.c
diff options
context:
space:
mode:
authorNick Pelly <npelly@google.com>2010-09-23 12:47:58 -0700
committerNick Pelly <npelly@google.com>2010-09-23 13:53:18 -0700
commit5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a (patch)
tree190f9251c6db03d3550ec7f30b51a2561c01d9cf /src/phFriNfc_MifStdFormat.c
parent4ff7c86a2c706b150078274455406f1b04966e1a (diff)
downloadexternal_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.zip
external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.gz
external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.bz2
Initial libnfc checkin
Source: Trusted_NFC_Device_Host_AA03.01e02_google.zip code drop (23-Sep-2010) Change-Id: Ie47f18423f949a8d3e0815d13f55c814312add24 Signed-off-by: Nick Pelly <npelly@google.com>
Diffstat (limited to 'src/phFriNfc_MifStdFormat.c')
-rw-r--r--src/phFriNfc_MifStdFormat.c1303
1 files changed, 1303 insertions, 0 deletions
diff --git a/src/phFriNfc_MifStdFormat.c b/src/phFriNfc_MifStdFormat.c
new file mode 100644
index 0000000..e53c086
--- /dev/null
+++ b/src/phFriNfc_MifStdFormat.c
@@ -0,0 +1,1303 @@
+/*
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * \file phFriNfc_MifStdFormat.c
+ * \brief NFC Ndef Formatting For Mifare standard card.
+ *
+ * Project: NFC-FRI
+ *
+ * $Date: Tue Oct 20 20:13:03 2009 $
+ * $Author: ing02260 $
+ * $Revision: 1.9 $
+ * $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 $
+ *
+ */
+
+#include <phFriNfc_MifStdFormat.h>
+#include <phFriNfc_OvrHal.h>
+
+/*! \ingroup grp_file_attributes
+ * \name NDEF Mapping
+ *
+ * File: \ref phFriNfc_MifStdFormat.c
+ *
+ */
+/*@{*/
+#define PHFRINFCMIFSTDFMT_FILEREVISION "$Revision: 1.9 $"
+#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 $"
+/*@}*/
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function fills the
+ * send buffer for transceive function
+ */
+static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
+ uint16_t BlockNo);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function authenticates
+ * a block or a sector from the card.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function calls
+ * disconnect.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
+ NFCSTATUS Status);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function calls
+ * disconnect.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+#ifndef PH_HAL4_ENABLE
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function calls
+ * disconnect.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_CallPoll(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+#endif /* #ifndef PH_HAL4_ENABLE */
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
+ * poll call.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
+ * authenticate call.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
+ * read access bit call.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
+ * write access bit call.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function writes the
+ * sector trailer using the block number.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function checks the
+ * access bits of each sector trailer.
+ */
+static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t BlockNo,
+ const uint8_t *RecvBuf,
+ const uint8_t AcsBits1[],
+ const uint8_t AcsBits2[]);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function change the
+ * authentication state and change the block number if required
+ */
+static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function finds the
+ * contiguous ndef compliant blocks.
+ */
+static void phFriNfc_MfStd_H_NdefComplSect(uint8_t CardTypes,
+ uint8_t Sector[]);
+
+/*!
+ * \brief \copydoc page_ovr Helper function for Mifare standard. This function writes the
+ * MAD block values.
+ */
+static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
+* the error status of the authentication
+*/
+static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
+* the error status of the writing sector trailer
+*/
+static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
+* the error status of the reading sector trailer
+*/
+static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
+* the error status of the writing sector trailer
+*/
+static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall store the
+* ndef compliant in the MAD array which will be later used for updating the MAD sector
+*/
+static void phFriNfc_MfStd_H_StrNdefData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall find the ndef compliant
+* and calculate the block number to write the NDEF TLV
+*/
+static void phFriNfc_MfStd_H_BlkNoToWrTLV(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+static int phFriNfc_MfStd_MemCompare ( void *s1, void *s2, unsigned int n );
+
+
+void phFriNfc_MfStd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ uint8_t NfcForSectArray[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT,
+ MADSectArray[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K;
+
+ /* Authentication state */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_VAL_1;
+
+ /* Set default key for A or B */
+ (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.Default_KeyA_OR_B,
+ PH_FRINFC_MFSTD_FMT_DEFAULT_KEY, /* 0xFF */
+ PH_FRINFC_MFSTD_FMT_VAL_6);
+
+ /* MAD sector key A */
+ (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_KeyA,
+ MADSectArray, //PH_FRINFC_MFSTD_FMT_VAL_0,
+ PH_FRINFC_MFSTD_FMT_VAL_6);
+
+ /* Copy access bits for MAD sectors */
+ (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits,
+ &MADSectArray[PH_FRINFC_MFSTD_FMT_VAL_6],
+ PH_FRINFC_MFSTD_FMT_VAL_3);
+
+ /* NFC forum sector key A */
+ (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_KeyA,
+ NfcForSectArray, //PH_FRINFC_MFSTD_FMT_VAL_0,
+ PH_FRINFC_MFSTD_FMT_VAL_6);
+
+ /* Copy access bits for NFC forum sectors */
+ (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits,
+ &NfcForSectArray[PH_FRINFC_MFSTD_FMT_VAL_6],
+ PH_FRINFC_MFSTD_FMT_VAL_3);
+
+ /* Sector compliant array initialised to 0 */
+ (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl,
+ PH_FRINFC_MFSTD_FMT_VAL_0, /* 0x00 */
+ PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
+
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_0;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
+
+}
+
+NFCSTATUS phFriNfc_MfStd_Format( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB )
+{
+ NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_PARAMETER);
+ uint8_t index = PH_FRINFC_MFSTD_FMT_VAL_0;
+
+ if(ScrtKeyB != NULL)
+ {
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
+ PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
+ /* Store Key B in the context */
+ while(index < PH_FRINFC_MFSTD_FMT_VAL_6)
+ {
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB[index] = ScrtKeyB[index];
+ index++;
+ }
+ /* Set the state */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
+ /* Initialise current block to the first sector trailer */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = PH_FRINFC_MFSTD_FMT_VAL_3;
+ /* Set the authenticate state */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
+ /* Start authentication */
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+ }
+ return Result;
+}
+
+void phFriNfc_MfStd_Process(void *Context,
+ NFCSTATUS Status)
+{
+ phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context;
+ /* Copy the formatting status */
+ NdefSmtCrdFmt->FmtProcStatus = Status;
+ if(Status == NFCSTATUS_SUCCESS)
+ {
+ switch(NdefSmtCrdFmt->State)
+ {
+ case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
+ Status = phFriNfc_MfStd_H_ProAuth(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_DIS_CON:
+#ifndef PH_HAL4_ENABLE
+ Status = phFriNfc_MfStd_H_CallPoll(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_POLL:
+#endif /* #ifndef PH_HAL4_ENABLE */
+ Status = phFriNfc_MfStd_H_CallCon(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_CON:
+ Status = phFriNfc_MfStd_H_ProCon(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
+ Status = phFriNfc_MfStd_H_ProRdSectTr(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
+ Status = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK:
+ Status = phFriNfc_MfStd_H_ProWrMADBlk(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_WR_TLV:
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK:
+ Status = phFriNfc_MfStd_H_ProUpdMADBlk(NdefSmtCrdFmt);
+ break;
+
+ default:
+ Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ }
+ else
+ {
+ switch(NdefSmtCrdFmt->State)
+ {
+ case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
+ Status = phFriNfc_MfStd_H_ProErrAuth(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
+ Status = phFriNfc_MfStd_H_ErrWrSectTr(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
+ Status = phFriNfc_MfStd_H_ErrRdSectTr(NdefSmtCrdFmt);
+ break;
+
+ default:
+ Status = NdefSmtCrdFmt->FmtProcStatus;
+ break;
+ }
+ }
+
+ /* Status is not success then call completion routine */
+ if(Status != NFCSTATUS_PENDING)
+ {
+ phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, Status);
+ }
+}
+
+static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
+ uint16_t BlockNo)
+{
+ void *mem = NULL;
+ uint8_t MADSectTr1k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K, /* MAD key A,
+ Access bits and GPB of MAD sector */
+ MADSectTr4k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_4K, /* MAD key A,
+ Access bits and GPB of MAD sector */
+ NFCSectTr[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT, /* NFC forum key A,
+ Access bits and GPB of NFC sector */
+ NDEFMsgTLV[16] = {0x03, 0x00, 0xFE, 0x00, 0x00, 0x00, /* NDEF message TLV (INITIALISED state) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00},
+ MADBlk[16] = {0x0F, 0x00, 0x03, 0xE1, 0x03, 0xE1,
+ 0x03, 0xE1, 0x03, 0xE1,
+ 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
+ /* Block number in send buffer */
+ NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_0] = (uint8_t)BlockNo;
+ /* Initialise send receive length */
+ *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_MFSTD_FMT_MAX_RECV_LENGTH;
+
+ /* Depending on the different state, fill the send buffer */
+ switch(NdefSmtCrdFmt->State)
+ {
+ case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
+ /* Depending on the authentication state, fill the send buffer */
+ switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)
+ {
+ case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:
+ case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:
+ /* Fill send buffer with the default key */
+ PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_DEF(mem);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:
+ /* Fill send buffer with NFC forum sector key */
+ PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_NFCSECT_KEYA(mem);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:
+ /* Fill send buffer with NFC forum sector key */
+ PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_SCRT_KEY(mem);
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:
+ default:
+ /* Fill send buffer with MAD sector key */
+ PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_MADSECT_KEYA(mem);
+ break;
+ }
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
+#ifdef PH_HAL4_ENABLE
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead;
+#else
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead;
+#endif /* #ifdef PH_HAL4_ENABLE */
+
+ /* Send length is always one for read operation */
+ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_1;
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
+ /* Fill send buffer for writing sector trailer */
+#ifdef PH_HAL4_ENABLE
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
+#else
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
+#endif /* #ifdef PH_HAL4_ENABLE */
+ /* Copy the relevant sector trailer value in the buffer */
+ switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock)
+ {
+ case PH_FRINFC_MFSTD_FMT_VAL_3:
+ if (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)
+ {
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ MADSectTr1k,
+ sizeof(MADSectTr1k));
+ }
+ else
+ {
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ MADSectTr4k,
+ sizeof(MADSectTr4k));
+ }
+ break;
+ case 67:
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ MADSectTr4k,
+ sizeof(MADSectTr4k));
+ break;
+ default:
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ NFCSectTr,
+ sizeof(NFCSectTr));
+ break;
+ }
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_11],
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB,
+ sizeof(NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB));
+
+ /* Send length is always 17 for write operation */
+ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_WR_TLV:
+ /* Fill send buffer for writing TLV */
+#ifdef PH_HAL4_ENABLE
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
+#else
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
+#endif /* #ifdef PH_HAL4_ENABLE */
+ /* Copy the NDEF message TLV */
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ NDEFMsgTLV, sizeof(NDEFMsgTLV));
+ /* Send length is always 17 for write operation */
+ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK:
+ /* Fill send buffer for writing MAD block */
+#ifdef PH_HAL4_ENABLE
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
+#else
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
+#endif /* #ifdef PH_HAL4_ENABLE */
+
+ if((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_2) ||
+ (BlockNo == 65) || (BlockNo == 66))
+ {
+ /* MAD block number 2, 65 and 66 has 0x03, 0xE1 in the
+ first two bytes */
+ MADBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x03;
+ MADBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0xE1;
+ }
+ /* Copy the MAD Block values */
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ MADBlk, sizeof(MADBlk));
+ /* Send length is always 17 for write operation */
+ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK:
+ default:
+ /* Fill send buffer for writing MAD block */
+#ifdef PH_HAL4_ENABLE
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
+#else
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
+#endif /* #ifdef PH_HAL4_ENABLE */
+ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
+ switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk)
+ {
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_1:
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk,
+ (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_2:
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[16],
+ (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_64:
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32],
+ (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_65:
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[48],
+ (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_66:
+ default:
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
+ &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[64],
+ (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
+ break;
+ }
+ break;
+ }
+ PHNFC_UNUSED_VARIABLE(mem);
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+
+ /* set the data for additional data exchange*/
+ NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
+ NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0;
+ NdefSmtCrdFmt->psDepAdditionalInfo.NAD = 0;
+
+ /*set the completion routines for the card operations*/
+ NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process;
+ NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt;
+
+ *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE;
+
+ /* Call the Overlapped HAL Transceive function */
+ Result = phFriNfc_OvrHal_Transceive( NdefSmtCrdFmt->LowerDevice,
+ &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
+ NdefSmtCrdFmt->psRemoteDevInfo,
+ NdefSmtCrdFmt->Cmd,
+ &NdefSmtCrdFmt->psDepAdditionalInfo,
+ NdefSmtCrdFmt->SendRecvBuf,
+ NdefSmtCrdFmt->SendLength,
+ NdefSmtCrdFmt->SendRecvBuf,
+ NdefSmtCrdFmt->SendRecvLength);
+ return Result;
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
+ NFCSTATUS Status)
+{
+ NFCSTATUS Result = Status;
+
+ /*Set Ndef State*/
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_DIS_CON;
+
+#ifdef PH_HAL4_ENABLE
+
+ /*Call the Overlapped HAL POLL function */
+ Result = phFriNfc_OvrHal_Reconnect( NdefSmtCrdFmt->LowerDevice,
+ &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
+ NdefSmtCrdFmt->psRemoteDevInfo);
+#else
+ /*Call the Overlapped HAL POLL function */
+ Result = phFriNfc_OvrHal_Disconnect( NdefSmtCrdFmt->LowerDevice,
+ &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
+ NdefSmtCrdFmt->psRemoteDevInfo);
+#endif /* #ifdef PH_HAL4_ENABLE */
+
+ return Result;
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+ /*Set Ndef State*/
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_CON;
+
+ /*Call the Overlapped HAL POLL function */
+#ifdef PH_HAL4_ENABLE
+ Result = phFriNfc_OvrHal_Connect( NdefSmtCrdFmt->LowerDevice,
+ &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
+ NdefSmtCrdFmt->psRemoteDevInfo,
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam);
+#else
+ Result = phFriNfc_OvrHal_Connect( NdefSmtCrdFmt->LowerDevice,
+ &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
+ phHal_eOpModesMifare,
+ NdefSmtCrdFmt->psRemoteDevInfo,
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam);
+#endif /* #ifdef PH_HAL4_ENABLE */
+
+ return Result;
+}
+
+#ifndef PH_HAL4_ENABLE
+
+static NFCSTATUS phFriNfc_MfStd_H_CallPoll(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+ /*Set ndef State*/
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_POLL;
+ /* Opmodes */
+ NdefSmtCrdFmt->OpModeType[PH_FRINFC_MFSTD_FMT_VAL_0] = phHal_eOpModesMifare;
+ NdefSmtCrdFmt->OpModeType[PH_FRINFC_MFSTD_FMT_VAL_1] = phHal_eOpModesArrayTerminator;
+
+ /* Number of devices to poll */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.NoOfDevices = PH_FRINFC_MFSTD_FMT_VAL_1;
+
+ /*Call the Overlapped HAL POLL function */
+ Result = phFriNfc_OvrHal_Poll( NdefSmtCrdFmt->LowerDevice,
+ &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
+ NdefSmtCrdFmt->OpModeType,
+ NdefSmtCrdFmt->psRemoteDevInfo,
+ &NdefSmtCrdFmt->AddInfo.MfStdInfo.NoOfDevices,
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam);
+ return Result;
+}
+
+#endif /* #ifndef PH_HAL4_ENABLE */
+
+static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+ uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
+ index = PH_FRINFC_MFSTD_FMT_VAL_1;
+ uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
+
+ phFriNfc_MfStd_H_ChangeAuthSt(NdefSmtCrdFmt);
+ if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
+ {
+ PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
+ }
+ else
+ {
+ /* Set the state */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
+ /* Start authentication */
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+ }
+ return Result;
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+
+ /* Depending on the authentication key check the */
+ switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)
+ {
+ case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:
+ if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
+ PH_FRINFC_MFSTD_FMT_VAL_3) &&
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag ==
+ PH_FRINFC_MFSTD_FMT_VAL_0))
+ {
+ /* Authenticate with default key for block 3 is successful,
+ so fill the MAD block of sector 0 */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
+ PH_FRINFC_MFSTD_FMT_VAL_1;
+ /* Write the MAD block */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
+ }
+ else if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67)
+ && (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag ==
+ PH_FRINFC_MFSTD_FMT_VAL_0))
+ {
+ /* Authenticate with default key for block 3 is successful,
+ so fill the MAD block of sector 64 */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 64;
+ /* Write the MAD block */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
+ }
+ else
+ {
+ /* Not a MAD sector */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
+ PH_FRINFC_MFSTD_FMT_VAL_0;
+ /* Write the MAD block */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
+ }
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:
+ if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_1) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_2) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_64) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_65) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
+ {
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk;
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK;
+ }
+ else
+ {
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
+ PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
+ }
+
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:
+ if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_1) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_2) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_64) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_65) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
+ {
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk;
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK;
+ }
+ else
+ {
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
+ PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
+ }
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:
+ case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:
+ default:
+ if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_66) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_2))
+ {
+ /* Updating the MAD block is complete */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
+ PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
+ /* If Mifare 4k card, write the TLV */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_TLV;
+ }
+ else
+ {
+ /* Depending on the sector trailer, check the access bit */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_RD_SECT_TR;
+ }
+ break;
+ }
+ /* Call read, write or authenticate */
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+ return Result;
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
+{
+ NFCSTATUS Result = NdefSmtCrdFmt->FmtProcStatus;
+ /* If default key A is used for authentication and if write fails, then try to
+ authenticate using key B*/
+ if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
+ PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)
+ {
+ /* Change the state to authentication */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
+ /* internal authenticate state = key B */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB;
+ /* Now call authenticate */
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+ }
+ else
+ {
+ Result = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt);
+ }
+ return Result;
+}
+static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+ uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
+ index = PH_FRINFC_MFSTD_FMT_VAL_1,
+ SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
+ uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
+
+ /* Calculate sector index */
+ SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
+
+ /* Depending on the sector trailer, check the access bit */
+ memcompare = phFriNfc_MfStd_H_ChkAcsBit(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock,
+ NdefSmtCrdFmt->SendRecvBuf,
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits,
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits);
+
+ /* Check the sector for ndef compliance */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
+ ((memcompare != PH_FRINFC_MFSTD_FMT_VAL_0)?
+ PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
+ PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
+
+ /* Increment the current block */
+ PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
+ SectIndex++;
+ if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
+ {
+ PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
+ }
+ else
+ {
+ /* Set the state */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
+ /* Set the authenticate state */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
+ PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
+ /* Start authentication */
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+ }
+ return Result;
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+ uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
+ index = PH_FRINFC_MFSTD_FMT_VAL_1,
+ SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
+ uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
+
+ /* Calculate sector index */
+ SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
+
+ /* Sector is ndef compliance */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
+ ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)?
+ PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
+ PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
+
+ /* Increment the current block */
+ PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
+ SectIndex++;
+ if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
+ {
+ PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
+ }
+ else
+ {
+ /* Set the state */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
+ /* Set the authenticate state */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
+ PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
+ /* Start authentication */
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+ }
+ return Result;
+}
+
+static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t BlockNo,
+ const uint8_t *RecvBuf,
+ const uint8_t AcsBits1[],
+ const uint8_t AcsBits2[])
+{
+ uint32_t mem = PH_FRINFC_MFSTD_FMT_VAL_0;
+
+ /* Compare the access bits read from the sector trailer */
+ mem = (uint32_t)(((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_3) ||
+ (BlockNo == 67))?
+ phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6],
+ (void*)AcsBits1,
+ PH_FRINFC_MFSTD_FMT_VAL_3):
+ phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6],
+ (void*)AcsBits2,
+ PH_FRINFC_MFSTD_FMT_VAL_3));
+
+ return mem;
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+ /* Fill send buffer and send length */
+ phFriNfc_MfStd_H_FillSendBuf(NdefSmtCrdFmt,
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock);
+ /* Call ovrhal transceive */
+ Result = phFriNfc_MfStd_H_Transceive(NdefSmtCrdFmt);
+
+ return Result;
+}
+
+static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ uint8_t SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
+
+ if( NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
+ PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)
+ {
+ /* Calculate sector index */
+ SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
+
+ /* Check the sector for ndef compliance */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] =
+ PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL;
+
+ PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
+ }
+ PH_FRINFC_MFSTD_FMT_NXT_AUTH_STATE();
+}
+
+static void phFriNfc_MfStd_H_NdefComplSect(uint8_t CardTypes,
+ uint8_t Sector[])
+{
+ uint8_t count = PH_FRINFC_MFSTD_FMT_VAL_0,
+ NdefComplSectMax = PH_FRINFC_MFSTD_FMT_VAL_0,
+ NdefComplSectTemp = PH_FRINFC_MFSTD_FMT_VAL_1,
+ SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0,
+ MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0,
+ MaxSect = PH_FRINFC_MFSTD_FMT_VAL_0;
+
+ /* Get the maximum sector depending on the sector */
+ MaxSect = ((CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)?
+ PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K:
+ PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
+ /* Sector index */
+ NdefComplSectTemp = SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1;
+ /* Check the sector index depending on the card type */
+ while(((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
+ (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
+ ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
+ (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)))
+ {
+ if (Sector[SectIndex] ==
+ PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL)
+ {
+ if (MaxCont > count)
+ {
+ /* Store the maximum contiguous */
+ NdefComplSectMax = NdefComplSectTemp;
+ count = MaxCont;
+ }
+ MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0;
+ /* Increment the sector index */
+ PH_FRINFC_MFSTD_FMT_INCR_SECT;
+ /* Get the next compliant sector */
+ NdefComplSectTemp = SectIndex;
+ }
+ else
+ {
+ /* Increment the sector index */
+ PH_FRINFC_MFSTD_FMT_INCR_SECT;
+ }
+ MaxCont ++;
+
+ }
+ if (MaxCont > count)
+ {
+ /* Store the maximum contiguous */
+ NdefComplSectMax = NdefComplSectTemp;
+ count = MaxCont;
+ }
+ /* Set the sector value has non ndef compliant which are not present with
+ contiguous ndef compliant sectors */
+ if((((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_1)) && (CardTypes
+ == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)) ||
+ ((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2)) && (CardTypes
+ == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD))) &&
+ ((NdefComplSectMax > PH_FRINFC_MFSTD_FMT_VAL_0) &&
+ (NdefComplSectMax < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2))))
+ {
+ (void)memset(&Sector[PH_FRINFC_MFSTD_FMT_VAL_1],
+ PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
+ (NdefComplSectMax - PH_FRINFC_MFSTD_FMT_VAL_1));
+
+ (void)memset(&Sector[(NdefComplSectMax + count)],
+ PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
+ (MaxSect - (NdefComplSectMax + count)));
+ }
+}
+
+
+static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+
+ switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock)
+ {
+ case PH_FRINFC_MFSTD_FMT_VAL_1:
+ /* MAD blocks, still not completed */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
+ /* MAD block number 2 */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
+ PH_FRINFC_MFSTD_FMT_VAL_2;
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_VAL_2:
+ /* Now write to MAD block is completed */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
+ PH_FRINFC_MFSTD_FMT_VAL_1;
+ /* Now write the sector trailer, so change the state */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
+ /* MAD block number 3 = Sector trailer */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
+ PH_FRINFC_MFSTD_FMT_VAL_3;
+ break;
+
+ case 64:
+ /* MAD blocks, still not completed */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 65;
+ break;
+
+ case 65:
+ /* MAD blocks, still not completed */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 66;
+ break;
+
+ case 66:
+ default:
+ /* Now write to MAD block is completed */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
+ PH_FRINFC_MFSTD_FMT_VAL_1;
+ /* Now write the sector trailer, so change the state */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 67;
+ break;
+
+ }
+ /* Write the block */
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+
+ return Result;
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
+{
+ NFCSTATUS Result = NdefSmtCrdFmt->FmtProcStatus;
+ uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
+ index = PH_FRINFC_MFSTD_FMT_VAL_1;
+ uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
+
+ if ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67) &&
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
+ PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB))
+ {
+ /* Error in the MAD sector 16, so the remaining sector
+ information cant be updated */
+ (void)memset(&NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[16],
+ PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
+ (PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K - 16));
+ PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
+ }
+ else if(((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >
+ PH_FRINFC_MFSTD_FMT_VAL_3) &&
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState !=
+ PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)) ||
+ ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
+ PH_FRINFC_MFSTD_FMT_VAL_3) &&
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState <
+ PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)))
+ {
+ /* Authenticate failed, so disconnect, poll and connect */
+ Result = phFriNfc_MfStd_H_CallDisCon(NdefSmtCrdFmt,
+ Result);
+ }
+ else
+ {
+ if (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
+ PH_FRINFC_MFSTD_FMT_VAL_3)
+ {
+ (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl,
+ PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
+ PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
+ }
+ }
+
+ return Result;
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+ switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk)
+ {
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_1:
+ /* Write the next MAD Block */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_2;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_2;
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_2:
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_66:
+ if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) ||
+ (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
+ {
+ /* Get the block from where the TLV has to be written */
+ phFriNfc_MfStd_H_BlkNoToWrTLV(NdefSmtCrdFmt);
+
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
+ PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY;
+ }
+ else
+ {
+ /* Write the next MAD Block */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_64;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_64;
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
+ PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB;
+ }
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_64:
+ /* Write the next MAD Block */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_65;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_65;
+ break;
+
+ case PH_FRINFC_MFSTD_FMT_MAD_BLK_65:
+ default:
+ /* Write the next MAD Block */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_66;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
+ PH_FRINFC_MFSTD_FMT_MAD_BLK_66;
+ break;
+ }
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+ return Result;
+}
+
+static void phFriNfc_MfStd_H_StrNdefData( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
+{
+ uint8_t SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1,
+ index = PH_FRINFC_MFSTD_FMT_VAL_0;
+
+ (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk,
+ 0x00,
+ PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
+
+ /* Zeroth sector of the Mifare card is MAD sector, CRC is 0x14 */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x14;
+ /* Info byte is 0x01, because the NDEF application is written and as per the MAD spec,
+ the value for miscellaneous application is 0x01 */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0x01;
+
+ if(NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)
+ {
+ /* If 4k card then sector number 16 is MAD sector, CRC is 0xE8 */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32] = 0xE8;
+ /* Info byte is 0x01, because the NDEF application is written and
+ as per the MAD spec,
+ the value for miscellaneous application is 0x01 */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[33] = 0x01;
+ }
+ /* NDEF information has to be updated from */
+ index = PH_FRINFC_MFSTD_FMT_VAL_2;
+ /* Depending on the card type, check the sector index */
+ while (((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
+ (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
+ ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
+ (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)))
+ {
+ /* Is the sector ndef compliant? */
+ if(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] ==
+ PH_FRINFC_MFSTD_FMT_NDEF_COMPL)
+ {
+ /* Ndef compliant sector, update the MAD sector array
+ in the context with values 0x03 and 0xE1
+ 0x03 and 0xE1 is NDEF information in MAD sector */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] =
+ PH_FRINFC_MFSTD_FMT_NDEF_INFO1;
+ index++;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] =
+ PH_FRINFC_MFSTD_FMT_NDEF_INFO2;
+ index++;
+ }
+ else
+ {
+ /* Not a Ndef compliant sector, update the MAD sector array
+ in the context with values 0x00 and 0x00
+ 0x00 and 0x00 is NDEF information in MAD sector */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00;
+ index++;
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00;
+ index++;
+ }
+ /* Go to next sector */
+ SectIndex++;
+ /* is the sector, a MAD sector 16? */
+ if(SectIndex == PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K)
+ {
+ /* MAD sector number 16, so skip this sector */
+ SectIndex = SectIndex + PH_FRINFC_MFSTD_FMT_VAL_1;
+ index = index + PH_FRINFC_MFSTD_FMT_VAL_2;
+ }
+ }
+}
+
+static void phFriNfc_MfStd_H_BlkNoToWrTLV( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
+{
+ uint8_t SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_1;
+ while (((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
+ (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
+ ((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
+ (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)))
+ {
+ if (NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] ==
+ (uint8_t)PH_FRINFC_MFSTD_FMT_NDEF_COMPL)
+ {
+ /* Get the first NFC forum sector's block */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = (uint16_t)
+ (((SectIndex & 0xE0) >= 32)?
+ (128 + ((SectIndex % 32) * 16)):
+ (SectIndex * (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_4));
+ /* Break out of the loop */
+ SectIndex += (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K;
+ }
+ SectIndex++;
+ }
+}
+
+static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
+{
+ NFCSTATUS Result = NdefSmtCrdFmt->FmtProcStatus;
+ uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
+ index = PH_FRINFC_MFSTD_FMT_VAL_1,
+ SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
+ uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
+ /* If default key A is used for authentication and if write fails, then try to
+ authenticate using key B*/
+ if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
+ PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)
+ {
+ /* Change the state to authentication */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
+ /* internal authenticate state = key B */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB;
+ /* Now call authenticate */
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+ }
+ else
+ {
+ /* Calculate sector index */
+ SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
+
+ /* Sector is ndef compliance */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
+ ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)?
+ PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
+ PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
+
+ /* Increment the current block */
+ PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
+ SectIndex++;
+ if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
+ {
+ PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
+ }
+ else
+ {
+ /* Set the state */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
+ /* Set the authenticate state */
+ NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
+ PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
+ /* Start authentication */
+ Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
+ }
+ }
+ return Result;
+}
+
+static int phFriNfc_MfStd_MemCompare( void *s1, void *s2, unsigned int n )
+{
+ int8_t diff = 0;
+ int8_t *char_1 =(int8_t *)s1;
+ int8_t *char_2 =(int8_t *)s2;
+ if(NULL == s1 || NULL == s2)
+ {
+ PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare");
+ }
+ else
+ {
+ for(;((n>0)&&(diff==0));n--,char_1++,char_2++)
+ {
+ diff = *char_1 - *char_2;
+ }
+ }
+ return (int)diff;
+}
+
+
+
+#ifdef UNIT_TEST
+#include <phUnitTestNfc_MifStdFormat_static.c>
+#endif