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_MifULFormat.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_MifULFormat.c')
-rw-r--r-- | src/phFriNfc_MifULFormat.c | 431 |
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; +} + |