2021-10-17 22:54:19 +00:00
/**
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* COPYRIGHT ( c ) 2020 STMicroelectronics
*
* Redistribution and use in source and binary forms , with or without modification ,
* are permitted provided that the following conditions are met :
* 1. Redistributions of source code must retain the above copyright notice ,
* this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY ,
* OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
/*! \file rfal_nfc.c
*
* \ author Gustavo Patricio
*
* \ brief RFAL NFC device
*
* This module provides the required features to behave as an NFC Poller
* or Listener device . It grants an easy to use interface for the following
* activities : Technology Detection , Collision Resollution , Activation ,
* Data Exchange , and Deactivation
*
* This layer is influenced by ( but not fully aligned with ) the NFC Forum
* specifications , in particular : Activity 2.0 and NCI 2.0
*
*/
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* INCLUDES
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
# include "rfal_nfc.h"
# include "utils.h"
# include "rfal_analogConfig.h"
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* GLOBAL DEFINES
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2022-01-05 16:10:18 +00:00
# define RFAL_NFC_MAX_DEVICES 5U /* Max number of devices supported */
2021-10-17 22:54:19 +00:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* GLOBAL MACROS
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2022-01-05 16:10:18 +00:00
# define rfalNfcNfcNotify(st) \
if ( gNfcDev . disc . notifyCb ! = NULL ) gNfcDev . disc . notifyCb ( st )
2021-10-17 22:54:19 +00:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* GLOBAL TYPES
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
/*! Buffer union, only one interface is used at a time */
2022-01-05 16:10:18 +00:00
typedef union { /* PRQA S 0750 # MISRA 19.2 - Members of the union will not be used concurrently, only one interface at a time */
rfalIsoDepBufFormat isoDepBuf ; /*!< ISO-DEP buffer format (with header/prologue) */
rfalNfcDepBufFormat nfcDepBuf ; /*!< NFC-DEP buffer format (with header/prologue) */
} rfalNfcTmpBuffer ;
typedef struct {
rfalNfcState state ; /* Main state */
uint16_t techsFound ; /* Technologies found bitmask */
uint16_t techs2do ; /* Technologies still to be performed */
rfalBitRate ap2pBR ; /* Bit rate to poll for AP2P */
uint8_t selDevIdx ; /* Selected device index */
rfalNfcDevice * activeDev ; /* Active device pointer */
rfalNfcDiscoverParam disc ; /* Discovery parameters */
rfalNfcDevice devList [ RFAL_NFC_MAX_DEVICES ] ; /*!< Location of device list */
uint8_t devCnt ; /* Decices found counter */
uint32_t discTmr ; /* Discovery Total duration timer */
ReturnCode dataExErr ; /* Last Data Exchange error */
bool discRestart ; /* Restart discover after deactivation flag */
bool isRxChaining ; /* Flag indicating Other device is chaining */
uint32_t lmMask ; /* Listen Mode mask */
bool isTechInit ; /* Flag indicating technology has been set */
bool isOperOngoing ; /* Flag indicating opration is ongoing */
rfalNfcBuffer txBuf ; /* Tx buffer for Data Exchange */
rfalNfcBuffer rxBuf ; /* Rx buffer for Data Exchange */
uint16_t rxLen ; /* Length of received data on Data Exchange */
2021-10-17 22:54:19 +00:00
# if RFAL_FEATURE_NFC_DEP || RFAL_FEATURE_ISO_DEP
2022-01-05 16:10:18 +00:00
rfalNfcTmpBuffer tmpBuf ; /* Tmp buffer for Data Exchange */
2021-10-17 22:54:19 +00:00
# endif /* RFAL_FEATURE_NFC_DEP || RFAL_FEATURE_ISO_DEP */
2022-01-05 16:10:18 +00:00
} rfalNfc ;
2021-10-17 22:54:19 +00:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* LOCAL VARIABLES
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
# ifdef RFAL_TEST_MODE
2022-01-05 16:10:18 +00:00
rfalNfc gNfcDev ;
2021-10-17 22:54:19 +00:00
# else /* RFAL_TEST_MODE */
2022-01-05 16:10:18 +00:00
static rfalNfc gNfcDev ;
2021-10-17 22:54:19 +00:00
# endif /* RFAL_TEST_MODE */
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* LOCAL FUNCTION PROTOTYPES
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2022-01-05 16:10:18 +00:00
static ReturnCode rfalNfcPollTechDetetection ( void ) ;
static ReturnCode rfalNfcPollCollResolution ( void ) ;
static ReturnCode rfalNfcPollActivation ( uint8_t devIt ) ;
static ReturnCode rfalNfcDeactivation ( void ) ;
2021-10-17 22:54:19 +00:00
# if RFAL_FEATURE_NFC_DEP
2022-01-05 16:10:18 +00:00
static ReturnCode rfalNfcNfcDepActivate (
rfalNfcDevice * device ,
rfalNfcDepCommMode commMode ,
const uint8_t * atrReq ,
uint16_t atrReqLen ) ;
2021-10-17 22:54:19 +00:00
# endif /* RFAL_FEATURE_NFC_DEP */
# if RFAL_FEATURE_LISTEN_MODE
2022-01-05 16:10:18 +00:00
static ReturnCode rfalNfcListenActivation ( void ) ;
2021-10-17 22:54:19 +00:00
# endif /* RFAL_FEATURE_LISTEN_MODE*/
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
ReturnCode rfalNfcInitialize ( void ) {
2021-10-17 22:54:19 +00:00
ReturnCode err ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
gNfcDev . state = RFAL_NFC_STATE_NOTINIT ;
2022-01-05 16:10:18 +00:00
rfalAnalogConfigInitialize ( ) ; /* Initialize RFAL's Analog Configs */
EXIT_ON_ERR ( err , rfalInitialize ( ) ) ; /* Initialize RFAL */
gNfcDev . state = RFAL_NFC_STATE_IDLE ; /* Go to initialized */
2021-10-17 22:54:19 +00:00
return ERR_NONE ;
}
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
ReturnCode rfalNfcDiscover ( const rfalNfcDiscoverParam * disParams ) {
2021-10-17 22:54:19 +00:00
/* Check if initialization has been performed */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . state ! = RFAL_NFC_STATE_IDLE ) {
2021-10-17 22:54:19 +00:00
return ERR_WRONG_STATE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Check valid parameters */
2022-01-05 16:10:18 +00:00
if ( ( disParams = = NULL ) | | ( disParams - > devLimit > RFAL_NFC_MAX_DEVICES ) | |
( disParams - > devLimit = = 0U ) | |
( ( disParams - > maxBR > RFAL_BR_1695 ) & & ( disParams - > maxBR ! = RFAL_BR_KEEP ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_POLL_TECH_F ) ! = 0U ) & &
( disParams - > nfcfBR ! = RFAL_BR_212 ) & & ( disParams - > nfcfBR ! = RFAL_BR_424 ) ) | |
( ( ( ( disParams - > techs2Find & RFAL_NFC_POLL_TECH_AP2P ) ! = 0U ) & &
( disParams - > ap2pBR > RFAL_BR_424 ) ) | |
( disParams - > GBLen > RFAL_NFCDEP_GB_MAX_LEN ) ) ) {
2021-10-17 22:54:19 +00:00
return ERR_PARAM ;
}
2022-01-05 16:10:18 +00:00
if ( ( ( ( disParams - > techs2Find & RFAL_NFC_POLL_TECH_A ) ! = 0U ) & & ! ( ( bool ) RFAL_FEATURE_NFCA ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_POLL_TECH_B ) ! = 0U ) & & ! ( ( bool ) RFAL_FEATURE_NFCB ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_POLL_TECH_F ) ! = 0U ) & & ! ( ( bool ) RFAL_FEATURE_NFCF ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_POLL_TECH_V ) ! = 0U ) & & ! ( ( bool ) RFAL_FEATURE_NFCV ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_POLL_TECH_ST25TB ) ! = 0U ) & &
! ( ( bool ) RFAL_FEATURE_ST25TB ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_POLL_TECH_AP2P ) ! = 0U ) & &
! ( ( bool ) RFAL_FEATURE_NFC_DEP ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_LISTEN_TECH_A ) ! = 0U ) & & ! ( ( bool ) RFAL_FEATURE_NFCA ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_LISTEN_TECH_B ) ! = 0U ) & & ! ( ( bool ) RFAL_FEATURE_NFCB ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_LISTEN_TECH_F ) ! = 0U ) & & ! ( ( bool ) RFAL_FEATURE_NFCF ) ) | |
( ( ( disParams - > techs2Find & RFAL_NFC_LISTEN_TECH_AP2P ) ! = 0U ) & &
! ( ( bool ) RFAL_FEATURE_NFC_DEP ) ) ) {
return ERR_DISABLED ; /* PRQA S 2880 # MISRA 2.1 - Unreachable code due to configuration option being set/unset */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Initialize context for discovery */
2022-01-05 16:10:18 +00:00
gNfcDev . activeDev = NULL ;
gNfcDev . techsFound = RFAL_NFC_TECH_NONE ;
gNfcDev . devCnt = 0 ;
gNfcDev . discRestart = true ;
gNfcDev . isTechInit = false ;
gNfcDev . disc = * disParams ;
2021-10-17 22:54:19 +00:00
/* Calculate Listen Mask */
2022-01-05 16:10:18 +00:00
gNfcDev . lmMask = 0U ;
gNfcDev . lmMask | =
( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_LISTEN_TECH_A ) ! = 0U ) ? RFAL_LM_MASK_NFCA : 0U ) ;
gNfcDev . lmMask | =
( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_LISTEN_TECH_B ) ! = 0U ) ? RFAL_LM_MASK_NFCB : 0U ) ;
gNfcDev . lmMask | =
( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_LISTEN_TECH_F ) ! = 0U ) ? RFAL_LM_MASK_NFCF : 0U ) ;
gNfcDev . lmMask | =
( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_LISTEN_TECH_AP2P ) ! = 0U ) ? RFAL_LM_MASK_ACTIVE_P2P :
0U ) ;
2021-10-17 22:54:19 +00:00
# if !RFAL_FEATURE_LISTEN_MODE
/* Check if Listen Mode is supported/Enabled */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . lmMask ! = 0U ) {
2021-10-17 22:54:19 +00:00
return ERR_DISABLED ;
}
# endif
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
gNfcDev . state = RFAL_NFC_STATE_START_DISCOVERY ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_NONE ;
}
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
ReturnCode rfalNfcDeactivate ( bool discovery ) {
2021-10-17 22:54:19 +00:00
/* Check for valid state */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . state < = RFAL_NFC_STATE_IDLE ) {
2021-10-17 22:54:19 +00:00
return ERR_WRONG_STATE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Check if discovery is to continue afterwards */
2022-01-05 16:10:18 +00:00
if ( ( discovery = = true ) & & ( gNfcDev . disc . techs2Find ! = RFAL_NFC_TECH_NONE ) ) {
2021-10-17 22:54:19 +00:00
/* If so let the state machine continue*/
gNfcDev . discRestart = discovery ;
2022-01-05 16:10:18 +00:00
gNfcDev . state = RFAL_NFC_STATE_DEACTIVATION ;
} else {
2021-10-17 22:54:19 +00:00
/* Otherwise deactivate immediately and go to IDLE */
rfalNfcDeactivation ( ) ;
gNfcDev . state = RFAL_NFC_STATE_IDLE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_NONE ;
}
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
ReturnCode rfalNfcSelect ( uint8_t devIdx ) {
2021-10-17 22:54:19 +00:00
/* Check for valid state */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . state ! = RFAL_NFC_STATE_POLL_SELECT ) {
2021-10-17 22:54:19 +00:00
return ERR_WRONG_STATE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
gNfcDev . selDevIdx = devIdx ;
2022-01-05 16:10:18 +00:00
gNfcDev . state = RFAL_NFC_STATE_POLL_ACTIVATION ;
2021-10-17 22:54:19 +00:00
return ERR_NONE ;
}
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
rfalNfcState rfalNfcGetState ( void ) {
2021-10-17 22:54:19 +00:00
return gNfcDev . state ;
}
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
ReturnCode rfalNfcGetDevicesFound ( rfalNfcDevice * * devList , uint8_t * devCnt ) {
2021-10-17 22:54:19 +00:00
/* Check for valid state */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . state < RFAL_NFC_STATE_POLL_SELECT ) {
2021-10-17 22:54:19 +00:00
return ERR_WRONG_STATE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Check valid parameters */
2022-01-05 16:10:18 +00:00
if ( ( devList = = NULL ) | | ( devCnt = = NULL ) ) {
2021-10-17 22:54:19 +00:00
return ERR_PARAM ;
}
2022-01-05 16:10:18 +00:00
* devCnt = gNfcDev . devCnt ;
2021-10-17 22:54:19 +00:00
* devList = gNfcDev . devList ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_NONE ;
}
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
ReturnCode rfalNfcGetActiveDevice ( rfalNfcDevice * * dev ) {
2021-10-17 22:54:19 +00:00
/* Check for valid state */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . state < RFAL_NFC_STATE_ACTIVATED ) {
2021-10-17 22:54:19 +00:00
return ERR_WRONG_STATE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Check valid parameter */
2022-01-05 16:10:18 +00:00
if ( dev = = NULL ) {
2021-10-17 22:54:19 +00:00
return ERR_PARAM ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Check for valid state */
2022-01-05 16:10:18 +00:00
if ( ( gNfcDev . devCnt = = 0U ) | | ( gNfcDev . activeDev = = NULL ) ) {
2021-10-17 22:54:19 +00:00
return ERR_REQUEST ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
* dev = gNfcDev . activeDev ;
return ERR_NONE ;
}
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
void rfalNfcWorker ( void ) {
2021-10-17 22:54:19 +00:00
ReturnCode err ;
2022-01-05 16:10:18 +00:00
rfalWorker ( ) ; /* Execute RFAL process */
switch ( gNfcDev . state ) {
/*******************************************************************************/
case RFAL_NFC_STATE_NOTINIT :
case RFAL_NFC_STATE_IDLE :
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_START_DISCOVERY :
/* Initialize context for discovery cycle */
gNfcDev . devCnt = 0 ;
gNfcDev . selDevIdx = 0 ;
gNfcDev . techsFound = RFAL_NFC_TECH_NONE ;
gNfcDev . techs2do = gNfcDev . disc . techs2Find ;
gNfcDev . state = RFAL_NFC_STATE_POLL_TECHDETECT ;
# if RFAL_FEATURE_WAKEUP_MODE
/* Check if Low power Wake-Up is to be performed */
if ( gNfcDev . disc . wakeupEnabled ) {
/* Initialize Low power Wake-up mode and wait */
err = rfalWakeUpModeStart (
( gNfcDev . disc . wakeupConfigDefault ? NULL : & gNfcDev . disc . wakeupConfig ) ) ;
if ( err = = ERR_NONE ) {
gNfcDev . state = RFAL_NFC_STATE_WAKEUP_MODE ;
rfalNfcNfcNotify ( gNfcDev . state ) ; /* Notify caller that WU was started */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
}
# endif /* RFAL_FEATURE_WAKEUP_MODE */
break ;
2021-10-17 22:54:19 +00:00
2022-01-05 16:10:18 +00:00
/*******************************************************************************/
case RFAL_NFC_STATE_WAKEUP_MODE :
# if RFAL_FEATURE_WAKEUP_MODE
/* Check if the Wake-up mode has woke */
if ( rfalWakeUpModeHasWoke ( ) ) {
rfalWakeUpModeStop ( ) ; /* Disable Wake-up mode */
gNfcDev . state = RFAL_NFC_STATE_POLL_TECHDETECT ; /* Go to Technology detection */
rfalNfcNfcNotify ( gNfcDev . state ) ; /* Notify caller that WU has woke */
}
# endif /* RFAL_FEATURE_WAKEUP_MODE */
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_POLL_TECHDETECT :
/* Start total duration timer */
platformTimerDestroy ( gNfcDev . discTmr ) ;
gNfcDev . discTmr = ( uint32_t ) platformTimerCreate ( gNfcDev . disc . totalDuration ) ;
err =
rfalNfcPollTechDetetection ( ) ; /* Perform Technology Detection */
if ( err ! = ERR_BUSY ) /* Wait until all technologies are performed */
{
if ( ( err ! = ERR_NONE ) | |
( gNfcDev . techsFound = =
RFAL_NFC_TECH_NONE ) ) /* Check if any error occurred or no techs were found */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
rfalFieldOff ( ) ;
gNfcDev . state =
RFAL_NFC_STATE_LISTEN_TECHDETECT ; /* Nothing found as poller, go to listener */
break ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do =
gNfcDev . techsFound ; /* Store the found technologies for collision resolution */
gNfcDev . state =
RFAL_NFC_STATE_POLL_COLAVOIDANCE ; /* One or more devices found, go to Collision Avoidance */
}
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_POLL_COLAVOIDANCE :
err =
rfalNfcPollCollResolution ( ) ; /* Resolve any eventual collision */
if ( err ! = ERR_BUSY ) /* Wait until all technologies are performed */
{
if ( ( err ! = ERR_NONE ) | |
( gNfcDev . devCnt = = 0U ) ) /* Check if any error occurred or no devices were found */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
gNfcDev . state = RFAL_NFC_STATE_DEACTIVATION ;
break ; /* Unable to retrieve any device, restart loop */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
/* Check if more than one device has been found */
if ( gNfcDev . devCnt > 1U ) {
/* If more than one device was found inform upper layer to choose which one to activate */
if ( gNfcDev . disc . notifyCb ! = NULL ) {
gNfcDev . state = RFAL_NFC_STATE_POLL_SELECT ;
gNfcDev . disc . notifyCb ( gNfcDev . state ) ;
2021-10-17 22:54:19 +00:00
break ;
}
}
2022-01-05 16:10:18 +00:00
/* If only one device or no callback has been set, activate the first device found */
gNfcDev . selDevIdx = 0U ;
gNfcDev . state = RFAL_NFC_STATE_POLL_ACTIVATION ;
}
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_POLL_ACTIVATION :
err = rfalNfcPollActivation ( gNfcDev . selDevIdx ) ;
if ( err ! = ERR_BUSY ) /* Wait until all Activation is complete */
{
if ( err ! = ERR_NONE ) /* Activation failed selected device */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
gNfcDev . state =
RFAL_NFC_STATE_DEACTIVATION ; /* If Activation failed, restart loop */
2021-10-17 22:54:19 +00:00
break ;
}
2022-01-05 16:10:18 +00:00
gNfcDev . state = RFAL_NFC_STATE_ACTIVATED ; /* Device has been properly activated */
rfalNfcNfcNotify (
gNfcDev . state ) ; /* Inform upper layer that a device has been activated */
}
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_DATAEXCHANGE :
rfalNfcDataExchangeGetStatus ( ) ; /* Run the internal state machine */
if ( gNfcDev . dataExErr ! = ERR_BUSY ) /* If Dataexchange has terminated */
{
gNfcDev . state = RFAL_NFC_STATE_DATAEXCHANGE_DONE ; /* Go to done state */
rfalNfcNfcNotify ( gNfcDev . state ) ; /* And notify caller */
}
if ( gNfcDev . dataExErr = = ERR_SLEEP_REQ ) /* Check if Listen mode has to go to Sleep */
{
gNfcDev . state = RFAL_NFC_STATE_LISTEN_SLEEP ; /* Go to Listen Sleep state */
rfalNfcNfcNotify ( gNfcDev . state ) ; /* And notify caller */
}
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_DEACTIVATION :
rfalNfcDeactivation ( ) ; /* Deactivate current device */
gNfcDev . state =
( ( gNfcDev . discRestart ) ? RFAL_NFC_STATE_START_DISCOVERY : RFAL_NFC_STATE_IDLE ) ;
rfalNfcNfcNotify ( gNfcDev . state ) ; /* Notify caller */
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_LISTEN_TECHDETECT :
if ( platformTimerIsExpired ( gNfcDev . discTmr ) ) {
# if RFAL_FEATURE_LISTEN_MODE
rfalListenStop ( ) ;
# else
rfalFieldOff ( ) ;
# endif /* RFAL_FEATURE_LISTEN_MODE */
gNfcDev . state = RFAL_NFC_STATE_START_DISCOVERY ; /* Restart the discovery loop */
rfalNfcNfcNotify ( gNfcDev . state ) ; /* Notify caller */
2021-10-17 22:54:19 +00:00
break ;
2022-01-05 16:10:18 +00:00
}
# if RFAL_FEATURE_LISTEN_MODE
if ( gNfcDev . lmMask ! = 0U ) /* Check if configured to perform Listen mode */
{
err = rfalListenStart (
gNfcDev . lmMask ,
& gNfcDev . disc . lmConfigPA ,
NULL ,
& gNfcDev . disc . lmConfigPF ,
( uint8_t * ) & gNfcDev . rxBuf . rfBuf ,
( uint16_t ) rfalConvBytesToBits ( sizeof ( gNfcDev . rxBuf . rfBuf ) ) ,
& gNfcDev . rxLen ) ;
if ( err = = ERR_NONE ) {
gNfcDev . state =
RFAL_NFC_STATE_LISTEN_COLAVOIDANCE ; /* Wait for listen mode to be activated */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
}
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_LISTEN_COLAVOIDANCE :
if ( platformTimerIsExpired (
gNfcDev . discTmr ) ) /* Check if the total duration has been reached */
{
rfalListenStop ( ) ;
gNfcDev . state = RFAL_NFC_STATE_START_DISCOVERY ; /* Restart the discovery loop */
rfalNfcNfcNotify ( gNfcDev . state ) ; /* Notify caller */
2021-10-17 22:54:19 +00:00
break ;
2022-01-05 16:10:18 +00:00
}
/* Check for external field */
if ( rfalListenGetState ( NULL , NULL ) > = RFAL_LM_STATE_IDLE ) {
gNfcDev . state =
RFAL_NFC_STATE_LISTEN_ACTIVATION ; /* Wait for listen mode to be activated */
}
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_LISTEN_ACTIVATION :
case RFAL_NFC_STATE_LISTEN_SLEEP :
err = rfalNfcListenActivation ( ) ;
if ( err ! = ERR_BUSY ) {
if ( err = = ERR_NONE ) {
gNfcDev . activeDev =
gNfcDev . devList ; /* Assign the active device to be used further on */
gNfcDev . devCnt + + ;
gNfcDev . state = RFAL_NFC_STATE_ACTIVATED ; /* Device has been properly activated */
rfalNfcNfcNotify (
gNfcDev . state ) ; /* Inform upper layer that a device has been activated */
} else {
rfalListenStop ( ) ;
gNfcDev . state = RFAL_NFC_STATE_START_DISCOVERY ; /* Restart the discovery loop */
rfalNfcNfcNotify ( gNfcDev . state ) ; /* Notify caller */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
}
# endif /* RFAL_FEATURE_LISTEN_MODE */
break ;
/*******************************************************************************/
case RFAL_NFC_STATE_ACTIVATED :
case RFAL_NFC_STATE_POLL_SELECT :
case RFAL_NFC_STATE_DATAEXCHANGE_DONE :
default :
return ;
2021-10-17 22:54:19 +00:00
}
}
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
ReturnCode rfalNfcDataExchangeStart (
uint8_t * txData ,
uint16_t txDataLen ,
uint8_t * * rxData ,
uint16_t * * rvdLen ,
uint32_t fwt ,
uint32_t flags ) {
ReturnCode err ;
2021-10-17 22:54:19 +00:00
rfalTransceiveContext ctx ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* The Data Exchange is divided in two different moments, the trigger/Start of *
* the transfer followed by the check until its completion */
2022-01-05 16:10:18 +00:00
if ( ( gNfcDev . state > = RFAL_NFC_STATE_ACTIVATED ) & & ( gNfcDev . activeDev ! = NULL ) ) {
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* In Listen mode is the Poller that initiates the communicatation */
/* Assign output parameters and rfalNfcDataExchangeGetStatus will return */
/* incoming data from Poller/Initiator */
2022-01-05 16:10:18 +00:00
if ( ( gNfcDev . state = = RFAL_NFC_STATE_ACTIVATED ) & &
rfalNfcIsRemDevPoller ( gNfcDev . activeDev - > type ) ) {
if ( txDataLen > 0U ) {
2021-10-17 22:54:19 +00:00
return ERR_WRONG_STATE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
* rvdLen = ( uint16_t * ) & gNfcDev . rxLen ;
* rxData = ( uint8_t * ) ( ( gNfcDev . activeDev - > rfInterface = = RFAL_NFC_INTERFACE_ISODEP ) ? gNfcDev . rxBuf . isoDepBuf . apdu :
( ( gNfcDev . activeDev - > rfInterface = = RFAL_NFC_INTERFACE_NFCDEP ) ? gNfcDev . rxBuf . nfcDepBuf . pdu : gNfcDev . rxBuf . rfBuf ) ) ;
if ( gNfcDev . disc . activate_after_sak ) {
gNfcDev . state = RFAL_NFC_STATE_DATAEXCHANGE_DONE ;
}
return ERR_NONE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
switch ( gNfcDev . activeDev
- > rfInterface ) /* Check which RF interface shall be used/has been activated */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
/*******************************************************************************/
case RFAL_NFC_INTERFACE_RF :
rfalCreateByteFlagsTxRxContext (
ctx ,
( uint8_t * ) txData ,
txDataLen ,
gNfcDev . rxBuf . rfBuf ,
sizeof ( gNfcDev . rxBuf . rfBuf ) ,
& gNfcDev . rxLen ,
flags ,
fwt ) ;
if ( flags = = RFAL_TXRX_FLAGS_RAW ) {
ctx . txBufLen = txDataLen ;
}
* rxData = ( uint8_t * ) gNfcDev . rxBuf . rfBuf ;
* rvdLen = ( uint16_t * ) & gNfcDev . rxLen ;
err = rfalStartTransceive ( & ctx ) ;
break ;
2022-03-23 22:14:34 +00:00
# if RFAL_FEATURE_ISO_DEP
/*******************************************************************************/
case RFAL_NFC_INTERFACE_ISODEP : {
rfalIsoDepApduTxRxParam isoDepTxRx ;
if ( txDataLen > sizeof ( gNfcDev . txBuf . isoDepBuf . apdu ) ) {
return ERR_NOMEM ;
}
if ( txDataLen > 0U ) {
ST_MEMCPY ( ( uint8_t * ) gNfcDev . txBuf . isoDepBuf . apdu , txData , txDataLen ) ;
}
isoDepTxRx . DID = RFAL_ISODEP_NO_DID ;
isoDepTxRx . ourFSx = RFAL_ISODEP_FSX_KEEP ;
isoDepTxRx . FSx = gNfcDev . activeDev - > proto . isoDep . info . FSx ;
isoDepTxRx . dFWT = gNfcDev . activeDev - > proto . isoDep . info . dFWT ;
isoDepTxRx . FWT = gNfcDev . activeDev - > proto . isoDep . info . FWT ;
isoDepTxRx . txBuf = & gNfcDev . txBuf . isoDepBuf ;
isoDepTxRx . txBufLen = txDataLen ;
isoDepTxRx . rxBuf = & gNfcDev . rxBuf . isoDepBuf ;
isoDepTxRx . rxLen = & gNfcDev . rxLen ;
isoDepTxRx . tmpBuf = & gNfcDev . tmpBuf . isoDepBuf ;
* rxData = ( uint8_t * ) gNfcDev . rxBuf . isoDepBuf . apdu ;
* rvdLen = ( uint16_t * ) & gNfcDev . rxLen ;
/*******************************************************************************/
/* Trigger a RFAL ISO-DEP Transceive */
err = rfalIsoDepStartApduTransceive ( isoDepTxRx ) ;
break ;
}
# endif /* RFAL_FEATURE_ISO_DEP */
# if RFAL_FEATURE_NFC_DEP
/*******************************************************************************/
case RFAL_NFC_INTERFACE_NFCDEP : {
rfalNfcDepPduTxRxParam nfcDepTxRx ;
if ( txDataLen > sizeof ( gNfcDev . txBuf . nfcDepBuf . pdu ) ) {
return ERR_NOMEM ;
}
if ( txDataLen > 0U ) {
ST_MEMCPY ( ( uint8_t * ) gNfcDev . txBuf . nfcDepBuf . pdu , txData , txDataLen ) ;
}
nfcDepTxRx . DID = RFAL_NFCDEP_DID_KEEP ;
nfcDepTxRx . FSx =
rfalNfcIsRemDevListener ( gNfcDev . activeDev - > type ) ?
rfalNfcDepLR2FS ( ( uint8_t ) rfalNfcDepPP2LR (
gNfcDev . activeDev - > proto . nfcDep . activation . Target . ATR_RES . PPt ) ) :
rfalNfcDepLR2FS ( ( uint8_t ) rfalNfcDepPP2LR (
gNfcDev . activeDev - > proto . nfcDep . activation . Initiator . ATR_REQ . PPi ) ) ;
nfcDepTxRx . dFWT = gNfcDev . activeDev - > proto . nfcDep . info . dFWT ;
nfcDepTxRx . FWT = gNfcDev . activeDev - > proto . nfcDep . info . FWT ;
nfcDepTxRx . txBuf = & gNfcDev . txBuf . nfcDepBuf ;
nfcDepTxRx . txBufLen = txDataLen ;
nfcDepTxRx . rxBuf = & gNfcDev . rxBuf . nfcDepBuf ;
nfcDepTxRx . rxLen = & gNfcDev . rxLen ;
nfcDepTxRx . tmpBuf = & gNfcDev . tmpBuf . nfcDepBuf ;
* rxData = ( uint8_t * ) gNfcDev . rxBuf . nfcDepBuf . pdu ;
* rvdLen = ( uint16_t * ) & gNfcDev . rxLen ;
/*******************************************************************************/
/* Trigger a RFAL NFC-DEP Transceive */
err = rfalNfcDepStartPduTransceive ( nfcDepTxRx ) ;
break ;
}
# endif /* RFAL_FEATURE_NFC_DEP */
/*******************************************************************************/
default :
err = ERR_PARAM ;
break ;
}
/* If a transceive has succesfully started flag Data Exchange as ongoing */
if ( err = = ERR_NONE ) {
gNfcDev . dataExErr = ERR_BUSY ;
gNfcDev . state = RFAL_NFC_STATE_DATAEXCHANGE ;
}
return err ;
}
return ERR_WRONG_STATE ;
}
ReturnCode rfalNfcDataExchangeCustomStart (
uint8_t * txData ,
uint16_t txDataLen ,
uint8_t * * rxData ,
uint16_t * * rvdLen ,
uint32_t fwt ,
uint32_t flags ) {
ReturnCode err ;
rfalTransceiveContext ctx ;
/*******************************************************************************/
/* The Data Exchange is divided in two different moments, the trigger/Start of *
* the transfer followed by the check until its completion */
if ( ( gNfcDev . state > = RFAL_NFC_STATE_ACTIVATED ) & & ( gNfcDev . activeDev ! = NULL ) ) {
/*******************************************************************************/
/* In Listen mode is the Poller that initiates the communicatation */
/* Assign output parameters and rfalNfcDataExchangeGetStatus will return */
/* incoming data from Poller/Initiator */
if ( ( gNfcDev . state = = RFAL_NFC_STATE_ACTIVATED ) & &
rfalNfcIsRemDevPoller ( gNfcDev . activeDev - > type ) ) {
if ( txDataLen > 0U ) {
return ERR_WRONG_STATE ;
}
* rvdLen = ( uint16_t * ) & gNfcDev . rxLen ;
* rxData = ( uint8_t * ) ( ( gNfcDev . activeDev - > rfInterface = = RFAL_NFC_INTERFACE_ISODEP ) ? gNfcDev . rxBuf . isoDepBuf . apdu :
( ( gNfcDev . activeDev - > rfInterface = = RFAL_NFC_INTERFACE_NFCDEP ) ? gNfcDev . rxBuf . nfcDepBuf . pdu : gNfcDev . rxBuf . rfBuf ) ) ;
if ( gNfcDev . disc . activate_after_sak ) {
gNfcDev . state = RFAL_NFC_STATE_DATAEXCHANGE_DONE ;
}
return ERR_NONE ;
}
/*******************************************************************************/
switch ( gNfcDev . activeDev
- > rfInterface ) /* Check which RF interface shall be used/has been activated */
{
/*******************************************************************************/
case RFAL_NFC_INTERFACE_RF :
2022-04-19 15:23:58 +00:00
ctx . rxBuf = gNfcDev . rxBuf . rfBuf ;
ctx . rxBufLen = 8 * sizeof ( gNfcDev . rxBuf . rfBuf ) ;
ctx . rxRcvdLen = & gNfcDev . rxLen ;
ctx . txBuf = txData ;
ctx . txBufLen = txDataLen ;
ctx . flags = flags ;
ctx . fwt = fwt ;
* rxData = ( uint8_t * ) gNfcDev . rxBuf . rfBuf ;
2022-03-23 22:14:34 +00:00
* rvdLen = ( uint16_t * ) & gNfcDev . rxLen ;
err = rfalStartTransceive ( & ctx ) ;
break ;
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_ISO_DEP
/*******************************************************************************/
case RFAL_NFC_INTERFACE_ISODEP : {
rfalIsoDepApduTxRxParam isoDepTxRx ;
2022-04-19 15:23:58 +00:00
uint16_t tx_bytes = txDataLen / 8 ;
2022-01-05 16:10:18 +00:00
2022-04-19 15:23:58 +00:00
if ( tx_bytes > sizeof ( gNfcDev . txBuf . isoDepBuf . apdu ) ) {
2022-01-05 16:10:18 +00:00
return ERR_NOMEM ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2022-04-19 15:23:58 +00:00
if ( tx_bytes > 0U ) {
ST_MEMCPY ( ( uint8_t * ) gNfcDev . txBuf . isoDepBuf . apdu , txData , tx_bytes ) ;
2022-01-05 16:10:18 +00:00
}
isoDepTxRx . DID = RFAL_ISODEP_NO_DID ;
isoDepTxRx . ourFSx = RFAL_ISODEP_FSX_KEEP ;
isoDepTxRx . FSx = gNfcDev . activeDev - > proto . isoDep . info . FSx ;
isoDepTxRx . dFWT = gNfcDev . activeDev - > proto . isoDep . info . dFWT ;
isoDepTxRx . FWT = gNfcDev . activeDev - > proto . isoDep . info . FWT ;
isoDepTxRx . txBuf = & gNfcDev . txBuf . isoDepBuf ;
2022-04-19 15:23:58 +00:00
isoDepTxRx . txBufLen = tx_bytes ;
2022-01-05 16:10:18 +00:00
isoDepTxRx . rxBuf = & gNfcDev . rxBuf . isoDepBuf ;
isoDepTxRx . rxLen = & gNfcDev . rxLen ;
isoDepTxRx . tmpBuf = & gNfcDev . tmpBuf . isoDepBuf ;
* rxData = ( uint8_t * ) gNfcDev . rxBuf . isoDepBuf . apdu ;
* rvdLen = ( uint16_t * ) & gNfcDev . rxLen ;
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
/* Trigger a RFAL ISO-DEP Transceive */
err = rfalIsoDepStartApduTransceive ( isoDepTxRx ) ;
break ;
}
# endif /* RFAL_FEATURE_ISO_DEP */
# if RFAL_FEATURE_NFC_DEP
/*******************************************************************************/
case RFAL_NFC_INTERFACE_NFCDEP : {
rfalNfcDepPduTxRxParam nfcDepTxRx ;
if ( txDataLen > sizeof ( gNfcDev . txBuf . nfcDepBuf . pdu ) ) {
return ERR_NOMEM ;
}
if ( txDataLen > 0U ) {
ST_MEMCPY ( ( uint8_t * ) gNfcDev . txBuf . nfcDepBuf . pdu , txData , txDataLen ) ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
nfcDepTxRx . DID = RFAL_NFCDEP_DID_KEEP ;
nfcDepTxRx . FSx =
rfalNfcIsRemDevListener ( gNfcDev . activeDev - > type ) ?
rfalNfcDepLR2FS ( ( uint8_t ) rfalNfcDepPP2LR (
gNfcDev . activeDev - > proto . nfcDep . activation . Target . ATR_RES . PPt ) ) :
rfalNfcDepLR2FS ( ( uint8_t ) rfalNfcDepPP2LR (
gNfcDev . activeDev - > proto . nfcDep . activation . Initiator . ATR_REQ . PPi ) ) ;
nfcDepTxRx . dFWT = gNfcDev . activeDev - > proto . nfcDep . info . dFWT ;
nfcDepTxRx . FWT = gNfcDev . activeDev - > proto . nfcDep . info . FWT ;
nfcDepTxRx . txBuf = & gNfcDev . txBuf . nfcDepBuf ;
nfcDepTxRx . txBufLen = txDataLen ;
nfcDepTxRx . rxBuf = & gNfcDev . rxBuf . nfcDepBuf ;
nfcDepTxRx . rxLen = & gNfcDev . rxLen ;
nfcDepTxRx . tmpBuf = & gNfcDev . tmpBuf . nfcDepBuf ;
* rxData = ( uint8_t * ) gNfcDev . rxBuf . nfcDepBuf . pdu ;
* rvdLen = ( uint16_t * ) & gNfcDev . rxLen ;
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
/* Trigger a RFAL NFC-DEP Transceive */
err = rfalNfcDepStartPduTransceive ( nfcDepTxRx ) ;
break ;
}
# endif /* RFAL_FEATURE_NFC_DEP */
/*******************************************************************************/
default :
err = ERR_PARAM ;
break ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* If a transceive has succesfully started flag Data Exchange as ongoing */
2022-01-05 16:10:18 +00:00
if ( err = = ERR_NONE ) {
2021-10-17 22:54:19 +00:00
gNfcDev . dataExErr = ERR_BUSY ;
2022-01-05 16:10:18 +00:00
gNfcDev . state = RFAL_NFC_STATE_DATAEXCHANGE ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return err ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_WRONG_STATE ;
}
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
ReturnCode rfalNfcDataExchangeGetStatus ( void ) {
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Check if it's the first frame received in Listen mode */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . state = = RFAL_NFC_STATE_ACTIVATED ) {
2021-10-17 22:54:19 +00:00
/* Continue data exchange as normal */
gNfcDev . dataExErr = ERR_BUSY ;
2022-01-05 16:10:18 +00:00
gNfcDev . state = RFAL_NFC_STATE_DATAEXCHANGE ;
2021-10-17 22:54:19 +00:00
/* Check if we performing in T3T CE */
2022-01-05 16:10:18 +00:00
if ( ( gNfcDev . activeDev - > type = = RFAL_NFC_POLL_TYPE_NFCF ) & &
( gNfcDev . activeDev - > rfInterface = = RFAL_NFC_INTERFACE_RF ) ) {
2021-10-17 22:54:19 +00:00
/* The first frame has been retrieved by rfalListenMode, flag data immediately */
/* Can only call rfalGetTransceiveStatus() after starting a transceive with rfalStartTransceive */
gNfcDev . dataExErr = ERR_NONE ;
}
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Check if we are in we have been placed to sleep, and return last error */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . state = = RFAL_NFC_STATE_LISTEN_SLEEP ) {
return gNfcDev . dataExErr ; /* ERR_SLEEP_REQ */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
/*******************************************************************************/
2021-10-17 22:54:19 +00:00
/* Check if Data exchange has been started */
2022-01-05 16:10:18 +00:00
if ( ( gNfcDev . state ! = RFAL_NFC_STATE_DATAEXCHANGE ) & &
( gNfcDev . state ! = RFAL_NFC_STATE_DATAEXCHANGE_DONE ) ) {
2021-10-17 22:54:19 +00:00
return ERR_WRONG_STATE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Check if Data exchange is still ongoing */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . dataExErr = = ERR_BUSY ) {
switch ( gNfcDev . activeDev - > rfInterface ) {
/*******************************************************************************/
case RFAL_NFC_INTERFACE_RF :
gNfcDev . dataExErr = rfalGetTransceiveStatus ( ) ;
break ;
# if RFAL_FEATURE_ISO_DEP
/*******************************************************************************/
case RFAL_NFC_INTERFACE_ISODEP :
gNfcDev . dataExErr = rfalIsoDepGetApduTransceiveStatus ( ) ;
break ;
# endif /* RFAL_FEATURE_ISO_DEP */
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_NFC_DEP
case RFAL_NFC_INTERFACE_NFCDEP :
gNfcDev . dataExErr = rfalNfcDepGetPduTransceiveStatus ( ) ;
break ;
# endif /* RFAL_FEATURE_NFC_DEP */
/*******************************************************************************/
default :
gNfcDev . dataExErr = ERR_PARAM ;
break ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_LISTEN_MODE
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* If a Sleep request has been received (Listen Mode) go to sleep immediately */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . dataExErr = = ERR_SLEEP_REQ ) {
EXIT_ON_ERR (
gNfcDev . dataExErr ,
rfalListenSleepStart (
RFAL_LM_STATE_SLEEP_A ,
gNfcDev . rxBuf . rfBuf ,
sizeof ( gNfcDev . rxBuf . rfBuf ) ,
& gNfcDev . rxLen ) ) ;
2021-10-17 22:54:19 +00:00
/* If set Sleep was succesfull keep restore the Sleep request signal */
gNfcDev . dataExErr = ERR_SLEEP_REQ ;
}
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_LISTEN_MODE */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return gNfcDev . dataExErr ;
}
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ brief Poller Technology Detection
*
* This method implements the Technology Detection / Poll for different
* device technologies .
*
* \ return ERR_NONE : Operation completed with no error
* \ return ERR_BUSY : Operation ongoing
* \ return ERR_XXXX : Error occurred
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2022-01-05 16:10:18 +00:00
static ReturnCode rfalNfcPollTechDetetection ( void ) {
ReturnCode err ;
2021-10-17 22:54:19 +00:00
err = ERR_NONE ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Supress warning when specific RFAL features have been disabled */
2022-01-05 16:10:18 +00:00
NO_WARNING ( err ) ;
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* AP2P Technology Detection */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_POLL_TECH_AP2P ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_AP2P ) ! = 0U ) ) {
# if RFAL_FEATURE_NFC_DEP
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR (
err ,
rfalSetMode ( RFAL_MODE_POLL_ACTIVE_P2P , gNfcDev . disc . ap2pBR , gNfcDev . disc . ap2pBR ) ) ;
rfalSetErrorHandling ( RFAL_ERRORHANDLING_NFC ) ;
rfalSetFDTListen ( RFAL_FDT_LISTEN_AP2P_POLLER ) ;
rfalSetFDTPoll ( RFAL_TIMING_NONE ) ;
rfalSetGT ( RFAL_GT_AP2P_ADJUSTED ) ;
EXIT_ON_ERR ( err , rfalFieldOnAndStartGT ( ) ) ; /* Turns the Field On and starts GT timer */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( rfalIsGTExpired ( ) ) /* Wait until Guard Time is fulfilled */
2021-10-17 22:54:19 +00:00
{
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_AP2P ;
2022-01-05 16:10:18 +00:00
err = rfalNfcNfcDepActivate (
gNfcDev . devList , RFAL_NFCDEP_COMM_ACTIVE , NULL , 0 ) ; /* Poll for NFC-A devices */
if ( err = = ERR_NONE ) {
2021-10-17 22:54:19 +00:00
gNfcDev . techsFound | = RFAL_NFC_POLL_TECH_AP2P ;
2022-01-05 16:10:18 +00:00
gNfcDev . devList - > type = RFAL_NFC_LISTEN_TYPE_AP2P ;
2021-10-17 22:54:19 +00:00
gNfcDev . devList - > rfInterface = RFAL_NFC_INTERFACE_NFCDEP ;
gNfcDev . devCnt + + ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_NONE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
rfalFieldOff ( ) ;
}
return ERR_BUSY ;
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_NFC_DEP */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive NFC-A Technology Detection */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_POLL_TECH_A ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_A ) ! = 0U ) ) {
# if RFAL_FEATURE_NFCA
rfalNfcaSensRes sensRes ;
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR ( err , rfalNfcaPollerInitialize ( ) ) ; /* Initialize RFAL for NFC-A */
EXIT_ON_ERR ( err , rfalFieldOnAndStartGT ( ) ) ; /* Turns the Field On and starts GT timer */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( rfalIsGTExpired ( ) ) /* Wait until Guard Time is fulfilled */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
err = rfalNfcaPollerTechnologyDetection (
gNfcDev . disc . compMode , & sensRes ) ; /* Poll for NFC-A devices */
if ( err = = ERR_NONE ) {
2021-10-17 22:54:19 +00:00
gNfcDev . techsFound | = RFAL_NFC_POLL_TECH_A ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_A ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_NFCA */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive NFC-B Technology Detection */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_POLL_TECH_B ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_B ) ! = 0U ) ) {
# if RFAL_FEATURE_NFCB
2021-10-17 22:54:19 +00:00
rfalNfcbSensbRes sensbRes ;
2022-01-05 16:10:18 +00:00
uint8_t sensbResLen ;
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR ( err , rfalNfcbPollerInitialize ( ) ) ; /* Initialize RFAL for NFC-B */
EXIT_ON_ERR (
err , rfalFieldOnAndStartGT ( ) ) ; /* As field is already On only starts GT timer */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( rfalIsGTExpired ( ) ) /* Wait until Guard Time is fulfilled */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
err = rfalNfcbPollerTechnologyDetection (
gNfcDev . disc . compMode , & sensbRes , & sensbResLen ) ; /* Poll for NFC-B devices */
if ( err = = ERR_NONE ) {
2021-10-17 22:54:19 +00:00
gNfcDev . techsFound | = RFAL_NFC_POLL_TECH_B ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_B ;
}
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_NFCB */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive NFC-F Technology Detection */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_POLL_TECH_F ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_F ) ! = 0U ) ) {
# if RFAL_FEATURE_NFCF
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR (
err ,
rfalNfcfPollerInitialize ( gNfcDev . disc . nfcfBR ) ) ; /* Initialize RFAL for NFC-F */
EXIT_ON_ERR (
err , rfalFieldOnAndStartGT ( ) ) ; /* As field is already On only starts GT timer */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( rfalIsGTExpired ( ) ) /* Wait until Guard Time is fulfilled */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
err = rfalNfcfPollerCheckPresence ( ) ; /* Poll for NFC-F devices */
if ( err = = ERR_NONE ) {
2021-10-17 22:54:19 +00:00
gNfcDev . techsFound | = RFAL_NFC_POLL_TECH_F ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_F ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_NFCF */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive NFC-V Technology Detection */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_POLL_TECH_V ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_V ) ! = 0U ) ) {
# if RFAL_FEATURE_NFCV
2021-10-17 22:54:19 +00:00
rfalNfcvInventoryRes invRes ;
2022-01-05 16:10:18 +00:00
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR ( err , rfalNfcvPollerInitialize ( ) ) ; /* Initialize RFAL for NFC-V */
EXIT_ON_ERR (
err , rfalFieldOnAndStartGT ( ) ) ; /* As field is already On only starts GT timer */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( rfalIsGTExpired ( ) ) /* Wait until Guard Time is fulfilled */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
err = rfalNfcvPollerCheckPresence ( & invRes ) ; /* Poll for NFC-V devices */
if ( err = = ERR_NONE ) {
2021-10-17 22:54:19 +00:00
gNfcDev . techsFound | = RFAL_NFC_POLL_TECH_V ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_V ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_NFCV */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive Proprietary Technology ST25TB */
2022-01-05 16:10:18 +00:00
/*******************************************************************************/
if ( ( ( gNfcDev . disc . techs2Find & RFAL_NFC_POLL_TECH_ST25TB ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_ST25TB ) ! = 0U ) ) {
# if RFAL_FEATURE_ST25TB
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR ( err , rfalSt25tbPollerInitialize ( ) ) ; /* Initialize RFAL for NFC-V */
EXIT_ON_ERR (
err , rfalFieldOnAndStartGT ( ) ) ; /* As field is already On only starts GT timer */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( rfalIsGTExpired ( ) ) /* Wait until Guard Time is fulfilled */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
err = rfalSt25tbPollerCheckPresence ( NULL ) ; /* Poll for ST25TB devices */
if ( err = = ERR_NONE ) {
2021-10-17 22:54:19 +00:00
gNfcDev . techsFound | = RFAL_NFC_POLL_TECH_ST25TB ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_ST25TB ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_ST25TB */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_NONE ;
}
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ brief Poller Collision Resolution
*
* This method implements the Collision Resolution on all technologies that
* have been detected before .
*
* \ return ERR_NONE : Operation completed with no error
* \ return ERR_BUSY : Operation ongoing
* \ return ERR_XXXX : Error occurred
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2022-01-05 16:10:18 +00:00
static ReturnCode rfalNfcPollCollResolution ( void ) {
uint8_t i ;
static uint8_t devCnt ;
2021-10-17 22:54:19 +00:00
ReturnCode err ;
2022-01-05 16:10:18 +00:00
err = ERR_NONE ;
i = 0 ;
2021-10-17 22:54:19 +00:00
/* Supress warning when specific RFAL features have been disabled */
NO_WARNING ( err ) ;
NO_WARNING ( devCnt ) ;
NO_WARNING ( i ) ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Check if device limit has been reached */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . devCnt > = gNfcDev . disc . devLimit ) {
2021-10-17 22:54:19 +00:00
return ERR_NONE ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* NFC-A Collision Resolution */
/*******************************************************************************/
# if RFAL_FEATURE_NFCA
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . techsFound & RFAL_NFC_POLL_TECH_A ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_A ) ! =
0U ) ) /* If a NFC-A device was found/detected, perform Collision Resolution */
2021-10-17 22:54:19 +00:00
{
static rfalNfcaListenDevice nfcaDevList [ RFAL_NFC_MAX_DEVICES ] ;
2022-01-05 16:10:18 +00:00
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR ( err , rfalNfcaPollerInitialize ( ) ) ; /* Initialize RFAL for NFC-A */
EXIT_ON_ERR ( err , rfalFieldOnAndStartGT ( ) ) ; /* Turns the Field On and starts GT timer */
gNfcDev . isTechInit = true ; /* Technology has been initialized */
gNfcDev . isOperOngoing = false ; /* No operation currently ongoing */
}
if ( ! rfalIsGTExpired ( ) ) {
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
2022-01-05 16:10:18 +00:00
if ( ! gNfcDev . isOperOngoing ) {
EXIT_ON_ERR (
err ,
rfalNfcaPollerStartFullCollisionResolution (
gNfcDev . disc . compMode ,
( gNfcDev . disc . devLimit - gNfcDev . devCnt ) ,
nfcaDevList ,
& devCnt ) ) ;
2021-10-17 22:54:19 +00:00
gNfcDev . isOperOngoing = true ;
return ERR_BUSY ;
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
err = rfalNfcaPollerGetFullCollisionResolutionStatus ( ) ;
2022-01-05 16:10:18 +00:00
if ( err ! = ERR_BUSY ) {
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_A ;
if ( ( err = = ERR_NONE ) & & ( devCnt ! = 0U ) ) {
for ( i = 0 ; i < devCnt ;
i + + ) /* Copy devices found form local Nfca list into global device list */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . type = RFAL_NFC_LISTEN_TYPE_NFCA ;
2021-10-17 22:54:19 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . dev . nfca = nfcaDevList [ i ] ;
gNfcDev . devCnt + + ;
}
}
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
# endif /* RFAL_FEATURE_NFCA */
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* NFC-B Collision Resolution */
/*******************************************************************************/
# if RFAL_FEATURE_NFCB
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . techsFound & RFAL_NFC_POLL_TECH_B ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_B ) ! =
0U ) ) /* If a NFC-B device was found/detected, perform Collision Resolution */
2021-10-17 22:54:19 +00:00
{
rfalNfcbListenDevice nfcbDevList [ RFAL_NFC_MAX_DEVICES ] ;
2022-01-05 16:10:18 +00:00
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR ( err , rfalNfcbPollerInitialize ( ) ) ; /* Initialize RFAL for NFC-B */
EXIT_ON_ERR (
err ,
rfalFieldOnAndStartGT ( ) ) ; /* Ensure GT again as other technologies have also been polled */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( ! rfalIsGTExpired ( ) ) {
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
2022-01-05 16:10:18 +00:00
devCnt = 0 ;
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_B ;
err = rfalNfcbPollerCollisionResolution (
gNfcDev . disc . compMode , ( gNfcDev . disc . devLimit - gNfcDev . devCnt ) , nfcbDevList , & devCnt ) ;
if ( ( err = = ERR_NONE ) & & ( devCnt ! = 0U ) ) {
for ( i = 0 ; i < devCnt ;
i + + ) /* Copy devices found form local Nfcb list into global device list */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . type = RFAL_NFC_LISTEN_TYPE_NFCB ;
2021-10-17 22:54:19 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . dev . nfcb = nfcbDevList [ i ] ;
gNfcDev . devCnt + + ;
}
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
# endif /* RFAL_FEATURE_NFCB*/
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* NFC-F Collision Resolution */
/*******************************************************************************/
# if RFAL_FEATURE_NFCF
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . techsFound & RFAL_NFC_POLL_TECH_F ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_F ) ! =
0U ) ) /* If a NFC-F device was found/detected, perform Collision Resolution */
2021-10-17 22:54:19 +00:00
{
rfalNfcfListenDevice nfcfDevList [ RFAL_NFC_MAX_DEVICES ] ;
2022-01-05 16:10:18 +00:00
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR (
err ,
rfalNfcfPollerInitialize ( gNfcDev . disc . nfcfBR ) ) ; /* Initialize RFAL for NFC-F */
EXIT_ON_ERR (
err ,
rfalFieldOnAndStartGT ( ) ) ; /* Ensure GT again as other technologies have also been polled */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( ! rfalIsGTExpired ( ) ) {
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
2022-01-05 16:10:18 +00:00
devCnt = 0 ;
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_F ;
err = rfalNfcfPollerCollisionResolution (
gNfcDev . disc . compMode , ( gNfcDev . disc . devLimit - gNfcDev . devCnt ) , nfcfDevList , & devCnt ) ;
if ( ( err = = ERR_NONE ) & & ( devCnt ! = 0U ) ) {
for ( i = 0 ; i < devCnt ;
i + + ) /* Copy devices found form local Nfcf list into global device list */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . type = RFAL_NFC_LISTEN_TYPE_NFCF ;
2021-10-17 22:54:19 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . dev . nfcf = nfcfDevList [ i ] ;
gNfcDev . devCnt + + ;
}
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
# endif /* RFAL_FEATURE_NFCF */
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* NFC-V Collision Resolution */
/*******************************************************************************/
# if RFAL_FEATURE_NFCV
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . techsFound & RFAL_NFC_POLL_TECH_V ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_V ) ! =
0U ) ) /* If a NFC-V device was found/detected, perform Collision Resolution */
2021-10-17 22:54:19 +00:00
{
rfalNfcvListenDevice nfcvDevList [ RFAL_NFC_MAX_DEVICES ] ;
2022-01-05 16:10:18 +00:00
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR ( err , rfalNfcvPollerInitialize ( ) ) ; /* Initialize RFAL for NFC-V */
EXIT_ON_ERR (
err ,
rfalFieldOnAndStartGT ( ) ) ; /* Ensure GT again as other technologies have also been polled */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( ! rfalIsGTExpired ( ) ) {
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
2022-01-05 16:10:18 +00:00
devCnt = 0 ;
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_V ;
err = rfalNfcvPollerCollisionResolution (
RFAL_COMPLIANCE_MODE_NFC ,
( gNfcDev . disc . devLimit - gNfcDev . devCnt ) ,
nfcvDevList ,
& devCnt ) ;
if ( ( err = = ERR_NONE ) & & ( devCnt ! = 0U ) ) {
for ( i = 0 ; i < devCnt ;
i + + ) /* Copy devices found form local Nfcf list into global device list */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . type = RFAL_NFC_LISTEN_TYPE_NFCV ;
2021-10-17 22:54:19 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . dev . nfcv = nfcvDevList [ i ] ;
gNfcDev . devCnt + + ;
}
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
# endif /* RFAL_FEATURE_NFCV */
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* ST25TB Collision Resolution */
/*******************************************************************************/
# if RFAL_FEATURE_ST25TB
2022-01-05 16:10:18 +00:00
if ( ( ( gNfcDev . techsFound & RFAL_NFC_POLL_TECH_ST25TB ) ! = 0U ) & &
( ( gNfcDev . techs2do & RFAL_NFC_POLL_TECH_ST25TB ) ! =
0U ) ) /* If a ST25TB device was found/detected, perform Collision Resolution */
2021-10-17 22:54:19 +00:00
{
rfalSt25tbListenDevice st25tbDevList [ RFAL_NFC_MAX_DEVICES ] ;
2022-01-05 16:10:18 +00:00
if ( ! gNfcDev . isTechInit ) {
EXIT_ON_ERR ( err , rfalSt25tbPollerInitialize ( ) ) ; /* Initialize RFAL for ST25TB */
EXIT_ON_ERR (
err ,
rfalFieldOnAndStartGT ( ) ) ; /* Ensure GT again as other technologies have also been polled */
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = true ;
}
2022-01-05 16:10:18 +00:00
if ( ! rfalIsGTExpired ( ) ) {
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
2022-01-05 16:10:18 +00:00
devCnt = 0 ;
2021-10-17 22:54:19 +00:00
gNfcDev . isTechInit = false ;
2022-01-05 16:10:18 +00:00
gNfcDev . techs2do & = ~ RFAL_NFC_POLL_TECH_ST25TB ;
err = rfalSt25tbPollerCollisionResolution (
( gNfcDev . disc . devLimit - gNfcDev . devCnt ) , st25tbDevList , & devCnt ) ;
if ( ( err = = ERR_NONE ) & & ( devCnt ! = 0U ) ) {
for ( i = 0 ; i < devCnt ;
i + + ) /* Copy devices found form local Nfcf list into global device list */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . type = RFAL_NFC_LISTEN_TYPE_ST25TB ;
2021-10-17 22:54:19 +00:00
gNfcDev . devList [ gNfcDev . devCnt ] . dev . st25tb = st25tbDevList [ i ] ;
gNfcDev . devCnt + + ;
}
}
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
# endif /* RFAL_FEATURE_ST25TB */
2022-01-05 16:10:18 +00:00
return ERR_NONE ; /* All technologies have been performed */
}
2021-10-17 22:54:19 +00:00
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ brief Poller Activation
*
* This method Activates a given device according to it ' s type and
* protocols supported
*
* \ param [ in ] devIt : device ' s position on the list to be activated
*
* \ return ERR_NONE : Operation completed with no error
* \ return ERR_BUSY : Operation ongoing
* \ return ERR_XXXX : Error occurred
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2022-01-05 16:10:18 +00:00
static ReturnCode rfalNfcPollActivation ( uint8_t devIt ) {
2021-10-17 22:54:19 +00:00
ReturnCode err ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
err = ERR_NONE ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* Supress warning when specific RFAL features have been disabled */
NO_WARNING ( err ) ;
2022-01-05 16:10:18 +00:00
if ( devIt > gNfcDev . devCnt ) {
2021-10-17 22:54:19 +00:00
return ERR_WRONG_STATE ;
}
2022-01-05 16:10:18 +00:00
switch ( gNfcDev . devList [ devIt ] . type ) {
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* AP2P Activation */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_NFC_DEP
case RFAL_NFC_LISTEN_TYPE_AP2P :
/* Activation has already been perfomed (ATR_REQ) */
gNfcDev . devList [ devIt ] . nfcid =
gNfcDev . devList [ devIt ] . proto . nfcDep . activation . Target . ATR_RES . NFCID3 ;
gNfcDev . devList [ devIt ] . nfcidLen = RFAL_NFCDEP_NFCID3_LEN ;
break ;
# endif /* RFAL_FEATURE_NFC_DEP */
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive NFC-A Activation */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_NFCA
case RFAL_NFC_LISTEN_TYPE_NFCA :
if ( ! gNfcDev . isTechInit ) {
rfalNfcaPollerInitialize ( ) ;
gNfcDev . isTechInit = true ;
gNfcDev . isOperOngoing = false ;
return ERR_BUSY ;
}
if ( gNfcDev . devList [ devIt ] . dev . nfca . isSleep ) /* Check if desired device is in Sleep */
{
rfalNfcaSensRes sensRes ;
rfalNfcaSelRes selRes ;
if ( ! gNfcDev . isOperOngoing ) {
/* Wake up all cards */
EXIT_ON_ERR (
err , rfalNfcaPollerCheckPresence ( RFAL_14443A_SHORTFRAME_CMD_WUPA , & sensRes ) ) ;
gNfcDev . isOperOngoing = true ;
} else {
/* Select specific device */
EXIT_ON_ERR (
err ,
rfalNfcaPollerSelect (
gNfcDev . devList [ devIt ] . dev . nfca . nfcId1 ,
gNfcDev . devList [ devIt ] . dev . nfca . nfcId1Len ,
& selRes ) ) ;
gNfcDev . devList [ devIt ] . dev . nfca . isSleep = false ;
2021-10-17 22:54:19 +00:00
gNfcDev . isOperOngoing = false ;
}
2022-01-05 16:10:18 +00:00
return ERR_BUSY ;
}
/* Set NFCID */
gNfcDev . devList [ devIt ] . nfcid = gNfcDev . devList [ devIt ] . dev . nfca . nfcId1 ;
gNfcDev . devList [ devIt ] . nfcidLen = gNfcDev . devList [ devIt ] . dev . nfca . nfcId1Len ;
/*******************************************************************************/
/* Perform protocol specific activation */
switch ( gNfcDev . devList [ devIt ] . dev . nfca . type ) {
/*******************************************************************************/
case RFAL_NFCA_T1T :
/* No further activation needed for T1T (RID already performed) */
gNfcDev . devList [ devIt ] . nfcid = gNfcDev . devList [ devIt ] . dev . nfca . ridRes . uid ;
gNfcDev . devList [ devIt ] . nfcidLen = RFAL_T1T_UID_LEN ;
gNfcDev . devList [ devIt ] . rfInterface = RFAL_NFC_INTERFACE_RF ;
break ;
case RFAL_NFCA_T2T :
/* No further activation needed for a T2T */
gNfcDev . devList [ devIt ] . rfInterface = RFAL_NFC_INTERFACE_RF ;
break ;
/*******************************************************************************/
case RFAL_NFCA_T4T : /* Device supports ISO-DEP */
# if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_POLL
if ( ! gNfcDev . isOperOngoing ) {
/* Perform ISO-DEP (ISO14443-4) activation: RATS and PPS if supported */
rfalIsoDepInitialize ( ) ;
EXIT_ON_ERR (
err ,
rfalIsoDepPollAStartActivation (
( rfalIsoDepFSxI ) RFAL_ISODEP_FSDI_DEFAULT ,
RFAL_ISODEP_NO_DID ,
gNfcDev . disc . maxBR ,
& gNfcDev . devList [ devIt ] . proto . isoDep ) ) ;
gNfcDev . isOperOngoing = true ;
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
2022-01-05 16:10:18 +00:00
err = rfalIsoDepPollAGetActivationStatus ( ) ;
if ( err ! = ERR_NONE ) {
return err ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
gNfcDev . devList [ devIt ] . rfInterface =
RFAL_NFC_INTERFACE_ISODEP ; /* NFC-A T4T device activated */
# else
gNfcDev . devList [ devIt ] . rfInterface =
RFAL_NFC_INTERFACE_RF ; /* No ISO-DEP supported activate using RF interface */
# endif /* RFAL_FEATURE_ISO_DEP_POLL */
2021-10-17 22:54:19 +00:00
break ;
2022-01-05 16:10:18 +00:00
/*******************************************************************************/
case RFAL_NFCA_T4T_NFCDEP : /* Device supports both T4T and NFC-DEP */
case RFAL_NFCA_NFCDEP : /* Device supports NFC-DEP */
# if RFAL_FEATURE_NFC_DEP
/* Perform NFC-DEP (P2P) activation: ATR and PSL if supported */
EXIT_ON_ERR (
err ,
rfalNfcNfcDepActivate ( & gNfcDev . devList [ devIt ] , RFAL_NFCDEP_COMM_PASSIVE , NULL , 0 ) ) ;
gNfcDev . devList [ devIt ] . nfcid =
gNfcDev . devList [ devIt ] . proto . nfcDep . activation . Target . ATR_RES . NFCID3 ;
gNfcDev . devList [ devIt ] . nfcidLen = RFAL_NFCDEP_NFCID3_LEN ;
gNfcDev . devList [ devIt ] . rfInterface =
RFAL_NFC_INTERFACE_NFCDEP ; /* NFC-A P2P device activated */
# else
gNfcDev . devList [ devIt ] . rfInterface =
RFAL_NFC_INTERFACE_RF ; /* No NFC-DEP supported activate using RF interface */
# endif /* RFAL_FEATURE_NFC_DEP */
break ;
/*******************************************************************************/
default :
return ERR_WRONG_STATE ;
}
break ;
# endif /* RFAL_FEATURE_NFCA */
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive NFC-B Activation */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_NFCB
case RFAL_NFC_LISTEN_TYPE_NFCB :
if ( ! gNfcDev . isTechInit ) {
rfalNfcbPollerInitialize ( ) ;
gNfcDev . isTechInit = true ;
gNfcDev . isOperOngoing = false ;
return ERR_BUSY ;
}
if ( gNfcDev . devList [ devIt ] . dev . nfcb . isSleep ) /* Check if desired device is in Sleep */
{
rfalNfcbSensbRes sensbRes ;
uint8_t sensbResLen ;
/* Wake up all cards. SENSB_RES may return collision but the NFCID0 is available to explicitly select NFC-B card via ATTRIB; so error will be ignored here */
rfalNfcbPollerCheckPresence (
RFAL_NFCB_SENS_CMD_ALLB_REQ , RFAL_NFCB_SLOT_NUM_1 , & sensbRes , & sensbResLen ) ;
}
/* Set NFCID */
gNfcDev . devList [ devIt ] . nfcid = gNfcDev . devList [ devIt ] . dev . nfcb . sensbRes . nfcid0 ;
gNfcDev . devList [ devIt ] . nfcidLen = RFAL_NFCB_NFCID0_LEN ;
# if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_POLL
/* Check if device supports ISO-DEP (ISO14443-4) */
if ( ( gNfcDev . devList [ devIt ] . dev . nfcb . sensbRes . protInfo . FsciProType &
RFAL_NFCB_SENSB_RES_PROTO_ISO_MASK ) ! = 0U ) {
if ( ! gNfcDev . isOperOngoing ) {
rfalIsoDepInitialize ( ) ;
/* Perform ISO-DEP (ISO14443-4) activation: ATTRIB */
EXIT_ON_ERR (
err ,
rfalIsoDepPollBStartActivation (
( rfalIsoDepFSxI ) RFAL_ISODEP_FSDI_DEFAULT ,
RFAL_ISODEP_NO_DID ,
gNfcDev . disc . maxBR ,
0x00 ,
& gNfcDev . devList [ devIt ] . dev . nfcb ,
NULL ,
0 ,
& gNfcDev . devList [ devIt ] . proto . isoDep ) ) ;
gNfcDev . isOperOngoing = true ;
2021-10-17 22:54:19 +00:00
return ERR_BUSY ;
}
2022-01-05 16:10:18 +00:00
err = rfalIsoDepPollBGetActivationStatus ( ) ;
if ( err ! = ERR_NONE ) {
return err ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
gNfcDev . devList [ devIt ] . rfInterface =
RFAL_NFC_INTERFACE_ISODEP ; /* NFC-B T4T device activated */
2021-10-17 22:54:19 +00:00
break ;
2022-01-05 16:10:18 +00:00
}
# endif /* RFAL_FEATURE_ISO_DEP_POLL */
gNfcDev . devList [ devIt ] . rfInterface =
RFAL_NFC_INTERFACE_RF ; /* NFC-B device activated */
break ;
# endif /* RFAL_FEATURE_NFCB */
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive NFC-F Activation */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_NFCF
case RFAL_NFC_LISTEN_TYPE_NFCF :
rfalNfcfPollerInitialize ( gNfcDev . disc . nfcfBR ) ;
# if RFAL_FEATURE_NFC_DEP
if ( rfalNfcfIsNfcDepSupported ( & gNfcDev . devList [ devIt ] . dev . nfcf ) ) {
/* Perform NFC-DEP (P2P) activation: ATR and PSL if supported */
EXIT_ON_ERR (
err ,
rfalNfcNfcDepActivate ( & gNfcDev . devList [ devIt ] , RFAL_NFCDEP_COMM_PASSIVE , NULL , 0 ) ) ;
2021-10-17 22:54:19 +00:00
/* Set NFCID */
2022-01-05 16:10:18 +00:00
gNfcDev . devList [ devIt ] . nfcid =
gNfcDev . devList [ devIt ] . proto . nfcDep . activation . Target . ATR_RES . NFCID3 ;
gNfcDev . devList [ devIt ] . nfcidLen = RFAL_NFCDEP_NFCID3_LEN ;
gNfcDev . devList [ devIt ] . rfInterface =
RFAL_NFC_INTERFACE_NFCDEP ; /* NFC-F P2P device activated */
2021-10-17 22:54:19 +00:00
break ;
2022-01-05 16:10:18 +00:00
}
# endif /* RFAL_FEATURE_NFC_DEP */
/* Set NFCID */
gNfcDev . devList [ devIt ] . nfcid = gNfcDev . devList [ devIt ] . dev . nfcf . sensfRes . NFCID2 ;
gNfcDev . devList [ devIt ] . nfcidLen = RFAL_NFCF_NFCID2_LEN ;
gNfcDev . devList [ devIt ] . rfInterface =
RFAL_NFC_INTERFACE_RF ; /* NFC-F T3T device activated */
break ;
# endif /* RFAL_FEATURE_NFCF */
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive NFC-V Activation */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_NFCV
case RFAL_NFC_LISTEN_TYPE_NFCV :
rfalNfcvPollerInitialize ( ) ;
/* No specific activation needed for a T5T */
/* Set NFCID */
gNfcDev . devList [ devIt ] . nfcid = gNfcDev . devList [ devIt ] . dev . nfcv . InvRes . UID ;
gNfcDev . devList [ devIt ] . nfcidLen = RFAL_NFCV_UID_LEN ;
gNfcDev . devList [ devIt ] . rfInterface =
RFAL_NFC_INTERFACE_RF ; /* NFC-V T5T device activated */
break ;
# endif /* RFAL_FEATURE_NFCV */
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* Passive ST25TB Activation */
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_ST25TB
case RFAL_NFC_LISTEN_TYPE_ST25TB :
rfalSt25tbPollerInitialize ( ) ;
/* No specific activation needed for a ST25TB */
/* Set NFCID */
gNfcDev . devList [ devIt ] . nfcid = gNfcDev . devList [ devIt ] . dev . st25tb . UID ;
gNfcDev . devList [ devIt ] . nfcidLen = RFAL_ST25TB_UID_LEN ;
gNfcDev . devList [ devIt ] . rfInterface = RFAL_NFC_INTERFACE_RF ; /* ST25TB device activated */
break ;
# endif /* RFAL_FEATURE_ST25TB */
/*******************************************************************************/
default :
return ERR_WRONG_STATE ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
gNfcDev . activeDev = & gNfcDev . devList [ devIt ] ; /* Assign active device to be used further on */
2021-10-17 22:54:19 +00:00
return ERR_NONE ;
}
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ brief Listener Activation
*
* This method handles the listen mode Activation according to the different
* protocols the Reader / Initiator performs
*
* \ return ERR_NONE : Operation completed with no error
* \ return ERR_BUSY : Operation ongoing
* \ return ERR_PROTO : Unexpected frame received
* \ return ERR_XXXX : Error occurred
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
# if RFAL_FEATURE_LISTEN_MODE
2022-01-05 16:10:18 +00:00
static ReturnCode rfalNfcListenActivation ( void ) {
bool isDataRcvd ;
ReturnCode ret ;
rfalLmState lmSt ;
rfalBitRate bitRate ;
# if RFAL_FEATURE_NFC_DEP
uint8_t hdrLen ;
2021-10-17 22:54:19 +00:00
/* Set the header length in NFC-A */
hdrLen = ( RFAL_NFCDEP_SB_LEN + RFAL_NFCDEP_LEN_LEN ) ;
# endif /* RFAL_FEATURE_NFC_DEP */
2022-01-05 16:10:18 +00:00
lmSt = rfalListenGetState ( & isDataRcvd , & bitRate ) ;
2021-10-17 22:54:19 +00:00
2022-01-05 16:10:18 +00:00
switch ( lmSt ) {
# if RFAL_FEATURE_NFCA
/*******************************************************************************/
case RFAL_LM_STATE_ACTIVE_A : /* NFC-A CE activation */
case RFAL_LM_STATE_ACTIVE_Ax :
2021-10-17 22:54:19 +00:00
2022-01-05 16:10:18 +00:00
if ( isDataRcvd ) /* Check if Reader/Initator has sent some data */
{
/* Check if received data is a Sleep request */
if ( rfalNfcaListenerIsSleepReq (
gNfcDev . rxBuf . rfBuf ,
rfalConvBitsToBytes ( gNfcDev . rxLen ) ) ) /* Check if received data is a SLP_REQ */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
/* Set the Listen Mode in Sleep state */
EXIT_ON_ERR (
ret ,
rfalListenSleepStart (
RFAL_LM_STATE_SLEEP_A ,
gNfcDev . rxBuf . rfBuf ,
sizeof ( gNfcDev . rxBuf . rfBuf ) ,
& gNfcDev . rxLen ) ) ;
}
2021-10-17 22:54:19 +00:00
2022-01-05 16:10:18 +00:00
else if ( gNfcDev . disc . activate_after_sak ) {
gNfcDev . devList - > type = RFAL_NFC_POLL_TYPE_NFCA ;
rfalListenSetState ( RFAL_LM_STATE_ACTIVE_A ) ;
return ERR_NONE ;
}
# if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_LISTEN
/* Check if received data is a valid RATS */
else if ( rfalIsoDepIsRats (
gNfcDev . rxBuf . rfBuf , ( uint8_t ) rfalConvBitsToBytes ( gNfcDev . rxLen ) ) ) {
rfalIsoDepAtsParam atsParam ;
rfalIsoDepListenActvParam rxParam ;
2021-10-17 22:54:19 +00:00
2022-01-05 16:10:18 +00:00
/* Set ATS parameters */
atsParam . fsci = ( uint8_t ) RFAL_ISODEP_DEFAULT_FSCI ;
atsParam . fwi = RFAL_ISODEP_DEFAULT_FWI ;
atsParam . sfgi = RFAL_ISODEP_DEFAULT_SFGI ;
atsParam . didSupport = false ;
atsParam . ta = RFAL_ISODEP_ATS_TA_SAME_D ;
atsParam . hb = NULL ;
atsParam . hbLen = 0 ;
/* Set Rx parameters */
rxParam . rxBuf =
( rfalIsoDepBufFormat * ) & gNfcDev . rxBuf
. isoDepBuf ; /* PRQA S 0310 # MISRA 11.3 - Intentional safe cast to avoiding large buffer duplication */
rxParam . rxLen = & gNfcDev . rxLen ;
rxParam . isoDepDev = & gNfcDev . devList - > proto . isoDep ;
rxParam . isRxChaining = & gNfcDev . isRxChaining ;
rfalListenSetState ( RFAL_LM_STATE_CARDEMU_4A ) ; /* Set next state CE T4T */
rfalIsoDepInitialize ( ) ; /* Initialize ISO-DEP layer to handle ISO14443-a activation / RATS */
/* Set ISO-DEP layer to digest RATS and handle activation */
EXIT_ON_ERR (
ret ,
rfalIsoDepListenStartActivation (
& atsParam , NULL , gNfcDev . rxBuf . rfBuf , gNfcDev . rxLen , rxParam ) ) ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_ISO_DEP_LISTEN */
2021-10-17 22:54:19 +00:00
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_NFC_DEP
/* Check if received data is a valid ATR_REQ */
else if ( rfalNfcDepIsAtrReq (
& gNfcDev . rxBuf . rfBuf [ hdrLen ] ,
( rfalConvBitsToBytes ( gNfcDev . rxLen ) - hdrLen ) ,
gNfcDev . devList - > nfcid ) ) {
gNfcDev . devList - > type = RFAL_NFC_POLL_TYPE_NFCA ;
EXIT_ON_ERR (
ret ,
rfalNfcNfcDepActivate (
gNfcDev . devList ,
RFAL_NFCDEP_COMM_PASSIVE ,
& gNfcDev . rxBuf . rfBuf [ hdrLen ] ,
( rfalConvBitsToBytes ( gNfcDev . rxLen ) - hdrLen ) ) ) ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_NFC_DEP */
else {
return ERR_PROTO ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
}
return ERR_BUSY ;
# endif /* RFAL_FEATURE_NFCA */
# if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_LISTEN
/*******************************************************************************/
case RFAL_LM_STATE_CARDEMU_4A : /* T4T ISO-DEP activation */
ret = rfalIsoDepListenGetActivationStatus ( ) ;
if ( ret = = ERR_NONE ) {
gNfcDev . devList - > type = RFAL_NFC_POLL_TYPE_NFCA ;
gNfcDev . devList - > rfInterface = RFAL_NFC_INTERFACE_ISODEP ;
gNfcDev . devList - > nfcid = NULL ;
gNfcDev . devList - > nfcidLen = 0 ;
}
return ret ;
# endif /* RFAL_FEATURE_ISO_DEP_LISTEN */
/*******************************************************************************/
case RFAL_LM_STATE_READY_F : /* NFC-F CE activation */
if ( isDataRcvd ) /* Wait for the first received data */
{
# if RFAL_FEATURE_NFC_DEP
/* Set the header length in NFC-F */
hdrLen = RFAL_NFCDEP_LEN_LEN ;
if ( rfalNfcDepIsAtrReq (
& gNfcDev . rxBuf . rfBuf [ hdrLen ] ,
( rfalConvBitsToBytes ( gNfcDev . rxLen ) - hdrLen ) ,
gNfcDev . devList - > nfcid ) ) {
gNfcDev . devList - > type = RFAL_NFC_POLL_TYPE_NFCF ;
EXIT_ON_ERR (
ret ,
rfalNfcNfcDepActivate (
gNfcDev . devList ,
RFAL_NFCDEP_COMM_PASSIVE ,
& gNfcDev . rxBuf . rfBuf [ hdrLen ] ,
( rfalConvBitsToBytes ( gNfcDev . rxLen ) - hdrLen ) ) ) ;
} else
# endif /* RFAL_FEATURE_NFC_DEP */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
rfalListenSetState (
RFAL_LM_STATE_CARDEMU_3 ) ; /* First data already received - set T3T CE */
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
}
return ERR_BUSY ;
/*******************************************************************************/
case RFAL_LM_STATE_CARDEMU_3 : /* T3T activated */
gNfcDev . devList - > type = RFAL_NFC_POLL_TYPE_NFCF ;
gNfcDev . devList - > rfInterface = RFAL_NFC_INTERFACE_RF ;
gNfcDev . devList - > nfcid = NULL ;
gNfcDev . devList - > nfcidLen = 0 ;
return ERR_NONE ;
# if RFAL_FEATURE_NFC_DEP
/*******************************************************************************/
case RFAL_LM_STATE_TARGET_A : /* NFC-DEP activation */
case RFAL_LM_STATE_TARGET_F :
ret = rfalNfcDepListenGetActivationStatus ( ) ;
if ( ret = = ERR_NONE ) {
gNfcDev . devList - > rfInterface = RFAL_NFC_INTERFACE_NFCDEP ;
gNfcDev . devList - > nfcidLen = RFAL_NFCDEP_NFCID3_LEN ;
}
return ret ;
# endif /* RFAL_FEATURE_NFC_DEP */
/*******************************************************************************/
case RFAL_LM_STATE_IDLE : /* AP2P activation */
if ( isDataRcvd ) /* Check if Reader/Initator has sent some data */
{
if ( ( gNfcDev . lmMask & RFAL_LM_MASK_ACTIVE_P2P ) ! = 0U ) /* Check if AP2P is enabled */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_NFC_DEP
/* Calculate the header length in NFC-A or NFC-F mode*/
hdrLen =
( ( bitRate = = RFAL_BR_106 ) ? ( RFAL_NFCDEP_SB_LEN + RFAL_NFCDEP_LEN_LEN ) :
RFAL_NFCDEP_LEN_LEN ) ;
if ( rfalNfcDepIsAtrReq (
& gNfcDev . rxBuf . rfBuf [ hdrLen ] ,
( rfalConvBitsToBytes ( gNfcDev . rxLen ) - hdrLen ) ,
NULL ) ) {
gNfcDev . devList - > type = RFAL_NFC_POLL_TYPE_AP2P ;
rfalSetMode ( ( RFAL_MODE_LISTEN_ACTIVE_P2P ) , bitRate , bitRate ) ;
EXIT_ON_ERR (
ret ,
rfalNfcNfcDepActivate (
gNfcDev . devList ,
RFAL_NFCDEP_COMM_ACTIVE ,
& gNfcDev . rxBuf . rfBuf [ hdrLen ] ,
( rfalConvBitsToBytes ( gNfcDev . rxLen ) - hdrLen ) ) ) ;
} else
# endif /* RFAL_FEATURE_NFC_DEP */
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
return ERR_PROTO ;
2021-10-17 22:54:19 +00:00
}
}
2022-01-05 16:10:18 +00:00
}
return ERR_BUSY ;
/*******************************************************************************/
case RFAL_LM_STATE_READY_A :
case RFAL_LM_STATE_READY_Ax :
case RFAL_LM_STATE_SLEEP_A :
case RFAL_LM_STATE_SLEEP_AF :
return ERR_BUSY ;
/*******************************************************************************/
case RFAL_LM_STATE_POWER_OFF :
return ERR_LINK_LOSS ;
default : /* Wait for activation */
break ;
2021-10-17 22:54:19 +00:00
}
return ERR_INTERNAL ;
}
# endif /* RFAL_FEATURE_LISTEN_MODE */
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ brief Poller NFC DEP Activate
*
* This method performs NFC - DEP Activation
*
* \ param [ in ] device : device info
* \ param [ in ] commMode : communication mode ( Passive / Active )
* \ param [ in ] atrReq : received ATR_REQ
* \ param [ in ] atrReqLen : received ATR_REQ size
*
* \ return ERR_NONE : Operation completed with no error
* \ return ERR_BUSY : Operation ongoing
* \ return ERR_XXXX : Error occurred
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
# if RFAL_FEATURE_NFC_DEP
2022-01-05 16:10:18 +00:00
static ReturnCode rfalNfcNfcDepActivate (
rfalNfcDevice * device ,
rfalNfcDepCommMode commMode ,
const uint8_t * atrReq ,
uint16_t atrReqLen ) {
rfalNfcDepAtrParam initParam ;
2021-10-17 22:54:19 +00:00
/* Supress warnings if Listen mode is disabled */
NO_WARNING ( atrReq ) ;
NO_WARNING ( atrReqLen ) ;
2022-01-05 16:10:18 +00:00
2021-10-17 22:54:19 +00:00
/* If we are in Poll mode */
2022-01-05 16:10:18 +00:00
if ( rfalNfcIsRemDevListener ( device - > type ) ) {
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
/* If Passive F use the NFCID2 retrieved from SENSF */
2022-01-05 16:10:18 +00:00
if ( device - > type = = RFAL_NFC_LISTEN_TYPE_NFCF ) {
initParam . nfcid = device - > dev . nfcf . sensfRes . NFCID2 ;
2021-10-17 22:54:19 +00:00
initParam . nfcidLen = RFAL_NFCF_NFCID2_LEN ;
2022-01-05 16:10:18 +00:00
} else {
initParam . nfcid = gNfcDev . disc . nfcid3 ;
2021-10-17 22:54:19 +00:00
initParam . nfcidLen = RFAL_NFCDEP_NFCID3_LEN ;
2022-01-05 16:10:18 +00:00
}
initParam . BS = RFAL_NFCDEP_Bx_NO_HIGH_BR ;
initParam . BR = RFAL_NFCDEP_Bx_NO_HIGH_BR ;
initParam . DID = RFAL_NFCDEP_DID_NO ;
initParam . NAD = RFAL_NFCDEP_NAD_NO ;
initParam . LR = RFAL_NFCDEP_LR_254 ;
initParam . GB = gNfcDev . disc . GB ;
initParam . GBLen = gNfcDev . disc . GBLen ;
initParam . commMode = commMode ;
initParam . operParam =
( RFAL_NFCDEP_OPER_FULL_MI_EN | RFAL_NFCDEP_OPER_EMPTY_DEP_DIS |
RFAL_NFCDEP_OPER_ATN_EN | RFAL_NFCDEP_OPER_RTOX_REQ_EN ) ;
2021-10-17 22:54:19 +00:00
rfalNfcDepInitialize ( ) ;
/* Perform NFC-DEP (P2P) activation: ATR and PSL if supported */
2022-01-05 16:10:18 +00:00
return rfalNfcDepInitiatorHandleActivation (
& initParam , gNfcDev . disc . maxBR , & device - > proto . nfcDep ) ;
2021-10-17 22:54:19 +00:00
}
/* If we are in Listen mode */
# if RFAL_FEATURE_LISTEN_MODE
2022-01-05 16:10:18 +00:00
else if ( rfalNfcIsRemDevPoller ( device - > type ) ) {
rfalNfcDepListenActvParam actvParams ;
rfalNfcDepTargetParam targetParam ;
2021-10-17 22:54:19 +00:00
ST_MEMCPY ( targetParam . nfcid3 , ( uint8_t * ) gNfcDev . disc . nfcid3 , RFAL_NFCDEP_NFCID3_LEN ) ;
2022-01-05 16:10:18 +00:00
targetParam . bst = RFAL_NFCDEP_Bx_NO_HIGH_BR ;
targetParam . brt = RFAL_NFCDEP_Bx_NO_HIGH_BR ;
targetParam . to = RFAL_NFCDEP_WT_TRG_MAX_L13 ; /* [LLCP] 1.3 6.2.1 */
targetParam . ppt = rfalNfcDepLR2PP ( RFAL_NFCDEP_LR_254 ) ;
if ( gNfcDev . disc . GBLen > = RFAL_NFCDEP_GB_MAX_LEN ) {
2021-10-17 22:54:19 +00:00
return ERR_PARAM ;
}
2022-01-05 16:10:18 +00:00
targetParam . GBtLen = gNfcDev . disc . GBLen ;
if ( gNfcDev . disc . GBLen > 0U ) {
2021-10-17 22:54:19 +00:00
ST_MEMCPY ( targetParam . GBt , gNfcDev . disc . GB , gNfcDev . disc . GBLen ) ;
}
2022-01-05 16:10:18 +00:00
targetParam . operParam =
( RFAL_NFCDEP_OPER_FULL_MI_EN | RFAL_NFCDEP_OPER_EMPTY_DEP_DIS |
RFAL_NFCDEP_OPER_ATN_EN | RFAL_NFCDEP_OPER_RTOX_REQ_EN ) ;
targetParam . commMode = commMode ;
2021-10-17 22:54:19 +00:00
/* Set activation buffer (including header) for NFC-DEP */
2022-01-05 16:10:18 +00:00
actvParams . rxBuf =
( rfalNfcDepBufFormat * ) & gNfcDev . rxBuf
. nfcDepBuf ; /* PRQA S 0310 # MISRA 11.3 - Intentional safe cast to avoiding large buffer duplication */
actvParams . rxLen = & gNfcDev . rxLen ;
2021-10-17 22:54:19 +00:00
actvParams . isRxChaining = & gNfcDev . isRxChaining ;
2022-01-05 16:10:18 +00:00
actvParams . nfcDepDev = & gNfcDev . devList - > proto . nfcDep ;
rfalListenSetState (
( ( device - > type = = RFAL_NFC_POLL_TYPE_NFCA ) ? RFAL_LM_STATE_TARGET_A :
RFAL_LM_STATE_TARGET_F ) ) ;
2021-10-17 22:54:19 +00:00
rfalNfcDepInitialize ( ) ;
/* Perform NFC-DEP (P2P) activation: send ATR_RES and handle activation */
2022-01-05 16:10:18 +00:00
return rfalNfcDepListenStartActivation ( & targetParam , atrReq , atrReqLen , actvParams ) ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
# endif /* RFAL_FEATURE_LISTEN_MODE */
else {
2021-10-17 22:54:19 +00:00
return ERR_INTERNAL ;
}
}
# endif /* RFAL_FEATURE_NFC_DEP */
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ brief Poller NFC Deactivate
*
* This method Deactivates the device if a deactivation procedure exists
*
* \ return ERR_NONE : Operation completed with no error
* \ return ERR_BUSY : Operation ongoing
* \ return ERR_XXXX : Error occurred
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
2022-01-05 16:10:18 +00:00
static ReturnCode rfalNfcDeactivation ( void ) {
2021-10-17 22:54:19 +00:00
/* Check if a device has been activated */
2022-01-05 16:10:18 +00:00
if ( gNfcDev . activeDev ! = NULL ) {
if ( rfalNfcIsRemDevListener (
gNfcDev . activeDev - > type ) ) /* Listen mode no additional deactivation to be performed*/
2021-10-17 22:54:19 +00:00
{
2022-01-05 16:10:18 +00:00
# ifndef RFAL_NFC_SKIP_DEACT
switch ( gNfcDev . activeDev - > rfInterface ) {
/*******************************************************************************/
case RFAL_NFC_INTERFACE_RF :
break ; /* No specific deactivation to be performed */
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_POLL
case RFAL_NFC_INTERFACE_ISODEP :
rfalIsoDepDeselect ( ) ; /* Send a Deselect to device */
break ;
# endif /* RFAL_FEATURE_ISO_DEP_POLL */
2021-10-17 22:54:19 +00:00
/*******************************************************************************/
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_NFC_DEP
case RFAL_NFC_INTERFACE_NFCDEP :
switch ( gNfcDev . activeDev - > type ) {
case RFAL_NFC_LISTEN_TYPE_AP2P :
rfalNfcDepRLS ( ) ; /* Send a Release to device */
2021-10-17 22:54:19 +00:00
break ;
default :
2022-01-05 16:10:18 +00:00
rfalNfcDepDSL ( ) ; /* Send a Deselect to device */
break ;
}
break ;
# endif /* RFAL_FEATURE_NFC_DEP */
default :
return ERR_REQUEST ;
2021-10-17 22:54:19 +00:00
}
2022-01-05 16:10:18 +00:00
# endif /* RFAL_NFC_SKIP_DEACT */
2021-10-17 22:54:19 +00:00
}
}
2022-01-05 16:10:18 +00:00
# if RFAL_FEATURE_WAKEUP_MODE
rfalWakeUpModeStop ( ) ;
# endif /* RFAL_FEATURE_WAKEUP_MODE */
# if RFAL_FEATURE_LISTEN_MODE
rfalListenStop ( ) ;
# else
rfalFieldOff ( ) ;
# endif
2021-10-17 22:54:19 +00:00
gNfcDev . activeDev = NULL ;
return ERR_NONE ;
}