/*
* 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: Fri Feb 20 14:38:17 2009 $
* $Author: ing07385 $
* $Revision: 1.4 $
* $Aliases: NFC_FRI1.1_WK908_R19_1,NFC_FRI1.1_WK910_PREP1,NFC_FRI1.1_WK910_R20_1,NFC_FRI1.1_WK912_PREP1,NFC_FRI1.1_WK912_R21_1,NFC_FRI1.1_WK914_PREP1,NFC_FRI1.1_WK914_R22_1,NFC_FRI1.1_WK914_R22_2,NFC_FRI1.1_WK916_R23_1,NFC_FRI1.1_WK918_R24_1,NFC_FRI1.1_WK920_PREP1,NFC_FRI1.1_WK920_R25_1,NFC_FRI1.1_WK922_PREP1,NFC_FRI1.1_WK922_R26_1,NFC_FRI1.1_WK924_PREP1,NFC_FRI1.1_WK924_R27_1,NFC_FRI1.1_WK926_R28_1,NFC_FRI1.1_WK928_R29_1,NFC_FRI1.1_WK930_R30_1,NFC_FRI1.1_WK934_PREP_1,NFC_FRI1.1_WK934_R31_1,NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,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 <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
-----------------------------------------------------------------------------------*/
/* 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);
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:
/* Instruction Cmd code */
NdefSmtCrdFmt->SendRecvBuf[CmdByte] = PH_FRINFC_DESF_CREATE_AID_CMD;
/* 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++;
NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NFCFORUM_APP_NO_OF_KEYS;
i++;
/* Le bytes*/
NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE;
i++;
/* set the length of the buffer*/
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++;
/* 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;
/* 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++;
/* 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;
/* 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_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++;
/* 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++;
/* 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(&NdefSmtCrdFmt->SendRecvBuf[i],
CCFileBytes,
PH_FRINFC_DESF_CC_FILE_SIZE);
i++;
i += PH_FRINFC_DESF_CC_FILE_SIZE;
/* Le bytes*/
NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE;
i++;
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++;
/* 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,
2);
i += 2;
/* 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 ( ( NdefSmtCrdFmt->AddInfo.Type4Info.MajorVersion == PH_FRINFC_DESF4_MAJOR_VERSION )&&
( NdefSmtCrdFmt->AddInfo.Type4Info.MinorVersion == PH_FRINFC_DESF4_MINOR_VERSION ))
{
/* card size of DESFire4 type */
NdefSmtCrdFmt->AddInfo.Type4Info.CardSize = PH_FRINFC_DESF4_MEMORY_SIZE;
}
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);
}
}
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;
status = phFriNfc_Desf_HGetHWVersion(NdefSmtCrdFmt);
return (status);
}
void phFriNfc_Desf_Process( void *Context,
NFCSTATUS Status)
{
phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt;
NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context;
if((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER))
{
switch(NdefSmtCrdFmt->State)
{
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 (( NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL0] == PH_FRINFC_DESF_NATIVE_RESP_BYTE1 )&&
( NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL1] == PH_FRINFC_DESF_NATIVE_RESP_BYTE2 ))
{
Status = PHNFCSTVAL(CID_NFC_NONE,
NFCSTATUS_SUCCESS);
NdefSmtCrdFmt->CardState = 0;
}
break;
default :
/*set the invalid state*/
Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
NFCSTATUS_INVALID_DEVICE_REQUEST);
break;
}
}
/* Handle the all the error cases*/
if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
{
/* call respective CR */
phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt,Status);
}
}