diff options
author | Nick Pelly <npelly@google.com> | 2010-09-23 12:47:58 -0700 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2010-09-23 13:53:18 -0700 |
commit | 5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a (patch) | |
tree | 190f9251c6db03d3550ec7f30b51a2561c01d9cf /src/phFriNfc_MifStdFormat.c | |
parent | 4ff7c86a2c706b150078274455406f1b04966e1a (diff) | |
download | external_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.c | 1303 |
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 |