rfal_nfc.c 87 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934
  1. /**
  2. ******************************************************************************
  3. *
  4. * COPYRIGHT(c) 2020 STMicroelectronics
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. * 1. Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  25. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. *
  28. ******************************************************************************
  29. */
  30. /*! \file rfal_nfc.c
  31. *
  32. * \author Gustavo Patricio
  33. *
  34. * \brief RFAL NFC device
  35. *
  36. * This module provides the required features to behave as an NFC Poller
  37. * or Listener device. It grants an easy to use interface for the following
  38. * activities: Technology Detection, Collision Resollution, Activation,
  39. * Data Exchange, and Deactivation
  40. *
  41. * This layer is influenced by (but not fully aligned with) the NFC Forum
  42. * specifications, in particular: Activity 2.0 and NCI 2.0
  43. *
  44. */
  45. /*
  46. ******************************************************************************
  47. * INCLUDES
  48. ******************************************************************************
  49. */
  50. #include "rfal_nfc.h"
  51. #include "utils.h"
  52. #include "rfal_analogConfig.h"
  53. /*
  54. ******************************************************************************
  55. * GLOBAL DEFINES
  56. ******************************************************************************
  57. */
  58. #define RFAL_NFC_MAX_DEVICES 5U /* Max number of devices supported */
  59. /*
  60. ******************************************************************************
  61. * GLOBAL MACROS
  62. ******************************************************************************
  63. */
  64. #define rfalNfcNfcNotify( st ) if( gNfcDev.disc.notifyCb != NULL ) gNfcDev.disc.notifyCb( st )
  65. /*
  66. ******************************************************************************
  67. * GLOBAL TYPES
  68. ******************************************************************************
  69. */
  70. /*! Buffer union, only one interface is used at a time */
  71. typedef union{ /* PRQA S 0750 # MISRA 19.2 - Members of the union will not be used concurrently, only one interface at a time */
  72. rfalIsoDepBufFormat isoDepBuf; /*!< ISO-DEP buffer format (with header/prologue) */
  73. rfalNfcDepBufFormat nfcDepBuf; /*!< NFC-DEP buffer format (with header/prologue) */
  74. }rfalNfcTmpBuffer;
  75. typedef struct{
  76. rfalNfcState state; /* Main state */
  77. uint16_t techsFound; /* Technologies found bitmask */
  78. uint16_t techs2do; /* Technologies still to be performed */
  79. rfalBitRate ap2pBR; /* Bit rate to poll for AP2P */
  80. uint8_t selDevIdx; /* Selected device index */
  81. rfalNfcDevice *activeDev; /* Active device pointer */
  82. rfalNfcDiscoverParam disc; /* Discovery parameters */
  83. rfalNfcDevice devList[RFAL_NFC_MAX_DEVICES]; /*!< Location of device list */
  84. uint8_t devCnt; /* Decices found counter */
  85. uint32_t discTmr; /* Discovery Total duration timer */
  86. ReturnCode dataExErr; /* Last Data Exchange error */
  87. bool discRestart; /* Restart discover after deactivation flag */
  88. bool isRxChaining; /* Flag indicating Other device is chaining */
  89. uint32_t lmMask; /* Listen Mode mask */
  90. bool isTechInit; /* Flag indicating technology has been set */
  91. bool isOperOngoing; /* Flag indicating opration is ongoing */
  92. rfalNfcBuffer txBuf; /* Tx buffer for Data Exchange */
  93. rfalNfcBuffer rxBuf; /* Rx buffer for Data Exchange */
  94. uint16_t rxLen; /* Length of received data on Data Exchange */
  95. #if RFAL_FEATURE_NFC_DEP || RFAL_FEATURE_ISO_DEP
  96. rfalNfcTmpBuffer tmpBuf; /* Tmp buffer for Data Exchange */
  97. #endif /* RFAL_FEATURE_NFC_DEP || RFAL_FEATURE_ISO_DEP */
  98. }rfalNfc;
  99. /*
  100. ******************************************************************************
  101. * LOCAL VARIABLES
  102. ******************************************************************************
  103. */
  104. #ifdef RFAL_TEST_MODE
  105. rfalNfc gNfcDev;
  106. #else /* RFAL_TEST_MODE */
  107. static rfalNfc gNfcDev;
  108. #endif /* RFAL_TEST_MODE */
  109. /*
  110. ******************************************************************************
  111. * LOCAL FUNCTION PROTOTYPES
  112. ******************************************************************************
  113. */
  114. static ReturnCode rfalNfcPollTechDetetection( void );
  115. static ReturnCode rfalNfcPollCollResolution( void );
  116. static ReturnCode rfalNfcPollActivation( uint8_t devIt );
  117. static ReturnCode rfalNfcDeactivation( void );
  118. #if RFAL_FEATURE_NFC_DEP
  119. static ReturnCode rfalNfcNfcDepActivate( rfalNfcDevice *device, rfalNfcDepCommMode commMode, const uint8_t *atrReq, uint16_t atrReqLen );
  120. #endif /* RFAL_FEATURE_NFC_DEP */
  121. #if RFAL_FEATURE_LISTEN_MODE
  122. static ReturnCode rfalNfcListenActivation( void );
  123. #endif /* RFAL_FEATURE_LISTEN_MODE*/
  124. /*******************************************************************************/
  125. ReturnCode rfalNfcInitialize( void )
  126. {
  127. ReturnCode err;
  128. gNfcDev.state = RFAL_NFC_STATE_NOTINIT;
  129. rfalAnalogConfigInitialize(); /* Initialize RFAL's Analog Configs */
  130. EXIT_ON_ERR( err, rfalInitialize() ); /* Initialize RFAL */
  131. gNfcDev.state = RFAL_NFC_STATE_IDLE; /* Go to initialized */
  132. return ERR_NONE;
  133. }
  134. /*******************************************************************************/
  135. ReturnCode rfalNfcDiscover( const rfalNfcDiscoverParam *disParams )
  136. {
  137. /* Check if initialization has been performed */
  138. if( gNfcDev.state != RFAL_NFC_STATE_IDLE )
  139. {
  140. return ERR_WRONG_STATE;
  141. }
  142. /* Check valid parameters */
  143. if( (disParams == NULL) || (disParams->devLimit > RFAL_NFC_MAX_DEVICES) || (disParams->devLimit == 0U) ||
  144. ( (disParams->maxBR > RFAL_BR_1695) && (disParams->maxBR != RFAL_BR_KEEP) ) ||
  145. ( ((disParams->techs2Find & RFAL_NFC_POLL_TECH_F) != 0U) && (disParams->nfcfBR != RFAL_BR_212) && (disParams->nfcfBR != RFAL_BR_424) ) ||
  146. ( (((disParams->techs2Find & RFAL_NFC_POLL_TECH_AP2P) != 0U) && (disParams->ap2pBR > RFAL_BR_424)) || (disParams->GBLen > RFAL_NFCDEP_GB_MAX_LEN) ) )
  147. {
  148. return ERR_PARAM;
  149. }
  150. if( (((disParams->techs2Find & RFAL_NFC_POLL_TECH_A) != 0U) && !((bool)RFAL_FEATURE_NFCA)) ||
  151. (((disParams->techs2Find & RFAL_NFC_POLL_TECH_B) != 0U) && !((bool)RFAL_FEATURE_NFCB)) ||
  152. (((disParams->techs2Find & RFAL_NFC_POLL_TECH_F) != 0U) && !((bool)RFAL_FEATURE_NFCF)) ||
  153. (((disParams->techs2Find & RFAL_NFC_POLL_TECH_V) != 0U) && !((bool)RFAL_FEATURE_NFCV)) ||
  154. (((disParams->techs2Find & RFAL_NFC_POLL_TECH_ST25TB) != 0U) && !((bool)RFAL_FEATURE_ST25TB)) ||
  155. (((disParams->techs2Find & RFAL_NFC_POLL_TECH_AP2P) != 0U) && !((bool)RFAL_FEATURE_NFC_DEP)) ||
  156. (((disParams->techs2Find & RFAL_NFC_LISTEN_TECH_A) != 0U) && !((bool)RFAL_FEATURE_NFCA)) ||
  157. (((disParams->techs2Find & RFAL_NFC_LISTEN_TECH_B) != 0U) && !((bool)RFAL_FEATURE_NFCB)) ||
  158. (((disParams->techs2Find & RFAL_NFC_LISTEN_TECH_F) != 0U) && !((bool)RFAL_FEATURE_NFCF)) ||
  159. (((disParams->techs2Find & RFAL_NFC_LISTEN_TECH_AP2P) != 0U) && !((bool)RFAL_FEATURE_NFC_DEP)) )
  160. {
  161. return ERR_DISABLED; /* PRQA S 2880 # MISRA 2.1 - Unreachable code due to configuration option being set/unset */
  162. }
  163. /* Initialize context for discovery */
  164. gNfcDev.activeDev = NULL;
  165. gNfcDev.techsFound = RFAL_NFC_TECH_NONE;
  166. gNfcDev.devCnt = 0;
  167. gNfcDev.discRestart = true;
  168. gNfcDev.isTechInit = false;
  169. gNfcDev.disc = *disParams;
  170. /* Calculate Listen Mask */
  171. gNfcDev.lmMask = 0U;
  172. gNfcDev.lmMask |= (((gNfcDev.disc.techs2Find & RFAL_NFC_LISTEN_TECH_A) != 0U) ? RFAL_LM_MASK_NFCA : 0U);
  173. gNfcDev.lmMask |= (((gNfcDev.disc.techs2Find & RFAL_NFC_LISTEN_TECH_B) != 0U) ? RFAL_LM_MASK_NFCB : 0U);
  174. gNfcDev.lmMask |= (((gNfcDev.disc.techs2Find & RFAL_NFC_LISTEN_TECH_F) != 0U) ? RFAL_LM_MASK_NFCF : 0U);
  175. gNfcDev.lmMask |= (((gNfcDev.disc.techs2Find & RFAL_NFC_LISTEN_TECH_AP2P) != 0U) ? RFAL_LM_MASK_ACTIVE_P2P : 0U);
  176. #if !RFAL_FEATURE_LISTEN_MODE
  177. /* Check if Listen Mode is supported/Enabled */
  178. if( gNfcDev.lmMask != 0U )
  179. {
  180. return ERR_DISABLED;
  181. }
  182. #endif
  183. gNfcDev.state = RFAL_NFC_STATE_START_DISCOVERY;
  184. return ERR_NONE;
  185. }
  186. /*******************************************************************************/
  187. ReturnCode rfalNfcDeactivate( bool discovery )
  188. {
  189. /* Check for valid state */
  190. if( gNfcDev.state <= RFAL_NFC_STATE_IDLE )
  191. {
  192. return ERR_WRONG_STATE;
  193. }
  194. /* Check if discovery is to continue afterwards */
  195. if( (discovery == true) && (gNfcDev.disc.techs2Find != RFAL_NFC_TECH_NONE) )
  196. {
  197. /* If so let the state machine continue*/
  198. gNfcDev.discRestart = discovery;
  199. gNfcDev.state = RFAL_NFC_STATE_DEACTIVATION;
  200. }
  201. else
  202. {
  203. /* Otherwise deactivate immediately and go to IDLE */
  204. rfalNfcDeactivation();
  205. gNfcDev.state = RFAL_NFC_STATE_IDLE;
  206. }
  207. return ERR_NONE;
  208. }
  209. /*******************************************************************************/
  210. ReturnCode rfalNfcSelect( uint8_t devIdx )
  211. {
  212. /* Check for valid state */
  213. if( gNfcDev.state != RFAL_NFC_STATE_POLL_SELECT )
  214. {
  215. return ERR_WRONG_STATE;
  216. }
  217. gNfcDev.selDevIdx = devIdx;
  218. gNfcDev.state = RFAL_NFC_STATE_POLL_ACTIVATION;
  219. return ERR_NONE;
  220. }
  221. /*******************************************************************************/
  222. rfalNfcState rfalNfcGetState( void )
  223. {
  224. return gNfcDev.state;
  225. }
  226. /*******************************************************************************/
  227. ReturnCode rfalNfcGetDevicesFound( rfalNfcDevice **devList, uint8_t *devCnt )
  228. {
  229. /* Check for valid state */
  230. if( gNfcDev.state < RFAL_NFC_STATE_POLL_SELECT )
  231. {
  232. return ERR_WRONG_STATE;
  233. }
  234. /* Check valid parameters */
  235. if( (devList == NULL) || (devCnt == NULL) )
  236. {
  237. return ERR_PARAM;
  238. }
  239. *devCnt = gNfcDev.devCnt;
  240. *devList = gNfcDev.devList;
  241. return ERR_NONE;
  242. }
  243. /*******************************************************************************/
  244. ReturnCode rfalNfcGetActiveDevice( rfalNfcDevice **dev )
  245. {
  246. /* Check for valid state */
  247. if( gNfcDev.state < RFAL_NFC_STATE_ACTIVATED )
  248. {
  249. return ERR_WRONG_STATE;
  250. }
  251. /* Check valid parameter */
  252. if( dev == NULL )
  253. {
  254. return ERR_PARAM;
  255. }
  256. /* Check for valid state */
  257. if( (gNfcDev.devCnt == 0U) || (gNfcDev.activeDev == NULL) )
  258. {
  259. return ERR_REQUEST;
  260. }
  261. *dev = gNfcDev.activeDev;
  262. return ERR_NONE;
  263. }
  264. /*******************************************************************************/
  265. void rfalNfcWorker( void )
  266. {
  267. ReturnCode err;
  268. rfalWorker(); /* Execute RFAL process */
  269. switch( gNfcDev.state )
  270. {
  271. /*******************************************************************************/
  272. case RFAL_NFC_STATE_NOTINIT:
  273. case RFAL_NFC_STATE_IDLE:
  274. break;
  275. /*******************************************************************************/
  276. case RFAL_NFC_STATE_START_DISCOVERY:
  277. /* Initialize context for discovery cycle */
  278. gNfcDev.devCnt = 0;
  279. gNfcDev.selDevIdx = 0;
  280. gNfcDev.techsFound = RFAL_NFC_TECH_NONE;
  281. gNfcDev.techs2do = gNfcDev.disc.techs2Find;
  282. gNfcDev.state = RFAL_NFC_STATE_POLL_TECHDETECT;
  283. #if RFAL_FEATURE_WAKEUP_MODE
  284. /* Check if Low power Wake-Up is to be performed */
  285. if( gNfcDev.disc.wakeupEnabled )
  286. {
  287. /* Initialize Low power Wake-up mode and wait */
  288. err = rfalWakeUpModeStart( (gNfcDev.disc.wakeupConfigDefault ? NULL : &gNfcDev.disc.wakeupConfig) );
  289. if( err == ERR_NONE )
  290. {
  291. gNfcDev.state = RFAL_NFC_STATE_WAKEUP_MODE;
  292. rfalNfcNfcNotify( gNfcDev.state ); /* Notify caller that WU was started */
  293. }
  294. }
  295. #endif /* RFAL_FEATURE_WAKEUP_MODE */
  296. break;
  297. /*******************************************************************************/
  298. case RFAL_NFC_STATE_WAKEUP_MODE:
  299. #if RFAL_FEATURE_WAKEUP_MODE
  300. /* Check if the Wake-up mode has woke */
  301. if( rfalWakeUpModeHasWoke() )
  302. {
  303. rfalWakeUpModeStop(); /* Disable Wake-up mode */
  304. gNfcDev.state = RFAL_NFC_STATE_POLL_TECHDETECT; /* Go to Technology detection */
  305. rfalNfcNfcNotify( gNfcDev.state ); /* Notify caller that WU has woke */
  306. }
  307. #endif /* RFAL_FEATURE_WAKEUP_MODE */
  308. break;
  309. /*******************************************************************************/
  310. case RFAL_NFC_STATE_POLL_TECHDETECT:
  311. /* Start total duration timer */
  312. platformTimerDestroy( gNfcDev.discTmr );
  313. gNfcDev.discTmr = (uint32_t)platformTimerCreate( gNfcDev.disc.totalDuration );
  314. err = rfalNfcPollTechDetetection(); /* Perform Technology Detection */
  315. if( err != ERR_BUSY ) /* Wait until all technologies are performed */
  316. {
  317. if( ( err != ERR_NONE) || (gNfcDev.techsFound == RFAL_NFC_TECH_NONE) )/* Check if any error occurred or no techs were found */
  318. {
  319. rfalFieldOff();
  320. gNfcDev.state = RFAL_NFC_STATE_LISTEN_TECHDETECT; /* Nothing found as poller, go to listener */
  321. break;
  322. }
  323. gNfcDev.techs2do = gNfcDev.techsFound; /* Store the found technologies for collision resolution */
  324. gNfcDev.state = RFAL_NFC_STATE_POLL_COLAVOIDANCE; /* One or more devices found, go to Collision Avoidance */
  325. }
  326. break;
  327. /*******************************************************************************/
  328. case RFAL_NFC_STATE_POLL_COLAVOIDANCE:
  329. err = rfalNfcPollCollResolution(); /* Resolve any eventual collision */
  330. if( err != ERR_BUSY ) /* Wait until all technologies are performed */
  331. {
  332. if( (err != ERR_NONE) || (gNfcDev.devCnt == 0U) ) /* Check if any error occurred or no devices were found */
  333. {
  334. gNfcDev.state = RFAL_NFC_STATE_DEACTIVATION;
  335. break; /* Unable to retrieve any device, restart loop */
  336. }
  337. /* Check if more than one device has been found */
  338. if( gNfcDev.devCnt > 1U )
  339. {
  340. /* If more than one device was found inform upper layer to choose which one to activate */
  341. if( gNfcDev.disc.notifyCb != NULL )
  342. {
  343. gNfcDev.state = RFAL_NFC_STATE_POLL_SELECT;
  344. gNfcDev.disc.notifyCb( gNfcDev.state );
  345. break;
  346. }
  347. }
  348. /* If only one device or no callback has been set, activate the first device found */
  349. gNfcDev.selDevIdx = 0U;
  350. gNfcDev.state = RFAL_NFC_STATE_POLL_ACTIVATION;
  351. }
  352. break;
  353. /*******************************************************************************/
  354. case RFAL_NFC_STATE_POLL_ACTIVATION:
  355. err = rfalNfcPollActivation( gNfcDev.selDevIdx );
  356. if( err != ERR_BUSY ) /* Wait until all Activation is complete */
  357. {
  358. if( err != ERR_NONE ) /* Activation failed selected device */
  359. {
  360. gNfcDev.state = RFAL_NFC_STATE_DEACTIVATION; /* If Activation failed, restart loop */
  361. break;
  362. }
  363. gNfcDev.state = RFAL_NFC_STATE_ACTIVATED; /* Device has been properly activated */
  364. rfalNfcNfcNotify( gNfcDev.state ); /* Inform upper layer that a device has been activated */
  365. }
  366. break;
  367. /*******************************************************************************/
  368. case RFAL_NFC_STATE_DATAEXCHANGE:
  369. rfalNfcDataExchangeGetStatus(); /* Run the internal state machine */
  370. if( gNfcDev.dataExErr != ERR_BUSY ) /* If Dataexchange has terminated */
  371. {
  372. gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE_DONE; /* Go to done state */
  373. rfalNfcNfcNotify( gNfcDev.state ); /* And notify caller */
  374. }
  375. if( gNfcDev.dataExErr == ERR_SLEEP_REQ ) /* Check if Listen mode has to go to Sleep */
  376. {
  377. gNfcDev.state = RFAL_NFC_STATE_LISTEN_SLEEP; /* Go to Listen Sleep state */
  378. rfalNfcNfcNotify( gNfcDev.state ); /* And notify caller */
  379. }
  380. break;
  381. /*******************************************************************************/
  382. case RFAL_NFC_STATE_DEACTIVATION:
  383. rfalNfcDeactivation(); /* Deactivate current device */
  384. gNfcDev.state = ((gNfcDev.discRestart) ? RFAL_NFC_STATE_START_DISCOVERY : RFAL_NFC_STATE_IDLE);
  385. rfalNfcNfcNotify( gNfcDev.state ); /* Notify caller */
  386. break;
  387. /*******************************************************************************/
  388. case RFAL_NFC_STATE_LISTEN_TECHDETECT:
  389. if( platformTimerIsExpired( gNfcDev.discTmr ) )
  390. {
  391. #if RFAL_FEATURE_LISTEN_MODE
  392. rfalListenStop();
  393. #else
  394. rfalFieldOff();
  395. #endif /* RFAL_FEATURE_LISTEN_MODE */
  396. gNfcDev.state = RFAL_NFC_STATE_START_DISCOVERY; /* Restart the discovery loop */
  397. rfalNfcNfcNotify( gNfcDev.state ); /* Notify caller */
  398. break;
  399. }
  400. #if RFAL_FEATURE_LISTEN_MODE
  401. if( gNfcDev.lmMask != 0U ) /* Check if configured to perform Listen mode */
  402. {
  403. 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 );
  404. if( err == ERR_NONE )
  405. {
  406. gNfcDev.state = RFAL_NFC_STATE_LISTEN_COLAVOIDANCE; /* Wait for listen mode to be activated */
  407. }
  408. }
  409. break;
  410. /*******************************************************************************/
  411. case RFAL_NFC_STATE_LISTEN_COLAVOIDANCE:
  412. if( platformTimerIsExpired( gNfcDev.discTmr ) ) /* Check if the total duration has been reached */
  413. {
  414. rfalListenStop();
  415. gNfcDev.state = RFAL_NFC_STATE_START_DISCOVERY; /* Restart the discovery loop */
  416. rfalNfcNfcNotify( gNfcDev.state ); /* Notify caller */
  417. break;
  418. }
  419. /* Check for external field */
  420. if( rfalListenGetState( NULL, NULL ) >= RFAL_LM_STATE_IDLE )
  421. {
  422. gNfcDev.state = RFAL_NFC_STATE_LISTEN_ACTIVATION; /* Wait for listen mode to be activated */
  423. }
  424. break;
  425. /*******************************************************************************/
  426. case RFAL_NFC_STATE_LISTEN_ACTIVATION:
  427. case RFAL_NFC_STATE_LISTEN_SLEEP:
  428. err = rfalNfcListenActivation();
  429. if( err != ERR_BUSY )
  430. {
  431. if( err == ERR_NONE )
  432. {
  433. gNfcDev.activeDev = gNfcDev.devList; /* Assign the active device to be used further on */
  434. gNfcDev.devCnt++;
  435. gNfcDev.state = RFAL_NFC_STATE_ACTIVATED; /* Device has been properly activated */
  436. rfalNfcNfcNotify( gNfcDev.state ); /* Inform upper layer that a device has been activated */
  437. }
  438. else
  439. {
  440. rfalListenStop();
  441. gNfcDev.state = RFAL_NFC_STATE_START_DISCOVERY; /* Restart the discovery loop */
  442. rfalNfcNfcNotify( gNfcDev.state ); /* Notify caller */
  443. }
  444. }
  445. #endif /* RFAL_FEATURE_LISTEN_MODE */
  446. break;
  447. /*******************************************************************************/
  448. case RFAL_NFC_STATE_ACTIVATED:
  449. case RFAL_NFC_STATE_POLL_SELECT:
  450. case RFAL_NFC_STATE_DATAEXCHANGE_DONE:
  451. default:
  452. return;
  453. }
  454. }
  455. /*******************************************************************************/
  456. ReturnCode rfalNfcDataExchangeStart( uint8_t *txData, uint16_t txDataLen, uint8_t **rxData, uint16_t **rvdLen, uint32_t fwt )
  457. {
  458. ReturnCode err;
  459. rfalTransceiveContext ctx;
  460. /*******************************************************************************/
  461. /* The Data Exchange is divided in two different moments, the trigger/Start of *
  462. * the transfer followed by the check until its completion */
  463. if( (gNfcDev.state >= RFAL_NFC_STATE_ACTIVATED) && (gNfcDev.activeDev != NULL) )
  464. {
  465. /*******************************************************************************/
  466. /* In Listen mode is the Poller that initiates the communicatation */
  467. /* Assign output parameters and rfalNfcDataExchangeGetStatus will return */
  468. /* incoming data from Poller/Initiator */
  469. if( (gNfcDev.state == RFAL_NFC_STATE_ACTIVATED) && rfalNfcIsRemDevPoller( gNfcDev.activeDev->type ) )
  470. {
  471. if( txDataLen > 0U )
  472. {
  473. return ERR_WRONG_STATE;
  474. }
  475. *rvdLen = (uint16_t*)&gNfcDev.rxLen;
  476. *rxData = (uint8_t*)( (gNfcDev.activeDev->rfInterface == RFAL_NFC_INTERFACE_ISODEP) ? gNfcDev.rxBuf.isoDepBuf.apdu :
  477. ((gNfcDev.activeDev->rfInterface == RFAL_NFC_INTERFACE_NFCDEP) ? gNfcDev.rxBuf.nfcDepBuf.pdu : gNfcDev.rxBuf.rfBuf));
  478. gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE_DONE;
  479. return ERR_NONE;
  480. }
  481. /*******************************************************************************/
  482. switch( gNfcDev.activeDev->rfInterface ) /* Check which RF interface shall be used/has been activated */
  483. {
  484. /*******************************************************************************/
  485. case RFAL_NFC_INTERFACE_RF:
  486. rfalCreateByteFlagsTxRxContext( ctx, (uint8_t*)txData, txDataLen, gNfcDev.rxBuf.rfBuf, sizeof(gNfcDev.rxBuf.rfBuf), &gNfcDev.rxLen, RFAL_TXRX_FLAGS_DEFAULT, fwt );
  487. *rxData = (uint8_t*)gNfcDev.rxBuf.rfBuf;
  488. *rvdLen = (uint16_t*)&gNfcDev.rxLen;
  489. err = rfalStartTransceive( &ctx );
  490. break;
  491. #if RFAL_FEATURE_ISO_DEP
  492. /*******************************************************************************/
  493. case RFAL_NFC_INTERFACE_ISODEP:
  494. {
  495. rfalIsoDepApduTxRxParam isoDepTxRx;
  496. if( txDataLen > sizeof(gNfcDev.txBuf.isoDepBuf.apdu) )
  497. {
  498. return ERR_NOMEM;
  499. }
  500. if( txDataLen > 0U )
  501. {
  502. ST_MEMCPY( (uint8_t*)gNfcDev.txBuf.isoDepBuf.apdu, txData, txDataLen );
  503. }
  504. isoDepTxRx.DID = RFAL_ISODEP_NO_DID;
  505. isoDepTxRx.ourFSx = RFAL_ISODEP_FSX_KEEP;
  506. isoDepTxRx.FSx = gNfcDev.activeDev->proto.isoDep.info.FSx;
  507. isoDepTxRx.dFWT = gNfcDev.activeDev->proto.isoDep.info.dFWT;
  508. isoDepTxRx.FWT = gNfcDev.activeDev->proto.isoDep.info.FWT;
  509. isoDepTxRx.txBuf = &gNfcDev.txBuf.isoDepBuf;
  510. isoDepTxRx.txBufLen = txDataLen;
  511. isoDepTxRx.rxBuf = &gNfcDev.rxBuf.isoDepBuf;
  512. isoDepTxRx.rxLen = &gNfcDev.rxLen;
  513. isoDepTxRx.tmpBuf = &gNfcDev.tmpBuf.isoDepBuf;
  514. *rxData = (uint8_t*)gNfcDev.rxBuf.isoDepBuf.apdu;
  515. *rvdLen = (uint16_t*)&gNfcDev.rxLen;
  516. /*******************************************************************************/
  517. /* Trigger a RFAL ISO-DEP Transceive */
  518. err = rfalIsoDepStartApduTransceive( isoDepTxRx );
  519. break;
  520. }
  521. #endif /* RFAL_FEATURE_ISO_DEP */
  522. #if RFAL_FEATURE_NFC_DEP
  523. /*******************************************************************************/
  524. case RFAL_NFC_INTERFACE_NFCDEP:
  525. {
  526. rfalNfcDepPduTxRxParam nfcDepTxRx;
  527. if( txDataLen > sizeof(gNfcDev.txBuf.nfcDepBuf.pdu) )
  528. {
  529. return ERR_NOMEM;
  530. }
  531. if( txDataLen > 0U)
  532. {
  533. ST_MEMCPY( (uint8_t*)gNfcDev.txBuf.nfcDepBuf.pdu, txData, txDataLen );
  534. }
  535. nfcDepTxRx.DID = RFAL_NFCDEP_DID_KEEP;
  536. nfcDepTxRx.FSx = rfalNfcIsRemDevListener(gNfcDev.activeDev->type) ?
  537. rfalNfcDepLR2FS( (uint8_t)rfalNfcDepPP2LR( gNfcDev.activeDev->proto.nfcDep.activation.Target.ATR_RES.PPt ) ) :
  538. rfalNfcDepLR2FS( (uint8_t)rfalNfcDepPP2LR( gNfcDev.activeDev->proto.nfcDep.activation.Initiator.ATR_REQ.PPi ) );
  539. nfcDepTxRx.dFWT = gNfcDev.activeDev->proto.nfcDep.info.dFWT;
  540. nfcDepTxRx.FWT = gNfcDev.activeDev->proto.nfcDep.info.FWT;
  541. nfcDepTxRx.txBuf = &gNfcDev.txBuf.nfcDepBuf;
  542. nfcDepTxRx.txBufLen = txDataLen;
  543. nfcDepTxRx.rxBuf = &gNfcDev.rxBuf.nfcDepBuf;
  544. nfcDepTxRx.rxLen = &gNfcDev.rxLen;
  545. nfcDepTxRx.tmpBuf = &gNfcDev.tmpBuf.nfcDepBuf;
  546. *rxData = (uint8_t*)gNfcDev.rxBuf.nfcDepBuf.pdu;
  547. *rvdLen = (uint16_t*)&gNfcDev.rxLen;
  548. /*******************************************************************************/
  549. /* Trigger a RFAL NFC-DEP Transceive */
  550. err = rfalNfcDepStartPduTransceive( nfcDepTxRx );
  551. break;
  552. }
  553. #endif /* RFAL_FEATURE_NFC_DEP */
  554. /*******************************************************************************/
  555. default:
  556. err = ERR_PARAM;
  557. break;
  558. }
  559. /* If a transceive has succesfully started flag Data Exchange as ongoing */
  560. if( err == ERR_NONE )
  561. {
  562. gNfcDev.dataExErr = ERR_BUSY;
  563. gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE;
  564. }
  565. return err;
  566. }
  567. return ERR_WRONG_STATE;
  568. }
  569. /*******************************************************************************/
  570. ReturnCode rfalNfcDataExchangeGetStatus( void )
  571. {
  572. /*******************************************************************************/
  573. /* Check if it's the first frame received in Listen mode */
  574. if( gNfcDev.state == RFAL_NFC_STATE_ACTIVATED )
  575. {
  576. /* Continue data exchange as normal */
  577. gNfcDev.dataExErr = ERR_BUSY;
  578. gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE;
  579. /* Check if we performing in T3T CE */
  580. if( (gNfcDev.activeDev->type == RFAL_NFC_POLL_TYPE_NFCF) && (gNfcDev.activeDev->rfInterface == RFAL_NFC_INTERFACE_RF) )
  581. {
  582. /* The first frame has been retrieved by rfalListenMode, flag data immediately */
  583. /* Can only call rfalGetTransceiveStatus() after starting a transceive with rfalStartTransceive */
  584. gNfcDev.dataExErr = ERR_NONE;
  585. }
  586. }
  587. /*******************************************************************************/
  588. /* Check if we are in we have been placed to sleep, and return last error */
  589. if( gNfcDev.state == RFAL_NFC_STATE_LISTEN_SLEEP )
  590. {
  591. return gNfcDev.dataExErr; /* ERR_SLEEP_REQ */
  592. }
  593. /*******************************************************************************/
  594. /* Check if Data exchange has been started */
  595. if( (gNfcDev.state != RFAL_NFC_STATE_DATAEXCHANGE) && (gNfcDev.state != RFAL_NFC_STATE_DATAEXCHANGE_DONE) )
  596. {
  597. return ERR_WRONG_STATE;
  598. }
  599. /* Check if Data exchange is still ongoing */
  600. if( gNfcDev.dataExErr == ERR_BUSY )
  601. {
  602. switch( gNfcDev.activeDev->rfInterface )
  603. {
  604. /*******************************************************************************/
  605. case RFAL_NFC_INTERFACE_RF:
  606. gNfcDev.dataExErr = rfalGetTransceiveStatus();
  607. break;
  608. #if RFAL_FEATURE_ISO_DEP
  609. /*******************************************************************************/
  610. case RFAL_NFC_INTERFACE_ISODEP:
  611. gNfcDev.dataExErr = rfalIsoDepGetApduTransceiveStatus();
  612. break;
  613. #endif /* RFAL_FEATURE_ISO_DEP */
  614. /*******************************************************************************/
  615. #if RFAL_FEATURE_NFC_DEP
  616. case RFAL_NFC_INTERFACE_NFCDEP:
  617. gNfcDev.dataExErr = rfalNfcDepGetPduTransceiveStatus();
  618. break;
  619. #endif /* RFAL_FEATURE_NFC_DEP */
  620. /*******************************************************************************/
  621. default:
  622. gNfcDev.dataExErr = ERR_PARAM;
  623. break;
  624. }
  625. #if RFAL_FEATURE_LISTEN_MODE
  626. /*******************************************************************************/
  627. /* If a Sleep request has been received (Listen Mode) go to sleep immediately */
  628. if( gNfcDev.dataExErr == ERR_SLEEP_REQ )
  629. {
  630. EXIT_ON_ERR( gNfcDev.dataExErr, rfalListenSleepStart( RFAL_LM_STATE_SLEEP_A, gNfcDev.rxBuf.rfBuf, sizeof(gNfcDev.rxBuf.rfBuf), &gNfcDev.rxLen ) );
  631. /* If set Sleep was succesfull keep restore the Sleep request signal */
  632. gNfcDev.dataExErr = ERR_SLEEP_REQ;
  633. }
  634. #endif /* RFAL_FEATURE_LISTEN_MODE */
  635. }
  636. return gNfcDev.dataExErr;
  637. }
  638. /*!
  639. ******************************************************************************
  640. * \brief Poller Technology Detection
  641. *
  642. * This method implements the Technology Detection / Poll for different
  643. * device technologies.
  644. *
  645. * \return ERR_NONE : Operation completed with no error
  646. * \return ERR_BUSY : Operation ongoing
  647. * \return ERR_XXXX : Error occurred
  648. *
  649. ******************************************************************************
  650. */
  651. static ReturnCode rfalNfcPollTechDetetection( void )
  652. {
  653. ReturnCode err;
  654. err = ERR_NONE;
  655. /* Supress warning when specific RFAL features have been disabled */
  656. NO_WARNING(err);
  657. /*******************************************************************************/
  658. /* AP2P Technology Detection */
  659. /*******************************************************************************/
  660. if( ((gNfcDev.disc.techs2Find & RFAL_NFC_POLL_TECH_AP2P) != 0U) && ((gNfcDev.techs2do & RFAL_NFC_POLL_TECH_AP2P) != 0U) )
  661. {
  662. #if RFAL_FEATURE_NFC_DEP
  663. if( !gNfcDev.isTechInit )
  664. {
  665. EXIT_ON_ERR( err, rfalSetMode( RFAL_MODE_POLL_ACTIVE_P2P, gNfcDev.disc.ap2pBR, gNfcDev.disc.ap2pBR ) );
  666. rfalSetErrorHandling( RFAL_ERRORHANDLING_NFC );
  667. rfalSetFDTListen( RFAL_FDT_LISTEN_AP2P_POLLER );
  668. rfalSetFDTPoll( RFAL_TIMING_NONE );
  669. rfalSetGT( RFAL_GT_AP2P_ADJUSTED );
  670. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* Turns the Field On and starts GT timer */
  671. gNfcDev.isTechInit = true;
  672. }
  673. if( rfalIsGTExpired() ) /* Wait until Guard Time is fulfilled */
  674. {
  675. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_AP2P;
  676. err = rfalNfcNfcDepActivate( gNfcDev.devList, RFAL_NFCDEP_COMM_ACTIVE, NULL, 0 );/* Poll for NFC-A devices */
  677. if( err == ERR_NONE )
  678. {
  679. gNfcDev.techsFound |= RFAL_NFC_POLL_TECH_AP2P;
  680. gNfcDev.devList->type = RFAL_NFC_LISTEN_TYPE_AP2P;
  681. gNfcDev.devList->rfInterface = RFAL_NFC_INTERFACE_NFCDEP;
  682. gNfcDev.devCnt++;
  683. return ERR_NONE;
  684. }
  685. gNfcDev.isTechInit = false;
  686. rfalFieldOff();
  687. }
  688. return ERR_BUSY;
  689. #endif /* RFAL_FEATURE_NFC_DEP */
  690. }
  691. /*******************************************************************************/
  692. /* Passive NFC-A Technology Detection */
  693. /*******************************************************************************/
  694. if( ((gNfcDev.disc.techs2Find & RFAL_NFC_POLL_TECH_A) != 0U) && ((gNfcDev.techs2do & RFAL_NFC_POLL_TECH_A) != 0U) )
  695. {
  696. #if RFAL_FEATURE_NFCA
  697. rfalNfcaSensRes sensRes;
  698. if( !gNfcDev.isTechInit )
  699. {
  700. EXIT_ON_ERR( err, rfalNfcaPollerInitialize() ); /* Initialize RFAL for NFC-A */
  701. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* Turns the Field On and starts GT timer */
  702. gNfcDev.isTechInit = true;
  703. }
  704. if( rfalIsGTExpired() ) /* Wait until Guard Time is fulfilled */
  705. {
  706. err = rfalNfcaPollerTechnologyDetection( gNfcDev.disc.compMode, &sensRes );/* Poll for NFC-A devices */
  707. if( err == ERR_NONE )
  708. {
  709. gNfcDev.techsFound |= RFAL_NFC_POLL_TECH_A;
  710. }
  711. gNfcDev.isTechInit = false;
  712. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_A;
  713. }
  714. return ERR_BUSY;
  715. #endif /* RFAL_FEATURE_NFCA */
  716. }
  717. /*******************************************************************************/
  718. /* Passive NFC-B Technology Detection */
  719. /*******************************************************************************/
  720. if( ((gNfcDev.disc.techs2Find & RFAL_NFC_POLL_TECH_B) != 0U) && ((gNfcDev.techs2do & RFAL_NFC_POLL_TECH_B) != 0U) )
  721. {
  722. #if RFAL_FEATURE_NFCB
  723. rfalNfcbSensbRes sensbRes;
  724. uint8_t sensbResLen;
  725. if( !gNfcDev.isTechInit )
  726. {
  727. EXIT_ON_ERR( err, rfalNfcbPollerInitialize() ); /* Initialize RFAL for NFC-B */
  728. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* As field is already On only starts GT timer */
  729. gNfcDev.isTechInit = true;
  730. }
  731. if( rfalIsGTExpired() ) /* Wait until Guard Time is fulfilled */
  732. {
  733. err = rfalNfcbPollerTechnologyDetection( gNfcDev.disc.compMode, &sensbRes, &sensbResLen ); /* Poll for NFC-B devices */
  734. if( err == ERR_NONE )
  735. {
  736. gNfcDev.techsFound |= RFAL_NFC_POLL_TECH_B;
  737. }
  738. gNfcDev.isTechInit = false;
  739. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_B;
  740. }
  741. return ERR_BUSY;
  742. #endif /* RFAL_FEATURE_NFCB */
  743. }
  744. /*******************************************************************************/
  745. /* Passive NFC-F Technology Detection */
  746. /*******************************************************************************/
  747. if( ((gNfcDev.disc.techs2Find & RFAL_NFC_POLL_TECH_F) != 0U) && ((gNfcDev.techs2do & RFAL_NFC_POLL_TECH_F) != 0U) )
  748. {
  749. #if RFAL_FEATURE_NFCF
  750. if( !gNfcDev.isTechInit )
  751. {
  752. EXIT_ON_ERR( err, rfalNfcfPollerInitialize( gNfcDev.disc.nfcfBR ) ); /* Initialize RFAL for NFC-F */
  753. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* As field is already On only starts GT timer */
  754. gNfcDev.isTechInit = true;
  755. }
  756. if( rfalIsGTExpired() ) /* Wait until Guard Time is fulfilled */
  757. {
  758. err = rfalNfcfPollerCheckPresence(); /* Poll for NFC-F devices */
  759. if( err == ERR_NONE )
  760. {
  761. gNfcDev.techsFound |= RFAL_NFC_POLL_TECH_F;
  762. }
  763. gNfcDev.isTechInit = false;
  764. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_F;
  765. }
  766. return ERR_BUSY;
  767. #endif /* RFAL_FEATURE_NFCF */
  768. }
  769. /*******************************************************************************/
  770. /* Passive NFC-V Technology Detection */
  771. /*******************************************************************************/
  772. if( ((gNfcDev.disc.techs2Find & RFAL_NFC_POLL_TECH_V) != 0U) && ((gNfcDev.techs2do & RFAL_NFC_POLL_TECH_V) != 0U) )
  773. {
  774. #if RFAL_FEATURE_NFCV
  775. rfalNfcvInventoryRes invRes;
  776. if( !gNfcDev.isTechInit )
  777. {
  778. EXIT_ON_ERR( err, rfalNfcvPollerInitialize() ); /* Initialize RFAL for NFC-V */
  779. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* As field is already On only starts GT timer */
  780. gNfcDev.isTechInit = true;
  781. }
  782. if( rfalIsGTExpired() ) /* Wait until Guard Time is fulfilled */
  783. {
  784. err = rfalNfcvPollerCheckPresence( &invRes ); /* Poll for NFC-V devices */
  785. if( err == ERR_NONE )
  786. {
  787. gNfcDev.techsFound |= RFAL_NFC_POLL_TECH_V;
  788. }
  789. gNfcDev.isTechInit = false;
  790. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_V;
  791. }
  792. return ERR_BUSY;
  793. #endif /* RFAL_FEATURE_NFCV */
  794. }
  795. /*******************************************************************************/
  796. /* Passive Proprietary Technology ST25TB */
  797. /*******************************************************************************/
  798. if( ((gNfcDev.disc.techs2Find & RFAL_NFC_POLL_TECH_ST25TB) != 0U) && ((gNfcDev.techs2do & RFAL_NFC_POLL_TECH_ST25TB) != 0U) )
  799. {
  800. #if RFAL_FEATURE_ST25TB
  801. if( !gNfcDev.isTechInit )
  802. {
  803. EXIT_ON_ERR( err, rfalSt25tbPollerInitialize() ); /* Initialize RFAL for NFC-V */
  804. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* As field is already On only starts GT timer */
  805. gNfcDev.isTechInit = true;
  806. }
  807. if( rfalIsGTExpired() ) /* Wait until Guard Time is fulfilled */
  808. {
  809. err = rfalSt25tbPollerCheckPresence( NULL ); /* Poll for ST25TB devices */
  810. if( err == ERR_NONE )
  811. {
  812. gNfcDev.techsFound |= RFAL_NFC_POLL_TECH_ST25TB;
  813. }
  814. gNfcDev.isTechInit = false;
  815. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_ST25TB;
  816. }
  817. return ERR_BUSY;
  818. #endif /* RFAL_FEATURE_ST25TB */
  819. }
  820. return ERR_NONE;
  821. }
  822. /*!
  823. ******************************************************************************
  824. * \brief Poller Collision Resolution
  825. *
  826. * This method implements the Collision Resolution on all technologies that
  827. * have been detected before.
  828. *
  829. * \return ERR_NONE : Operation completed with no error
  830. * \return ERR_BUSY : Operation ongoing
  831. * \return ERR_XXXX : Error occurred
  832. *
  833. ******************************************************************************
  834. */
  835. static ReturnCode rfalNfcPollCollResolution( void )
  836. {
  837. uint8_t i;
  838. static uint8_t devCnt;
  839. ReturnCode err;
  840. err = ERR_NONE;
  841. i = 0;
  842. /* Supress warning when specific RFAL features have been disabled */
  843. NO_WARNING(err);
  844. NO_WARNING(devCnt);
  845. NO_WARNING(i);
  846. /* Check if device limit has been reached */
  847. if( gNfcDev.devCnt >= gNfcDev.disc.devLimit )
  848. {
  849. return ERR_NONE;
  850. }
  851. /*******************************************************************************/
  852. /* NFC-A Collision Resolution */
  853. /*******************************************************************************/
  854. #if RFAL_FEATURE_NFCA
  855. 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 */
  856. {
  857. static rfalNfcaListenDevice nfcaDevList[RFAL_NFC_MAX_DEVICES];
  858. if( !gNfcDev.isTechInit )
  859. {
  860. EXIT_ON_ERR( err, rfalNfcaPollerInitialize() ); /* Initialize RFAL for NFC-A */
  861. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* Turns the Field On and starts GT timer */
  862. gNfcDev.isTechInit = true; /* Technology has been initialized */
  863. gNfcDev.isOperOngoing = false; /* No operation currently ongoing */
  864. }
  865. if( !rfalIsGTExpired() )
  866. {
  867. return ERR_BUSY;
  868. }
  869. if( !gNfcDev.isOperOngoing )
  870. {
  871. EXIT_ON_ERR( err, rfalNfcaPollerStartFullCollisionResolution( gNfcDev.disc.compMode, (gNfcDev.disc.devLimit - gNfcDev.devCnt), nfcaDevList, &devCnt ) );
  872. gNfcDev.isOperOngoing = true;
  873. return ERR_BUSY;
  874. }
  875. err = rfalNfcaPollerGetFullCollisionResolutionStatus();
  876. if( err != ERR_BUSY )
  877. {
  878. gNfcDev.isTechInit = false;
  879. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_A;
  880. if( (err == ERR_NONE) && (devCnt != 0U) )
  881. {
  882. for( i=0; i<devCnt; i++ ) /* Copy devices found form local Nfca list into global device list */
  883. {
  884. gNfcDev.devList[gNfcDev.devCnt].type = RFAL_NFC_LISTEN_TYPE_NFCA;
  885. gNfcDev.devList[gNfcDev.devCnt].dev.nfca = nfcaDevList[i];
  886. gNfcDev.devCnt++;
  887. }
  888. }
  889. }
  890. return ERR_BUSY;
  891. }
  892. #endif /* RFAL_FEATURE_NFCA */
  893. /*******************************************************************************/
  894. /* NFC-B Collision Resolution */
  895. /*******************************************************************************/
  896. #if RFAL_FEATURE_NFCB
  897. 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 */
  898. {
  899. rfalNfcbListenDevice nfcbDevList[RFAL_NFC_MAX_DEVICES];
  900. if( !gNfcDev.isTechInit )
  901. {
  902. EXIT_ON_ERR( err, rfalNfcbPollerInitialize()); /* Initialize RFAL for NFC-B */
  903. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* Ensure GT again as other technologies have also been polled */
  904. gNfcDev.isTechInit = true;
  905. }
  906. if( !rfalIsGTExpired() )
  907. {
  908. return ERR_BUSY;
  909. }
  910. devCnt = 0;
  911. gNfcDev.isTechInit = false;
  912. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_B;
  913. err = rfalNfcbPollerCollisionResolution( gNfcDev.disc.compMode, (gNfcDev.disc.devLimit - gNfcDev.devCnt), nfcbDevList, &devCnt );
  914. if( (err == ERR_NONE) && (devCnt != 0U) )
  915. {
  916. for( i=0; i<devCnt; i++ ) /* Copy devices found form local Nfcb list into global device list */
  917. {
  918. gNfcDev.devList[gNfcDev.devCnt].type = RFAL_NFC_LISTEN_TYPE_NFCB;
  919. gNfcDev.devList[gNfcDev.devCnt].dev.nfcb = nfcbDevList[i];
  920. gNfcDev.devCnt++;
  921. }
  922. }
  923. return ERR_BUSY;
  924. }
  925. #endif /* RFAL_FEATURE_NFCB*/
  926. /*******************************************************************************/
  927. /* NFC-F Collision Resolution */
  928. /*******************************************************************************/
  929. #if RFAL_FEATURE_NFCF
  930. 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 */
  931. {
  932. rfalNfcfListenDevice nfcfDevList[RFAL_NFC_MAX_DEVICES];
  933. if( !gNfcDev.isTechInit )
  934. {
  935. EXIT_ON_ERR( err, rfalNfcfPollerInitialize( gNfcDev.disc.nfcfBR )); /* Initialize RFAL for NFC-F */
  936. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* Ensure GT again as other technologies have also been polled */
  937. gNfcDev.isTechInit = true;
  938. }
  939. if( !rfalIsGTExpired() )
  940. {
  941. return ERR_BUSY;
  942. }
  943. devCnt = 0;
  944. gNfcDev.isTechInit = false;
  945. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_F;
  946. err = rfalNfcfPollerCollisionResolution( gNfcDev.disc.compMode, (gNfcDev.disc.devLimit - gNfcDev.devCnt), nfcfDevList, &devCnt );
  947. if( (err == ERR_NONE) && (devCnt != 0U) )
  948. {
  949. for( i=0; i<devCnt; i++ ) /* Copy devices found form local Nfcf list into global device list */
  950. {
  951. gNfcDev.devList[gNfcDev.devCnt].type = RFAL_NFC_LISTEN_TYPE_NFCF;
  952. gNfcDev.devList[gNfcDev.devCnt].dev.nfcf = nfcfDevList[i];
  953. gNfcDev.devCnt++;
  954. }
  955. }
  956. return ERR_BUSY;
  957. }
  958. #endif /* RFAL_FEATURE_NFCF */
  959. /*******************************************************************************/
  960. /* NFC-V Collision Resolution */
  961. /*******************************************************************************/
  962. #if RFAL_FEATURE_NFCV
  963. 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 */
  964. {
  965. rfalNfcvListenDevice nfcvDevList[RFAL_NFC_MAX_DEVICES];
  966. if( !gNfcDev.isTechInit )
  967. {
  968. EXIT_ON_ERR( err, rfalNfcvPollerInitialize()); /* Initialize RFAL for NFC-V */
  969. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* Ensure GT again as other technologies have also been polled */
  970. gNfcDev.isTechInit = true;
  971. }
  972. if( !rfalIsGTExpired() )
  973. {
  974. return ERR_BUSY;
  975. }
  976. devCnt = 0;
  977. gNfcDev.isTechInit = false;
  978. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_V;
  979. err = rfalNfcvPollerCollisionResolution( RFAL_COMPLIANCE_MODE_NFC, (gNfcDev.disc.devLimit - gNfcDev.devCnt), nfcvDevList, &devCnt );
  980. if( (err == ERR_NONE) && (devCnt != 0U) )
  981. {
  982. for( i=0; i<devCnt; i++ ) /* Copy devices found form local Nfcf list into global device list */
  983. {
  984. gNfcDev.devList[gNfcDev.devCnt].type = RFAL_NFC_LISTEN_TYPE_NFCV;
  985. gNfcDev.devList[gNfcDev.devCnt].dev.nfcv = nfcvDevList[i];
  986. gNfcDev.devCnt++;
  987. }
  988. }
  989. return ERR_BUSY;
  990. }
  991. #endif /* RFAL_FEATURE_NFCV */
  992. /*******************************************************************************/
  993. /* ST25TB Collision Resolution */
  994. /*******************************************************************************/
  995. #if RFAL_FEATURE_ST25TB
  996. 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 */
  997. {
  998. rfalSt25tbListenDevice st25tbDevList[RFAL_NFC_MAX_DEVICES];
  999. if( !gNfcDev.isTechInit )
  1000. {
  1001. EXIT_ON_ERR( err, rfalSt25tbPollerInitialize() ); /* Initialize RFAL for ST25TB */
  1002. EXIT_ON_ERR( err, rfalFieldOnAndStartGT() ); /* Ensure GT again as other technologies have also been polled */
  1003. gNfcDev.isTechInit = true;
  1004. }
  1005. if( !rfalIsGTExpired() )
  1006. {
  1007. return ERR_BUSY;
  1008. }
  1009. devCnt = 0;
  1010. gNfcDev.isTechInit = false;
  1011. gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_ST25TB;
  1012. err = rfalSt25tbPollerCollisionResolution( (gNfcDev.disc.devLimit - gNfcDev.devCnt), st25tbDevList, &devCnt );
  1013. if( (err == ERR_NONE) && (devCnt != 0U) )
  1014. {
  1015. for( i=0; i<devCnt; i++ ) /* Copy devices found form local Nfcf list into global device list */
  1016. {
  1017. gNfcDev.devList[gNfcDev.devCnt].type = RFAL_NFC_LISTEN_TYPE_ST25TB;
  1018. gNfcDev.devList[gNfcDev.devCnt].dev.st25tb = st25tbDevList[i];
  1019. gNfcDev.devCnt++;
  1020. }
  1021. }
  1022. return ERR_BUSY;
  1023. }
  1024. #endif /* RFAL_FEATURE_ST25TB */
  1025. return ERR_NONE; /* All technologies have been performed */
  1026. }
  1027. /*!
  1028. ******************************************************************************
  1029. * \brief Poller Activation
  1030. *
  1031. * This method Activates a given device according to it's type and
  1032. * protocols supported
  1033. *
  1034. * \param[in] devIt : device's position on the list to be activated
  1035. *
  1036. * \return ERR_NONE : Operation completed with no error
  1037. * \return ERR_BUSY : Operation ongoing
  1038. * \return ERR_XXXX : Error occurred
  1039. *
  1040. ******************************************************************************
  1041. */
  1042. static ReturnCode rfalNfcPollActivation( uint8_t devIt )
  1043. {
  1044. ReturnCode err;
  1045. err = ERR_NONE;
  1046. /* Supress warning when specific RFAL features have been disabled */
  1047. NO_WARNING(err);
  1048. if( devIt > gNfcDev.devCnt )
  1049. {
  1050. return ERR_WRONG_STATE;
  1051. }
  1052. switch( gNfcDev.devList[devIt].type )
  1053. {
  1054. /*******************************************************************************/
  1055. /* AP2P Activation */
  1056. /*******************************************************************************/
  1057. #if RFAL_FEATURE_NFC_DEP
  1058. case RFAL_NFC_LISTEN_TYPE_AP2P:
  1059. /* Activation has already been perfomed (ATR_REQ) */
  1060. gNfcDev.devList[devIt].nfcid = gNfcDev.devList[devIt].proto.nfcDep.activation.Target.ATR_RES.NFCID3;
  1061. gNfcDev.devList[devIt].nfcidLen = RFAL_NFCDEP_NFCID3_LEN;
  1062. break;
  1063. #endif /* RFAL_FEATURE_NFC_DEP */
  1064. /*******************************************************************************/
  1065. /* Passive NFC-A Activation */
  1066. /*******************************************************************************/
  1067. #if RFAL_FEATURE_NFCA
  1068. case RFAL_NFC_LISTEN_TYPE_NFCA:
  1069. if( !gNfcDev.isTechInit )
  1070. {
  1071. rfalNfcaPollerInitialize();
  1072. gNfcDev.isTechInit = true;
  1073. gNfcDev.isOperOngoing = false;
  1074. return ERR_BUSY;
  1075. }
  1076. if( gNfcDev.devList[devIt].dev.nfca.isSleep ) /* Check if desired device is in Sleep */
  1077. {
  1078. rfalNfcaSensRes sensRes;
  1079. rfalNfcaSelRes selRes;
  1080. if( !gNfcDev.isOperOngoing )
  1081. {
  1082. /* Wake up all cards */
  1083. EXIT_ON_ERR( err, rfalNfcaPollerCheckPresence( RFAL_14443A_SHORTFRAME_CMD_WUPA, &sensRes ) );
  1084. gNfcDev.isOperOngoing = true;
  1085. }
  1086. else
  1087. {
  1088. /* Select specific device */
  1089. EXIT_ON_ERR( err, rfalNfcaPollerSelect( gNfcDev.devList[devIt].dev.nfca.nfcId1, gNfcDev.devList[devIt].dev.nfca.nfcId1Len, &selRes ) );
  1090. gNfcDev.devList[devIt].dev.nfca.isSleep = false;
  1091. gNfcDev.isOperOngoing = false;
  1092. }
  1093. return ERR_BUSY;
  1094. }
  1095. /* Set NFCID */
  1096. gNfcDev.devList[devIt].nfcid = gNfcDev.devList[devIt].dev.nfca.nfcId1;
  1097. gNfcDev.devList[devIt].nfcidLen = gNfcDev.devList[devIt].dev.nfca.nfcId1Len;
  1098. /*******************************************************************************/
  1099. /* Perform protocol specific activation */
  1100. switch( gNfcDev.devList[devIt].dev.nfca.type )
  1101. {
  1102. /*******************************************************************************/
  1103. case RFAL_NFCA_T1T:
  1104. /* No further activation needed for T1T (RID already performed) */
  1105. gNfcDev.devList[devIt].nfcid = gNfcDev.devList[devIt].dev.nfca.ridRes.uid;
  1106. gNfcDev.devList[devIt].nfcidLen = RFAL_T1T_UID_LEN;
  1107. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_RF;
  1108. break;
  1109. case RFAL_NFCA_T2T:
  1110. /* No further activation needed for a T2T */
  1111. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_RF;
  1112. break;
  1113. /*******************************************************************************/
  1114. case RFAL_NFCA_T4T: /* Device supports ISO-DEP */
  1115. #if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_POLL
  1116. if( !gNfcDev.isOperOngoing )
  1117. {
  1118. /* Perform ISO-DEP (ISO14443-4) activation: RATS and PPS if supported */
  1119. rfalIsoDepInitialize();
  1120. EXIT_ON_ERR( err, rfalIsoDepPollAStartActivation( (rfalIsoDepFSxI)RFAL_ISODEP_FSDI_DEFAULT, RFAL_ISODEP_NO_DID, gNfcDev.disc.maxBR, &gNfcDev.devList[devIt].proto.isoDep ) );
  1121. gNfcDev.isOperOngoing = true;
  1122. return ERR_BUSY;
  1123. }
  1124. err = rfalIsoDepPollAGetActivationStatus();
  1125. if( err != ERR_NONE )
  1126. {
  1127. return err;
  1128. }
  1129. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_ISODEP; /* NFC-A T4T device activated */
  1130. #else
  1131. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_RF; /* No ISO-DEP supported activate using RF interface */
  1132. #endif /* RFAL_FEATURE_ISO_DEP_POLL */
  1133. break;
  1134. /*******************************************************************************/
  1135. case RFAL_NFCA_T4T_NFCDEP: /* Device supports both T4T and NFC-DEP */
  1136. case RFAL_NFCA_NFCDEP: /* Device supports NFC-DEP */
  1137. #if RFAL_FEATURE_NFC_DEP
  1138. /* Perform NFC-DEP (P2P) activation: ATR and PSL if supported */
  1139. EXIT_ON_ERR( err, rfalNfcNfcDepActivate( &gNfcDev.devList[devIt], RFAL_NFCDEP_COMM_PASSIVE, NULL, 0 ) );
  1140. gNfcDev.devList[devIt].nfcid = gNfcDev.devList[devIt].proto.nfcDep.activation.Target.ATR_RES.NFCID3;
  1141. gNfcDev.devList[devIt].nfcidLen = RFAL_NFCDEP_NFCID3_LEN;
  1142. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_NFCDEP; /* NFC-A P2P device activated */
  1143. #else
  1144. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_RF; /* No NFC-DEP supported activate using RF interface */
  1145. #endif /* RFAL_FEATURE_NFC_DEP */
  1146. break;
  1147. /*******************************************************************************/
  1148. default:
  1149. return ERR_WRONG_STATE;
  1150. }
  1151. break;
  1152. #endif /* RFAL_FEATURE_NFCA */
  1153. /*******************************************************************************/
  1154. /* Passive NFC-B Activation */
  1155. /*******************************************************************************/
  1156. #if RFAL_FEATURE_NFCB
  1157. case RFAL_NFC_LISTEN_TYPE_NFCB:
  1158. if( !gNfcDev.isTechInit )
  1159. {
  1160. rfalNfcbPollerInitialize();
  1161. gNfcDev.isTechInit = true;
  1162. gNfcDev.isOperOngoing = false;
  1163. return ERR_BUSY;
  1164. }
  1165. if( gNfcDev.devList[devIt].dev.nfcb.isSleep ) /* Check if desired device is in Sleep */
  1166. {
  1167. rfalNfcbSensbRes sensbRes;
  1168. uint8_t sensbResLen;
  1169. /* 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 */
  1170. rfalNfcbPollerCheckPresence( RFAL_NFCB_SENS_CMD_ALLB_REQ, RFAL_NFCB_SLOT_NUM_1, &sensbRes, &sensbResLen );
  1171. }
  1172. /* Set NFCID */
  1173. gNfcDev.devList[devIt].nfcid = gNfcDev.devList[devIt].dev.nfcb.sensbRes.nfcid0;
  1174. gNfcDev.devList[devIt].nfcidLen = RFAL_NFCB_NFCID0_LEN;
  1175. #if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_POLL
  1176. /* Check if device supports ISO-DEP (ISO14443-4) */
  1177. if( (gNfcDev.devList[devIt].dev.nfcb.sensbRes.protInfo.FsciProType & RFAL_NFCB_SENSB_RES_PROTO_ISO_MASK) != 0U )
  1178. {
  1179. if( !gNfcDev.isOperOngoing )
  1180. {
  1181. rfalIsoDepInitialize();
  1182. /* Perform ISO-DEP (ISO14443-4) activation: ATTRIB */
  1183. 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 ) );
  1184. gNfcDev.isOperOngoing = true;
  1185. return ERR_BUSY;
  1186. }
  1187. err = rfalIsoDepPollBGetActivationStatus();
  1188. if( err != ERR_NONE )
  1189. {
  1190. return err;
  1191. }
  1192. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_ISODEP; /* NFC-B T4T device activated */
  1193. break;
  1194. }
  1195. #endif /* RFAL_FEATURE_ISO_DEP_POLL */
  1196. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_RF; /* NFC-B device activated */
  1197. break;
  1198. #endif /* RFAL_FEATURE_NFCB */
  1199. /*******************************************************************************/
  1200. /* Passive NFC-F Activation */
  1201. /*******************************************************************************/
  1202. #if RFAL_FEATURE_NFCF
  1203. case RFAL_NFC_LISTEN_TYPE_NFCF:
  1204. rfalNfcfPollerInitialize( gNfcDev.disc.nfcfBR );
  1205. #if RFAL_FEATURE_NFC_DEP
  1206. if( rfalNfcfIsNfcDepSupported( &gNfcDev.devList[devIt].dev.nfcf ) )
  1207. {
  1208. /* Perform NFC-DEP (P2P) activation: ATR and PSL if supported */
  1209. EXIT_ON_ERR( err, rfalNfcNfcDepActivate( &gNfcDev.devList[devIt], RFAL_NFCDEP_COMM_PASSIVE, NULL, 0 ) );
  1210. /* Set NFCID */
  1211. gNfcDev.devList[devIt].nfcid = gNfcDev.devList[devIt].proto.nfcDep.activation.Target.ATR_RES.NFCID3;
  1212. gNfcDev.devList[devIt].nfcidLen = RFAL_NFCDEP_NFCID3_LEN;
  1213. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_NFCDEP; /* NFC-F P2P device activated */
  1214. break;
  1215. }
  1216. #endif /* RFAL_FEATURE_NFC_DEP */
  1217. /* Set NFCID */
  1218. gNfcDev.devList[devIt].nfcid = gNfcDev.devList[devIt].dev.nfcf.sensfRes.NFCID2;
  1219. gNfcDev.devList[devIt].nfcidLen = RFAL_NFCF_NFCID2_LEN;
  1220. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_RF; /* NFC-F T3T device activated */
  1221. break;
  1222. #endif /* RFAL_FEATURE_NFCF */
  1223. /*******************************************************************************/
  1224. /* Passive NFC-V Activation */
  1225. /*******************************************************************************/
  1226. #if RFAL_FEATURE_NFCV
  1227. case RFAL_NFC_LISTEN_TYPE_NFCV:
  1228. rfalNfcvPollerInitialize();
  1229. /* No specific activation needed for a T5T */
  1230. /* Set NFCID */
  1231. gNfcDev.devList[devIt].nfcid = gNfcDev.devList[devIt].dev.nfcv.InvRes.UID;
  1232. gNfcDev.devList[devIt].nfcidLen = RFAL_NFCV_UID_LEN;
  1233. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_RF; /* NFC-V T5T device activated */
  1234. break;
  1235. #endif /* RFAL_FEATURE_NFCV */
  1236. /*******************************************************************************/
  1237. /* Passive ST25TB Activation */
  1238. /*******************************************************************************/
  1239. #if RFAL_FEATURE_ST25TB
  1240. case RFAL_NFC_LISTEN_TYPE_ST25TB:
  1241. rfalSt25tbPollerInitialize();
  1242. /* No specific activation needed for a ST25TB */
  1243. /* Set NFCID */
  1244. gNfcDev.devList[devIt].nfcid = gNfcDev.devList[devIt].dev.st25tb.UID;
  1245. gNfcDev.devList[devIt].nfcidLen = RFAL_ST25TB_UID_LEN;
  1246. gNfcDev.devList[devIt].rfInterface = RFAL_NFC_INTERFACE_RF; /* ST25TB device activated */
  1247. break;
  1248. #endif /* RFAL_FEATURE_ST25TB */
  1249. /*******************************************************************************/
  1250. default:
  1251. return ERR_WRONG_STATE;
  1252. }
  1253. gNfcDev.activeDev = &gNfcDev.devList[devIt]; /* Assign active device to be used further on */
  1254. return ERR_NONE;
  1255. }
  1256. /*!
  1257. ******************************************************************************
  1258. * \brief Listener Activation
  1259. *
  1260. * This method handles the listen mode Activation according to the different
  1261. * protocols the Reader/Initiator performs
  1262. *
  1263. * \return ERR_NONE : Operation completed with no error
  1264. * \return ERR_BUSY : Operation ongoing
  1265. * \return ERR_PROTO : Unexpected frame received
  1266. * \return ERR_XXXX : Error occurred
  1267. *
  1268. ******************************************************************************
  1269. */
  1270. #if RFAL_FEATURE_LISTEN_MODE
  1271. static ReturnCode rfalNfcListenActivation( void )
  1272. {
  1273. bool isDataRcvd;
  1274. ReturnCode ret;
  1275. rfalLmState lmSt;
  1276. rfalBitRate bitRate;
  1277. #if RFAL_FEATURE_NFC_DEP
  1278. uint8_t hdrLen;
  1279. /* Set the header length in NFC-A */
  1280. hdrLen = (RFAL_NFCDEP_SB_LEN + RFAL_NFCDEP_LEN_LEN);
  1281. #endif /* RFAL_FEATURE_NFC_DEP */
  1282. lmSt = rfalListenGetState( &isDataRcvd, &bitRate );
  1283. switch(lmSt)
  1284. {
  1285. #if RFAL_FEATURE_NFCA
  1286. /*******************************************************************************/
  1287. case RFAL_LM_STATE_ACTIVE_A: /* NFC-A CE activation */
  1288. case RFAL_LM_STATE_ACTIVE_Ax:
  1289. if( isDataRcvd ) /* Check if Reader/Initator has sent some data */
  1290. {
  1291. /* Check if received data is a Sleep request */
  1292. if( rfalNfcaListenerIsSleepReq( gNfcDev.rxBuf.rfBuf, rfalConvBitsToBytes(gNfcDev.rxLen)) ) /* Check if received data is a SLP_REQ */
  1293. {
  1294. /* Set the Listen Mode in Sleep state */
  1295. EXIT_ON_ERR( ret, rfalListenSleepStart( RFAL_LM_STATE_SLEEP_A, gNfcDev.rxBuf.rfBuf, sizeof(gNfcDev.rxBuf.rfBuf), &gNfcDev.rxLen ) );
  1296. }
  1297. else if(gNfcDev.disc.activate_after_sak) {
  1298. gNfcDev.devList->type = RFAL_NFC_POLL_TYPE_NFCA;
  1299. rfalListenSetState(RFAL_LM_STATE_ACTIVE_A);
  1300. return ERR_NONE;
  1301. }
  1302. #if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_LISTEN
  1303. /* Check if received data is a valid RATS */
  1304. else if( rfalIsoDepIsRats( gNfcDev.rxBuf.rfBuf, (uint8_t)rfalConvBitsToBytes(gNfcDev.rxLen) ) )
  1305. {
  1306. rfalIsoDepAtsParam atsParam;
  1307. rfalIsoDepListenActvParam rxParam;
  1308. /* Set ATS parameters */
  1309. atsParam.fsci = (uint8_t)RFAL_ISODEP_DEFAULT_FSCI;
  1310. atsParam.fwi = RFAL_ISODEP_DEFAULT_FWI;
  1311. atsParam.sfgi = RFAL_ISODEP_DEFAULT_SFGI;
  1312. atsParam.didSupport = false;
  1313. atsParam.ta = RFAL_ISODEP_ATS_TA_SAME_D;
  1314. atsParam.hb = NULL;
  1315. atsParam.hbLen = 0;
  1316. /* Set Rx parameters */
  1317. rxParam.rxBuf = (rfalIsoDepBufFormat*) &gNfcDev.rxBuf.isoDepBuf; /* PRQA S 0310 # MISRA 11.3 - Intentional safe cast to avoiding large buffer duplication */
  1318. rxParam.rxLen = &gNfcDev.rxLen;
  1319. rxParam.isoDepDev = &gNfcDev.devList->proto.isoDep;
  1320. rxParam.isRxChaining = &gNfcDev.isRxChaining;
  1321. rfalListenSetState( RFAL_LM_STATE_CARDEMU_4A ); /* Set next state CE T4T */
  1322. rfalIsoDepInitialize(); /* Initialize ISO-DEP layer to handle ISO14443-a activation / RATS */
  1323. /* Set ISO-DEP layer to digest RATS and handle activation */
  1324. EXIT_ON_ERR( ret, rfalIsoDepListenStartActivation( &atsParam, NULL, gNfcDev.rxBuf.rfBuf, gNfcDev.rxLen, rxParam ) );
  1325. }
  1326. #endif /* RFAL_FEATURE_ISO_DEP_LISTEN */
  1327. #if RFAL_FEATURE_NFC_DEP
  1328. /* Check if received data is a valid ATR_REQ */
  1329. else if( rfalNfcDepIsAtrReq( &gNfcDev.rxBuf.rfBuf[hdrLen], (rfalConvBitsToBytes(gNfcDev.rxLen) - hdrLen), gNfcDev.devList->nfcid ) )
  1330. {
  1331. gNfcDev.devList->type = RFAL_NFC_POLL_TYPE_NFCA;
  1332. EXIT_ON_ERR( ret, rfalNfcNfcDepActivate( gNfcDev.devList, RFAL_NFCDEP_COMM_PASSIVE, &gNfcDev.rxBuf.rfBuf[hdrLen], (rfalConvBitsToBytes(gNfcDev.rxLen) - hdrLen) ) );
  1333. }
  1334. #endif /* RFAL_FEATURE_NFC_DEP */
  1335. else
  1336. {
  1337. return ERR_PROTO;
  1338. }
  1339. }
  1340. return ERR_BUSY;
  1341. #endif /* RFAL_FEATURE_NFCA */
  1342. #if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_LISTEN
  1343. /*******************************************************************************/
  1344. case RFAL_LM_STATE_CARDEMU_4A: /* T4T ISO-DEP activation */
  1345. ret = rfalIsoDepListenGetActivationStatus();
  1346. if( ret == ERR_NONE )
  1347. {
  1348. gNfcDev.devList->type = RFAL_NFC_POLL_TYPE_NFCA;
  1349. gNfcDev.devList->rfInterface = RFAL_NFC_INTERFACE_ISODEP;
  1350. gNfcDev.devList->nfcid = NULL;
  1351. gNfcDev.devList->nfcidLen = 0;
  1352. }
  1353. return ret;
  1354. #endif /* RFAL_FEATURE_ISO_DEP_LISTEN */
  1355. /*******************************************************************************/
  1356. case RFAL_LM_STATE_READY_F: /* NFC-F CE activation */
  1357. if( isDataRcvd ) /* Wait for the first received data */
  1358. {
  1359. #if RFAL_FEATURE_NFC_DEP
  1360. /* Set the header length in NFC-F */
  1361. hdrLen = RFAL_NFCDEP_LEN_LEN;
  1362. if( rfalNfcDepIsAtrReq( &gNfcDev.rxBuf.rfBuf[hdrLen], (rfalConvBitsToBytes(gNfcDev.rxLen) - hdrLen), gNfcDev.devList->nfcid ) )
  1363. {
  1364. gNfcDev.devList->type = RFAL_NFC_POLL_TYPE_NFCF;
  1365. EXIT_ON_ERR( ret, rfalNfcNfcDepActivate( gNfcDev.devList, RFAL_NFCDEP_COMM_PASSIVE, &gNfcDev.rxBuf.rfBuf[hdrLen], (rfalConvBitsToBytes(gNfcDev.rxLen) - hdrLen) ) );
  1366. }
  1367. else
  1368. #endif /* RFAL_FEATURE_NFC_DEP */
  1369. {
  1370. rfalListenSetState( RFAL_LM_STATE_CARDEMU_3 ); /* First data already received - set T3T CE */
  1371. }
  1372. }
  1373. return ERR_BUSY;
  1374. /*******************************************************************************/
  1375. case RFAL_LM_STATE_CARDEMU_3: /* T3T activated */
  1376. gNfcDev.devList->type = RFAL_NFC_POLL_TYPE_NFCF;
  1377. gNfcDev.devList->rfInterface = RFAL_NFC_INTERFACE_RF;
  1378. gNfcDev.devList->nfcid = NULL;
  1379. gNfcDev.devList->nfcidLen = 0;
  1380. return ERR_NONE;
  1381. #if RFAL_FEATURE_NFC_DEP
  1382. /*******************************************************************************/
  1383. case RFAL_LM_STATE_TARGET_A: /* NFC-DEP activation */
  1384. case RFAL_LM_STATE_TARGET_F:
  1385. ret = rfalNfcDepListenGetActivationStatus();
  1386. if( ret == ERR_NONE )
  1387. {
  1388. gNfcDev.devList->rfInterface = RFAL_NFC_INTERFACE_NFCDEP;
  1389. gNfcDev.devList->nfcidLen = RFAL_NFCDEP_NFCID3_LEN;
  1390. }
  1391. return ret;
  1392. #endif /* RFAL_FEATURE_NFC_DEP */
  1393. /*******************************************************************************/
  1394. case RFAL_LM_STATE_IDLE: /* AP2P activation */
  1395. if( isDataRcvd ) /* Check if Reader/Initator has sent some data */
  1396. {
  1397. if( (gNfcDev.lmMask & RFAL_LM_MASK_ACTIVE_P2P) != 0U ) /* Check if AP2P is enabled */
  1398. {
  1399. #if RFAL_FEATURE_NFC_DEP
  1400. /* Calculate the header length in NFC-A or NFC-F mode*/
  1401. hdrLen = ( (bitRate == RFAL_BR_106) ? (RFAL_NFCDEP_SB_LEN + RFAL_NFCDEP_LEN_LEN) : RFAL_NFCDEP_LEN_LEN );
  1402. if( rfalNfcDepIsAtrReq( &gNfcDev.rxBuf.rfBuf[hdrLen], (rfalConvBitsToBytes(gNfcDev.rxLen) - hdrLen), NULL) )
  1403. {
  1404. gNfcDev.devList->type = RFAL_NFC_POLL_TYPE_AP2P;
  1405. rfalSetMode( (RFAL_MODE_LISTEN_ACTIVE_P2P), bitRate, bitRate );
  1406. EXIT_ON_ERR( ret, rfalNfcNfcDepActivate( gNfcDev.devList, RFAL_NFCDEP_COMM_ACTIVE, &gNfcDev.rxBuf.rfBuf[hdrLen], (rfalConvBitsToBytes(gNfcDev.rxLen) - hdrLen) ) );
  1407. }
  1408. else
  1409. #endif /* RFAL_FEATURE_NFC_DEP */
  1410. {
  1411. return ERR_PROTO;
  1412. }
  1413. }
  1414. }
  1415. return ERR_BUSY;
  1416. /*******************************************************************************/
  1417. case RFAL_LM_STATE_READY_A:
  1418. case RFAL_LM_STATE_READY_Ax:
  1419. case RFAL_LM_STATE_SLEEP_A:
  1420. case RFAL_LM_STATE_SLEEP_AF:
  1421. return ERR_BUSY;
  1422. /*******************************************************************************/
  1423. case RFAL_LM_STATE_POWER_OFF:
  1424. return ERR_LINK_LOSS;
  1425. default: /* Wait for activation */
  1426. break;
  1427. }
  1428. return ERR_INTERNAL;
  1429. }
  1430. #endif /* RFAL_FEATURE_LISTEN_MODE */
  1431. /*!
  1432. ******************************************************************************
  1433. * \brief Poller NFC DEP Activate
  1434. *
  1435. * This method performs NFC-DEP Activation
  1436. *
  1437. * \param[in] device : device info
  1438. * \param[in] commMode : communication mode (Passive/Active)
  1439. * \param[in] atrReq : received ATR_REQ
  1440. * \param[in] atrReqLen : received ATR_REQ size
  1441. *
  1442. * \return ERR_NONE : Operation completed with no error
  1443. * \return ERR_BUSY : Operation ongoing
  1444. * \return ERR_XXXX : Error occurred
  1445. *
  1446. ******************************************************************************
  1447. */
  1448. #if RFAL_FEATURE_NFC_DEP
  1449. static ReturnCode rfalNfcNfcDepActivate( rfalNfcDevice *device, rfalNfcDepCommMode commMode, const uint8_t *atrReq, uint16_t atrReqLen )
  1450. {
  1451. rfalNfcDepAtrParam initParam;
  1452. /* Supress warnings if Listen mode is disabled */
  1453. NO_WARNING(atrReq);
  1454. NO_WARNING(atrReqLen);
  1455. /* If we are in Poll mode */
  1456. if( rfalNfcIsRemDevListener( device->type ) )
  1457. {
  1458. /*******************************************************************************/
  1459. /* If Passive F use the NFCID2 retrieved from SENSF */
  1460. if( device->type == RFAL_NFC_LISTEN_TYPE_NFCF )
  1461. {
  1462. initParam.nfcid = device->dev.nfcf.sensfRes.NFCID2;
  1463. initParam.nfcidLen = RFAL_NFCF_NFCID2_LEN;
  1464. }
  1465. else
  1466. {
  1467. initParam.nfcid = gNfcDev.disc.nfcid3;
  1468. initParam.nfcidLen = RFAL_NFCDEP_NFCID3_LEN;
  1469. }
  1470. initParam.BS = RFAL_NFCDEP_Bx_NO_HIGH_BR;
  1471. initParam.BR = RFAL_NFCDEP_Bx_NO_HIGH_BR;
  1472. initParam.DID = RFAL_NFCDEP_DID_NO;
  1473. initParam.NAD = RFAL_NFCDEP_NAD_NO;
  1474. initParam.LR = RFAL_NFCDEP_LR_254;
  1475. initParam.GB = gNfcDev.disc.GB;
  1476. initParam.GBLen = gNfcDev.disc.GBLen;
  1477. initParam.commMode = commMode;
  1478. 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);
  1479. rfalNfcDepInitialize();
  1480. /* Perform NFC-DEP (P2P) activation: ATR and PSL if supported */
  1481. return rfalNfcDepInitiatorHandleActivation( &initParam, gNfcDev.disc.maxBR, &device->proto.nfcDep );
  1482. }
  1483. /* If we are in Listen mode */
  1484. #if RFAL_FEATURE_LISTEN_MODE
  1485. else if( rfalNfcIsRemDevPoller( device->type ) )
  1486. {
  1487. rfalNfcDepListenActvParam actvParams;
  1488. rfalNfcDepTargetParam targetParam;
  1489. ST_MEMCPY(targetParam.nfcid3, (uint8_t*)gNfcDev.disc.nfcid3, RFAL_NFCDEP_NFCID3_LEN);
  1490. targetParam.bst = RFAL_NFCDEP_Bx_NO_HIGH_BR;
  1491. targetParam.brt = RFAL_NFCDEP_Bx_NO_HIGH_BR;
  1492. targetParam.to = RFAL_NFCDEP_WT_TRG_MAX_L13; /* [LLCP] 1.3 6.2.1 */
  1493. targetParam.ppt = rfalNfcDepLR2PP(RFAL_NFCDEP_LR_254);
  1494. if( gNfcDev.disc.GBLen >= RFAL_NFCDEP_GB_MAX_LEN )
  1495. {
  1496. return ERR_PARAM;
  1497. }
  1498. targetParam.GBtLen = gNfcDev.disc.GBLen;
  1499. if( gNfcDev.disc.GBLen > 0U )
  1500. {
  1501. ST_MEMCPY(targetParam.GBt, gNfcDev.disc.GB, gNfcDev.disc.GBLen);
  1502. }
  1503. 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);
  1504. targetParam.commMode = commMode;
  1505. /* Set activation buffer (including header) for NFC-DEP */
  1506. actvParams.rxBuf = (rfalNfcDepBufFormat*) &gNfcDev.rxBuf.nfcDepBuf; /* PRQA S 0310 # MISRA 11.3 - Intentional safe cast to avoiding large buffer duplication */
  1507. actvParams.rxLen = &gNfcDev.rxLen;
  1508. actvParams.isRxChaining = &gNfcDev.isRxChaining;
  1509. actvParams.nfcDepDev = &gNfcDev.devList->proto.nfcDep;
  1510. rfalListenSetState( ((device->type == RFAL_NFC_POLL_TYPE_NFCA) ? RFAL_LM_STATE_TARGET_A : RFAL_LM_STATE_TARGET_F) );
  1511. rfalNfcDepInitialize();
  1512. /* Perform NFC-DEP (P2P) activation: send ATR_RES and handle activation */
  1513. return rfalNfcDepListenStartActivation( &targetParam, atrReq, atrReqLen, actvParams );
  1514. }
  1515. #endif /* RFAL_FEATURE_LISTEN_MODE */
  1516. else
  1517. {
  1518. return ERR_INTERNAL;
  1519. }
  1520. }
  1521. #endif /* RFAL_FEATURE_NFC_DEP */
  1522. /*!
  1523. ******************************************************************************
  1524. * \brief Poller NFC Deactivate
  1525. *
  1526. * This method Deactivates the device if a deactivation procedure exists
  1527. *
  1528. * \return ERR_NONE : Operation completed with no error
  1529. * \return ERR_BUSY : Operation ongoing
  1530. * \return ERR_XXXX : Error occurred
  1531. *
  1532. ******************************************************************************
  1533. */
  1534. static ReturnCode rfalNfcDeactivation( void )
  1535. {
  1536. /* Check if a device has been activated */
  1537. if( gNfcDev.activeDev != NULL )
  1538. {
  1539. if( rfalNfcIsRemDevListener( gNfcDev.activeDev->type ) ) /* Listen mode no additional deactivation to be performed*/
  1540. {
  1541. #ifndef RFAL_NFC_SKIP_DEACT
  1542. switch( gNfcDev.activeDev->rfInterface )
  1543. {
  1544. /*******************************************************************************/
  1545. case RFAL_NFC_INTERFACE_RF:
  1546. break; /* No specific deactivation to be performed */
  1547. /*******************************************************************************/
  1548. #if RFAL_FEATURE_ISO_DEP && RFAL_FEATURE_ISO_DEP_POLL
  1549. case RFAL_NFC_INTERFACE_ISODEP:
  1550. rfalIsoDepDeselect(); /* Send a Deselect to device */
  1551. break;
  1552. #endif /* RFAL_FEATURE_ISO_DEP_POLL */
  1553. /*******************************************************************************/
  1554. #if RFAL_FEATURE_NFC_DEP
  1555. case RFAL_NFC_INTERFACE_NFCDEP:
  1556. switch ( gNfcDev.activeDev->type )
  1557. {
  1558. case RFAL_NFC_LISTEN_TYPE_AP2P:
  1559. rfalNfcDepRLS(); /* Send a Release to device */
  1560. break;
  1561. default:
  1562. rfalNfcDepDSL(); /* Send a Deselect to device */
  1563. break;
  1564. }
  1565. break;
  1566. #endif /* RFAL_FEATURE_NFC_DEP */
  1567. default:
  1568. return ERR_REQUEST;
  1569. }
  1570. #endif /* RFAL_NFC_SKIP_DEACT */
  1571. }
  1572. }
  1573. #if RFAL_FEATURE_WAKEUP_MODE
  1574. rfalWakeUpModeStop();
  1575. #endif /* RFAL_FEATURE_WAKEUP_MODE */
  1576. #if RFAL_FEATURE_LISTEN_MODE
  1577. rfalListenStop();
  1578. #else
  1579. rfalFieldOff();
  1580. #endif
  1581. gNfcDev.activeDev = NULL;
  1582. return ERR_NONE;
  1583. }