summaryrefslogtreecommitdiffstats
path: root/src/phFriNfc_MifULFormat.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_MifULFormat.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_MifULFormat.c')
-rw-r--r--src/phFriNfc_MifULFormat.c431
1 files changed, 431 insertions, 0 deletions
diff --git a/src/phFriNfc_MifULFormat.c b/src/phFriNfc_MifULFormat.c
new file mode 100644
index 0000000..894d455
--- /dev/null
+++ b/src/phFriNfc_MifULFormat.c
@@ -0,0 +1,431 @@
+/*
+ * 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_MifULFormat.c
+ * \brief NFC Ndef Formatting For Mifare ultralight card.
+ *
+ * Project: NFC-FRI
+ *
+ * $Date: Fri Oct 23 12:00:05 2009 $
+ * $Author: ing02260 $
+ * $Revision: 1.8 $
+ * $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_MifULFormat.h>
+#include <phFriNfc_OvrHal.h>
+
+/*! \ingroup grp_file_attributes
+ * \name NDEF Mapping
+ *
+ * File: \ref phFriNfc_MifULFormat.c
+ *
+ */
+/*@{*/
+#define PHFRINFCMIFULFORMAT_FILEREVISION "$Revision: 1.8 $"
+#define PHFRINFCMIFULFORMAT_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 UL. This function calls the
+* transceive function
+*/
+static NFCSTATUS phFriNfc_MfUL_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare UL. This function calls the
+* read or write operation
+*/
+static NFCSTATUS phFriNfc_MfUL_H_WrRd(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare UL. This function fills the
+* send buffer for transceive function
+*/
+static void phFriNfc_MfUL_H_fillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
+ uint8_t BlockNo);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare UL. This function shall process
+* the read bytes
+*/
+static NFCSTATUS phFriNfc_MfUL_H_ProRd16Bytes(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+/*!
+* \brief \copydoc page_ovr Helper function for Mifare UL. This function shall process the
+* OTP bytes written
+*/
+static NFCSTATUS phFriNfc_MfUL_H_ProWrOTPBytes(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
+
+static int MemCompare1 ( void *s1, void *s2, unsigned int n );
+/*The function does a comparision of two strings and returns a non zero value
+if two strings are unequal*/
+static int MemCompare1 ( 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;
+}
+
+void phFriNfc_MfUL_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ uint8_t OTPByte[] = PH_FRINFC_MFUL_FMT_OTP_BYTES;
+
+ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_0;
+ (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
+ OTPByte,
+ sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes));
+}
+
+NFCSTATUS phFriNfc_MfUL_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+ uint8_t OTPByte[] = PH_FRINFC_MFUL_FMT_OTP_BYTES;
+
+ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_0;
+ (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
+ OTPByte,
+ sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes));
+
+ /* Set the state */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RD_16BYTES;
+ /* Initialise current block to the lock bits block */
+ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_2;
+
+ /* Start authentication */
+ Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt);
+ return Result;
+}
+
+void phFriNfc_MfUL_Process(void *Context,
+ NFCSTATUS Status)
+{
+ phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context;
+
+ if(Status == NFCSTATUS_SUCCESS)
+ {
+ switch(NdefSmtCrdFmt->State)
+ {
+ case PH_FRINFC_MFUL_FMT_RD_16BYTES:
+ Status = phFriNfc_MfUL_H_ProRd16Bytes(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFUL_FMT_WR_OTPBYTES:
+ Status = phFriNfc_MfUL_H_ProWrOTPBytes(NdefSmtCrdFmt);
+ break;
+
+ case PH_FRINFC_MFUL_FMT_WR_TLV:
+#ifdef PH_NDEF_MIFARE_ULC
+ if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD)
+ {
+ /* Write NDEF TLV in block number 5 */
+ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
+ PH_FRINFC_MFUL_FMT_VAL_5;
+ /* Card already have the OTP bytes so write TLV */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV1;
+
+ Status = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt);
+ }
+#endif /* #ifdef PH_NDEF_MIFARE_ULC */
+
+ break;
+
+#ifdef PH_NDEF_MIFARE_ULC
+ case PH_FRINFC_MFUL_FMT_WR_TLV1:
+
+ break;
+#endif /* #ifdef PH_NDEF_MIFARE_ULC */
+
+ default:
+ Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ }
+ /* Status is not success then call completion routine */
+ if(Status != NFCSTATUS_PENDING)
+ {
+ phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, Status);
+ }
+}
+
+static NFCSTATUS phFriNfc_MfUL_H_WrRd( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+
+ /* Fill the send buffer */
+ phFriNfc_MfUL_H_fillSendBuf(NdefSmtCrdFmt,
+ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock);
+
+ /* Call transceive */
+ Result = phFriNfc_MfUL_H_Transceive(NdefSmtCrdFmt);
+
+ return Result;
+}
+
+static NFCSTATUS phFriNfc_MfUL_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 void phFriNfc_MfUL_H_fillSendBuf( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
+ uint8_t BlockNo)
+{
+#ifdef PH_NDEF_MIFARE_ULC
+ uint8_t NDEFTLV1[4] = {0x01, 0x03, 0xA0, 0x10};
+ uint8_t NDEFTLV2[4] = {0x44, 0x03, 0x00, 0xFE};
+#endif /* #ifdef PH_NDEF_MIFARE_ULC */
+ uint8_t NDEFTLV[4] = {0x03, 0x00, 0xFE, 0x00};
+
+
+
+
+ /* First byte for send buffer is always the block number */
+ NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_0] = (uint8_t)BlockNo;
+ switch(NdefSmtCrdFmt->State)
+ {
+ case PH_FRINFC_MFUL_FMT_RD_16BYTES:
+#ifdef PH_HAL4_ENABLE
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead;
+#else
+ /* Read command */
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead;
+#endif /* #ifdef PH_HAL4_ENABLE */
+ /* Send length for read command is always one */
+ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1;
+ break;
+
+ case PH_FRINFC_MFUL_FMT_WR_OTPBYTES:
+ /* Send length for read command is always Five */
+ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5;
+ /* Write command */
+#ifdef PH_HAL4_ENABLE
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4;
+#else
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4;
+#endif /* #ifdef PH_HAL4_ENABLE */
+ /* Copy the OTP bytes */
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
+ NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
+ PH_FRINFC_MFUL_FMT_VAL_4);
+ break;
+
+ case PH_FRINFC_MFUL_FMT_WR_TLV:
+#ifndef PH_NDEF_MIFARE_ULC
+ default:
+#endif /* #ifndef PH_NDEF_MIFARE_ULC */
+ /* Send length for read command is always Five */
+ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5;
+ /* Write command */
+#ifdef PH_HAL4_ENABLE
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4;
+#else
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4;
+#endif /* #ifdef PH_HAL4_ENABLE */
+ /* Copy the NDEF TLV */
+#ifdef PH_NDEF_MIFARE_ULC
+
+ if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD)
+ {
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
+ NDEFTLV1,
+ PH_FRINFC_MFUL_FMT_VAL_4);
+ }
+ else if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_UL_CARD)
+ {
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
+ NDEFTLV,
+ PH_FRINFC_MFUL_FMT_VAL_4);
+ }
+ else
+ {
+ }
+#else
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
+ NDEFTLV,
+ PH_FRINFC_MFUL_FMT_VAL_4);
+
+#endif /* #ifdef PH_NDEF_MIFARE_ULC */
+
+ break;
+
+#ifdef PH_NDEF_MIFARE_ULC
+ case PH_FRINFC_MFUL_FMT_WR_TLV1:
+ if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD)
+ {
+ /* Send length for write command is always Five */
+ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5;
+ /* Write command */
+ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4;
+ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
+ NDEFTLV2,
+ PH_FRINFC_MFUL_FMT_VAL_4);
+ }
+ break;
+ default:
+ break;
+#endif /* #ifdef PH_NDEF_MIFARE_ULC */
+
+
+ }
+}
+
+static NFCSTATUS phFriNfc_MfUL_H_ProRd16Bytes( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
+{
+ NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_FORMAT_ERROR);
+ uint32_t memcompare = PH_FRINFC_MFUL_FMT_VAL_0;
+ uint8_t ZeroBuf[] = {0x00, 0x00, 0x00, 0x00};
+
+#ifdef PH_NDEF_MIFARE_ULC
+ uint8_t OTPByteUL[] = PH_FRINFC_MFUL_FMT_OTP_BYTES;
+ uint8_t OTPByteULC[] = PH_FRINFC_MFULC_FMT_OTP_BYTES;
+#endif /* #ifdef PH_NDEF_MIFARE_ULC */
+
+ /* Check the lock bits (byte number 2 and 3 of block number 2) */
+ if ((NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_2] ==
+ PH_FRINFC_MFUL_FMT_LOCK_BITS_VAL) &&
+ (NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_3] ==
+ PH_FRINFC_MFUL_FMT_LOCK_BITS_VAL))
+ {
+
+#ifdef PH_NDEF_MIFARE_ULC
+
+ if (NdefSmtCrdFmt->SendRecvBuf[8] == 0x02 &&
+ NdefSmtCrdFmt->SendRecvBuf[9] == 0x00)
+ {
+ NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD;
+
+ (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
+ OTPByteULC,
+ sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes));
+ }
+ else if (NdefSmtCrdFmt->SendRecvBuf[8] == 0xFF &&
+ NdefSmtCrdFmt->SendRecvBuf[9] == 0xFF)
+ {
+ NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD;
+
+ (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
+ OTPByteUL,
+ sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes));
+ }
+ else
+ {
+ NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD;
+ }
+
+#endif /* #ifdef PH_NDEF_MIFARE_ULC */
+
+ memcompare = (uint32_t)
+ MemCompare1(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_4],
+ NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
+ PH_FRINFC_MFUL_FMT_VAL_4);
+
+ if (memcompare == PH_FRINFC_MFUL_FMT_VAL_0)
+ {
+ /* Write NDEF TLV in block number 4 */
+ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
+ PH_FRINFC_MFUL_FMT_VAL_4;
+ /* Card already have the OTP bytes so write TLV */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV;
+ }
+ else
+ {
+ /* IS the card new, OTP bytes = {0x00, 0x00, 0x00, 0x00} */
+ memcompare = (uint32_t)MemCompare1(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_4],
+ ZeroBuf,
+ PH_FRINFC_MFUL_FMT_VAL_4);
+ /* If OTP bytes are Zero then the card is Zero */
+ if (memcompare == PH_FRINFC_MFUL_FMT_VAL_0)
+ {
+ /* Write OTP bytes in block number 3 */
+ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
+ PH_FRINFC_MFUL_FMT_VAL_3;
+ /* Card already have the OTP bytes so write TLV */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_OTPBYTES;
+ }
+ }
+ }
+
+
+
+#ifdef PH_NDEF_MIFARE_ULC
+ if(
+ ((NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_TLV) ||
+ (NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_OTPBYTES)) &&
+ ((NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) ||
+ (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_UL_CARD))
+ )
+#else
+ if((NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_TLV) ||
+ (NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_OTPBYTES))
+#endif /* #ifdef PH_NDEF_MIFARE_ULC */
+ {
+ Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt);
+ }
+ return Result;
+}
+
+static NFCSTATUS phFriNfc_MfUL_H_ProWrOTPBytes( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+ /* Card already have the OTP bytes so write TLV */
+ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV;
+
+ /* Write NDEF TLV in block number 4 */
+ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
+ PH_FRINFC_MFUL_FMT_VAL_4;
+
+ Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt);
+ return Result;
+}
+