Files
NxpNfcRdLib/Examples/NfcrdlibEx3_NFCForum/NfcrdlibEx3_NFCForum.c
2024-07-08 21:03:06 +08:00

1507 lines
63 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
* Example Source for NfcrdlibEx3_NFCForum.c that uses the Discovery loop for polling and performs Tag Operations and SNEP PUT operation.
* Discovery loop is configured for both POLL and LISTEN modes. This example displays detected tag information(like UID, SAK, Product Type)
* and prints information when it detects NFC Forum Tags and gets activated as a target by an external initiator/reader.
* Whenever multiple technologies are detected, example will select last detected technology to resolve.
* Example will activate device at last index whenever multiple devices are detected.
*
* If a P2P device is detected then this example performs SNEP PUT operation if both SNEP client and server are enabled.
* By default SNEP PUT of URI message (www.nxp.com) will be performed.
*
* If remote P2P device wants to perform SNEP PUT that should be received by this example then SNEP client should be disabled, in this case
* phone acts as client and on screen (Touch to Beam) pops up, when user taps the screen then SNEP PUT will be done by the phone and this
* application will receive this SNEP PUT message and displays on console only in Debug mode (Maximum SNEP PUT
* message that can be received is 1024Bytes as per default SNEP server specification).
*
* Please refer Readme.txt file for hardware pin configuration, software configuration and steps to build and
* execute the project. This file is present in the same project directory.
* $Author: $
* $Revision: $ (v07.10.00)
* $Date: $
*
*/
/**
* Reader Library Headers
*/
#include <phApp_Init.h>
/* Local headers */
#include <cards.h>
#include "NfcrdlibEx3_NFCForum.h"
/*******************************************************************************
** Definitions
*******************************************************************************/
#if defined (NXPBUILD__PHHAL_HW_RC663) || defined (NXPBUILD__PHHAL_HW_PN7640)
# warning "This example is not supported for RC663 and PN7640"
int main() {
DEBUG_PRINTF("This example is not supported for RC663 and PN7640.");
while (1){
}
return 0;
}
/* Actual main defined below has no purpose in this example and hence over-riding it. */
# define main dummy_main
#endif /* NXPBUILD__PHHAL_HW_RC663 */
phacDiscLoop_Sw_DataParams_t * pDiscLoop; /* Discovery loop component */
#ifdef NXPBUILD__PHPAL_I18092MPI_SW
void * ppalI18092mPI;
#endif /* NXPBUILD__PHPAL_I18092MPI_SW */
#ifdef NXPBUILD__PHPAL_I18092MT_SW
void * ppalI18092mT;
#endif /* NXPBUILD__PHPAL_I18092MT_SW */
void * palTop;
#ifdef SNEP_SERVER
phnpSnep_Sw_DataParams_t snpSnepServer; /* SNEP component holder */
phlnLlcp_Transport_Socket_t ServerSocket; /* SNEP Server socket and buffers. */
uint8_t bServerRxBuffer[260]; /* SNEP Server socket application buffer to copy data from HAL Rx Buff. */
uint8_t baSnepAppBuffer[1033]; /* SNEP Server application buffer to store received PUT Message */
#endif /* SNEP_SERVER */
#ifdef SNEP_CLIENT
phnpSnep_Sw_DataParams_t snpSnepClient; /* SNEP component holder */
phlnLlcp_Transport_Socket_t ClientSocket; /* SNEP Client socket */
uint8_t bClientRxBuffer[260]; /* SNEP Client socket application buffer to copy data from HAL Rx Buff. */
uint32_t dwClientRxBuffLength = sizeof(bClientRxBuffer);
#endif /* SNEP_CLIENT */
#if ! defined(SNEP_SERVER)
uint8_t baSnepAppBuffer[500]; /* Buffer used to store NDEF data (poll mode) */
#endif /* SNEP_SERVER */
uint32_t baSnepRxLen = 0;
uint8_t bDid = 0; /* DID is not used by default. */
uint8_t bBst = 0x00;
uint8_t bBrt = 0x00;
uint8_t bTo = 8; /* Set TO (time out) value in ATR_RES which will be used to set FDT/FWT on P2P initiator. */
uint8_t bLrt = 3; /* Set LRT value to 3. AS LLCP mandates that LRT value to be 3. */
uint16_t wAtrResLength;
/*The below variables are been initialized according to target mode requirements by this application */
uint8_t sens_res[2] = {0x04, 0x00}; /* ATQ bytes - needed for anti-collision */
uint8_t nfc_id1[3] = {0xA1, 0xA2, 0xA3}; /* user defined bytes of the UID (one is hardcoded) - needed for anti-collision */
uint8_t sel_res = 0x40; /* SAK (ISO18092mT) - needed for anti-collision */
uint8_t nfc_id3 = 0xFA; /* NFC3 byte - required for anti-collision */
uint8_t poll_res[18] = {0x01, 0xFE, 0xB2, 0xB3, 0xB4, 0xB5,
0xB6, 0xB7, 0xC0, 0xC1, 0xC2, 0xC3,
0xC4, 0xC5, 0xC6, 0xC7, 0x23, 0x45 }; /* felica - needed for anti-collision */
/*
* Internal variables used in this application.
*/
uint8_t bSNEPServer;
uint8_t bSNEPClient;
/*******************************************************************************
** Extern Defines
*******************************************************************************/
#if defined(NXPBUILD__PHPAL_I18092MPI_SW) || defined(NXPBUILD__PHPAL_I18092MT_SW)
/* Defined in phApp_Init.c */
extern uint8_t aLLCPGeneralBytes[];
extern uint8_t bLLCPGBLength;
#endif /* defined(NXPBUILD__PHPAL_I18092MPI_SW) || defined(NXPBUILD__PHPAL_I18092MT_SW) */
/* ATR response holder */
extern uint8_t aResponseHolder[64];
/*******************************************************************************
** Const Defines
*******************************************************************************/
/* Timeout specification structure */
const phOsal_TimerPeriodObj_t abs_timeout= {OS_TIMER_UNIT_MSEC, 1000};
/*******************************************************************************
** Static Defines
*******************************************************************************/
/* This is used to save and restore poll configuration if in case application
* has updated/changed polling configuration to resolve a particular technology
* when multiple technologies were detected
*/
static uint16_t bSavePollTechCfg = 0;
#ifdef NXPBUILD__PHNP_SNEP_SW
static uint32_t dwDataLen = sizeof(baSnepAppBuf);
#endif /* NXPBUILD__PHNP_SNEP_SW */
/* Semaphore used in this example application to synchronize tasks to print the received SNEP message by SNEP server. */
#ifdef SNEP_SERVER
phOsal_SemObj_t xTaskSema;
#endif /* SNEP_SERVER */
#ifdef PHOSAL_FREERTOS_STATIC_MEM_ALLOCATION
uint32_t RdLibTaskBuffer[RDLIB_TASK_STACK];
uint32_t SnepServerTaskBuffer[SNEP_SERVER_TASK_STACK];
uint32_t SnepClientTaskBuffer[SNEP_CLIENT_TASK_STACK];
#else /* PHOSAL_FREERTOS_STATIC_MEM_ALLOCATION */
#define RdLibTaskBuffer NULL
#define SnepServerTaskBuffer NULL
#define SnepClientTaskBuffer NULL
#endif /* PHOSAL_FREERTOS_STATIC_MEM_ALLOCATION */
#ifdef PH_OSAL_FREERTOS
const uint8_t bTaskNameMain[configMAX_TASK_NAME_LEN] = {"RdLib"};
const uint8_t bTaskNameServer[configMAX_TASK_NAME_LEN] = {"SnepServer"};
const uint8_t bTaskNameClient[configMAX_TASK_NAME_LEN] = {"SnepClient"};
#else
const uint8_t bTaskNameMain[] = {"RdLib"};
const uint8_t bTaskNameServer[] = {"SnepServer"};
const uint8_t bTaskNameClient[] = {"SnepClient"};
#endif /* PH_OSAL_FREERTOS */
static volatile uint8_t bInfLoop = 1U;
/*******************************************************************************
** Prototypes
*******************************************************************************/
static void GetTagInfo(phacDiscLoop_Sw_DataParams_t *pDataParams, uint16_t wNumberOfTags, uint16_t wTagsDetected);
static phStatus_t LoadDiscoveryConfiguration(void);
/*******************************************************************************
** Extern function for RTOX
** This example will not need RTOX and the function implementation is empty.
*******************************************************************************/
void pRtoxCallBck(void)
{
}
/*******************************************************************************
** Code
*******************************************************************************/
int main(void)
{
do
{
phStatus_t status = PH_ERR_INTERNAL_ERROR;
phOsal_ThreadObj_t RdLib;
phNfcLib_Status_t dwStatus;
phNfcLib_AppContext_t AppContext = {0};
/* Perform Controller specific initialization. */
phApp_CPU_Init();
/* Perform OSAL Initialization. */
(void)phOsal_Init();
DEBUG_PRINTF("\n NFC Forum Example: \n");
#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.pRtoxCallback = (void *)pRtoxCallBck;
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);
#ifdef NXPBUILD__PHPAL_I18092MPI_SW
ppalI18092mPI = phNfcLib_GetDataParams(PH_COMP_PAL_I18092MPI);
#endif /* NXPBUILD__PHPAL_I18092MPI_SW */
#ifdef NXPBUILD__PHPAL_I18092MT_SW
ppalI18092mT = phNfcLib_GetDataParams(PH_COMP_PAL_I18092MT);
#endif /* NXPBUILD__PHPAL_I18092MT_SW */
palTop = phNfcLib_GetDataParams(PH_COMP_AL_TOP);
pDiscLoop = phNfcLib_GetDataParams(PH_COMP_AC_DISCLOOP);
/* 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;
RdLib.pTaskName = (uint8_t *)bTaskNameMain;
RdLib.pStackBuffer = RdLibTaskBuffer;
RdLib.priority = RDLIB_TASK_PRIO;
RdLib.stackSizeInNum = RDLIB_TASK_STACK;
phOsal_ThreadCreate(&RdLib.ThreadHandle, &RdLib, &TReaderLibrary, pDiscLoop);
#ifdef SNEP_SERVER
phOsal_ThreadObj_t SnepServer;
SnepServer.pTaskName = (uint8_t *)bTaskNameServer;
SnepServer.pStackBuffer = SnepServerTaskBuffer;
SnepServer.priority = SNEP_SERVER_TASK_PRIO;
SnepServer.stackSizeInNum = SNEP_SERVER_TASK_STACK;
phOsal_ThreadCreate(&SnepServer.ThreadHandle, &SnepServer, &TSNEPServer, &slnLlcp);
#endif /* SNEP_SERVER */
#ifdef SNEP_CLIENT
phOsal_ThreadObj_t SnepClient;
SnepClient.pTaskName = (uint8_t *)bTaskNameClient;
SnepClient.pStackBuffer = SnepClientTaskBuffer;
SnepClient.priority = SNEP_CLIENT_TASK_PRIO;
SnepClient.stackSizeInNum = SNEP_CLIENT_TASK_STACK;
phOsal_ThreadCreate(&SnepClient.ThreadHandle, &SnepClient, &TSNEPClient, &slnLlcp);
#endif /* SNEP_CLIENT */
phOsal_StartScheduler();
DEBUG_PRINTF("RTOS error : Scheduler exited. \n");
} while(0);
while(bInfLoop); /* Comes here if initialization failure or scheduler exit due to error */
return 0;
}
/**
* This Task demonstrates the usage of discovery loop.
* It detects and reports the NFC technology type and performs read NDEF in case any NFC forum tags are detected.
* If a P2P device is detected then LLCP activate will be called to perform Client/Server operation from another Task.
* \param pDataParams The discovery loop data parameters
* \note This Task will never return and Discovery loop run will be called in a infinite while loop.
*/
void TReaderLibrary(void *pDataParams)
{
phStatus_t status;
#ifdef NXPBUILD__PHPAL_I18092MPI_SW
phStatus_t statustmp;
#endif /* NXPBUILD__PHPAL_I18092MPI_SW */
uint16_t wTagsDetected = 0;
uint16_t wNumberOfTags = 0;
uint16_t wEntryPoint;
uint16_t wValue;
#ifdef NXPBUILD__PHPAL_I18092MT_SW
#ifdef NXPBUILD__PHAC_DISCLOOP_TARGET
uint16_t wGeneralBytesLength;
uint8_t * pGeneralBytes;
#endif /* NXPBUILD__PHAC_DISCLOOP_TARGET */
#endif /* NXPBUILD__PHPAL_I18092MT_SW */
#ifdef NXPBUILD__PHPAL_I18092MPI_SW
uint16_t wGtLength;
uint8_t bGBLen = 0;
#endif /* NXPBUILD__PHPAL_I18092MPI_SW */
uint8_t bIndex;
#ifdef SNEP_SERVER
uint32_t i = 0;
#endif /* SNEP_SERVER */
/* This call shall allocate secure context before calling any secure function,
* when FreeRtos trust zone is enabled.
* */
phOsal_ThreadSecureStack( 512 );
/* Configure HAL target parameters */
status = phApp_HALConfigAutoColl();
CHECK_STATUS(status);
/* Configure discover loop based on the enabled macros i.e. ACTIVE_MODE, PASSIVE_MODE, INITIATOR_MODE, TARGET_MODE. */
LoadDiscoveryConfiguration();
#ifdef NXPBUILD__PHPAL_I18092MPI_SW
/* Set max retry count of 1 in PAL 18092 Initiator to allow only one MAC recovery cycle. */
status = phpalI18092mPI_SetConfig(ppalI18092mPI, PHPAL_I18092MPI_CONFIG_MAXRETRYCOUNT, 0x01);
CHECK_STATUS(status);
#endif /* NXPBUILD__PHPAL_I18092MPI_SW */
#if defined INITIATOR_MODE
/* Start in poll mode */
wEntryPoint = PHAC_DISCLOOP_ENTRY_POINT_POLL;
status = PHAC_DISCLOOP_LPCD_NO_TECH_DETECTED;
#elif defined TARGET_MODE
/* Start in listen mode */
wEntryPoint = PHAC_DISCLOOP_ENTRY_POINT_LISTEN;
#endif
while(bInfLoop)
{
#ifdef PH_EXAMPLE3_LPCD_ENABLE
/* Configure LPCD */
if((status & PH_ERR_MASK) == PHAC_DISCLOOP_LPCD_NO_TECH_DETECTED)
{
status = phApp_ConfigureLPCD();
CHECK_STATUS(status);
}
/* Bool to enable LPCD feature. */
status = phacDiscLoop_SetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_ENABLE_LPCD, PH_ON);
CHECK_STATUS(status);
#endif /* PH_EXAMPLE3_LPCD_ENABLE */
#ifdef NXPBUILD__PHPAL_I18092MPI_SW
/* Reset local variables used. */
bGBLen = 0;
#endif /* NXPBUILD__PHPAL_I18092MPI_SW */
/* Set Discovery poll state to detection */
status = phacDiscLoop_SetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_NEXT_POLL_STATE, PHAC_DISCLOOP_POLL_STATE_DETECTION);
CHECK_STATUS(status);
/* Switch off RF field */
status = phhalHw_FieldOff(pHal);
CHECK_STATUS(status);
/* Wait for field-off time-out */
status = phhalHw_Wait(pHal, PHHAL_HW_TIME_MICROSECONDS, 5100);
CHECK_STATUS(status);
/* Start discovery loop */
status = phacDiscLoop_Run(pDataParams, wEntryPoint);
if(wEntryPoint == PHAC_DISCLOOP_ENTRY_POINT_POLL)
{
if((status & PH_ERR_MASK) == PHAC_DISCLOOP_MULTI_TECH_DETECTED)
{
DEBUG_PRINTF (" \n Multiple technology detected: \n");
status = phacDiscLoop_GetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_TECH_DETECTED, &wTagsDetected);
CHECK_STATUS(status);
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_A))
{
DEBUG_PRINTF (" \tType A detected... \n");
}
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_B))
{
DEBUG_PRINTF (" \tType B detected... \n");
}
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_F212))
{
DEBUG_PRINTF (" \tType F detected with baud rate 212... \n");
}
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_F424))
{
DEBUG_PRINTF (" \tType F detected with baud rate 424... \n");
}
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_V))
{
DEBUG_PRINTF(" \tType V / ISO 15693 / T5T detected... \n");
}
/* Store user configured poll configuration. */
status = phacDiscLoop_GetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_PAS_POLL_TECH_CFG, &bSavePollTechCfg);
CHECK_STATUS(status);
/* Select last detected technology to resolve. */
for(bIndex = 0; bIndex < PHAC_DISCLOOP_PASS_POLL_MAX_TECHS_SUPPORTED; bIndex++)
{
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, (1 << bIndex)))
{
/* Configure for one of the detected technology. */
status = phacDiscLoop_SetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_PAS_POLL_TECH_CFG, (1 << bIndex));
CHECK_STATUS(status);
}
}
DEBUG_PRINTF ("\tResolving selected technology \n");
/* Set Discovery loop poll state to collision resolution. */
status = phacDiscLoop_SetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_NEXT_POLL_STATE, PHAC_DISCLOOP_POLL_STATE_COLLISION_RESOLUTION);
CHECK_STATUS(status);
/* Start Discovery loop in pool mode from collision resolution phase */
status = phacDiscLoop_Run(pDataParams, wEntryPoint);
if((status & PH_ERR_MASK) == PHAC_DISCLOOP_MULTI_DEVICES_RESOLVED)
{
/* Get detected technology type */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TECH_DETECTED, &wTagsDetected);
CHECK_STATUS(status);
/* Get number of tags detected */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_NR_TAGS_FOUND, &wNumberOfTags);
CHECK_STATUS(status);
DEBUG_PRINTF (" \n Multiple cards resolved: %d cards \n",wNumberOfTags);
GetTagInfo(pDataParams, wNumberOfTags, wTagsDetected);
if(wNumberOfTags > 1)
{
/* Get 1st Detected Tag and Activate device at index 0*/
for(bIndex = 0; bIndex < PHAC_DISCLOOP_PASS_POLL_MAX_TECHS_SUPPORTED; bIndex++)
{
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, (1 << bIndex)))
{
DEBUG_PRINTF("\t Activating one card...\n");
status = phacDiscLoop_ActivateCard(pDataParams, bIndex, 0);
break;
}
}
if(((status & PH_ERR_MASK) == PHAC_DISCLOOP_DEVICE_ACTIVATED) ||
((status & PH_ERR_MASK) == PHAC_DISCLOOP_PASSIVE_TARGET_ACTIVATED))
{
/* Get Activated Technology Type */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TECH_DETECTED, &wTagsDetected);
CHECK_STATUS(status);
/* Print card details */
GetTagInfo(pDataParams, 0x01, wTagsDetected);
DEBUG_PRINTF("\tActivation successful\n");
}
else
{
DEBUG_PRINTF("\tCard activation failed\n");
}
}
}
else if((status & PH_ERR_MASK) == PHAC_DISCLOOP_DEVICE_ACTIVATED)
{
DEBUG_PRINTF (" \tCard detected and activated successfully. \n");
/* Get activated technology type */
status = phacDiscLoop_GetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_TECH_DETECTED, &wTagsDetected);
CHECK_STATUS(status);
/*Print card info*/
GetTagInfo(pDataParams, 0x01, wTagsDetected);
}
#ifdef NXPBUILD__PHLN_LLCP_SW
else if ((status & PH_ERR_MASK) == PHAC_DISCLOOP_PASSIVE_TARGET_ACTIVATED)
{
DEBUG_PRINTF (" \nPassive P2P target detected and activated successfully after collision resolution: \n");
/* Assign the PAL 18092 initiator parameters once LLPC should be activated in initiator mode. */
slnLlcp.pPalI18092DataParams = ppalI18092mPI;
/* Get the ATR_RES length. */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TYPEF_P2P_ATR_RES_LEN, &wGtLength);
CHECK_STATUS(status);
bGBLen = (uint8_t)wGtLength;
if (bGBLen >= PHLN_LLCP_ATR_RES_MIN_LEN + 3)
{
/* Activate LLCP with the received ATR_RES in initiator mode. */
status = phlnLlcp_Activate(&slnLlcp,
&aResponseHolder[PHLN_LLCP_ATR_RES_MIN_LEN],
(bGBLen - PHLN_LLCP_ATR_RES_MIN_LEN),
PHLN_LLCP_INITIATOR
);
phOsal_EventClear(&slnLlcp.LlcpEventObj.EventHandle, E_OS_EVENT_OPT_NONE, E_PH_OSAL_EVT_LLCP_ACTIVATED, NULL);
if (!(((status & PH_ERR_MASK) == PH_ERR_LLCP_DEACTIVATED) ||
((status & PH_ERR_MASK) == PH_ERR_PEER_DISCONNECTED)))
{
if ((status & PH_ERR_MASK) == PH_ERR_ABORTED)
{
PRINT_INFO("LLCP exited because of LTO timeout. \n");
}
else if ((status & PH_ERR_MASK) == PH_ERR_RF_ERROR)
{
PRINT_INFO("LLCP exited because of RF error. \n");
}
else
{
PRINT_INFO("\n LLCP exited unexpectedly:");
PrintErrorInfo(status);
}
}
/* Perform LLCP DeInit procedure to release acquired resources. */
status = phlnLlcp_DeInit(&slnLlcp);
CHECK_STATUS(status);
if (bSNEPClient == SNEP_PUT)
{
DEBUG_PRINTF("\t SNEP Client : Performed SNEP PUT\n\t PUT data length is:%d\n\n", dwDataLen);
}
#ifdef SNEP_SERVER
/*
* Waits on SNEP server to receive SNEP message from a client.
* If the server gives this semaphore, then it indicates that
* the message has been received and gets printed.
*/
status = phOsal_SemPend(&xTaskSema.SemHandle, abs_timeout);
if ((bSNEPServer == SNEP_RECEIVED_PUT) && (status == PH_ERR_SUCCESS))
{
DEBUG_PRINTF("\t SNEP Server : Received PUT message of length %d bytes\n", baSnepRxLen);
for(i = 0; i < baSnepRxLen; i++)
{
if((baSnepAppBuffer[i] < 0x20) || (baSnepAppBuffer[i] > 0x7e))
{
baSnepAppBuffer[i] = '.';
}
}
baSnepAppBuffer[baSnepRxLen] = '\0';
DEBUG_PRINTF("\t PUT message : %s\n", baSnepAppBuffer);
baSnepRxLen = 0;
}
#endif /* SNEP_SERVER */
bSNEPClient = 0;
bSNEPServer = 0;
}
else
{
PRINT_INFO("Received ATR_RES length is wrong. \n");
}
}
#endif /* NXPBUILD__PHLN_LLCP_SW */
else
{
PRINT_INFO("\tFailed to resolve selected technology.\n");
}
/* Re-Store user configured poll configuration. */
status = phacDiscLoop_SetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_PAS_POLL_TECH_CFG, bSavePollTechCfg);
CHECK_STATUS(status);
/* Switch to LISTEN mode if supported after POLL mode */
}/* PHAC_DISCLOOP_MULTI_TECH_DETECTED - End */
else if (((status & PH_ERR_MASK) == PHAC_DISCLOOP_NO_TECH_DETECTED) ||
((status & PH_ERR_MASK) == PHAC_DISCLOOP_NO_DEVICE_RESOLVED))
{
/* Switch to LISTEN mode if supported after POLL mode */
}
else if((status & PH_ERR_MASK) == PHAC_DISCLOOP_EXTERNAL_RFON)
{
/*
* If external RF is detected during POLL, return back so that the application
* can restart the loop in LISTEN mode if supported.
*/
}
#ifdef NXPBUILD__PHPAL_I18092MPI_SW
else if(((status & PH_ERR_MASK) == PHAC_DISCLOOP_PASSIVE_TARGET_ACTIVATED)
||((status & PH_ERR_MASK) == PHAC_DISCLOOP_ACTIVE_TARGET_ACTIVATED)
||((status & PH_ERR_MASK) == PHAC_DISCLOOP_MERGED_SEL_RES_FOUND))
{
/* Get detected technology type */
statustmp = phacDiscLoop_GetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_TECH_DETECTED, &wTagsDetected);
CHECK_STATUS(statustmp);
if ((status & PH_ERR_MASK) == PHAC_DISCLOOP_ACTIVE_TARGET_ACTIVATED)
{
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_ACT_POS_BIT_MASK_106))
{
DEBUG_PRINTF ("\nActive P2P target detected and activated successfully at 106kbps. \n");
/* Get the ATR_RES length. */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TYPEA_P2P_ATR_RES_LEN, &wGtLength);
CHECK_STATUS(status);
}
else if((PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_ACT_POS_BIT_MASK_212)) ||
(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_ACT_POS_BIT_MASK_424)))
{
DEBUG_PRINTF ("\nActive P2P target detected and activated successfully at 212/424kbps. \n");
/* Get the ATR_RES length. */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TYPEF_P2P_ATR_RES_LEN, &wGtLength);
CHECK_STATUS(status);
}
else
{
DEBUG_PRINTF("\nUnknown Active P2P target detected. \n");
}
/* Save the ATR_RES length. */
bGBLen = (uint8_t)wGtLength;
}
else if ((status & PH_ERR_MASK) == PHAC_DISCLOOP_MERGED_SEL_RES_FOUND)
{
DEBUG_PRINTF (" \n Merged SAK: Device having T4T and NFC-DEP support detected.\n");
/* Send ATR_REQ to activate device in P2P mode. */
status = phpalI18092mPI_Atr(ppalI18092mPI,
pDiscLoop->sTypeATargetInfo.aTypeA_I3P3[0].aUid,
0x00,
0x03,
0x00,
0x00,
aLLCPGeneralBytes,
pDiscLoop->sTypeATargetInfo.sTypeA_P2P.bGiLength,
aResponseHolder,
&bGBLen
);
CHECK_STATUS(status);
}
else
{
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_A))
{
DEBUG_PRINTF ("\nPassive P2P target detected and activated successfully at 106kbps. \n");
/* Get the ATR_RES Length. */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TYPEA_P2P_ATR_RES_LEN, &wGtLength);
CHECK_STATUS(status);
}
else if((PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_F212)) ||
(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_F424)))
{
DEBUG_PRINTF ("\nPassive P2P target detected and activated successfully at 212/424kbps. \n");
/* Get the ATR_RES Length. */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TYPEF_P2P_ATR_RES_LEN, &wGtLength);
CHECK_STATUS(status);
}
else
{
DEBUG_PRINTF("\nUnknown passive P2P target detected. \n");
}
/* Save the ATR_RES length. */
bGBLen = (uint8_t)wGtLength;
}
/* Assign the PAL 18092 Initiator Parameters once LLPC should be activated in Initiator Mode. */
slnLlcp.pPalI18092DataParams = ppalI18092mPI;
if (bGBLen >= (PHLN_LLCP_ATR_RES_MIN_LEN + 3))
{
/* Activate LLCP with the received ATR_RES in initiator mode. */
status = phlnLlcp_Activate(&slnLlcp,
&aResponseHolder[PHLN_LLCP_ATR_RES_MIN_LEN],
(bGBLen - PHLN_LLCP_ATR_RES_MIN_LEN),
PHLN_LLCP_INITIATOR
);
phOsal_EventClear(&slnLlcp.LlcpEventObj.EventHandle, E_OS_EVENT_OPT_NONE, E_PH_OSAL_EVT_LLCP_ACTIVATED, NULL);
if (!(((status & PH_ERR_MASK) == PH_ERR_LLCP_DEACTIVATED) ||
((status & PH_ERR_MASK) == PH_ERR_PEER_DISCONNECTED)))
{
if ((status & PH_ERR_MASK) == PH_ERR_ABORTED)
{
PRINT_INFO("LLCP exited because of LTO timeout. \n");
}
else if ((status & PH_ERR_MASK) == PH_ERR_RF_ERROR)
{
PRINT_INFO("LLCP exited because of active RF error. \n");
}
else
{
PRINT_INFO("\n LLCP exited unexpectedly:");
PrintErrorInfo(status);
}
}
/* Perform LLCP DeInit procedure to release acquired resources. */
status = phlnLlcp_DeInit(&slnLlcp);
CHECK_STATUS(status);
if (bSNEPClient == SNEP_PUT)
{
DEBUG_PRINTF("\t SNEP Client : Performed SNEP PUT\n\t PUT data length is:%d\n\n", dwDataLen);
}
#ifdef SNEP_SERVER
/*
* Waits on SNEP server to receive SNEP message from a client.
* If the server gives this semaphore, then it indicates that
* the message has been received and gets printed.
*/
status = phOsal_SemPend(&xTaskSema.SemHandle, abs_timeout);
if ((bSNEPServer == SNEP_RECEIVED_PUT) && (status == PH_ERR_SUCCESS))
{
DEBUG_PRINTF("\t SNEP Server : Received PUT message of length %d bytes\n", baSnepRxLen);
for(i = 0; i < baSnepRxLen; i++)
{
if((baSnepAppBuffer[i] < 0x20) || (baSnepAppBuffer[i] > 0x7e))
{
baSnepAppBuffer[i] = '.';
}
}
baSnepAppBuffer[baSnepRxLen] = '\0';
DEBUG_PRINTF("\t PUT Message : %s\n", baSnepAppBuffer);
baSnepRxLen = 0;
}
#endif /* SNEP_SERVER */
bSNEPClient = 0;
bSNEPServer = 0;
}
else
{
PRINT_INFO("Received ATR_RES doesn't contain LLCP magic bytes. Raw P2P is possible. \n");
}
/* Switch to LISTEN mode if supported after POLL mode */
}
#endif /* NXPBUILD__PHPAL_I18092MPI_SW */
else if((status & PH_ERR_MASK) == PHAC_DISCLOOP_MULTI_DEVICES_RESOLVED)
{
/*
* Multiple cards resolved. It enters here if DEVICE LIMIT > 1 and more than one devices are
* detected and resolved.
*/
DEBUG_PRINTF (" \n Multiple cards resolved: \n");
/* Get detected technology type */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TECH_DETECTED, &wTagsDetected);
CHECK_STATUS(status);
/* Get number of tags detected */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_NR_TAGS_FOUND, &wNumberOfTags);
CHECK_STATUS(status);
DEBUG_PRINTF ("\tNumber of tags: %d \n",wNumberOfTags);
GetTagInfo(pDataParams, wNumberOfTags, wTagsDetected);
if(wNumberOfTags > 1)
{
/* Get 1st detected tag and activate device at index 0 */
for(bIndex = 0; bIndex < PHAC_DISCLOOP_PASS_POLL_MAX_TECHS_SUPPORTED; bIndex++)
{
if(PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, (1 << bIndex)))
{
DEBUG_PRINTF("\t Activating device @ index 0\n");
status = phacDiscLoop_ActivateCard(pDataParams, bIndex, 0);
break;
}
}
if( ((status & PH_ERR_MASK) == PHAC_DISCLOOP_DEVICE_ACTIVATED) ||
((status & PH_ERR_MASK) == PHAC_DISCLOOP_PASSIVE_TARGET_ACTIVATED))
{
/* Get detected technology type */
status = phacDiscLoop_GetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TECH_DETECTED, &wTagsDetected);
CHECK_STATUS(status);
GetTagInfo(pDataParams, 0x01, wTagsDetected);
DEBUG_PRINTF("\t\t Activation successful\n");
}
else
{
DEBUG_PRINTF("\t\tCard activation failed\n");
}
}
/* Switch to LISTEN mode if supported after POLL mode */
}
else if((status & PH_ERR_MASK) == PHAC_DISCLOOP_DEVICE_ACTIVATED)
{
DEBUG_PRINTF (" \n Card detected and activated successfully \n");
status = phacDiscLoop_GetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_NR_TAGS_FOUND, &wNumberOfTags);
CHECK_STATUS(status);
/* Get detected technology type */
status = phacDiscLoop_GetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_TECH_DETECTED, &wTagsDetected);
CHECK_STATUS(status);
DEBUG_PRINTF ("\tNumber of tags: %d \n",wNumberOfTags);
GetTagInfo(pDataParams, wNumberOfTags, wTagsDetected);
/* Switch to LISTEN mode if supported after POLL mode */
}
else
{
if((status & PH_ERR_MASK) == PHAC_DISCLOOP_FAILURE)
{
status = phacDiscLoop_GetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_ADDITIONAL_INFO, &wValue);
CHECK_STATUS(status);
PRINT_INFO("\n Discovery loop:");
DEBUG_ERROR_PRINT(PrintErrorInfo(wValue));
}
else
{
PRINT_INFO("\n Discovery loop:");
DEBUG_ERROR_PRINT(PrintErrorInfo(wValue));
}
}
#ifdef TARGET_MODE
/* Start in listen mode */
wEntryPoint = PHAC_DISCLOOP_ENTRY_POINT_LISTEN;
#endif /* TARGET_MODE */
}
else
{
if((status & PH_ERR_MASK) == PHAC_DISCLOOP_EXTERNAL_RFOFF)
{
/*
* Enters here if in the target/card mode and external RF is not available
* Wait for LISTEN timeout till an external RF is detected.
* Application may choose to go into standby at this point.
*/
status = phhalHw_EventConsume(pHal);
CHECK_STATUS(status);
status = phhalHw_SetConfig(pHal, PHHAL_HW_CONFIG_RFON_INTERRUPT, PH_ON);
CHECK_STATUS(status);
status = phhalHw_EventWait(pHal, LISTEN_PHASE_TIME_MS);
if((status & PH_ERR_MASK) == PH_ERR_IO_TIMEOUT)
{
/* Switch to poll mode */
wEntryPoint = PHAC_DISCLOOP_ENTRY_POINT_POLL;
}
else
{
/* Switch to listen mode */
wEntryPoint = PHAC_DISCLOOP_ENTRY_POINT_LISTEN;
}
}
#ifdef NXPBUILD__PHPAL_I18092MT_SW
else if((status & PH_ERR_MASK) == PHAC_DISCLOOP_ACTIVATED_BY_PEER)
{
DEBUG_PRINTF ("\nDevice activated in listen mode. \n");
#ifdef NXPBUILD__PHAC_DISCLOOP_TARGET
/* Assign the PAL 18092 target parameters once LLPC should be activated in listen mode. */
slnLlcp.pPalI18092DataParams = ppalI18092mT;
memcpy(aResponseHolder, poll_res,10);
#ifdef NXPBUILD__PHHAL_HW_PN7462AU
aResponseHolder[8] = 0xC0;
aResponseHolder[9] = 0xC1;
#endif /* NXPBUILD__PHHAL_HW_PN7462AU*/
aResponseHolder[10] = bBst;
aResponseHolder[11] = bBrt;
aResponseHolder[12] = bTo;
aResponseHolder[13] = bLrt << 4 | 0x02; /* Frame Size is 254 and ATR_RES contains General Bytes. */
memcpy(&aResponseHolder[14], aLLCPGeneralBytes, bLLCPGBLength);
wAtrResLength = 14 + bLLCPGBLength;
status = phpalI18092mT_Activate(ppalI18092mT,
pDiscLoop->sTargetParams.pRxBuffer,
pDiscLoop->sTargetParams.wRxBufferLen,
aResponseHolder,
wAtrResLength,
&pGeneralBytes,
&wGeneralBytesLength
);
if((status & PH_ERR_MASK) == PH_ERR_SUCCESS)
{
/* Activate LLCP with the received ATR_REQ in target mode. */
status = phlnLlcp_Activate(&slnLlcp,
pGeneralBytes,
wGeneralBytesLength,
PHLN_LLCP_TARGET
);
phOsal_EventClear(&slnLlcp.LlcpEventObj.EventHandle, E_OS_EVENT_OPT_NONE, E_PH_OSAL_EVT_LLCP_ACTIVATED, NULL);
if (!(((status & PH_ERR_MASK) == PH_ERR_LLCP_DEACTIVATED) ||
((status & PH_ERR_MASK) == PH_ERR_PEER_DISCONNECTED)))
{
if ((status & PH_ERR_MASK) == PH_ERR_ABORTED)
{
PRINT_INFO("LLCP exited because of LTO timeout. \n");
}
else if ((status & PH_ERR_MASK) == PH_ERR_EXT_RF_ERROR)
{
PRINT_INFO("LLCP exited because of external RF Off. \n");
}
else if ((status & PH_ERR_MASK) == PH_ERR_RF_ERROR)
{
PRINT_INFO("LLCP exited because of active RF error. \n");
}
else
{
PRINT_INFO("\n LLCP exited unexpectedly:");
PrintErrorInfo(status);
}
}
if (bSNEPClient == SNEP_PUT)
{
DEBUG_PRINTF("\t SNEP Client : Performed SNEP PUT\n\t PUT data length is:%d\n\n", dwDataLen);
}
#ifdef SNEP_SERVER
/*
* Waits on SNEP server to receive SNEP message from a client.
* If the server gives this semaphore, then it indicates that
* the message has been received and gets printed.
*/
status = phOsal_SemPend(&xTaskSema.SemHandle, abs_timeout);
if ((bSNEPServer == SNEP_RECEIVED_PUT) && (status == PH_ERR_SUCCESS))
{
DEBUG_PRINTF("\t SNEP Server : Received PUT message of length %d bytes\n", baSnepRxLen);
for(i = 0; i < baSnepRxLen; i++)
{
if((baSnepAppBuffer[i] < 0x20) || (baSnepAppBuffer[i] > 0x7e))
{
baSnepAppBuffer[i] = '.';
}
}
baSnepAppBuffer[baSnepRxLen] = '\0';
DEBUG_PRINTF("\t PUT Message : %s\n", baSnepAppBuffer);
baSnepRxLen = 0;
}
#endif /* SNEP_SERVER */
bSNEPClient = 0;
bSNEPServer = 0;
/* Perform LLCP DeInit procedure to release acquired resources. */
status = phlnLlcp_DeInit(&slnLlcp);
CHECK_STATUS(status);
}
else
{
PRINT_INFO("\n phpalI18092mT_Activate failed :");
PrintErrorInfo(status);
}
#endif /* NXPBUILD__PHAC_DISCLOOP_TARGET */
}
#endif /* NXPBUILD__PHPAL_I18092MT_SW */
else
{
if((status & PH_ERR_MASK) == PHAC_DISCLOOP_FAILURE)
{
status = phacDiscLoop_GetConfig(pDataParams, PHAC_DISCLOOP_CONFIG_ADDITIONAL_INFO, &wValue);
CHECK_STATUS(status);
PRINT_INFO("\n Discovery loop:");
DEBUG_ERROR_PRINT(PrintErrorInfo(wValue));
}
else
{
PRINT_INFO("\n Discovery loop:");
DEBUG_ERROR_PRINT(PrintErrorInfo(wValue));
}
}
/* On successful activated by Peer, switch to POLL mode */
wEntryPoint = PHAC_DISCLOOP_ENTRY_POINT_POLL;
}
/* Reset state of layers. */
(void)phalTop_Reset(palTop);
#ifdef NXPBUILD__PHPAL_I14443P4_SW
(void)phpalI14443p4_ResetProtocol(phNfcLib_GetDataParams(PH_COMP_PAL_ISO14443P4));
#endif /* NXPBUILD__PHPAL_I14443P4_SW */
#ifdef NXPBUILD__PHPAL_I18092MPI_SW
(void)phpalI18092mPI_ResetProtocol(ppalI18092mPI);
#endif /* NXPBUILD__PHPAL_I14443P4_SW */
#ifdef NXPBUILD__PHPAL_I18092MT_SW
/* This component is disabled for Rc663. But the example have to build for Rc663 in Linux. */
(void)phpalI18092mT_ResetProtocol(ppalI18092mT);
#endif /* NXPBUILD__PHPAL_I14443P4_SW */
}
}
#ifdef SNEP_SERVER
/**
* Task 2 : SNEP server task
* This task will first block on LLCP activated event from reader library thread, once
* event is obtained this task will register SNEP server socket on LLCP running in reader
* library thread and will wait for remote client to get connected and perform SNEP PUT operation.
* \note : SNEP server task will run in a infinite while loop.
*/
void TSNEPServer(void * pLlcp)
{
phStatus_t status = 0;
uint32_t dwServerRxBuffLength = sizeof(bServerRxBuffer);
uint32_t baSnepAppBufSize = sizeof(baSnepAppBuffer) - 1;
uint8_t bClientReq;
int ret;
ret = phOsal_SemCreate(&xTaskSema.SemHandle, &xTaskSema, E_OS_SEM_OPT_SIGNALLING_SEM);
if (ret != 0)
{
DEBUG_PRINTF ("Server task application semaphore could not be created.\n");
}
do{
/* Wait until LLCP activation is complete. */
status = phlnLlcp_WaitForActivation(pLlcp);
CHECK_STATUS(status);
baSnepRxLen = 0;
bSNEPServer = 0;
/* Initialize SNEP server component. */
status = phnpSnep_Sw_Init(&snpSnepServer, sizeof(phnpSnep_Sw_DataParams_t), &slnLlcp, &ServerSocket);
CHECK_STATUS(status);
/* Perform server initialization to handle remote SNEP client connection. */
status = phnpSnep_ServerInit(&snpSnepServer, phnpSnep_Default_Server, NULL, bServerRxBuffer, dwServerRxBuffLength);
if (status == PH_ERR_SUCCESS)
{
do
{
/* Handle client PUT request. */
status = phnpSnep_ServerListen(&snpSnepServer, 0, NULL, NULL, &bClientReq);
if (status == PH_ERR_SUCCESS)
{
status = phnpSnep_ServerSendResponse(&snpSnepServer, bClientReq, NULL, 0, baSnepAppBufSize, baSnepAppBuffer, &baSnepRxLen);
}
}while(!status);
if (!(((status & PH_ERR_MASK) == PH_ERR_PEER_DISCONNECTED) ||
((status & PH_ERR_MASK) == PH_ERR_LLCP_DEACTIVATED)) ||
((status & PH_ERR_MASK) == PH_ERR_SUCCESS))
{
CHECK_STATUS(status);
}
else
{
if (baSnepRxLen > 0)
{
/* Print only if server received PUT message of length greater than 0 bytes. */
bSNEPServer = SNEP_RECEIVED_PUT;
}
}
status = phOsal_SemPost(&xTaskSema.SemHandle, E_OS_SEM_OPT_NONE);
}
else
{
/* Server initialization is un-successful as peer did not send CONNECT PDU. */
}
phOsal_EventClear(&slnLlcp.LlcpEventObj.EventHandle, E_OS_EVENT_OPT_NONE, E_PH_OSAL_EVT_LLCP_ACTIVATED, NULL);
/* Perform server de-init. */
status = phnpSnep_ServerDeInit(&snpSnepServer);
CHECK_STATUS(status);
}while(bInfLoop);
}
#endif /* SNEP_SERVER */
#ifdef SNEP_CLIENT
/**
* Task 3 : SNEP client task.
* This task will first block on LLCP activated event from reader library thread, once
* event is obtained this task will register client socket on LLCP running in reader
* library thread and will connect to remote SNEP server and performs SNEP PUT operation.
* \note : SNEP client task will run in a infinite while loop.
*/
void TSNEPClient(void * pLlcp)
{
phStatus_t status = 0;
while (bInfLoop)
{
do{
/* Wait until LLCP activation is complete. */
status = phlnLlcp_WaitForActivation(&slnLlcp);
CHECK_STATUS(status);
/* Initialize SNEP client component */
status = phnpSnep_Sw_Init(&snpSnepClient, sizeof(snpSnepClient), &slnLlcp, &ClientSocket);
CHECK_STATUS(status);
/* Perform SNEP client Initialization and connect to remote SNEP server. */
status = phnpSnep_ClientInit(&snpSnepClient, phnpSnep_Default_Server, NULL, bClientRxBuffer, dwClientRxBuffLength);
if (status == PH_ERR_SUCCESS)
{
status = phnpSnep_Put(&snpSnepClient, (uint8_t *)baSnepAppBuf, dwDataLen);
ClientSocket.fReady = true;
phOsal_EventClear(&slnLlcp.LlcpEventObj.EventHandle, E_OS_EVENT_OPT_NONE, E_PH_OSAL_EVT_LLCP_ACTIVATED, NULL);
if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS)
{
status = phnpSnep_ClientDeInit(&snpSnepClient);
if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS)
{
status = phlnLlcp_Deactivate(&slnLlcp);
}
bSNEPClient = SNEP_PUT;
}
else
{
status = phlnLlcp_Transport_Socket_Unregister(snpSnepClient.plnLlcpDataParams, snpSnepClient.psSocket);
CHECK_STATUS(status);
}
}
else
{
phOsal_EventClear(&slnLlcp.LlcpEventObj.EventHandle, E_OS_EVENT_OPT_NONE, E_PH_OSAL_EVT_LLCP_ACTIVATED, NULL);
/* Client initialization is un-successful as failed to connect to remote server.
* Release RTOS memory by performing socket unregister. */
status = phlnLlcp_Transport_Socket_Unregister(snpSnepClient.plnLlcpDataParams, snpSnepClient.psSocket);
CHECK_STATUS(status);
}
} while ((status == PH_ERR_PEER_DISCONNECTED) ||
(status == PH_ERR_LLCP_DEACTIVATED) ||
(status == PH_ERR_SUCCESS));
}
}
#endif /* SNEP_CLIENT */
/**
* This function will load/configure Discovery loop with default values based on interested profiles.
* Application can read these values from EEPROM area and load/configure Discovery loop via SetConfig
* \param bProfile Reader Library Profile
* \note Values used below are default and is for demonstration purpose.
*/
static phStatus_t LoadDiscoveryConfiguration(void)
{
phStatus_t status = PH_ERR_SUCCESS;
uint16_t wPasPollConfig = 0;
uint16_t wActPollConfig = 0;
uint16_t wPasLisConfig = 0;
uint16_t wActLisConfig = 0;
#ifdef INITIATOR_MODE
#ifdef PASSIVE_MODE
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEA_TAGS
wPasPollConfig |= PHAC_DISCLOOP_POS_BIT_MASK_A;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEA_TAGS */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEB_TAGS
wPasPollConfig |= PHAC_DISCLOOP_POS_BIT_MASK_B;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEB_TAGS */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEF_TAGS
wPasPollConfig |= (PHAC_DISCLOOP_POS_BIT_MASK_F212 | PHAC_DISCLOOP_POS_BIT_MASK_F424);
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEF_TAGS */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEV_TAGS
wPasPollConfig |= PHAC_DISCLOOP_POS_BIT_MASK_V;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEV_TAGS */
#ifdef NXPBUILD__PHAC_DISCLOOP_I18000P3M3_TAGS
wPasPollConfig |= PHAC_DISCLOOP_POS_BIT_MASK_18000P3M3;
#endif /* NXPBUILD__PHAC_DISCLOOP_I18000P3M3_TAGS */
#endif /* PASSIVE_MODE */
#ifdef ACTIVE_MODE
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_ACTIVE
wActPollConfig |= PHAC_DISCLOOP_ACT_POS_BIT_MASK_106;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_ACTIVE */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEF212_P2P_ACTIVE
wActPollConfig |= PHAC_DISCLOOP_ACT_POS_BIT_MASK_212;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEF212_P2P_ACTIVE */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEF424_P2P_ACTIVE
wActPollConfig |= PHAC_DISCLOOP_ACT_POS_BIT_MASK_424;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEF424_P2P_ACTIVE */
#endif /* ACTIVE_MODE */
#endif /* INITIATOR_MODE */
#ifdef TARGET_MODE
#ifdef PASSIVE_MODE
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEA_TARGET_PASSIVE
wPasLisConfig |= PHAC_DISCLOOP_POS_BIT_MASK_A;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEA_TARGET_PASSIVE */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEF212_TARGET_PASSIVE
wPasLisConfig |= PHAC_DISCLOOP_POS_BIT_MASK_F212;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEF212_TARGET_PASSIVE */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEF424_TARGET_PASSIVE
wPasLisConfig |= PHAC_DISCLOOP_POS_BIT_MASK_F424;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEF424_TARGET_PASSIVE */
#endif /* PASSIVE_MODE */
#ifdef ACTIVE_MODE
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEA_TARGET_ACTIVE
wActLisConfig |= PHAC_DISCLOOP_POS_BIT_MASK_A;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEA_TARGET_ACTIVE */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEF212_TARGET_ACTIVE
wActLisConfig |= PHAC_DISCLOOP_POS_BIT_MASK_F212;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEF212_TARGET_ACTIVE */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEF424_TARGET_ACTIVE
wActLisConfig |= PHAC_DISCLOOP_POS_BIT_MASK_F424;
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEF424_TARGET_ACTIVE */
#endif /* ACTIVE_MODE */
#endif /* TARGET_MODE */
/* Passive poll bitmap configuration. */
status = phacDiscLoop_SetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_PAS_POLL_TECH_CFG, wPasPollConfig);
CHECK_STATUS(status);
/* Active poll bitmap configuration. */
status = phacDiscLoop_SetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_ACT_POLL_TECH_CFG, wActPollConfig);
CHECK_STATUS(status);
/* Passive listen bitmap configuration. */
status = phacDiscLoop_SetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_PAS_LIS_TECH_CFG, wPasLisConfig);
CHECK_STATUS(status);
/* Active listen bitmap configuration. */
status = phacDiscLoop_SetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_ACT_LIS_TECH_CFG, wActLisConfig);
CHECK_STATUS(status);
/* Passive Bailout bitmap configuration. */
status = phacDiscLoop_SetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_BAIL_OUT, 0x00);
CHECK_STATUS(status);
#if defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_TAGS) || defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_ACTIVE)
/* Set LRI value for Type-A polling to 3. LLCP mandates that LRI value to be 3. */
status = phacDiscLoop_SetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TYPEA_P2P_LRI, 3);
CHECK_STATUS(status);
/* Set LRI value for Type-F polling to 3. LLCP mandates that LRI value to be 3. */
status = phacDiscLoop_SetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_TYPEF_P2P_LRI, 3);
CHECK_STATUS(status);
#endif /* defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_TAGS) || defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_ACTIVE) */
/* Reset collision pending */
status = phacDiscLoop_SetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_COLLISION_PENDING, PH_OFF);
CHECK_STATUS(status);
/* Set Discovery loop mode to NFC mode. */
status = phacDiscLoop_SetConfig(pDiscLoop, PHAC_DISCLOOP_CONFIG_OPE_MODE, RD_LIB_MODE_NFC);
CHECK_STATUS(status);
return status;
}
/**
* This function will retrieve and print tag information like UID, NFC type etc..
* \param pDataParams The discovery loop data parameters
* \param wNumberOfTags Total number of tags detected
* \param wTagsDetected Technology detected
*/
static void GetTagInfo(phacDiscLoop_Sw_DataParams_t *pDataParams, uint16_t wNumberOfTags, uint16_t wTagsDetected)
{
uint16_t bIndex;
#if defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_TAGS) || defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_ACTIVE)
uint8_t bTagType;
#endif
phStatus_t status = 0;
/* Required if DETECT_ERROR is not set. DETECT_ERROR is required for debugging purpose only */
PH_UNUSED_VARIABLE(status);
#if defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_TAGS) || defined(NXPBUILD__PHAC_DISCLOOP_TYPEA_P2P_ACTIVE)
/* Check for Type A tag */
if (PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_A))
{
/* Check for T1T */
if(pDataParams->sTypeATargetInfo.bT1TFlag)
{
DEBUG_PRINTF("\tType A : T1T detected \n");
/* Check for NDEF and Read */
status = ReadNdefMessage(PHAL_TOP_TAG_TYPE_T1T_TAG);
if (status != PH_ERR_SUCCESS)
{
DEBUG_ERROR_PRINT(status);
}
}
else
{
DEBUG_PRINTF("\tTechnology : Type A");
/* Loop through all the detected tags (if multiple tags are
* detected) */
for(bIndex = 0; bIndex < wNumberOfTags; bIndex++)
{
DEBUG_PRINTF ("\n\t\tCard : %d",bIndex + 1);
DEBUG_PRINTF ("\n\t\tUID :");
phApp_Print_Buff( pDataParams->sTypeATargetInfo.aTypeA_I3P3[bIndex].aUid,
pDataParams->sTypeATargetInfo.aTypeA_I3P3[bIndex].bUidSize);
DEBUG_PRINTF ("\n\t\tSAK: 0x%x",pDataParams->sTypeATargetInfo.aTypeA_I3P3[bIndex].aSak);
if ((pDataParams->sTypeATargetInfo.aTypeA_I3P3[bIndex].aSak & (uint8_t) ~0xFB) == 0)
{
/* Bit b3 is set to zero, [Digital] 4.8.2 */
/* Mask out all other bits except for b7 and b6 */
bTagType = (pDataParams->sTypeATargetInfo.aTypeA_I3P3[bIndex].aSak & 0x60);
bTagType = bTagType >> 5;
/* Switch to tag type */
switch(bTagType)
{
case PHAC_DISCLOOP_TYPEA_TYPE2_TAG_CONFIG_MASK:
DEBUG_PRINTF ("\n\t\tType : Type 2 tag\n");
if (!DetectClassic(
pDataParams->sTypeATargetInfo.aTypeA_I3P3[bIndex].aAtqa,
&pDataParams->sTypeATargetInfo.aTypeA_I3P3[bIndex].aSak))
{
/* Check for NDEF and Read NDEF if mifare Ultralite card is detected. */
status = ReadNdefMessage(PHAL_TOP_TAG_TYPE_T2T_TAG);
DEBUG_ERROR_PRINT(status);
}
break;
case PHAC_DISCLOOP_TYPEA_TYPE4A_TAG_CONFIG_MASK:
DEBUG_PRINTF ("\n\t\tType : Type 4A tag\n");
/* Check for NDEF and Read NDEF */
status = ReadNdefMessage(PHAL_TOP_TAG_TYPE_T4T_TAG);
DEBUG_ERROR_PRINT(status);
break;
case PHAC_DISCLOOP_TYPEA_TYPE_NFC_DEP_TAG_CONFIG_MASK:
DEBUG_PRINTF ("\n\t\tType : P2P\n");
break;
case PHAC_DISCLOOP_TYPEA_TYPE_NFC_DEP_TYPE4A_TAG_CONFIG_MASK:
DEBUG_PRINTF ("\n\t\tType : Type NFC_DEP and 4A tag\n");
break;
default:
break;
}
}
}
}
}
#endif
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEB_TAGS
/* Check for Type B tag */
if (PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_B))
{
DEBUG_PRINTF("\tTechnology: Type B");
/* Loop through all the Type B tags detected and print the PUPI */
for (bIndex = 0; bIndex < wNumberOfTags; bIndex++)
{
DEBUG_PRINTF ("\n\t\tCard : %d",bIndex + 1);
DEBUG_PRINTF ("\n\t\tUID :");
/* PUPI Length is always 4 bytes */
phApp_Print_Buff( pDataParams->sTypeBTargetInfo.aTypeB_I3P3[bIndex].aPupi, 0x04);
}
DEBUG_PRINTF("\n");
}
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEB_TAGS */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEF_TAGS
/* Check for Type F tag */
if( PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_F212) ||
PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_F424))
{
DEBUG_PRINTF("\tTechnology: Type F");
/* Loop through all the type F tags and print the IDm */
for (bIndex = 0; bIndex < wNumberOfTags; bIndex++)
{
DEBUG_PRINTF ("\n\t\tCard : %d",bIndex + 1);
DEBUG_PRINTF ("\n\t\tUID :");
phApp_Print_Buff( pDataParams->sTypeFTargetInfo.aTypeFTag[bIndex].aIDmPMm,
PHAC_DISCLOOP_FELICA_IDM_LENGTH );
/* Check data rate */
if(pDataParams->sTypeFTargetInfo.aTypeFTag[bIndex].bBaud != PHAC_DISCLOOP_CON_BITR_212)
{
DEBUG_PRINTF ("\n\t\tBit Rate: 424 kbps");
}
else
{
DEBUG_PRINTF ("\n\t\tBit Rate: 212 kbps");
}
if ((pDataParams->sTypeFTargetInfo.aTypeFTag[bIndex].aIDmPMm[0] == 0x01) &&
(pDataParams->sTypeFTargetInfo.aTypeFTag[bIndex].aIDmPMm[1] == 0xFE))
{
/* This is type F tag with P2P capabilities */
DEBUG_PRINTF ("\n\t\tType : P2P\n");
}
else
{
/* This is Type F T3T tag */
DEBUG_PRINTF ("\n\t\tType : Type 3 tag\n");
/* Check for NDEF and read NDEF */
status = ReadNdefMessage(PHAL_TOP_TAG_TYPE_T3T_TAG);
DEBUG_ERROR_PRINT(status);
}
}
}
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEF_TAGS */
#ifdef NXPBUILD__PHAC_DISCLOOP_TYPEV_TAGS
if (PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_V))
{
DEBUG_PRINTF("\tTechnology : Type V / ISO 15693 / T5T");
/* Loop through all the Type V tags detected and print the UIDs */
for (bIndex = 0; bIndex < wNumberOfTags; bIndex++)
{
DEBUG_PRINTF ("\n\t\tCard: %d",bIndex + 1);
DEBUG_PRINTF ("\n\t\tUID :");
phApp_Print_Buff( pDataParams->sTypeVTargetInfo.aTypeV[bIndex].aUid, 0x08);
/* Check for NDEF and Read */
status = ReadNdefMessage(PHAL_TOP_TAG_TYPE_T5T_TAG);
if (status != PH_ERR_SUCCESS)
{
DEBUG_ERROR_PRINT(status);
}
}
DEBUG_PRINTF("\n");
}
#endif /* NXPBUILD__PHAC_DISCLOOP_TYPEV_TAGS */
#ifdef NXPBUILD__PHAC_DISCLOOP_I18000P3M3_TAGS
if (PHAC_DISCLOOP_CHECK_ANDMASK(wTagsDetected, PHAC_DISCLOOP_POS_BIT_MASK_18000P3M3))
{
DEBUG_PRINTF("\tTechnology : ISO 18000p3m3 / EPC Gen2");
/* Loop through all the 18000p3m3 tags detected and print the UII */
for (bIndex = 0; bIndex < wNumberOfTags; bIndex++)
{
DEBUG_PRINTF("\n\t\tCard: %d",bIndex + 1);
DEBUG_PRINTF("\n\t\tUII :");
phApp_Print_Buff(
pDataParams->sI18000p3m3TargetInfo.aI18000p3m3[bIndex].aUii,
(pDataParams->sI18000p3m3TargetInfo.aI18000p3m3[bIndex].wUiiLength / 8));
}
DEBUG_PRINTF("\n");
}
#endif /* NXPBUILD__PHAC_DISCLOOP_I18000P3M3_TAGS */
}
/**
* Reads NDEF Message if the detected tag has a valid NDEF message
*/
phStatus_t ReadNdefMessage(uint8_t TopTagType)
{
phStatus_t status;
uint8_t bTagState = 0;
uint32_t dwDataLength = 0;
/* Configure Top layer for specified tag type */
status = phalTop_SetConfig(palTop, PHAL_TOP_CONFIG_TAG_TYPE, TopTagType);
DEBUG_ERROR_PRINT(status);
/* Check for NDEF presence */
status = phalTop_CheckNdef(palTop, &bTagState);
DEBUG_ERROR_PRINT(status);
if((bTagState == PHAL_TOP_STATE_READONLY) || (bTagState == PHAL_TOP_STATE_READWRITE))
{
/* Read NDEF message */
status = phalTop_ReadNdef(palTop, baSnepAppBuffer, &dwDataLength);
DEBUG_ERROR_PRINT(status);
/* Print NDEF message, if not NULL NDEF */
if(dwDataLength)
{
DEBUG_PRINTF("\tNDEF detected...\n");
DEBUG_PRINTF("\tNDEF length: %d\n", dwDataLength);
DEBUG_PRINTF("\tNDEF message:\n");
//DumpBuffer(aData, dwDataLength);
DumpBuffer(baSnepAppBuffer, 50);
}
else
{
DEBUG_PRINTF("\tNDEF content is NULL...\n");
}
}
else
{
DEBUG_PRINTF("\tNo NDEF content detected...\n");
}
return status;
}