692 lines
23 KiB
C
692 lines
23 KiB
C
/*----------------------------------------------------------------------------*/
|
|
/* Copyright 2016-2023 NXP */
|
|
/* */
|
|
/* NXP Confidential. This software is owned or controlled by NXP and may only */
|
|
/* be used strictly in accordance with the applicable license terms. */
|
|
/* By expressly accepting such terms or by downloading, installing, */
|
|
/* activating and/or otherwise using the software, you are agreeing that you */
|
|
/* have read, and that you agree to comply with and are bound by, such */
|
|
/* license terms. If you do not agree to be bound by the applicable license */
|
|
/* terms, then you may not retain, install, activate or otherwise use the */
|
|
/* software. */
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
/** \file
|
|
* NFC Type 4A Card Emulation application.
|
|
* $Author: NXP $
|
|
* $Revision: $ (v07.10.00)
|
|
* $Date: $
|
|
*/
|
|
|
|
/**
|
|
* Reader Library Headers
|
|
*/
|
|
#include <phApp_Init.h>
|
|
|
|
/* Local headers */
|
|
#include "NfcrdlibEx8_HCE_T4T.h"
|
|
|
|
#ifdef NXPBUILD__PHHAL_HW_PN7462AU
|
|
#include "phhalRng.h"
|
|
#endif /* NXPBUILD__PHHAL_HW_PN7462AU */
|
|
|
|
/*******************************************************************************
|
|
** Definitions
|
|
*******************************************************************************/
|
|
|
|
#ifdef NXPBUILD__PHHAL_HW_RC663
|
|
# warning "This example is not supported for RC663"
|
|
int main() {
|
|
DEBUG_PRINTF("This example is not supported for RC663.");
|
|
while (1){
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
/* Actual main defined below has no purpose in this example and hence over-riding it. */
|
|
# define main dummy_main
|
|
#endif
|
|
|
|
/* Check if all required reader library layers are enabled. */
|
|
#if NXPBUILD_EX8_MANDATORY_LAYERS
|
|
phacDiscLoop_Sw_DataParams_t * pDiscLoop; /* Pointer to Discovery loop data-params */
|
|
phpalI14443p4mC_Sw_DataParams_t * ppalI14443p4mC; /* Pointer to PAL 14443-4mC data-params */
|
|
phceT4T_Sw_DataParams_t * pceT4T; /* Pointer to HCE data-params */
|
|
|
|
/**
|
|
* Parameters for L3 activation during AUTOCOLL (used in
|
|
* phhalHw_Rc523_SetListenParameters)
|
|
* */
|
|
uint8_t sens_res[2] = {0x04, 0x00}; /* ATQ bytes - needed for anti-collision */
|
|
uint8_t nfc_id1[3] = {0xA1, 0xA2, 0xA3}; /* UID bytes (one byte defined by HW) */
|
|
uint8_t sel_res = 0x20; /* SAK (ISO14443P4 Card) */
|
|
uint8_t nfc_id3 = 0xFA; /* NFCID3 byte */
|
|
uint8_t poll_res[18] = {0x01, 0xFE, 0xB2, 0xB3, 0xB4, 0xB5,
|
|
0xB6, 0xB7, 0xC0, 0xC1, 0xC2, 0xC3,
|
|
0xC4, 0xC5, 0xC6, 0xC7, 0x23, 0x45};
|
|
|
|
#ifdef PHOSAL_FREERTOS_STATIC_MEM_ALLOCATION
|
|
uint32_t aRdLibTaskBuffer[RDLIB_TASK_STACK];
|
|
uint32_t aHceAppTaskBuffer[APPLICATION_TASK_STACK];
|
|
#else /* PHOSAL_FREERTOS_STATIC_MEM_ALLOCATION */
|
|
#define aRdLibTaskBuffer NULL
|
|
#define aHceAppTaskBuffer NULL
|
|
#endif /* PHOSAL_FREERTOS_STATIC_MEM_ALLOCATION */
|
|
|
|
#ifdef PH_OSAL_FREERTOS
|
|
const uint8_t bTaskNameMain[configMAX_TASK_NAME_LEN] = {"RdLib"};
|
|
const uint8_t bTaskNameHce[configMAX_TASK_NAME_LEN] = {"HceApp"};
|
|
#else
|
|
const uint8_t bTaskNameMain[] = {"RdLib"};
|
|
const uint8_t bTaskNameHce[] = {"HceApp"};
|
|
#endif /* PH_OSAL_FREERTOS */
|
|
|
|
const phOsal_TimerPeriodObj_t abs_timeout= {OS_TIMER_UNIT_MSEC, PHOSAL_MAX_DELAY};
|
|
|
|
static volatile uint8_t bInfLoop = 1U;
|
|
|
|
/**
|
|
* Parameters for PAL 14443p4mC ATS configuration (Activation).
|
|
* Refer phpalI14443p4mC_Activate for more info.
|
|
* Used in listen mode / card emulation.
|
|
* */
|
|
uint8_t aAtsRes[5] = {0x05, 0x75, 0x00, 0x88, 0x00}; /* ATS Response send for
|
|
* RATS: |TL|T0|TA|TB|TC|
|
|
*/
|
|
uint16_t wAtsLength = 5; /* ATS length */
|
|
|
|
/**
|
|
* Parameters for T4T CE (card emulation layer)
|
|
* */
|
|
/* Mandatory Capability Container (CC) file. It's set using
|
|
* phceT4T_SetElementaryFile. */
|
|
uint8_t aCcFile[23] = {0};
|
|
|
|
/* Mandatory NDEF file. It's set using phceT4T_SetElementaryFile. */
|
|
uint8_t aNdefFile[1024] = {0x00, 0x0C, 0xD1, 0x01, 0x08, 0x55, 0x02,
|
|
0x6E, 0x78, 0x70, 0x2E, 0x63, 0x6F, 0x6D};
|
|
|
|
#ifdef NXPBUILD__PHCE_T4T_PROPRIETARY
|
|
/* Optional proprietary file (not used in this example. Added to demonstrate
|
|
* support). It's set using phceT4T_SetElementaryFile. */
|
|
uint8_t aProprietaryFile[100] = {0};
|
|
#endif /* NXPBUILD__PHCE_T4T_PROPRIETARY */
|
|
|
|
/**
|
|
* RTOS objects.
|
|
* Semaphores for synchronization between application thread and reader library
|
|
* thread.
|
|
* */
|
|
phOsal_SemObj_t appstart; /* Used to synchronize start of one
|
|
cycle of application processing */
|
|
phOsal_SemObj_t appexit; /* Used to synchronize end of one
|
|
cycle of application processing */
|
|
#if ISO_10373_6_PICC_TEST_BENCH
|
|
phOsal_SemObj_t timerwtx; /* Used in PICC ISO 10373-6 test bench
|
|
to create WTX */
|
|
#endif /* ISO_10373_6_PICC_TEST_BENCH */
|
|
#endif /* NXPBUILD_EX8_MANDATORY_LAYERS */
|
|
|
|
/*******************************************************************************
|
|
** Prototypes
|
|
*******************************************************************************/
|
|
|
|
void pWtoxCallBck(void);
|
|
|
|
/*******************************************************************************
|
|
** Code
|
|
*******************************************************************************/
|
|
|
|
int main(void)
|
|
{
|
|
do
|
|
{
|
|
#if NXPBUILD_EX8_MANDATORY_LAYERS
|
|
phStatus_t status = PH_ERR_INTERNAL_ERROR;
|
|
phNfcLib_Status_t dwStatus;
|
|
phNfcLib_AppContext_t AppContext = {0};
|
|
|
|
phOsal_ThreadObj_t RdLib;
|
|
|
|
/* Perform Controller specific initialization. */
|
|
phApp_CPU_Init();
|
|
|
|
/* Perform OSAL Initialization. */
|
|
(void)phOsal_Init();
|
|
|
|
#ifdef PH_PLATFORM_HAS_ICFRONTEND
|
|
status = phbalReg_Init(&sBalParams, sizeof(phbalReg_Type_t));
|
|
CHECK_STATUS(status);
|
|
|
|
AppContext.pBalDataparams = &sBalParams;
|
|
#endif /* PH_PLATFORM_HAS_ICFRONTEND */
|
|
|
|
AppContext.pWtxCallback = (void *)pWtoxCallBck;
|
|
dwStatus = phNfcLib_SetContext(&AppContext);
|
|
CHECK_NFCLIB_STATUS(dwStatus);
|
|
|
|
/* Initialize library */
|
|
dwStatus = phNfcLib_Init();
|
|
CHECK_NFCLIB_STATUS(dwStatus);
|
|
if(dwStatus != PH_NFCLIB_STATUS_SUCCESS) break;
|
|
|
|
/* Set the generic pointer */
|
|
pHal = phNfcLib_GetDataParams(PH_COMP_HAL);
|
|
pDiscLoop = (phacDiscLoop_Sw_DataParams_t *) phNfcLib_GetDataParams(PH_COMP_AC_DISCLOOP);
|
|
ppalI14443p4mC = (phpalI14443p4mC_Sw_DataParams_t *) phNfcLib_GetDataParams(PH_COMP_PAL_I14443P4MC);
|
|
pceT4T = (phceT4T_Sw_DataParams_t *) phNfcLib_GetDataParams(PH_COMP_CE_T4T);
|
|
|
|
/* Initialize other components that are not initialized by NFCLIB and configure Discovery Loop. */
|
|
status = phApp_Comp_Init(pDiscLoop);
|
|
CHECK_STATUS(status);
|
|
if(status != PH_ERR_SUCCESS) break;
|
|
|
|
/* Perform Platform Init */
|
|
status = phApp_Configure_IRQ();
|
|
CHECK_STATUS(status);
|
|
if(status != PH_ERR_SUCCESS) break;
|
|
|
|
/* Initialize/Configure components required by this Example */
|
|
phApp_Initialize();
|
|
DEBUG_PRINTF("\nCard Emulation Application...\n");
|
|
|
|
RdLib.pTaskName = (uint8_t *)bTaskNameMain;
|
|
RdLib.pStackBuffer = aRdLibTaskBuffer;
|
|
RdLib.priority = RDLIB_TASK_PRIO;
|
|
RdLib.stackSizeInNum = RDLIB_TASK_STACK;
|
|
phOsal_ThreadCreate(&RdLib.ThreadHandle, &RdLib, &TReaderLibrary, NULL);
|
|
|
|
phOsal_ThreadObj_t HceApp;
|
|
|
|
/* Create application thread (to handle UPDATE_BINARY and proprietary
|
|
* commands) */
|
|
HceApp.pTaskName = (uint8_t *)bTaskNameHce;
|
|
HceApp.pStackBuffer = aHceAppTaskBuffer;
|
|
HceApp.priority = APPLICATION_TASK_PRIO;
|
|
HceApp.stackSizeInNum = APPLICATION_TASK_STACK;
|
|
phOsal_ThreadCreate(&HceApp.ThreadHandle, &HceApp, &TApplication, NULL);
|
|
|
|
phOsal_StartScheduler();
|
|
|
|
/* Scheduler exit hook */
|
|
ERROR_CRITICAL("Error...Scheduler exited...\n");
|
|
|
|
#else /* NXPBUILD_EX8_MANDATORY_LAYERS */
|
|
DEBUG_PRINTF("\n\tERROR: Missing required reader library components in build...");
|
|
#endif /* NXPBUILD_EX8_MANDATORY_LAYERS */
|
|
|
|
} while(0);
|
|
|
|
while(bInfLoop); /* Comes here if initialization failure or scheduler exit due to error */
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if NXPBUILD_EX8_MANDATORY_LAYERS
|
|
|
|
/**
|
|
* Reader library thread. This is the main thread which starts discovery loop
|
|
* in listen mode and poll mode (one at a time) and manages switching between
|
|
* both listen and poll modes.
|
|
* */
|
|
void TReaderLibrary(
|
|
void *pParams
|
|
)
|
|
{
|
|
phStatus_t status;
|
|
|
|
/* This call shall allocate secure context before calling any secure function,
|
|
* when FreeRtos trust zone is enabled.
|
|
* */
|
|
phOsal_ThreadSecureStack( 512 );
|
|
|
|
PRINT_INFO("Reader Library thread started...\n");
|
|
|
|
/* Configure target mode HAL parameters */
|
|
status = phApp_HALConfigAutoColl();
|
|
CHECK_STATUS(status);
|
|
|
|
/* Be in card emulation mode */
|
|
while(bInfLoop)
|
|
{
|
|
/* T4T Card Emulation mode */
|
|
T4TCardEmulation();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Do card emulation by starting discovery loop in listen mode and activating
|
|
* ISO 14443p4mC.
|
|
* This function calls phceT4T_Activate() to do T4T emulation.
|
|
* Refer phceT4T_Activate() in phceT4T.h for more info.
|
|
* */
|
|
void T4TCardEmulation(void)
|
|
{
|
|
phStatus_t status = 0;
|
|
phStatus_t wDiscLoop_status = 0;
|
|
#if ISO_10373_6_PICC_TEST_BENCH
|
|
#ifdef NXPBUILD__PHHAL_HW_PN7462AU
|
|
uint16_t wCMAState = 0;
|
|
#endif /* NXPBUILD__PHHAL_HW_PN7462AU */
|
|
#endif /* ISO_10373_6_PICC_TEST_BENCH */
|
|
|
|
/* Start discovery loop in listen mode */
|
|
wDiscLoop_status = phacDiscLoop_Run(
|
|
pDiscLoop,
|
|
PHAC_DISCLOOP_ENTRY_POINT_LISTEN);
|
|
|
|
if((wDiscLoop_status & PH_ERR_MASK) == PHAC_DISCLOOP_EXTERNAL_RFOFF)
|
|
{
|
|
/* Reset SLEEP_AF state (Respond to WupA ("52")/ReqA ("26")) as Field
|
|
* Off is observed.*/
|
|
status = phhalHw_SetConfig(
|
|
pHal,
|
|
PHHAL_HW_CONFIG_MFHALTED,
|
|
PH_OFF);
|
|
CHECK_STATUS(status);
|
|
|
|
#ifdef NXPBUILD__PHHAL_HW_PN7462AU
|
|
phhalRng_GenerateRng(&((phhalHw_PN7462AU_DataParams_t*)pDiscLoop->pHalDataParams)->pAutocoll.pNfcId1[0], 3);
|
|
#endif /* NXPBUILD__PHHAL_HW_PN7462AU*/
|
|
}
|
|
|
|
if((wDiscLoop_status & PH_ERR_MASK) == PHAC_DISCLOOP_ACTIVATED_BY_PEER)
|
|
{
|
|
/* Validate RATS and send ATS */
|
|
status = phpalI14443p4mC_Activate(
|
|
ppalI14443p4mC,
|
|
pDiscLoop->sTargetParams.pRxBuffer,
|
|
(uint8_t)pDiscLoop->sTargetParams.wRxBufferLen,
|
|
aAtsRes,
|
|
wAtsLength);
|
|
|
|
if((status & PH_ERR_MASK) != PH_ERR_SUCCESS)
|
|
{
|
|
if(status == (PH_COMP_PAL_I14443P4MC | PH_ERR_PROTOCOL_ERROR))
|
|
{
|
|
/* Invalid RATS: Set to SLEEP_AF state if needed. */
|
|
#if ISO_10373_6_PICC_TEST_BENCH
|
|
#ifdef NXPBUILD__PHHAL_HW_PN7462AU /* This is required for PN640 for the G.11 test case, where the Card state has to be put to MUTE for scenario */
|
|
status = phhalHw_GetConfig(pHal, PHHAL_HW_CONFIG_MFHALTED, &wCMAState);
|
|
CHECK_STATUS(status);
|
|
|
|
status = phhalHw_SetConfig (pHal, PHHAL_HW_CONFIG_MFHALTED, wCMAState);
|
|
CHECK_STATUS(status);
|
|
#endif /* NXPBUILD__PHHAL_HW_PN7462AU */
|
|
#endif /* ISO_10373_6_PICC_TEST_BENCH */
|
|
}
|
|
else if(status == (PH_COMP_PAL_I14443P4MC | PH_ERR_INVALID_PARAMETER))
|
|
{
|
|
/* Invalid ATS */
|
|
ERROR_CRITICAL("ATS configured is invalid...\n");
|
|
}
|
|
else
|
|
{
|
|
DEBUG_ERROR_PRINT(status);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Trigger AppProcessCmd in Application thread to start */
|
|
status = phOsal_SemPost(&appstart.SemHandle, E_OS_SEM_OPT_NONE);
|
|
if(status != PH_ERR_SUCCESS)
|
|
{
|
|
ERROR_CRITICAL("ReaderLibThread: Releasing Semaphore failed...\n");
|
|
}
|
|
|
|
/* Activates HCE. This handles all the main functionalities of
|
|
* card emulation...receive request from reader...process
|
|
* received request...pass UPDATE BINARY/proprietary commands to
|
|
* application thread if enabled...and send the response back
|
|
* to reader. */
|
|
status = phceT4T_Activate(pceT4T);
|
|
if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS_DESELECTED)
|
|
{
|
|
/* Set SLEEP_AF state (Respond only to WupA ("52"), not to
|
|
* ReqA ("26")), so set MFHalted bit. After this setting is
|
|
* done "phhalHw_Autocoll" should be called immediately from
|
|
* Application so that HAL will know if there is any Field
|
|
* reset in "phhalHw_Autocoll" API and reset this setting. */
|
|
status = phhalHw_SetConfig(
|
|
pHal,
|
|
PHHAL_HW_CONFIG_MFHALTED,
|
|
PH_ON);
|
|
CHECK_STATUS(status);
|
|
}
|
|
|
|
/* Wait for AppProcessCmd in Application thread to exit */
|
|
status = phOsal_SemPend(&appexit.SemHandle, abs_timeout);
|
|
if(status != PH_ERR_SUCCESS)
|
|
{
|
|
ERROR_CRITICAL("ReaderLibThread: Getting Semaphore failed...\n");
|
|
}
|
|
}
|
|
|
|
/* Reset Reader library layers */
|
|
status = phpalI14443p4mC_ResetProtocol(ppalI14443p4mC);
|
|
DEBUG_ERROR_PRINT(status);
|
|
|
|
status = phceT4T_Reset(pceT4T);
|
|
DEBUG_ERROR_PRINT(status);
|
|
}
|
|
|
|
status = phOsal_EventClear(
|
|
&pceT4T->T4TEventObj.EventHandle,
|
|
E_OS_EVENT_OPT_NONE,
|
|
(E_PH_OSAL_EVT_RXDATA_AVAILABLE | E_PH_OSAL_EVT_TXDATA_AVAILABLE |
|
|
E_PH_OSAL_EVT_ABORT | E_PH_OSAL_EVT_ERROR | E_PH_OSAL_EVT_RTO_TIMEOUT),
|
|
NULL);
|
|
DEBUG_ERROR_PRINT(status);
|
|
}
|
|
|
|
/**
|
|
* Application thread. This calls phceT4T_AppProcessCmd() to handle update
|
|
* binary and proprietary commands.
|
|
* Refer phceT4T_AppProcessCmd in phceT4T.h for more info.
|
|
* APIs which does PAL or HAL exchange should not be called from application
|
|
* thread.
|
|
* */
|
|
void TApplication(
|
|
void *pParams
|
|
)
|
|
{
|
|
phStatus_t status;
|
|
|
|
/* This call shall allocate secure context before calling any secure function,
|
|
* when FreeRtos trust zone is enabled.
|
|
* */
|
|
phOsal_ThreadSecureStack( 100 );
|
|
|
|
PRINT_INFO("Application thread started...\n");
|
|
|
|
while(bInfLoop)
|
|
{
|
|
/* Wait for trigger from reader library thread to start */
|
|
status = phOsal_SemPend(&appstart.SemHandle, abs_timeout);
|
|
if(status != PH_ERR_SUCCESS)
|
|
{
|
|
ERROR_CRITICAL("AppThread: Getting Semaphore failed...\n");
|
|
}
|
|
|
|
/* Start Application processing of HCE */
|
|
#if USE_APP_CALLBACK
|
|
/* Use application callback to handle UPDATE_BINARY and proprietary
|
|
* commands. */
|
|
status = phceT4T_AppProcessCmd(
|
|
pceT4T,
|
|
AppProcessCmdCallback);
|
|
#else /* USE_APP_CALLBACK */
|
|
/* Application callback not used. Proprietary commands are not handled
|
|
* (unsupported command is returned as status) and UPDATE BINARY will be
|
|
* handled internally by AppProcessCmd. */
|
|
status = phceT4T_AppProcessCmd(
|
|
pceT4T,
|
|
NULL);
|
|
#endif /* USE_APP_CALLBACK */
|
|
|
|
/* Trigger reader library thread about the phceT4T_AppProcessCmd exit */
|
|
status = phOsal_SemPost(&appexit.SemHandle, E_OS_SEM_OPT_NONE);
|
|
if(status != PH_ERR_SUCCESS)
|
|
{
|
|
ERROR_CRITICAL("AppThread: Releasing Semaphore failed...\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
#if USE_APP_CALLBACK
|
|
/**
|
|
* Application callback to handle UPDATE BINARY and proprietary commands.
|
|
* Refer phceT4T_AppCallback_t in phceT4T.h for more info.
|
|
* */
|
|
phStatus_t AppProcessCmdCallback(
|
|
uint8_t bState,
|
|
uint16_t wRxOption,
|
|
uint8_t *pRxData,
|
|
uint16_t wRxDataLen,
|
|
uint16_t *pStatusWord,
|
|
uint8_t **ppTxData,
|
|
uint16_t *pTxDataLen
|
|
)
|
|
{
|
|
phStatus_t status;
|
|
uint16_t wSelectedFileId;
|
|
uint8_t *pSelectedFile;
|
|
uint32_t dwSelectedFileSize;
|
|
uint8_t bWriteAccess;
|
|
uint32_t dwFileOffset;
|
|
#if ISO_10373_6_PICC_TEST_BENCH
|
|
phOsal_TimerPeriodObj_t timePeriodToWait;
|
|
/* Command to create WTX while running 10373-6 PICC test bench. */
|
|
uint8_t aWaitForWtx[4] = {0xDE, 0xAD, 0xFE, 0xED};
|
|
#endif /* ISO_10373_6_PICC_TEST_BENCH */
|
|
|
|
if(bState == PHCE_T4T_STATE_FILE_UPDATE)
|
|
{
|
|
/* Get Selected file info */
|
|
status = phceT4T_GetSelectedFileInfo(
|
|
pceT4T,
|
|
&wSelectedFileId,
|
|
&pSelectedFile,
|
|
&dwSelectedFileSize,
|
|
&bWriteAccess,
|
|
&dwFileOffset);
|
|
|
|
if((status & PH_ERR_MASK) == PH_ERR_SUCCESS)
|
|
{
|
|
/* Update file */
|
|
(void)memcpy(&pSelectedFile[dwFileOffset], pRxData, wRxDataLen);
|
|
|
|
/* File update success */
|
|
*pStatusWord = 0x9000;
|
|
*ppTxData = NULL;
|
|
*pTxDataLen = 0;
|
|
}
|
|
/* This condition shall never come */
|
|
else
|
|
{
|
|
DEBUG_PRINTF("Application Callback: Getting file Info failed...\n");
|
|
/* Could not update file */
|
|
*pStatusWord = 0x6A82;
|
|
*ppTxData = NULL;
|
|
*pTxDataLen = 0;
|
|
|
|
/* Return same error back */
|
|
return (status & PH_ERR_MASK);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* ---Do the proprietary command handling here--- */
|
|
|
|
#if ISO_10373_6_PICC_TEST_BENCH
|
|
/* Create WTX while running 10373-6 PICC test bench. Waits for WTX
|
|
* timer expire, if received "DEADFEED..." */
|
|
if(memcmp(&pRxData[1], aWaitForWtx, 4) == 0)
|
|
{
|
|
/* Wait for trigger from WTX callback */
|
|
timePeriodToWait.unitPeriod = OS_TIMER_UNIT_MSEC;
|
|
timePeriodToWait.period = 0xFFFFFFFF;
|
|
status = phOsal_SemPend(&timerwtx.SemHandle, timePeriodToWait);
|
|
if(status != PH_ERR_SUCCESS)
|
|
{
|
|
DEBUG_PRINTF("Application Callback: Getting WTX Semaphore failed...\n");
|
|
while(bInfLoop);
|
|
}
|
|
}
|
|
#endif /* ISO_10373_6_PICC_TEST_BENCH */
|
|
|
|
/* No proprietary support */
|
|
*pStatusWord = 0x6D00;
|
|
*ppTxData = NULL;
|
|
*pTxDataLen = 0;
|
|
}
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
#endif /* USE_APP_CALLBACK */
|
|
|
|
/*
|
|
* Initialize/Configure components required by this Example.
|
|
*/
|
|
void phApp_Initialize(void)
|
|
{
|
|
phStatus_t status;
|
|
int ret;
|
|
|
|
/* Configure Card Emulation parameters */
|
|
status = ConfigureCardEmulation();
|
|
if((status & PH_ERR_MASK) != PH_ERR_SUCCESS)
|
|
{
|
|
ERROR_CRITICAL("Configuring card emulation failed...\n");
|
|
}
|
|
|
|
/* Create semaphore for sync. between threads */
|
|
ret = phOsal_SemCreate(&appexit.SemHandle, &appexit, E_OS_SEM_OPT_SIGNALLING_SEM);
|
|
if (ret != 0)
|
|
{
|
|
ERROR_CRITICAL("Semaphore creation failed...\n");
|
|
}
|
|
|
|
/* Create semaphore for sync. between threads */
|
|
ret = phOsal_SemCreate(&appstart.SemHandle, &appstart, E_OS_SEM_OPT_SIGNALLING_SEM);
|
|
if (ret != 0)
|
|
{
|
|
ERROR_CRITICAL("Semaphore creation failed...\n");
|
|
}
|
|
|
|
#if ISO_10373_6_PICC_TEST_BENCH
|
|
/* Create semaphore for testing WTX */
|
|
ret = phOsal_SemCreate(&timerwtx.SemHandle, &timerwtx, E_OS_SEM_OPT_SIGNALLING_SEM);
|
|
if(timerwtx.SemHandle == NULL)
|
|
{
|
|
DEBUG_PRINTF("Semaphore creation failed...\n");
|
|
while(bInfLoop);
|
|
}
|
|
#endif /* ISO_10373_6_PICC_TEST_BENCH */
|
|
}
|
|
|
|
/**
|
|
* Configure 14443p4mC and ceT4T parameters.
|
|
* */
|
|
phStatus_t ConfigureCardEmulation(void)
|
|
{
|
|
phStatus_t status = PH_ERR_SUCCESS;
|
|
uint32_t dwContentLen = 0;
|
|
uint8_t aDataBuff[20];
|
|
|
|
/* Configure CET4T NDEF message mapping version to 2.0, default version is 3.0 */
|
|
status = phceT4T_SetConfig(
|
|
pceT4T,
|
|
PHCE_T4T_CONFIG_VNO,
|
|
NXPBUILD_EX8_CET4T_NDEF_VERSION);
|
|
CHECK_SUCCESS(status);
|
|
|
|
/* Set CC File */
|
|
status = phceT4T_SetElementaryFile(
|
|
pceT4T,
|
|
PHCE_T4T_FILE_CC,
|
|
aCcFile,
|
|
0xE103,
|
|
sizeof(aCcFile),
|
|
GET_CCFILE_CONTENT_LEN(aCcFile));
|
|
CHECK_SUCCESS(status);
|
|
|
|
dwContentLen = GET_FILE_CONTENT_LEN(aNdefFile);
|
|
|
|
/* Backup NdefFile buffer */
|
|
(void)memcpy(aDataBuff, aNdefFile, dwContentLen);
|
|
|
|
if(pceT4T ->bVno == PHCE_T4T_NDEF_SUPPORTED_VNO)
|
|
{
|
|
for(uint8_t bIndex = 0; bIndex < dwContentLen; bIndex++)
|
|
{
|
|
aNdefFile[bIndex + 2] = aDataBuff[bIndex];
|
|
}
|
|
|
|
aNdefFile[0] = 0x00;
|
|
aNdefFile[1] = 0x00;
|
|
|
|
dwContentLen = GET_EXT_FILE_CONTENT_LEN(aNdefFile);
|
|
}
|
|
|
|
/* Set NDEF File */
|
|
status = phceT4T_SetElementaryFile(
|
|
pceT4T,
|
|
PHCE_T4T_FILE_NDEF,
|
|
aNdefFile,
|
|
0xE104,
|
|
sizeof(aNdefFile),
|
|
dwContentLen);
|
|
CHECK_SUCCESS(status);
|
|
|
|
#ifdef NXPBUILD__PHCE_T4T_PROPRIETARY
|
|
/* Set Proprietary File */
|
|
status = phceT4T_SetElementaryFile(
|
|
pceT4T,
|
|
PHCE_T4T_FILE_PROPRIETARY,
|
|
aProprietaryFile,
|
|
0xE105,
|
|
sizeof(aProprietaryFile),
|
|
GET_FILE_CONTENT_LEN(aProprietaryFile));
|
|
CHECK_SUCCESS(status);
|
|
#endif /* NXPBUILD__PHCE_T4T_PROPRIETARY */
|
|
|
|
#if USE_APP_CALLBACK
|
|
/* Enable support for proprietary command handling by application
|
|
* callback. */
|
|
status = phceT4T_SetConfig(
|
|
pceT4T,
|
|
PHCE_T4T_CONFIG_RECEIVE_PROPRIETARY,
|
|
PH_ON);
|
|
CHECK_SUCCESS(status);
|
|
#endif /* USE_APP_CALLBACK */
|
|
|
|
/* Configure MLe (This is optional; default MLe is 255) */
|
|
status = phceT4T_SetConfig(
|
|
pceT4T,
|
|
PHCE_T4T_CONFIG_MLE,
|
|
0x3B);
|
|
CHECK_SUCCESS(status);
|
|
|
|
/* Configure MLc (This is optional; default MLc is 255) */
|
|
status = phceT4T_SetConfig(
|
|
pceT4T,
|
|
PHCE_T4T_CONFIG_MLC,
|
|
0x34);
|
|
CHECK_SUCCESS(status);
|
|
|
|
/* Configure WTX time (WTX will be triggered after this much % of FWT) */
|
|
status = phpalI14443p4mC_SetConfig(
|
|
ppalI14443p4mC,
|
|
PHPAL_I14443P4MC_CONFIG_WT_PERCENTAGE,
|
|
40);
|
|
CHECK_SUCCESS(status);
|
|
|
|
#ifdef PH_OSAL_LINUX
|
|
/* Disable WTX for Linux Build */
|
|
status = phpalI14443p4mC_SetConfig(
|
|
ppalI14443p4mC,
|
|
PHPAL_I14443P4MC_CONFIG_WTX,
|
|
PH_OFF);
|
|
CHECK_SUCCESS(status);
|
|
#endif
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* WTX Callback called from WTX timer of 14443p3mC PAL.
|
|
*/
|
|
void pWtoxCallBck(void)
|
|
{
|
|
phOsal_EventPost(&pceT4T->T4TEventObj.EventHandle, E_OS_EVENT_OPT_POST_ISR, E_PH_OSAL_EVT_RTO_TIMEOUT, NULL);
|
|
|
|
#if ISO_10373_6_PICC_TEST_BENCH
|
|
/* Trigger Application callback (AppProcessCmdCallback) about WTX for ISO
|
|
* 10373-6 test bench.*/
|
|
phOsal_SemPost(&timerwtx.SemHandle, E_OS_SEM_OPT_POST_FROM_ISR);
|
|
#endif /* ISO_10373_6_PICC_TEST_BENCH */
|
|
}
|
|
|
|
#endif /* NXPBUILD_EX8_MANDATORY_LAYERS */
|