/* * 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_SmtCrdFmt.c * \brief This component encapsulates different smart and simple tag formatting functionalities, * for the mapping layer. * * Project: NFC-FRI * * $Date: Mon Dec 13 14:14:13 2010 $ * $Author: ing02260 $ * $Revision: 1.9 $ * $Aliases: $ * */ #ifndef PH_FRINFC_CARD_FORMAT_DISABLED #include <phNfcTypes.h> #include <phFriNfc_OvrHal.h> #include <phFriNfc_SmtCrdFmt.h> #ifdef DISABLE_FORMAT #include <phFriNfc_TopazFormat.h> #endif /* #ifdef DISABLE_FORMAT */ #include <phFriNfc_MifULFormat.h> #include <phFriNfc_DesfireFormat.h> #include <phFriNfc_MifStdFormat.h> #ifndef PH_FRINFC_FMT_ISO15693_DISABLED #include <phFriNfc_ISO15693Format.h> #endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */ /*! \ingroup grp_file_attributes * \name NDEF Mapping * * File: \ref phFriNfc_CardFormatFunctions.c * */ /*@{*/ // file versions /*@}*/ void phFriNfc_SmtCrdFmt_HCrHandler(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, NFCSTATUS Status) { /* set the state back to the Reset_Init state*/ NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT; /* set the completion routine*/ NdefSmtCrdFmt->CompletionRoutine[PH_FRINFC_SMTCRDFMT_CR_FORMAT]. CompletionRoutine(NdefSmtCrdFmt->CompletionRoutine->Context, Status); } /*! * \brief Used to Reset the context variables , before the actual smart card formatting * procedure. * */ NFCSTATUS phFriNfc_NdefSmtCrd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, void *LowerDevice, phHal_sRemoteDevInformation_t *psRemoteDevInfo, phHal_sDevInputParam_t *psDevInputParam, uint8_t *SendRecvBuffer, uint16_t *SendRecvBuffLen) { NFCSTATUS result = NFCSTATUS_SUCCESS; uint8_t index; if ( (SendRecvBuffLen == NULL) || (NdefSmtCrdFmt == NULL) || (psRemoteDevInfo == NULL) || (SendRecvBuffer == NULL) || (LowerDevice == NULL) || (*SendRecvBuffLen == 0) || (psDevInputParam == NULL) || (*SendRecvBuffLen < PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE) ) { result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); } else { /* Initialise the state to Init */ NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT; for(index = 0;index<PH_FRINFC_SMTCRDFMT_CR;index++) { /* Initialise the NdefMap Completion Routine to Null */ NdefSmtCrdFmt->CompletionRoutine[index].CompletionRoutine = NULL; /* Initialise the NdefMap Completion Routine context to Null */ NdefSmtCrdFmt->CompletionRoutine[index].Context = NULL; } /* Lower Device(Always Overlapped HAL Struct initialised in application is registred in NdefMap Lower Device) */ NdefSmtCrdFmt->LowerDevice = LowerDevice; /* Remote Device info received from Manual Device Discovery is registered here */ NdefSmtCrdFmt->psRemoteDevInfo = psRemoteDevInfo; /* Trx Buffer registered */ NdefSmtCrdFmt->SendRecvBuf = SendRecvBuffer; /* Trx Buffer Size */ NdefSmtCrdFmt->SendRecvLength = SendRecvBuffLen; /* Register Transfer Buffer Length */ NdefSmtCrdFmt->SendLength = 0; /* Initialise the Format status flag*/ NdefSmtCrdFmt->FmtProcStatus = 0; /* Reset the Card Type */ NdefSmtCrdFmt->CardType = 0; /* Reset MapCompletion Info*/ NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = NULL; NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NULL; #ifndef PH_FRINFC_FMT_TOPAZ_DISABLED phFriNfc_Topaz_Reset(NdefSmtCrdFmt); #endif /* PH_FRINFC_FMT_TOPAZ_DISABLED */ #ifndef PH_FRINFC_FMT_DESFIRE_DISABLED /*Reset Desfire Cap Container elements*/ phFriNfc_Desfire_Reset(NdefSmtCrdFmt); #endif /* PH_FRINFC_FMT_DESFIRE_DISABLED */ #ifndef PH_FRINFC_FMT_MIFARESTD_DISABLED /*Reset Mifare Standard Container elements*/ NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam = psDevInputParam; phFriNfc_MfStd_Reset(NdefSmtCrdFmt); #endif /* PH_FRINFC_MAP_MIFARESTD_DISABLED */ #ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED phFriNfc_MfUL_Reset(NdefSmtCrdFmt); #endif /* #ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED */ #ifndef PH_FRINFC_FMT_ISO15693_DISABLED phFriNfc_ISO15693_FmtReset (NdefSmtCrdFmt); #endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */ #ifdef PHFRINFC_OVRHAL_MOCKUP /*Reset Desfire Cap Container elements*/ // phFriNfc_Mockup_H_Reset(NdefSmtCrdFmt); #endif /* PHFRINFC_OVRHAL_MOCKUP */ } return (result); } /*! * \brief Completion Routine initialisation * */ NFCSTATUS phFriNfc_NdefSmtCrd_SetCR(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, uint8_t FunctionID, pphFriNfc_Cr_t CompletionRoutine, void *CompletionRoutineContext) { NFCSTATUS status = NFCSTATUS_SUCCESS; if ((NdefSmtCrdFmt == NULL) || (FunctionID >= PH_FRINFC_SMTCRDFMT_CR) || (CompletionRoutine == NULL) || (CompletionRoutineContext == NULL)) { status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); } else { /* Register the application callback with the NdefMap Completion Routine */ NdefSmtCrdFmt->CompletionRoutine[FunctionID].CompletionRoutine = CompletionRoutine; /* Register the application context with the NdefMap Completion Routine context */ NdefSmtCrdFmt->CompletionRoutine[FunctionID].Context = CompletionRoutineContext; } return status; } #ifdef FRINFC_READONLY_NDEF NFCSTATUS phFriNfc_NdefSmtCrd_ConvertToReadOnly ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); uint8_t sak = 0; if((NdefSmtCrdFmt != NULL) && (NdefSmtCrdFmt->CompletionRoutine->CompletionRoutine != NULL) && (NdefSmtCrdFmt->CompletionRoutine->Context != NULL)) { sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; switch (NdefSmtCrdFmt->psRemoteDevInfo->RemDevType) { case phHal_eMifare_PICC: { if (0x00 == sak) { result = phFriNfc_MfUL_ConvertToReadOnly (NdefSmtCrdFmt); } else { /* MIFARE classic 1k/4k is not supported */ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); } break; } case phHal_eISO14443_A_PICC: { result = phFriNfc_Desfire_ConvertToReadOnly (NdefSmtCrdFmt); break; } default : { /* Remote device is not recognised. Probably not NDEF compliant */ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); break; } } } return result; } #endif /* #ifdef FRINFC_READONLY_NDEF */ /*! * \brief Used to format the different smart cards. * */ NFCSTATUS phFriNfc_NdefSmtCrd_Format( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB ) { /* Component ID needs to be changed */ NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); uint8_t sak = 0; /* Check for the correct context structure */ if((NdefSmtCrdFmt != NULL) && (NdefSmtCrdFmt->CompletionRoutine->CompletionRoutine != NULL) && (NdefSmtCrdFmt->CompletionRoutine->Context != NULL)) { #ifdef PH_HAL4_ENABLE /* SAK (Select response) */ sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; /* Depending on the Opmodes, call the respective card functions */ switch ( NdefSmtCrdFmt->psRemoteDevInfo->RemDevType ) #else /* SAK (Select response) */ sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.CardInfo106. Startup106.SelRes; /* Depending on the Opmodes, call the respective card functions */ switch ( NdefSmtCrdFmt->psRemoteDevInfo->OpMode ) #endif /* #ifdef PH_HAL4_ENABLE */ { #ifdef PH_HAL4_ENABLE case phHal_eMifare_PICC : #else case phHal_eOpModesMifare : #endif /* #ifdef PH_HAL4_ENABLE */ /* Remote device is Mifare card . Check for Mifare NDEF compliance */ if(0x00 == sak) { #ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED /* The SAK/Sel_Res says the card is of the type Mifare UL */ NdefSmtCrdFmt->CardType = PH_FRINFC_SMTCRDFMT_MIFARE_UL_CARD; if (NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength == 7 && NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[0] == 0x04) { Result = phFriNfc_MfUL_Format( NdefSmtCrdFmt); } else { Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); } #else Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); #endif /* #ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED */ } else if((0x08 == (sak & 0x18)) || (0x18 == (sak & 0x18)) || (0x01 == sak)) { #ifndef PH_FRINFC_FMT_MIFARESTD_DISABLED NdefSmtCrdFmt->CardType = (uint8_t) (((sak & 0x18) == 0x08)? PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD: PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD); /* The SAK/Sel_Res says the card is of the type Mifare standard */ Result = phFriNfc_MfStd_Format( NdefSmtCrdFmt, ScrtKeyB); #else Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); #endif /* #ifndef PH_FRINFC_FMT_MIFARESTD_DISABLED */ } else { /* Invalid Mifare card, as the remote device info - opmode says its a Mifare card but, The SAK/Sel_Res is wrong */ Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); } break; #ifdef PH_HAL4_ENABLE case phHal_eISO14443_A_PICC : #else case phHal_eOpModesISO14443_4A : #endif /* #ifdef PH_HAL4_ENABLE */ /* Remote device is Desfire card . Check for Desfire NDEF compliancy */ if(0x20 == (sak & 0xFF)) { #ifndef PH_FRINFC_FMT_DESFIRE_DISABLED NdefSmtCrdFmt->CardType = PH_FRINFC_SMTCRDFMT_ISO14443_4A_CARD; /* The SAK/Sel_Res says the card is of the type ISO14443_4A */ Result = phFriNfc_Desfire_Format(NdefSmtCrdFmt); #else Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); #endif /* #ifndef PH_FRINFC_FMT_DESFIRE_DISABLED */ } else { /* Invalid Desfire card, as the remote device info - opmode says its a desfire card but, The SAK/Sel_Res is wrong */ Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); } break; #ifdef PH_HAL4_ENABLE case phHal_eJewel_PICC : #else case phHal_eOpModesJewel : #endif /* #ifdef PH_HAL4_ENABLE */ /* Remote device is Topaz card . Check for Topaz NDEF compliancy */ if(0xC2 == sak) { #ifndef PH_FRINFC_FMT_TOPAZ_DISABLED NdefSmtCrdFmt->CardType = PH_FRINFC_SMTCRDFMT_TOPAZ_CARD; /* The SAK/Sel_Res says the card is of the type ISO14443_4A */ Result = phFriNfc_Topaz_Format(NdefSmtCrdFmt); #else Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); #endif /* #ifndef PH_FRINFC_FMT_TOPAZ_DISABLED */ } else { /* Invalid Topaz card, as the remote device info - opmode says its a desfire card but, The SAK/Sel_Res is wrong */ Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); } break; #ifdef PHFRINFC_OVRHAL_MOCKUP case phHal_eOpModesMockup : /*Set the OpMode Ttype Flag*/ NdefSmtCrdFmt->OpModeType[0] = phHal_eOpModesMockup; NdefSmtCrdFmt->OpModeType[1] = phHal_eOpModesArrayTerminator; //Result = phFriNfc_Mockup_ChkNdef(NdefSmtCrdFmt); break; #endif /* PHFRINFC_OVRHAL_MOCKUP */ #ifndef PH_FRINFC_FMT_ISO15693_DISABLED case phHal_eISO15693_PICC: { Result = phFriNfc_ISO15693_Format (NdefSmtCrdFmt); break; } #endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */ default : /* Remote device is not recognised. Probably not NDEF compliant */ Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); break; } } return Result; } /*! * \brief Handles different request and responses from the integration layer. * */ void phFriNfc_NdefSmtCrd_Process(void *Context, NFCSTATUS Status) { if ( Context != NULL ) { phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context; #ifdef PH_HAL4_ENABLE switch ( NdefSmtCrdFmt->psRemoteDevInfo->RemDevType ) #else switch ( NdefSmtCrdFmt->psRemoteDevInfo->OpMode ) #endif /* #ifdef PH_HAL4_ENABLE */ { #ifdef PH_HAL4_ENABLE case phHal_eMifare_PICC : #else case phHal_eOpModesMifare : #endif /* #ifdef PH_HAL4_ENABLE */ if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) || (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) { #ifndef PH_FRINFC_FMT_MIFARESTD_DISABLED /* Remote device is Mifare Standard card */ phFriNfc_MfStd_Process(NdefSmtCrdFmt,Status); #else /* PH_FRINFC_FMT_MIFARESTD_DISABLED*/ Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); #endif /* PH_FRINFC_FMT_MIFARESTD_DISABLED*/ } else { #ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED /* Remote device is Mifare UL card */ phFriNfc_MfUL_Process(NdefSmtCrdFmt,Status); #else /* PH_FRINFC_FMT_MIFAREUL_DISABLED*/ Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); #endif /* PH_FRINFC_FMT_MIFAREUL_DISABLED*/ } break; #ifdef PH_HAL4_ENABLE case phHal_eISO14443_A_PICC : #else case phHal_eOpModesISO14443_4A : #endif /* #ifdef PH_HAL4_ENABLE */ #ifndef PH_FRINFC_FMT_DESFIRE_DISABLED /* Remote device is Desfire card */ phFriNfc_Desf_Process(NdefSmtCrdFmt, Status); #else /* PH_FRINFC_FMT_DESFIRE_DISABLED*/ Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); #endif /* PH_FRINFC_FMT_DESFIRE_DISABLED*/ break; #ifdef PH_HAL4_ENABLE case phHal_eJewel_PICC : #else case phHal_eOpModesJewel: #endif /* #ifdef PH_HAL4_ENABLE */ #ifndef PH_FRINFC_FMT_TOPAZ_DISABLED /* Remote device is Topaz Smart card */ phFriNfc_Topaz_Process(NdefSmtCrdFmt, Status); #else /* PH_FRINFC_FMT_TOPAZ_DISABLED*/ Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); #endif /* PH_FRINFC_FMT_TOPAZ_DISABLED*/ break; #ifndef PH_FRINFC_FMT_ISO15693_DISABLED case phHal_eISO15693_PICC : { phFriNfc_ISO15693_FmtProcess (NdefSmtCrdFmt, Status); break; } #endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */ #ifdef PHFRINFC_OVRHAL_MOCKUP case phHal_eOpModesMockup: /* Remote device is Desfire card */ //phFriNfc_Mockup_Process(NdefSmtCrdFmt, Status); break; #endif /* PHFRINFC_OVRHAL_MOCKUP*/ default : /* Remote device opmode not recognised. Probably not NDEF compliant */ Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); /* set the state back to the Reset_Init state*/ NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT; /* set the completion routine*/ NdefSmtCrdFmt->CompletionRoutine[PH_FRINFC_SMTCRDFMT_CR_INVALID_OPE]. CompletionRoutine(NdefSmtCrdFmt->CompletionRoutine->Context, Status); break; } } else { Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,\ NFCSTATUS_INVALID_PARAMETER); /* The control should not come here. As Context itself is NULL , Can't call the CR*/ } } #endif /* PH_FRINFC_CARD_FORMAT_DISABLED */