/* * 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_DesfireFormat.c * \brief This component encapsulates different format functinalities , * for the Type4/Desfire card. * * Project: NFC-FRI * * $Date: Thu Oct 28 17:44:00 2010 $ * $Author: ing02260 $ * $Revision: 1.8 $ * $Aliases: $ * */ #include <phNfcTypes.h> #include <phFriNfc_OvrHal.h> #include <phFriNfc_SmtCrdFmt.h> #include <phFriNfc_DesfireFormat.h> /* Following section details, how to wrap the native DESFire commands in to ISO commands Following are different native commands are wrapped under the ISO commands : 1. Crate Application 2. Select File 3. Get version 4. Create CC/NDEF File 5. Write data to STD File In this File above commands are sent using the ISO Wrapper. Wrapping the native DESFire APDU's procedure -------------------------------------------------------------------------------- CLA INS P1 P2 Lc Data Le 0x90 Cmd 0x00 0x00 Data Len Cmd. Par's 0x00 -----------------------------------------------------------------------------------*/ /****************************** Macro definitions start ********************************/ /* This settings can be changed, depending on the requirement*/ #define PH_FRINFC_DESF_PICC_NFC_KEY_SETTING 0x0FU #ifdef FRINFC_READONLY_NDEF #define READ_ONLY_NDEF_DESFIRE 0xFFU #define CC_BYTES_SIZE 0x0FU #define PH_FRINFC_DESF_READ_DATA_CMD 0xBDU #define NATIVE_WRAPPER_READ_DATA_LC_VALUE 0x07U #endif /* #ifdef FRINFC_READONLY_NDEF */ #ifdef DESFIRE_FMT_EV1 #define DESFIRE_CARD_TYPE_EV1 0x01U #define DESFIRE_EV1_MAPPING_VERSION 0x20U #define DESFIRE_EV1_HW_MAJOR_VERSION 0x01U #define DESFIRE_EV1_HW_MINOR_VERSION 0x00U #define DESFIRE_EV1_SW_MAJOR_VERSION 0x01U #define DESFIRE_EV1_SW_MINOR_VERSION 0x03U /* The below values are received for the command GET VERSION */ #define DESFIRE_TAG_SIZE_IDENTIFIER_2K 0x16U #define DESFIRE_TAG_SIZE_IDENTIFIER_4K 0x18U #define DESFIRE_TAG_SIZE_IDENTIFIER_8K 0x1AU #define DESFIRE_2K_CARD 2048U #define DESFIRE_4K_CARD 4096U #define DESFIRE_8K_CARD 7680U #define DESFIRE_EV1_KEY_SETTINGS_2 0x21U #define DESFIRE_EV1_FIRST_AID_BYTE 0x01U #define DESFIRE_EV1_SECOND_AID_BYTE 0x00U #define DESFIRE_EV1_THIRD_AID_BYTE 0x00U #define DESFIRE_EV1_FIRST_ISO_FILE_ID 0x05U #define DESFIRE_EV1_SECOND_ISO_FILE_ID 0xE1U #define DESFIRE_EV1_ISO_APP_DF_NAME {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01} #define DESFIRE_EV1_CC_FILE_ID 0x01U #define DESFIRE_EV1_FIRST_CC_FILE_ID_BYTE 0x03U #define DESFIRE_EV1_SECOND_CC_FILE_ID_BYTE 0xE1U #define DESFIRE_EV1_NDEF_FILE_ID 0x02U #define DESFIRE_EV1_FIRST_NDEF_FILE_ID_BYTE 0x04U #define DESFIRE_EV1_SECOND_NDEF_FILE_ID_BYTE 0xE1U #define PH_FRINFC_DESF_STATE_REACTIVATE 0x0FU #endif /* #ifdef DESFIRE_FMT_EV1 */ /****************************** Macro definitions end ********************************/ /* Helper functions to create app/select app/create data file/read /write from the CC file and NDEF files */ static void phFriNfc_Desf_HWrapISONativeCmds(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,uint8_t CmdType); /* Gets H/W version details*/ static NFCSTATUS phFriNfc_Desf_HGetHWVersion(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); /* Gets S/W version details*/ static NFCSTATUS phFriNfc_Desf_HGetSWVersion(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); /* Updates the version details to context structure*/ static NFCSTATUS phFriNfc_Desf_HUpdateVersionDetails(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); /*Gets UID details*/ static NFCSTATUS phFriNfc_Desf_HGetUIDDetails(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt); /*Creates Application*/ static NFCSTATUS phFriNfc_Desf_HCreateApp(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); /* Selects Application*/ static NFCSTATUS phFriNfc_Desf_HSelectApp(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); /*Creates Capability Container File*/ static NFCSTATUS phFriNfc_Desf_HCreatCCFile(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); /* Create NDEF File*/ static NFCSTATUS phFriNfc_Desf_HCreatNDEFFile(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); /* Writes CC Bytes to CC File*/ static NFCSTATUS phFriNfc_Desf_HWrCCBytes(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); /* Writes NDEF data into NDEF File*/ static NFCSTATUS phFriNfc_Desf_HWrNDEFData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); /* Transceive Cmd initiation*/ static NFCSTATUS phFriNfc_Desf_HSendTransCmd(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); #ifdef FRINFC_READONLY_NDEF #if 0 static NFCSTATUS phFriNfc_Desf_HReadOnlySelectCCFile ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); #endif /* #if 0 */ static NFCSTATUS phFriNfc_Desf_HReadOnlyReadCCFile ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); static NFCSTATUS phFriNfc_Desf_HReadOnlyWriteCCFile ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); static NFCSTATUS phFriNfc_Desf_HReadOnlySelectApp ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); #ifdef DESFIRE_FMT_EV1 static NFCSTATUS phFriNfc_Desf_HReadOnlySelectAppEV1 ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); #endif /* #ifdef DESFIRE_FMT_EV1 */ #endif /* #ifdef FRINFC_READONLY_NDEF */ void phFriNfc_Desfire_Reset( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { /* This piece of code may not be useful for the current supported DESFire formatting feature*/ /* Currently, s/w doesn't support authenticating either PICC Master key nor NFC Forum Application Master key*/ /*NdefSmtCrdFmt->AddInfo.Type4Info.PICCMasterKey[] = PH_FRINFC_SMTCRDFMT_DESF_PICC_MASTER_KEY; NdefSmtCrdFmt->AddInfo.Type4Info.NFCForumMasterkey[] = PH_FRINFC_SMTCRDFMT_DESF_NFCFORUM_APP_KEY;*/ /* reset to zero PICC and NFC FORUM master keys*/ (void)memset((void *)NdefSmtCrdFmt->AddInfo.Type4Info.PICCMasterKey, 0x00, 16); (void)memset((void *)NdefSmtCrdFmt->AddInfo.Type4Info.NFCForumMasterkey, 0x00, 16); NdefSmtCrdFmt->AddInfo.Type4Info.PrevState = 0; } static void phFriNfc_Desf_HWrapISONativeCmds(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,uint8_t CmdType) { uint16_t i=0, CmdByte=1; uint8_t NdefFileBytes[] = PH_FRINFC_DESF_NDEFFILE_BYTES; uint8_t CCFileBytes[] = PH_FRINFC_DESF_CCFILE_BYTES; /* common elements for all the native commands*/ /* Class Byte */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CLASS_BYTE; /* let the place to store the cmd byte type, point to next index*/ i += 2; /* P1/P2 offsets always set to zero */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P1; i++; NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P2; i++; switch(CmdType) { case PH_FRINFC_DESF_GET_HW_VERSION_CMD : case PH_FRINFC_DESF_GET_SW_VERSION_CMD : case PH_FRINFC_DESF_GET_UID_CMD : { if (CmdType == PH_FRINFC_DESF_GET_HW_VERSION_CMD ) { /* Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_GET_VER_CMD; } else { /* Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_PICC_ADDI_FRAME_RESP; } /* Lc: Length of wrapped data */ NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; /* NO Data to send in this cmd*/ /* we are not suppose to set Le*/ /* set the length of the buffer*/ NdefSmtCrdFmt->SendLength = i; break; } case PH_FRINFC_DESF_CREATEAPP_CMD: { #ifdef DESFIRE_FMT_EV1 uint8_t df_name[] = DESFIRE_EV1_ISO_APP_DF_NAME; #endif /* #ifdef DESFIRE_FMT_EV1 */ /* Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_CREATE_AID_CMD; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* Lc: Length of wrapped data, here the magic number 2 is for the ISO File ID for the application */ NdefSmtCrdFmt->SendRecvBuf[i] = (uint8_t)(PH_FRINFC_DESF_NATIVE_CRAPP_WRDT_LEN + sizeof (df_name) + 2); i++; /* NFC FORUM APPLICATION ID*/ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_FIRST_AID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_SECOND_AID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_THIRD_AID_BYTE; i++; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* Lc: Length of wrapped data */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CRAPP_WRDT_LEN; i++; /* NFC FORUM APPLICATION ID*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_FIRST_AID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_SEC_AID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_THIRD_AID_BYTE; i++; } /* set key settings and number of keys*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_PICC_NFC_KEY_SETTING; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* set key settings and number of keys*/ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_KEY_SETTINGS_2; i++; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NFCFORUM_APP_NO_OF_KEYS; i++; } #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* ISO File ID */ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_FIRST_ISO_FILE_ID; i++; NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_SECOND_ISO_FILE_ID; i++; /* DF file name */ (void)memcpy ((void *)&NdefSmtCrdFmt->SendRecvBuf[i], (void *)df_name, sizeof (df_name)); i = (uint16_t)(i + sizeof (df_name)); } #endif /* #ifdef DESFIRE_FMT_EV1 */ /* Le bytes*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* set the length of the buffer*/ NdefSmtCrdFmt->SendLength = i; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_CREATEAPP_CMD_SNLEN; } break; } case PH_FRINFC_DESF_SELECTAPP_CMD: { /* Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_SLECT_APP_CMD; /* Lc: Length of wrapped data */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_SLAPP_WRDT_LEN; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* Data*/ /* set the send buffer to create the application identifier*/ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_FIRST_AID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_SECOND_AID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_THIRD_AID_BYTE; i++; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* Data*/ /* set the send buffer to create the application identifier*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_FIRST_AID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_SEC_AID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_THIRD_AID_BYTE; i++; } /* Le bytes*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; i++; /* set the length of the buffer*/ NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_SELECTAPP_CMD_SNLEN; break; } case PH_FRINFC_DESF_CREATECC_CMD: { /* Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_CREATE_DATA_FILE_CMD; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* Lc: Length of wrapped data, here the magic number 2 is added as part of the ISO File ID in the packet */ NdefSmtCrdFmt->SendRecvBuf[i] = (uint8_t) (PH_FRINFC_DESF_NATIVE_CRCCNDEF_WRDT_LEN + 2); i++; /* set cc file id* */ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_CC_FILE_ID; i++; /* ISO File ID */ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_FIRST_CC_FILE_ID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_SECOND_CC_FILE_ID_BYTE; i++; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* Lc: Length of wrapped data */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CRCCNDEF_WRDT_LEN; i++; /* set cc file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_ID; i++; } NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_COMM_SETTINGS; i++; /* set the Access Rights are set to full read/write, full cntrl*/ NdefSmtCrdFmt->SendRecvBuf[i] = 0xEE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0xEE; i++; /* set the file size*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_SIZE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; /* Le bytes*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* set the length of the buffer*/ NdefSmtCrdFmt->SendLength = i; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* set the length of the buffer*/ NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_CREATECCNDEF_CMD_SNLEN; } break; } case PH_FRINFC_DESF_CREATENDEF_CMD: { /* Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_CREATE_DATA_FILE_CMD; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* Lc: Length of wrapped data, here the magic number 2 is added as part of the ISO File ID in the packet */ NdefSmtCrdFmt->SendRecvBuf[i] = (uint8_t) (PH_FRINFC_DESF_NATIVE_CRCCNDEF_WRDT_LEN + 2); i++; /* set NDEF file id* */ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_NDEF_FILE_ID; i++; /* ISO File ID */ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_FIRST_NDEF_FILE_ID_BYTE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_SECOND_NDEF_FILE_ID_BYTE; i++; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* Lc: Length of wrapped data */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CRCCNDEF_WRDT_LEN; i++; /* set NDEF file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NDEF_FILE_ID; i++; } NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_COMM_SETTINGS; i++; /* set the r/w access rights.Once Authentication part is fixed, we will use the constants*/ NdefSmtCrdFmt->SendRecvBuf[i] = 0xEE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0xEE; i++; NdefSmtCrdFmt->SendRecvBuf[i]= (uint8_t)NdefSmtCrdFmt->AddInfo.Type4Info.CardSize; i++; NdefSmtCrdFmt->SendRecvBuf[i]= (uint8_t) (NdefSmtCrdFmt->AddInfo.Type4Info.CardSize >> 8); i++; NdefSmtCrdFmt->SendRecvBuf[i]= (uint8_t) (NdefSmtCrdFmt->AddInfo.Type4Info.CardSize >> 16); i++; /* Le bytes*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* set the length of the buffer*/ NdefSmtCrdFmt->SendLength = i; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* set the length of the buffer*/ NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_CREATECCNDEF_CMD_SNLEN; } break; } case PH_FRINFC_DESF_WRITECC_CMD: { /* Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_WRITE_CMD; /* Lc: Length of wrapped data */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_WRCC_WRDT_LEN; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* set the file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_CC_FILE_ID; i++; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* set the file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_ID; i++; } /* set the offset to zero*/ NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; /* Set the length of data available to write*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_SIZE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { CCFileBytes[2] = (uint8_t)DESFIRE_EV1_MAPPING_VERSION; /* Length value is updated in the CC as per the card size received from the GetVersion command */ CCFileBytes[11] = (uint8_t) (NdefSmtCrdFmt->AddInfo.Type4Info.CardSize >> 8); CCFileBytes[12] = (uint8_t) (NdefSmtCrdFmt->AddInfo.Type4Info.CardSize); } #endif /* #ifdef DESFIRE_FMT_EV1 */ /*set the data to be written to the CC file*/ (void)memcpy ((void *)&NdefSmtCrdFmt->SendRecvBuf[i], (void *)CCFileBytes, sizeof (CCFileBytes)); #ifdef DESFIRE_FMT_EV1 #else i++; #endif /* #ifdef DESFIRE_FMT_EV1 */ i = (uint16_t)(i + sizeof (CCFileBytes)); /* Le bytes*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { NdefSmtCrdFmt->SendLength = i; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_WRITECC_CMD_SNLEN; } break; } case PH_FRINFC_DESF_WRITENDEF_CMD: { /* Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_WRITE_CMD; /* Lc: Length of wrapped data */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_WRNDEF_WRDT_LEN; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* set the file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_NDEF_FILE_ID; i++; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* set the file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NDEF_FILE_ID; i++; } /* set the offset to zero*/ NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; /* Set the length of data available to write*/ NdefSmtCrdFmt->SendRecvBuf[i] = 0x02; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; /*set the data to be written to the CC file*/ (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[i], NdefFileBytes, sizeof (NdefFileBytes)); i = (uint16_t)(i + sizeof (NdefFileBytes)); /* Le bytes*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; i++; NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_WRITENDEF_CMD_SNLEN; break; } default: { break; } } } static NFCSTATUS phFriNfc_Desf_HGetHWVersion(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS status = NFCSTATUS_SUCCESS; #ifdef PH_HAL4_ENABLE /* Removed uint8_t i=0; */ #else uint8_t i=0; #endif /* #ifdef PH_HAL4_ENABLE */ /*set the state*/ NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_GET_HW_VERSION; /* Helper routine to wrap the native DESFire cmds*/ phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_GET_HW_VERSION_CMD); status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt); return ( status); } static NFCSTATUS phFriNfc_Desf_HGetSWVersion(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); if( ( NdefSmtCrdFmt->SendRecvBuf[*(NdefSmtCrdFmt->SendRecvLength)- 1] == PH_FRINFC_DESF_PICC_ADDI_FRAME_RESP) ) { /*set the state*/ NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_GET_SW_VERSION; /* Helper routine to wrap the native DESFire cmds*/ phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_GET_SW_VERSION_CMD); status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt); } return status; } static NFCSTATUS phFriNfc_Desf_HUpdateVersionDetails(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS); if( ( NdefSmtCrdFmt->SendRecvBuf[*(NdefSmtCrdFmt->SendRecvLength)- PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_PICC_ADDI_FRAME_RESP ) ) { NdefSmtCrdFmt->AddInfo.Type4Info.MajorVersion = NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL3]; NdefSmtCrdFmt->AddInfo.Type4Info.MinorVersion = NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL4]; if ((PH_FRINFC_DESF4_MAJOR_VERSION == NdefSmtCrdFmt->AddInfo.Type4Info.MajorVersion) && (PH_FRINFC_DESF4_MINOR_VERSION == NdefSmtCrdFmt->AddInfo.Type4Info.MinorVersion)) { /* card size of DESFire4 type */ NdefSmtCrdFmt->AddInfo.Type4Info.CardSize = PH_FRINFC_DESF4_MEMORY_SIZE; } #ifdef DESFIRE_FMT_EV1 else if ((DESFIRE_EV1_SW_MAJOR_VERSION == NdefSmtCrdFmt->AddInfo.Type4Info.MajorVersion) && (DESFIRE_EV1_SW_MINOR_VERSION == NdefSmtCrdFmt->AddInfo.Type4Info.MinorVersion)) { NdefSmtCrdFmt->CardType = DESFIRE_CARD_TYPE_EV1; } #endif /* #ifdef DESFIRE_FMT_EV1 */ else { // need to handle the Desfire8 type cards // need to use get free memory status = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); } #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { switch (NdefSmtCrdFmt->SendRecvBuf[5]) { case DESFIRE_TAG_SIZE_IDENTIFIER_2K: { NdefSmtCrdFmt->AddInfo.Type4Info.CardSize = DESFIRE_2K_CARD; break; } case DESFIRE_TAG_SIZE_IDENTIFIER_4K: { NdefSmtCrdFmt->AddInfo.Type4Info.CardSize = DESFIRE_4K_CARD; break; } case DESFIRE_TAG_SIZE_IDENTIFIER_8K: { NdefSmtCrdFmt->AddInfo.Type4Info.CardSize = DESFIRE_8K_CARD; break; } default: { status = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_REMOTE_DEVICE); break; } } } #endif /* #ifdef DESFIRE_FMT_EV1 */ } return status; } static NFCSTATUS phFriNfc_Desf_HGetUIDDetails(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt) { NFCSTATUS status = NFCSTATUS_PENDING; if( ( NdefSmtCrdFmt->SendRecvBuf[*(NdefSmtCrdFmt->SendRecvLength)- PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_PICC_ADDI_FRAME_RESP) ) { /*set the state*/ NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_GET_UID; /* Helper routine to wrap the native desfire cmds*/ phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_GET_UID_CMD); status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt); } return status; } static NFCSTATUS phFriNfc_Desf_HCreateApp(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL14] == PH_FRINFC_DESF_NAT_WRAP_FIRST_RESP_BYTE) && (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL15] == PH_FRINFC_DESF_NAT_WRAP_SEC_RESP_BYTE )) { /*set the state*/ NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_CREATE_AID; /* Helper routine to wrap the native DESFire cmds*/ phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_CREATEAPP_CMD); status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt); } return ( status); } static NFCSTATUS phFriNfc_Desf_HSelectApp(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); /* check for the response of previous operation, before issuing the next command*/ if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NAT_WRAP_FIRST_RESP_BYTE) && (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NAT_WRAP_SEC_RESP_BYTE )) { /*set the state*/ NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_SELECT_APP; /* Helper routine to wrap the native DESFire cmds*/ phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_SELECTAPP_CMD); status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt); } return ( status); } static NFCSTATUS phFriNfc_Desf_HCreatCCFile(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1) && (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 )) { /*set the state*/ NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_CREATE_CCFILE; /* Helper routine to wrap the native DESFire cmds*/ phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_CREATECC_CMD); status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt); } return ( status); } static NFCSTATUS phFriNfc_Desf_HCreatNDEFFile(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1) && (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 )) { /*set the state*/ NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_CREATE_NDEFFILE; /* Helper routine to wrap the native desfire cmds*/ phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_CREATENDEF_CMD); status = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt); } return ( status); } static NFCSTATUS phFriNfc_Desf_HWrCCBytes(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1) && (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 )) { /*set the state*/ NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_WRITE_CC_FILE; /* Helper routine to wrap the native DESFire cmds*/ phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_WRITECC_CMD); result = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt); } return (result); } static NFCSTATUS phFriNfc_Desf_HWrNDEFData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); if ( (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1) && (NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 )) { /*set the state*/ NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_WRITE_NDEF_FILE; /* Helper routine to wrap the native DESFire cmds*/ phFriNfc_Desf_HWrapISONativeCmds(NdefSmtCrdFmt,PH_FRINFC_DESF_WRITENDEF_CMD); Result = phFriNfc_Desf_HSendTransCmd(NdefSmtCrdFmt); } return (Result); } static NFCSTATUS phFriNfc_Desf_HSendTransCmd(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS status = NFCSTATUS_SUCCESS; /* set the command type*/ #ifdef PH_HAL4_ENABLE NdefSmtCrdFmt->Cmd.Iso144434Cmd = phHal_eIso14443_4_Raw; #else NdefSmtCrdFmt->Cmd.Iso144434Cmd = phHal_eIso14443_4_CmdListTClCmd; #endif /* #ifdef PH_HAL4_ENABLE */ /* set the Additional Info*/ NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0; NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0; /*set the completion routines for the desfire card operations*/ NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process; NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt; /* set the receive length */ *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE; /*Call the Overlapped HAL Transceive function */ status = phFriNfc_OvrHal_Transceive(NdefSmtCrdFmt->LowerDevice, &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo, NdefSmtCrdFmt->psRemoteDevInfo, NdefSmtCrdFmt->Cmd, &NdefSmtCrdFmt->psDepAdditionalInfo, NdefSmtCrdFmt->SendRecvBuf, NdefSmtCrdFmt->SendLength, NdefSmtCrdFmt->SendRecvBuf, NdefSmtCrdFmt->SendRecvLength); return (status); } NFCSTATUS phFriNfc_Desfire_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS status = NFCSTATUS_SUCCESS; #ifdef DESFIRE_FMT_EV1 NdefSmtCrdFmt->CardType = 0; #endif /* #ifdef DESFIRE_FMT_EV1 */ status = phFriNfc_Desf_HGetHWVersion(NdefSmtCrdFmt); return (status); } #ifdef FRINFC_READONLY_NDEF #if 0 static NFCSTATUS phFriNfc_Desf_HReadOnlySelectCCFile ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS result = NFCSTATUS_SUCCESS; return result; } #endif /* #if 0 */ static NFCSTATUS phFriNfc_Desf_HReadOnlyReadCCFile ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS result = NFCSTATUS_SUCCESS; uint16_t i = 0; if ((PH_FRINFC_DESF_NATIVE_RESP_BYTE1 == NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 2)]) && (PH_FRINFC_DESF_NATIVE_RESP_BYTE2 == NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 1)])) { NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_RO_READ_CC_FILE; /* Class Byte */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CLASS_BYTE; i++; /* let the place to store the cmd byte type, point to next index Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_READ_DATA_CMD; i++; /* P1/P2 offsets always set to zero */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P1; i++; NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P2; i++; /* Lc: Length of wrapped data */ NdefSmtCrdFmt->SendRecvBuf[i] = NATIVE_WRAPPER_READ_DATA_LC_VALUE; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* set the file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_CC_FILE_ID; i++; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* set the file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_ID; i++; } /* set the offset to zero*/ NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; /* Set the length of data available to read */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_SIZE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; /* Le Value is set 0 */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; i++; NdefSmtCrdFmt->SendLength = i; result = phFriNfc_Desf_HSendTransCmd (NdefSmtCrdFmt); } else { result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); } return result; } static NFCSTATUS phFriNfc_Desf_HReadOnlyWriteCCFile ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS result = NFCSTATUS_SUCCESS; uint8_t read_cc_btyes[CC_BYTES_SIZE] = {0}; uint16_t i = 0; if ((PH_FRINFC_DESF_NATIVE_RESP_BYTE1 == NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 2)]) && (PH_FRINFC_DESF_NATIVE_RESP_BYTE2 == NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 1)])) { NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_RO_UPDATE_CC_FILE; memcpy ((void *)read_cc_btyes, (void *)NdefSmtCrdFmt->SendRecvBuf, sizeof (read_cc_btyes)); read_cc_btyes[(sizeof (read_cc_btyes) - 1)] = READ_ONLY_NDEF_DESFIRE; /* Class Byte */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CLASS_BYTE; i++; /* let the place to store the cmd byte type, point to next index Instruction Cmd code */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_WRITE_CMD; i++; /* P1/P2 offsets always set to zero */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P1; i++; NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P2; i++; /* Lc: Length of wrapped data */ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_WRCC_WRDT_LEN; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { /* set the file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_CC_FILE_ID; i++; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { /* set the file id*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_ID; i++; } /* set the offset to zero*/ NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; /* Set the length of data available to write*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_SIZE; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; i++; /*set the data to be written to the CC file*/ (void)memcpy ((void *)&NdefSmtCrdFmt->SendRecvBuf[i], (void *)read_cc_btyes, sizeof (read_cc_btyes)); #ifdef DESFIRE_FMT_EV1 #else i++; #endif /* #ifdef DESFIRE_FMT_EV1 */ i = (uint16_t)(i + sizeof (read_cc_btyes)); /* Le bytes*/ NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; i++; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { NdefSmtCrdFmt->SendLength = i; } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_WRITECC_CMD_SNLEN; } result = phFriNfc_Desf_HSendTransCmd (NdefSmtCrdFmt); } else { result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); } return result; } static NFCSTATUS phFriNfc_Desf_HReadOnlySelectApp ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS result = NFCSTATUS_SUCCESS; NdefSmtCrdFmt->CardType = 0; NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_RO_SELECT_APP; /* Helper routine to wrap the native DESFire cmds */ phFriNfc_Desf_HWrapISONativeCmds (NdefSmtCrdFmt, PH_FRINFC_DESF_SELECTAPP_CMD); result = phFriNfc_Desf_HSendTransCmd (NdefSmtCrdFmt); return result; } #ifdef DESFIRE_FMT_EV1 static NFCSTATUS phFriNfc_Desf_HReadOnlySelectAppEV1 ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS result = NFCSTATUS_SUCCESS; NdefSmtCrdFmt->CardType = DESFIRE_CARD_TYPE_EV1; NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_RO_SELECT_APP_EV1; /* Helper routine to wrap the native DESFire cmds */ phFriNfc_Desf_HWrapISONativeCmds (NdefSmtCrdFmt, PH_FRINFC_DESF_SELECTAPP_CMD); result = phFriNfc_Desf_HSendTransCmd (NdefSmtCrdFmt); return result; } #endif /* #ifdef DESFIRE_FMT_EV1 */ NFCSTATUS phFriNfc_Desfire_ConvertToReadOnly ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS result = NFCSTATUS_SUCCESS; #ifdef DESFIRE_FMT_EV1 result = phFriNfc_Desf_HReadOnlySelectAppEV1 (NdefSmtCrdFmt); #else result = phFriNfc_Desf_HReadOnlySelectApp (NdefSmtCrdFmt); #endif /* #ifdef DESFIRE_FMT_EV1 */ return result; } #endif /* #ifdef FRINFC_READONLY_NDEF */ void phFriNfc_Desf_Process( void *Context, NFCSTATUS Status) { phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt; NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context; if((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER)) { switch(NdefSmtCrdFmt->State) { #ifdef FRINFC_READONLY_NDEF #ifdef DESFIRE_FMT_EV1 case PH_FRINFC_DESF_STATE_RO_SELECT_APP_EV1: { if ((PH_FRINFC_DESF_NATIVE_RESP_BYTE1 == NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 2)]) && (PH_FRINFC_DESF_NATIVE_RESP_BYTE2 == NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 1)])) { Status = phFriNfc_Desf_HReadOnlyReadCCFile (NdefSmtCrdFmt); } else { Status = phFriNfc_Desf_HReadOnlySelectApp (NdefSmtCrdFmt); } break; } #endif /* #ifdef DESFIRE_FMT_EV1 */ case PH_FRINFC_DESF_STATE_RO_SELECT_APP: { Status = phFriNfc_Desf_HReadOnlyReadCCFile (NdefSmtCrdFmt); break; } case PH_FRINFC_DESF_STATE_RO_READ_CC_FILE: { Status = phFriNfc_Desf_HReadOnlyWriteCCFile (NdefSmtCrdFmt); break; } case PH_FRINFC_DESF_STATE_RO_UPDATE_CC_FILE: { if ((PH_FRINFC_DESF_NATIVE_RESP_BYTE1 == NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 2)]) && (PH_FRINFC_DESF_NATIVE_RESP_BYTE2 == NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 1)])) { /* SUCCESSFULL Formatting */ #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { Status = phFriNfc_OvrHal_Reconnect ( NdefSmtCrdFmt->LowerDevice, &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo, NdefSmtCrdFmt->psRemoteDevInfo); if (NFCSTATUS_PENDING == Status) { NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_REACTIVATE; } } #endif /* #ifdef DESFIRE_FMT_EV1 */ } else { Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); } break; } #endif /* #ifdef FRINFC_READONLY_NDEF */ case PH_FRINFC_DESF_STATE_GET_HW_VERSION: { /* Check and store the h/w and s/w specific details. Ex: Major/Minor version, memory storage info. */ Status = phFriNfc_Desf_HGetSWVersion (NdefSmtCrdFmt); break; } case PH_FRINFC_DESF_STATE_GET_SW_VERSION: { /* Check and store the h/w and s/w specific details. Ex: Major/Minor version, memory storage info. */ Status = phFriNfc_Desf_HUpdateVersionDetails (NdefSmtCrdFmt); if ( Status == NFCSTATUS_SUCCESS ) { Status = phFriNfc_Desf_HGetUIDDetails (NdefSmtCrdFmt); } break; } case PH_FRINFC_DESF_STATE_GET_UID: { Status = phFriNfc_Desf_HCreateApp (NdefSmtCrdFmt); break; } case PH_FRINFC_DESF_STATE_CREATE_AID: { Status = phFriNfc_Desf_HSelectApp (NdefSmtCrdFmt); break; } case PH_FRINFC_DESF_STATE_SELECT_APP: { Status = phFriNfc_Desf_HCreatCCFile (NdefSmtCrdFmt); break; } case PH_FRINFC_DESF_STATE_CREATE_CCFILE: { Status = phFriNfc_Desf_HCreatNDEFFile (NdefSmtCrdFmt); break; } case PH_FRINFC_DESF_STATE_CREATE_NDEFFILE: { Status = phFriNfc_Desf_HWrCCBytes (NdefSmtCrdFmt); break; } case PH_FRINFC_DESF_STATE_WRITE_CC_FILE: { Status = phFriNfc_Desf_HWrNDEFData (NdefSmtCrdFmt); break; } case PH_FRINFC_DESF_STATE_WRITE_NDEF_FILE: { if ((PH_FRINFC_DESF_NATIVE_RESP_BYTE1 == NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0]) && (PH_FRINFC_DESF_NATIVE_RESP_BYTE2 == NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1])) { NdefSmtCrdFmt->CardState = 0; #ifdef DESFIRE_FMT_EV1 if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) { Status = phFriNfc_OvrHal_Reconnect ( NdefSmtCrdFmt->LowerDevice, &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo, NdefSmtCrdFmt->psRemoteDevInfo); if (NFCSTATUS_PENDING == Status) { NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_REACTIVATE; } } else #endif /* #ifdef DESFIRE_FMT_EV1 */ { Status = PHNFCSTVAL (CID_NFC_NONE, NFCSTATUS_SUCCESS); } } break; } #ifdef DESFIRE_FMT_EV1 case PH_FRINFC_DESF_STATE_REACTIVATE: { /* Do nothing */ break; } #endif /* #ifdef DESFIRE_FMT_EV1 */ default: { /*set the invalid state*/ Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_DEVICE_REQUEST); break; } } } /* Handle the all the error cases*/ if ((NFCSTATUS_PENDING & PHNFCSTBLOWER) != (Status & PHNFCSTBLOWER)) { /* call respective CR */ phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt,Status); } }