rfal_nfca.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. /******************************************************************************
  2. * \attention
  3. *
  4. * <h2><center>&copy; COPYRIGHT 2020 STMicroelectronics</center></h2>
  5. *
  6. * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
  7. * You may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at:
  9. *
  10. * www.st.com/myliberty
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
  15. * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. *
  20. ******************************************************************************/
  21. /*
  22. * PROJECT: ST25R391x firmware
  23. * Revision:
  24. * LANGUAGE: ISO C99
  25. */
  26. /*! \file rfal_nfca.c
  27. *
  28. * \author Gustavo Patricio
  29. *
  30. * \brief Provides several NFC-A convenience methods and definitions
  31. *
  32. * It provides a Poller (ISO14443A PCD) interface and as well as
  33. * some NFC-A Listener (ISO14443A PICC) helpers.
  34. *
  35. * The definitions and helpers methods provided by this module are only
  36. * up to ISO14443-3 layer
  37. *
  38. */
  39. /*
  40. ******************************************************************************
  41. * INCLUDES
  42. ******************************************************************************
  43. */
  44. #include "rfal_nfca.h"
  45. #include "utils.h"
  46. /*
  47. ******************************************************************************
  48. * ENABLE SWITCH
  49. ******************************************************************************
  50. */
  51. #ifndef RFAL_FEATURE_NFCA
  52. #define RFAL_FEATURE_NFCA false /* NFC-A module configuration missing. Disabled by default */
  53. #endif
  54. #if RFAL_FEATURE_NFCA
  55. /*
  56. ******************************************************************************
  57. * GLOBAL DEFINES
  58. ******************************************************************************
  59. */
  60. #define RFAL_NFCA_SLP_FWT rfalConvMsTo1fc(1) /*!< Check 1ms for any modulation ISO14443-3 6.4.3 */
  61. #define RFAL_NFCA_SLP_CMD 0x50U /*!< SLP cmd (byte1) Digital 1.1 6.9.1 & Table 20 */
  62. #define RFAL_NFCA_SLP_BYTE2 0x00U /*!< SLP byte2 Digital 1.1 6.9.1 & Table 20 */
  63. #define RFAL_NFCA_SLP_CMD_POS 0U /*!< SLP cmd position Digital 1.1 6.9.1 & Table 20 */
  64. #define RFAL_NFCA_SLP_BYTE2_POS 1U /*!< SLP byte2 position Digital 1.1 6.9.1 & Table 20 */
  65. #define RFAL_NFCA_SDD_CT 0x88U /*!< Cascade Tag value Digital 1.1 6.7.2 */
  66. #define RFAL_NFCA_SDD_CT_LEN 1U /*!< Cascade Tag length */
  67. #define RFAL_NFCA_SLP_REQ_LEN 2U /*!< SLP_REQ length */
  68. #define RFAL_NFCA_SEL_CMD_LEN 1U /*!< SEL_CMD length */
  69. #define RFAL_NFCA_SEL_PAR_LEN 1U /*!< SEL_PAR length */
  70. #define RFAL_NFCA_SEL_SELPAR rfalNfcaSelPar(7U, 0U)/*!< SEL_PAR on Select is always with 4 data/nfcid */
  71. #define RFAL_NFCA_BCC_LEN 1U /*!< BCC length */
  72. #define RFAL_NFCA_SDD_REQ_LEN (RFAL_NFCA_SEL_CMD_LEN + RFAL_NFCA_SEL_PAR_LEN) /*!< SDD_REQ length */
  73. #define RFAL_NFCA_SDD_RES_LEN (RFAL_NFCA_CASCADE_1_UID_LEN + RFAL_NFCA_BCC_LEN) /*!< SDD_RES length */
  74. #define RFAL_NFCA_T_RETRANS 5U /*!< t RETRANSMISSION [3, 33]ms EMVCo 2.6 A.5 */
  75. #define RFAL_NFCA_N_RETRANS 2U /*!< Number of retries EMVCo 2.6 9.6.1.3 */
  76. /*! SDD_REQ (Select) Cascade Levels */
  77. enum
  78. {
  79. RFAL_NFCA_SEL_CASCADE_L1 = 0, /*!< SDD_REQ Cascade Level 1 */
  80. RFAL_NFCA_SEL_CASCADE_L2 = 1, /*!< SDD_REQ Cascade Level 2 */
  81. RFAL_NFCA_SEL_CASCADE_L3 = 2 /*!< SDD_REQ Cascade Level 3 */
  82. };
  83. /*! SDD_REQ (Select) request Cascade Level command Digital 1.1 Table 15 */
  84. enum
  85. {
  86. RFAL_NFCA_CMD_SEL_CL1 = 0x93, /*!< SDD_REQ command Cascade Level 1 */
  87. RFAL_NFCA_CMD_SEL_CL2 = 0x95, /*!< SDD_REQ command Cascade Level 2 */
  88. RFAL_NFCA_CMD_SEL_CL3 = 0x97, /*!< SDD_REQ command Cascade Level 3 */
  89. };
  90. /*
  91. ******************************************************************************
  92. * GLOBAL MACROS
  93. ******************************************************************************
  94. */
  95. #define rfalNfcaSelPar( nBy, nbi ) (uint8_t)((((nBy)<<4U) & 0xF0U) | ((nbi)&0x0FU) ) /*!< Calculates SEL_PAR with the bytes/bits to be sent */
  96. #define rfalNfcaCLn2SELCMD( cl ) (uint8_t)((uint8_t)(RFAL_NFCA_CMD_SEL_CL1) + (2U*(cl))) /*!< Calculates SEL_CMD with the given cascade level */
  97. #define rfalNfcaNfcidLen2CL( len ) ((len) / 5U) /*!< Calculates cascade level by the NFCID length */
  98. #define rfalNfcaRunBlocking( e, fn ) do{ (e)=(fn); rfalWorker(); }while( (e) == ERR_BUSY ) /*!< Macro used for the blocking methods */
  99. /*
  100. ******************************************************************************
  101. * GLOBAL TYPES
  102. ******************************************************************************
  103. */
  104. /*! Colission Resolution states */
  105. typedef enum{
  106. RFAL_NFCA_CR_IDLE, /*!< IDLE state */
  107. RFAL_NFCA_CR_CL, /*!< New Cascading Level state */
  108. RFAL_NFCA_CR_SDD, /*!< Perform anticollsion state */
  109. RFAL_NFCA_CR_SEL, /*!< Perform CL Selection state */
  110. RFAL_NFCA_CR_DONE /*!< Collision Resolution done state */
  111. }colResState;
  112. /*! Colission Resolution context */
  113. typedef struct{
  114. uint8_t devLimit; /*!< Device limit to be used */
  115. rfalComplianceMode compMode; /*!< Compliancy mode to be used */
  116. rfalNfcaListenDevice* nfcaDevList; /*!< Location of the device list */
  117. uint8_t* devCnt; /*!< Location of the device counter */
  118. bool collPending; /*!< Collision pending flag */
  119. bool* collPend; /*!< Location of collision pending flag (Single CR) */
  120. rfalNfcaSelReq selReq; /*!< SelReqused during anticollision (Single CR) */
  121. rfalNfcaSelRes* selRes; /*!< Location to place of the SEL_RES(SAK) (Single CR) */
  122. uint8_t* nfcId1; /*!< Location to place the NFCID1 (Single CR) */
  123. uint8_t* nfcId1Len; /*!< Location to place the NFCID1 length (Single CR) */
  124. uint8_t cascadeLv; /*!< Current Cascading Level (Single CR) */
  125. colResState state; /*!< Single Collision Resolution state (Single CR) */
  126. uint8_t bytesTxRx; /*!< TxRx bytes used during anticollision loop (Single CR) */
  127. uint8_t bitsTxRx; /*!< TxRx bits used during anticollision loop (Single CR) */
  128. uint16_t rxLen;
  129. uint32_t tmrFDT; /*!< FDT timer used between SED_REQs (Single CR) */
  130. uint8_t retries; /*!< Retries to be performed upon a timeout error (Single CR)*/
  131. uint8_t backtrackCnt; /*!< Backtrack retries (Single CR) */
  132. bool doBacktrack; /*!< Backtrack flag (Single CR) */
  133. }colResParams;
  134. /*! RFAL NFC-A instance */
  135. typedef struct{
  136. colResParams CR; /*!< Collision Resolution context */
  137. } rfalNfca;
  138. /*! SLP_REQ (HLTA) format Digital 1.1 6.9.1 & Table 20 */
  139. typedef struct
  140. {
  141. uint8_t frame[RFAL_NFCA_SLP_REQ_LEN]; /*!< SLP: 0x50 0x00 */
  142. } rfalNfcaSlpReq;
  143. /*
  144. ******************************************************************************
  145. * LOCAL VARIABLES
  146. ******************************************************************************
  147. */
  148. static rfalNfca gNfca; /*!< RFAL NFC-A instance */
  149. /*
  150. ******************************************************************************
  151. * LOCAL FUNCTION PROTOTYPES
  152. ******************************************************************************
  153. */
  154. static uint8_t rfalNfcaCalculateBcc( const uint8_t* buf, uint8_t bufLen );
  155. static ReturnCode rfalNfcaPollerStartSingleCollisionResolution( uint8_t devLimit, bool *collPending, rfalNfcaSelRes *selRes, uint8_t *nfcId1, uint8_t *nfcId1Len );
  156. static ReturnCode rfalNfcaPollerGetSingleCollisionResolutionStatus( void );
  157. /*
  158. ******************************************************************************
  159. * LOCAL FUNCTIONS
  160. ******************************************************************************
  161. */
  162. static uint8_t rfalNfcaCalculateBcc( const uint8_t* buf, uint8_t bufLen )
  163. {
  164. uint8_t i;
  165. uint8_t BCC;
  166. BCC = 0;
  167. /* BCC is XOR over first 4 bytes of the SDD_RES Digital 1.1 6.7.2 */
  168. for(i = 0; i < bufLen; i++)
  169. {
  170. BCC ^= buf[i];
  171. }
  172. return BCC;
  173. }
  174. /*******************************************************************************/
  175. static ReturnCode rfalNfcaPollerStartSingleCollisionResolution( uint8_t devLimit, bool *collPending, rfalNfcaSelRes *selRes, uint8_t *nfcId1, uint8_t *nfcId1Len )
  176. {
  177. /* Check parameters */
  178. if( (collPending == NULL) || (selRes == NULL) || (nfcId1 == NULL) || (nfcId1Len == NULL) )
  179. {
  180. return ERR_PARAM;
  181. }
  182. /* Initialize output parameters */
  183. *collPending = false; /* Activity 1.1 9.3.4.6 */
  184. *nfcId1Len = 0;
  185. ST_MEMSET( nfcId1, 0x00, RFAL_NFCA_CASCADE_3_UID_LEN );
  186. /* Save parameters */
  187. gNfca.CR.devLimit = devLimit;
  188. gNfca.CR.collPend = collPending;
  189. gNfca.CR.selRes = selRes;
  190. gNfca.CR.nfcId1 = nfcId1;
  191. gNfca.CR.nfcId1Len = nfcId1Len;
  192. platformTimerDestroy( gNfca.CR.tmrFDT );
  193. gNfca.CR.tmrFDT = 0U;
  194. gNfca.CR.retries = RFAL_NFCA_N_RETRANS;
  195. gNfca.CR.cascadeLv = (uint8_t)RFAL_NFCA_SEL_CASCADE_L1;
  196. gNfca.CR.state = RFAL_NFCA_CR_CL;
  197. gNfca.CR.doBacktrack = false;
  198. gNfca.CR.backtrackCnt = 3U;
  199. return ERR_NONE;
  200. }
  201. /*******************************************************************************/
  202. static ReturnCode rfalNfcaPollerGetSingleCollisionResolutionStatus( void )
  203. {
  204. ReturnCode ret;
  205. uint8_t collBit = 1U; /* standards mandate or recommend collision bit to be set to One. */
  206. /* Check if FDT timer is still running */
  207. if( !platformTimerIsExpired( gNfca.CR.tmrFDT ) && (gNfca.CR.tmrFDT != 0U) )
  208. {
  209. return ERR_BUSY;
  210. }
  211. /*******************************************************************************/
  212. /* Go through all Cascade Levels Activity 1.1 9.3.4 */
  213. if( gNfca.CR.cascadeLv > (uint8_t)RFAL_NFCA_SEL_CASCADE_L3 )
  214. {
  215. return ERR_INTERNAL;
  216. }
  217. switch( gNfca.CR.state )
  218. {
  219. /*******************************************************************************/
  220. case RFAL_NFCA_CR_CL:
  221. /* Initialize the SDD_REQ to send for the new cascade level */
  222. ST_MEMSET( (uint8_t*)&gNfca.CR.selReq, 0x00, sizeof(rfalNfcaSelReq) );
  223. gNfca.CR.bytesTxRx = RFAL_NFCA_SDD_REQ_LEN;
  224. gNfca.CR.bitsTxRx = 0U;
  225. gNfca.CR.state = RFAL_NFCA_CR_SDD;
  226. /* fall through */
  227. /*******************************************************************************/
  228. case RFAL_NFCA_CR_SDD: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
  229. /* Calculate SEL_CMD and SEL_PAR with the bytes/bits to be sent */
  230. gNfca.CR.selReq.selCmd = rfalNfcaCLn2SELCMD( gNfca.CR.cascadeLv );
  231. gNfca.CR.selReq.selPar = rfalNfcaSelPar(gNfca.CR.bytesTxRx, gNfca.CR.bitsTxRx);
  232. /* Send SDD_REQ (Anticollision frame) */
  233. ret = rfalISO14443ATransceiveAnticollisionFrame( (uint8_t*)&gNfca.CR.selReq, &gNfca.CR.bytesTxRx, &gNfca.CR.bitsTxRx, &gNfca.CR.rxLen, RFAL_NFCA_FDTMIN );
  234. /* Retry upon timeout EMVCo 2.6 9.6.1.3 */
  235. if( (ret == ERR_TIMEOUT) && (gNfca.CR.devLimit==0U) && (gNfca.CR.retries != 0U) )
  236. {
  237. gNfca.CR.retries--;
  238. platformTimerDestroy( gNfca.CR.tmrFDT );
  239. gNfca.CR.tmrFDT = platformTimerCreate( RFAL_NFCA_T_RETRANS );
  240. break;
  241. }
  242. /* Covert rxLen into bytes */
  243. gNfca.CR.rxLen = rfalConvBitsToBytes( gNfca.CR.rxLen );
  244. if( (ret == ERR_TIMEOUT) && (gNfca.CR.backtrackCnt != 0U) && (!gNfca.CR.doBacktrack)
  245. && !((RFAL_NFCA_SDD_REQ_LEN == gNfca.CR.bytesTxRx) && (0U == gNfca.CR.bitsTxRx)) )
  246. {
  247. /* In multiple card scenarios it may always happen that some
  248. * collisions of a weaker tag go unnoticed. If then a later
  249. * collision is recognized and the strong tag has a 0 at the
  250. * collision position then no tag will respond. Catch this
  251. * corner case and then try with the bit being sent as zero. */
  252. rfalNfcaSensRes sensRes;
  253. ret = ERR_RF_COLLISION;
  254. rfalNfcaPollerCheckPresence( RFAL_14443A_SHORTFRAME_CMD_REQA, &sensRes );
  255. /* Algorithm below does a post-increment, decrement to go back to current position */
  256. if (0U == gNfca.CR.bitsTxRx)
  257. {
  258. gNfca.CR.bitsTxRx = 7;
  259. gNfca.CR.bytesTxRx--;
  260. }
  261. else
  262. {
  263. gNfca.CR.bitsTxRx--;
  264. }
  265. collBit = (uint8_t)( ((uint8_t*)&gNfca.CR.selReq)[gNfca.CR.bytesTxRx] & (1U << gNfca.CR.bitsTxRx) );
  266. collBit = (uint8_t)((0U==collBit)?1U:0U); // invert the collision bit
  267. gNfca.CR.doBacktrack = true;
  268. gNfca.CR.backtrackCnt--;
  269. }
  270. else
  271. {
  272. gNfca.CR.doBacktrack = false;
  273. }
  274. if( ret == ERR_RF_COLLISION )
  275. {
  276. /* Check received length */
  277. if( (gNfca.CR.bytesTxRx + ((gNfca.CR.bitsTxRx != 0U) ? 1U : 0U)) > (RFAL_NFCA_SDD_RES_LEN + RFAL_NFCA_SDD_REQ_LEN) )
  278. {
  279. return ERR_PROTO;
  280. }
  281. if( ((gNfca.CR.bytesTxRx + ((gNfca.CR.bitsTxRx != 0U) ? 1U : 0U)) > (RFAL_NFCA_CASCADE_1_UID_LEN + RFAL_NFCA_SDD_REQ_LEN)) && (gNfca.CR.backtrackCnt != 0U) )
  282. { /* Collision in BCC: Anticollide only UID part */
  283. gNfca.CR.backtrackCnt--;
  284. gNfca.CR.bytesTxRx = RFAL_NFCA_CASCADE_1_UID_LEN + RFAL_NFCA_SDD_REQ_LEN - 1U;
  285. gNfca.CR.bitsTxRx = 7;
  286. collBit = (uint8_t)( ((uint8_t*)&gNfca.CR.selReq)[gNfca.CR.bytesTxRx] & (1U << gNfca.CR.bitsTxRx) ); /* Not a real collision, extract the actual bit for the subsequent code */
  287. }
  288. if( (gNfca.CR.devLimit == 0U) && !(*gNfca.CR.collPend) )
  289. {
  290. /* Activity 1.0 & 1.1 9.3.4.12: If CON_DEVICES_LIMIT has a value of 0, then
  291. * NFC Forum Device is configured to perform collision detection only */
  292. *gNfca.CR.collPend = true;
  293. return ERR_IGNORE;
  294. }
  295. *gNfca.CR.collPend = true;
  296. /* Set and select the collision bit, with the number of bytes/bits successfully TxRx */
  297. if (collBit != 0U)
  298. {
  299. ((uint8_t*)&gNfca.CR.selReq)[gNfca.CR.bytesTxRx] = (uint8_t)(((uint8_t*)&gNfca.CR.selReq)[gNfca.CR.bytesTxRx] | (1U << gNfca.CR.bitsTxRx)); /* MISRA 10.3 */
  300. }
  301. else
  302. {
  303. ((uint8_t*)&gNfca.CR.selReq)[gNfca.CR.bytesTxRx] = (uint8_t)(((uint8_t*)&gNfca.CR.selReq)[gNfca.CR.bytesTxRx] & ~(1U << gNfca.CR.bitsTxRx)); /* MISRA 10.3 */
  304. }
  305. gNfca.CR.bitsTxRx++;
  306. /* Check if number of bits form a byte */
  307. if( gNfca.CR.bitsTxRx == RFAL_BITS_IN_BYTE )
  308. {
  309. gNfca.CR.bitsTxRx = 0;
  310. gNfca.CR.bytesTxRx++;
  311. }
  312. break;
  313. }
  314. /*******************************************************************************/
  315. /* Check if Collision loop has failed */
  316. if( ret != ERR_NONE )
  317. {
  318. return ret;
  319. }
  320. /* If collisions are to be reported check whether the response is complete */
  321. if( (gNfca.CR.devLimit == 0U) && (gNfca.CR.rxLen != sizeof(rfalNfcaSddRes)) )
  322. {
  323. return ERR_PROTO;
  324. }
  325. /* Check if the received BCC match */
  326. if( gNfca.CR.selReq.bcc != rfalNfcaCalculateBcc( gNfca.CR.selReq.nfcid1, RFAL_NFCA_CASCADE_1_UID_LEN ) )
  327. {
  328. return ERR_PROTO;
  329. }
  330. /*******************************************************************************/
  331. /* Anticollision OK, Select this Cascade Level */
  332. gNfca.CR.selReq.selPar = RFAL_NFCA_SEL_SELPAR;
  333. gNfca.CR.retries = RFAL_NFCA_N_RETRANS;
  334. gNfca.CR.state = RFAL_NFCA_CR_SEL;
  335. break;
  336. /*******************************************************************************/
  337. case RFAL_NFCA_CR_SEL:
  338. /* Send SEL_REQ (Select command) - Retry upon timeout EMVCo 2.6 9.6.1.3 */
  339. ret = rfalTransceiveBlockingTxRx( (uint8_t*)&gNfca.CR.selReq, sizeof(rfalNfcaSelReq), (uint8_t*)gNfca.CR.selRes, sizeof(rfalNfcaSelRes), &gNfca.CR.rxLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_NFCA_FDTMIN );
  340. /* Retry upon timeout EMVCo 2.6 9.6.1.3 */
  341. if( (ret == ERR_TIMEOUT) && (gNfca.CR.devLimit==0U) && (gNfca.CR.retries != 0U) )
  342. {
  343. gNfca.CR.retries--;
  344. platformTimerDestroy( gNfca.CR.tmrFDT );
  345. gNfca.CR.tmrFDT = platformTimerCreate( RFAL_NFCA_T_RETRANS );
  346. break;
  347. }
  348. if( ret != ERR_NONE )
  349. {
  350. return ret;
  351. }
  352. /* Ensure proper response length */
  353. if( gNfca.CR.rxLen != sizeof(rfalNfcaSelRes) )
  354. {
  355. return ERR_PROTO;
  356. }
  357. /*******************************************************************************/
  358. /* Check cascade byte, if cascade tag then go next cascade level */
  359. if( *gNfca.CR.selReq.nfcid1 == RFAL_NFCA_SDD_CT )
  360. {
  361. /* Cascade Tag present, store nfcid1 bytes (excluding cascade tag) and continue for next CL */
  362. ST_MEMCPY( &gNfca.CR.nfcId1[*gNfca.CR.nfcId1Len], &((uint8_t*)&gNfca.CR.selReq.nfcid1)[RFAL_NFCA_SDD_CT_LEN], (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN) );
  363. *gNfca.CR.nfcId1Len += (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN);
  364. /* Go to next cascade level */
  365. gNfca.CR.state = RFAL_NFCA_CR_CL;
  366. gNfca.CR.cascadeLv++;
  367. }
  368. else
  369. {
  370. /* UID Selection complete, Stop Cascade Level loop */
  371. ST_MEMCPY( &gNfca.CR.nfcId1[*gNfca.CR.nfcId1Len], (uint8_t*)&gNfca.CR.selReq.nfcid1, RFAL_NFCA_CASCADE_1_UID_LEN );
  372. *gNfca.CR.nfcId1Len += RFAL_NFCA_CASCADE_1_UID_LEN;
  373. gNfca.CR.state = RFAL_NFCA_CR_DONE;
  374. break; /* Only flag operation complete on the next execution */
  375. }
  376. break;
  377. /*******************************************************************************/
  378. case RFAL_NFCA_CR_DONE:
  379. return ERR_NONE;
  380. /*******************************************************************************/
  381. default:
  382. return ERR_WRONG_STATE;
  383. }
  384. return ERR_BUSY;
  385. }
  386. /*
  387. ******************************************************************************
  388. * GLOBAL FUNCTIONS
  389. ******************************************************************************
  390. */
  391. /*******************************************************************************/
  392. ReturnCode rfalNfcaPollerInitialize( void )
  393. {
  394. ReturnCode ret;
  395. EXIT_ON_ERR( ret, rfalSetMode( RFAL_MODE_POLL_NFCA, RFAL_BR_106, RFAL_BR_106 ) );
  396. rfalSetErrorHandling( RFAL_ERRORHANDLING_NFC );
  397. rfalSetGT( RFAL_GT_NFCA );
  398. rfalSetFDTListen( RFAL_FDT_LISTEN_NFCA_POLLER );
  399. rfalSetFDTPoll( RFAL_FDT_POLL_NFCA_POLLER );
  400. return ERR_NONE;
  401. }
  402. /*******************************************************************************/
  403. ReturnCode rfalNfcaPollerCheckPresence( rfal14443AShortFrameCmd cmd, rfalNfcaSensRes *sensRes )
  404. {
  405. ReturnCode ret;
  406. uint16_t rcvLen;
  407. /* Digital 1.1 6.10.1.3 For Commands ALL_REQ, SENS_REQ, SDD_REQ, and SEL_REQ, the NFC Forum Device *
  408. * MUST treat receipt of a Listen Frame at a time after FDT(Listen, min) as a Timeour Error */
  409. ret = rfalISO14443ATransceiveShortFrame( cmd, (uint8_t*)sensRes, (uint8_t)rfalConvBytesToBits(sizeof(rfalNfcaSensRes)), &rcvLen, RFAL_NFCA_FDTMIN );
  410. if( (ret == ERR_RF_COLLISION) || (ret == ERR_CRC) || (ret == ERR_NOMEM) || (ret == ERR_FRAMING) || (ret == ERR_PAR) )
  411. {
  412. ret = ERR_NONE;
  413. }
  414. return ret;
  415. }
  416. /*******************************************************************************/
  417. ReturnCode rfalNfcaPollerTechnologyDetection( rfalComplianceMode compMode, rfalNfcaSensRes *sensRes )
  418. {
  419. ReturnCode ret;
  420. EXIT_ON_ERR( ret, rfalNfcaPollerCheckPresence( ((compMode == RFAL_COMPLIANCE_MODE_EMV) ? RFAL_14443A_SHORTFRAME_CMD_WUPA : RFAL_14443A_SHORTFRAME_CMD_REQA), sensRes ) );
  421. /* Send SLP_REQ as Activity 1.1 9.2.3.6 and EMVCo 2.6 9.2.1.3 */
  422. if( compMode != RFAL_COMPLIANCE_MODE_ISO)
  423. {
  424. rfalNfcaPollerSleep();
  425. }
  426. return ERR_NONE;
  427. }
  428. /*******************************************************************************/
  429. ReturnCode rfalNfcaPollerSingleCollisionResolution( uint8_t devLimit, bool *collPending, rfalNfcaSelRes *selRes, uint8_t *nfcId1, uint8_t *nfcId1Len )
  430. {
  431. ReturnCode ret;
  432. EXIT_ON_ERR( ret, rfalNfcaPollerStartSingleCollisionResolution( devLimit, collPending, selRes, nfcId1, nfcId1Len ) );
  433. rfalNfcaRunBlocking( ret, rfalNfcaPollerGetSingleCollisionResolutionStatus() );
  434. return ret;
  435. }
  436. /*******************************************************************************/
  437. ReturnCode rfalNfcaPollerStartFullCollisionResolution( rfalComplianceMode compMode, uint8_t devLimit, rfalNfcaListenDevice *nfcaDevList, uint8_t *devCnt )
  438. {
  439. ReturnCode ret;
  440. rfalNfcaSensRes sensRes;
  441. uint16_t rcvLen;
  442. if( (nfcaDevList == NULL) || (devCnt == NULL) )
  443. {
  444. return ERR_PARAM;
  445. }
  446. *devCnt = 0;
  447. ret = ERR_NONE;
  448. /*******************************************************************************/
  449. /* Send ALL_REQ before Anticollision if a Sleep was sent before Activity 1.1 9.3.4.1 and EMVco 2.6 9.3.2.1 */
  450. if( compMode != RFAL_COMPLIANCE_MODE_ISO )
  451. {
  452. ret = rfalISO14443ATransceiveShortFrame( RFAL_14443A_SHORTFRAME_CMD_WUPA, (uint8_t*)&nfcaDevList->sensRes, (uint8_t)rfalConvBytesToBits(sizeof(rfalNfcaSensRes)), &rcvLen, RFAL_NFCA_FDTMIN );
  453. if(ret != ERR_NONE)
  454. {
  455. if( (compMode == RFAL_COMPLIANCE_MODE_EMV) || ((ret != ERR_RF_COLLISION) && (ret != ERR_CRC) && (ret != ERR_FRAMING) && (ret != ERR_PAR)) )
  456. {
  457. return ret;
  458. }
  459. }
  460. /* Check proper SENS_RES/ATQA size */
  461. if( (ret == ERR_NONE) && (rfalConvBytesToBits(sizeof(rfalNfcaSensRes)) != rcvLen) )
  462. {
  463. return ERR_PROTO;
  464. }
  465. }
  466. /*******************************************************************************/
  467. /* Store the SENS_RES from Technology Detection or from WUPA */
  468. sensRes = nfcaDevList->sensRes;
  469. if( devLimit > 0U ) /* MISRA 21.18 */
  470. {
  471. ST_MEMSET( nfcaDevList, 0x00, (sizeof(rfalNfcaListenDevice) * devLimit) );
  472. }
  473. /* Restore the prev SENS_RES, assuming that the SENS_RES received is from first device
  474. * When only one device is detected it's not woken up then we'll have no SENS_RES (ATQA) */
  475. nfcaDevList->sensRes = sensRes;
  476. /* Save parameters */
  477. gNfca.CR.devCnt = devCnt;
  478. gNfca.CR.devLimit = devLimit;
  479. gNfca.CR.nfcaDevList = nfcaDevList;
  480. gNfca.CR.compMode = compMode;
  481. #if RFAL_FEATURE_T1T
  482. /*******************************************************************************/
  483. /* Only check for T1T if previous SENS_RES was received without a transmission *
  484. * error. When collisions occur bits in the SENS_RES may look like a T1T */
  485. /* If T1T Anticollision is not supported Activity 1.1 9.3.4.3 */
  486. if( rfalNfcaIsSensResT1T( &nfcaDevList->sensRes ) && (devLimit != 0U) && (ret == ERR_NONE) && (compMode != RFAL_COMPLIANCE_MODE_EMV) )
  487. {
  488. /* RID_REQ shall be performed Activity 1.1 9.3.4.24 */
  489. rfalT1TPollerInitialize();
  490. EXIT_ON_ERR( ret, rfalT1TPollerRid( &nfcaDevList->ridRes ) );
  491. *devCnt = 1U;
  492. nfcaDevList->isSleep = false;
  493. nfcaDevList->type = RFAL_NFCA_T1T;
  494. nfcaDevList->nfcId1Len = RFAL_NFCA_CASCADE_1_UID_LEN;
  495. ST_MEMCPY( &nfcaDevList->nfcId1, &nfcaDevList->ridRes.uid, RFAL_NFCA_CASCADE_1_UID_LEN );
  496. return ERR_NONE;
  497. }
  498. #endif /* RFAL_FEATURE_T1T */
  499. return rfalNfcaPollerStartSingleCollisionResolution( devLimit, &gNfca.CR.collPending, &nfcaDevList->selRes, (uint8_t*)&nfcaDevList->nfcId1, &nfcaDevList->nfcId1Len );
  500. }
  501. /*******************************************************************************/
  502. ReturnCode rfalNfcaPollerGetFullCollisionResolutionStatus( void )
  503. {
  504. ReturnCode ret;
  505. uint8_t newDevType;
  506. if( (gNfca.CR.nfcaDevList == NULL) || (gNfca.CR.devCnt == NULL) )
  507. {
  508. return ERR_WRONG_STATE;
  509. }
  510. /*******************************************************************************/
  511. /* Check whether a T1T has already been detected */
  512. if( rfalNfcaIsSensResT1T( &gNfca.CR.nfcaDevList->sensRes ) && (gNfca.CR.nfcaDevList->type == RFAL_NFCA_T1T) )
  513. {
  514. /* T1T doesn't support Anticollision */
  515. return ERR_NONE;
  516. }
  517. /*******************************************************************************/
  518. EXIT_ON_ERR( ret, rfalNfcaPollerGetSingleCollisionResolutionStatus() );
  519. /* Assign Listen Device */
  520. newDevType = ((uint8_t)gNfca.CR.nfcaDevList[*gNfca.CR.devCnt].selRes.sak) & RFAL_NFCA_SEL_RES_CONF_MASK; /* MISRA 10.8 */
  521. /* PRQA S 4342 1 # MISRA 10.5 - Guaranteed that no invalid enum values are created: see guard_eq_RFAL_NFCA_T2T, .... */
  522. gNfca.CR.nfcaDevList[*gNfca.CR.devCnt].type = (rfalNfcaListenDeviceType) newDevType;
  523. gNfca.CR.nfcaDevList[*gNfca.CR.devCnt].isSleep = false;
  524. (*gNfca.CR.devCnt)++;
  525. /* If a collision was detected and device counter is lower than limit Activity 1.1 9.3.4.21 */
  526. if( (*gNfca.CR.devCnt < gNfca.CR.devLimit) && (gNfca.CR.collPending) )
  527. {
  528. /* Put this device to Sleep Activity 1.1 9.3.4.22 */
  529. rfalNfcaPollerSleep();
  530. gNfca.CR.nfcaDevList[(*gNfca.CR.devCnt - 1U)].isSleep = true;
  531. /* Send a new SENS_REQ to check for other cards Activity 1.1 9.3.4.23 */
  532. ret = rfalNfcaPollerCheckPresence( RFAL_14443A_SHORTFRAME_CMD_REQA, &gNfca.CR.nfcaDevList[*gNfca.CR.devCnt].sensRes );
  533. if( ret == ERR_TIMEOUT )
  534. {
  535. /* No more devices found, exit */
  536. gNfca.CR.collPending = false;
  537. }
  538. else
  539. {
  540. /* Another device found, continue loop */
  541. gNfca.CR.collPending = true;
  542. }
  543. }
  544. else
  545. {
  546. /* Exit loop */
  547. gNfca.CR.collPending = false;
  548. }
  549. /*******************************************************************************/
  550. /* Check if collision resolution shall continue */
  551. if( (*gNfca.CR.devCnt < gNfca.CR.devLimit) && (gNfca.CR.collPending) )
  552. {
  553. EXIT_ON_ERR( ret, rfalNfcaPollerStartSingleCollisionResolution( gNfca.CR.devLimit,
  554. &gNfca.CR.collPending,
  555. &gNfca.CR.nfcaDevList[*gNfca.CR.devCnt].selRes,
  556. (uint8_t*)&gNfca.CR.nfcaDevList[*gNfca.CR.devCnt].nfcId1,
  557. &gNfca.CR.nfcaDevList[*gNfca.CR.devCnt].nfcId1Len ) );
  558. return ERR_BUSY;
  559. }
  560. return ERR_NONE;
  561. }
  562. /*******************************************************************************/
  563. ReturnCode rfalNfcaPollerFullCollisionResolution( rfalComplianceMode compMode, uint8_t devLimit, rfalNfcaListenDevice *nfcaDevList, uint8_t *devCnt )
  564. {
  565. ReturnCode ret;
  566. EXIT_ON_ERR( ret, rfalNfcaPollerStartFullCollisionResolution( compMode, devLimit, nfcaDevList, devCnt ) );
  567. rfalNfcaRunBlocking( ret, rfalNfcaPollerGetFullCollisionResolutionStatus() );
  568. return ret;
  569. }
  570. ReturnCode rfalNfcaPollerSleepFullCollisionResolution( uint8_t devLimit, rfalNfcaListenDevice *nfcaDevList, uint8_t *devCnt )
  571. {
  572. bool firstRound;
  573. uint8_t tmpDevCnt;
  574. ReturnCode ret;
  575. if( (nfcaDevList == NULL) || (devCnt == NULL) )
  576. {
  577. return ERR_PARAM;
  578. }
  579. /* Only use ALL_REQ (WUPA) on the first round */
  580. firstRound = true;
  581. *devCnt = 0;
  582. /* Perform collision resolution until no new device is found */
  583. do
  584. {
  585. tmpDevCnt = 0;
  586. ret = rfalNfcaPollerFullCollisionResolution( (firstRound ? RFAL_COMPLIANCE_MODE_NFC : RFAL_COMPLIANCE_MODE_ISO), (devLimit - *devCnt), &nfcaDevList[*devCnt], &tmpDevCnt );
  587. if( (ret == ERR_NONE) && (tmpDevCnt > 0U) )
  588. {
  589. *devCnt += tmpDevCnt;
  590. /* Check whether to seacrh for more devices */
  591. if( *devCnt < devLimit )
  592. {
  593. /* Set last found device to sleep (all others are slept already) */
  594. rfalNfcaPollerSleep();
  595. nfcaDevList[((*devCnt)-1U)].isSleep = true;
  596. /* Check if any other device is present */
  597. ret = rfalNfcaPollerCheckPresence( RFAL_14443A_SHORTFRAME_CMD_REQA, &nfcaDevList[*devCnt].sensRes );
  598. if( ret == ERR_NONE )
  599. {
  600. firstRound = false;
  601. continue;
  602. }
  603. }
  604. }
  605. break;
  606. }
  607. while( true );
  608. return ((*devCnt > 0U) ? ERR_NONE : ret);
  609. }
  610. /*******************************************************************************/
  611. ReturnCode rfalNfcaPollerSelect( const uint8_t *nfcid1, uint8_t nfcidLen, rfalNfcaSelRes *selRes )
  612. {
  613. uint8_t i;
  614. uint8_t cl;
  615. uint8_t nfcidOffset;
  616. uint16_t rxLen;
  617. ReturnCode ret;
  618. rfalNfcaSelReq selReq;
  619. if( (nfcid1 == NULL) || (nfcidLen > RFAL_NFCA_CASCADE_3_UID_LEN) || (selRes == NULL) )
  620. {
  621. return ERR_PARAM;
  622. }
  623. /* Calculate Cascate Level */
  624. cl = rfalNfcaNfcidLen2CL( nfcidLen );
  625. nfcidOffset = 0;
  626. /*******************************************************************************/
  627. /* Go through all Cascade Levels Activity 1.1 9.4.4 */
  628. for( i = RFAL_NFCA_SEL_CASCADE_L1; i <= cl; i++ )
  629. {
  630. /* Assign SEL_CMD according to the CLn and SEL_PAR*/
  631. selReq.selCmd = rfalNfcaCLn2SELCMD(i);
  632. selReq.selPar = RFAL_NFCA_SEL_SELPAR;
  633. /* Compute NFCID/Data on the SEL_REQ command Digital 1.1 Table 18 */
  634. if( cl != i )
  635. {
  636. *selReq.nfcid1 = RFAL_NFCA_SDD_CT;
  637. ST_MEMCPY( &selReq.nfcid1[RFAL_NFCA_SDD_CT_LEN], &nfcid1[nfcidOffset], (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN) );
  638. nfcidOffset += (RFAL_NFCA_CASCADE_1_UID_LEN - RFAL_NFCA_SDD_CT_LEN);
  639. }
  640. else
  641. {
  642. ST_MEMCPY( selReq.nfcid1, &nfcid1[nfcidOffset], RFAL_NFCA_CASCADE_1_UID_LEN );
  643. }
  644. /* Calculate nfcid's BCC */
  645. selReq.bcc = rfalNfcaCalculateBcc( (uint8_t*)&selReq.nfcid1, sizeof(selReq.nfcid1) );
  646. /*******************************************************************************/
  647. /* Send SEL_REQ */
  648. EXIT_ON_ERR( ret, rfalTransceiveBlockingTxRx( (uint8_t*)&selReq, sizeof(rfalNfcaSelReq), (uint8_t*)selRes, sizeof(rfalNfcaSelRes), &rxLen, RFAL_TXRX_FLAGS_DEFAULT, RFAL_NFCA_FDTMIN ) );
  649. /* Ensure proper response length */
  650. if( rxLen != sizeof(rfalNfcaSelRes) )
  651. {
  652. return ERR_PROTO;
  653. }
  654. }
  655. /* REMARK: Could check if NFCID1 is complete */
  656. return ERR_NONE;
  657. }
  658. /*******************************************************************************/
  659. ReturnCode rfalNfcaPollerSleep( void )
  660. {
  661. rfalNfcaSlpReq slpReq;
  662. uint8_t rxBuf; /* dummy buffer, just to perform Rx */
  663. slpReq.frame[RFAL_NFCA_SLP_CMD_POS] = RFAL_NFCA_SLP_CMD;
  664. slpReq.frame[RFAL_NFCA_SLP_BYTE2_POS] = RFAL_NFCA_SLP_BYTE2;
  665. rfalTransceiveBlockingTxRx( (uint8_t*)&slpReq, sizeof(rfalNfcaSlpReq), &rxBuf, sizeof(rxBuf), NULL, RFAL_TXRX_FLAGS_DEFAULT, RFAL_NFCA_SLP_FWT );
  666. /* ISO14443-3 6.4.3 HLTA - If PICC responds with any modulation during 1 ms this response shall be interpreted as not acknowledge
  667. Digital 2.0 6.9.2.1 & EMVCo 3.0 5.6.2.1 - consider the HLTA command always acknowledged
  668. No check to be compliant with NFC and EMVCo, and to improve interoprability (Kovio RFID Tag)
  669. */
  670. return ERR_NONE;
  671. }
  672. /*******************************************************************************/
  673. bool rfalNfcaListenerIsSleepReq( const uint8_t *buf, uint16_t bufLen )
  674. {
  675. /* Check if length and payload match */
  676. if( (bufLen != sizeof(rfalNfcaSlpReq)) || (buf[RFAL_NFCA_SLP_CMD_POS] != RFAL_NFCA_SLP_CMD) || (buf[RFAL_NFCA_SLP_BYTE2_POS] != RFAL_NFCA_SLP_BYTE2) )
  677. {
  678. return false;
  679. }
  680. return true;
  681. }
  682. /* If the guards here don't compile then the code above cannot work anymore. */
  683. extern uint8_t guard_eq_RFAL_NFCA_T2T[((RFAL_NFCA_SEL_RES_CONF_MASK&(uint8_t)RFAL_NFCA_T2T) == (uint8_t)RFAL_NFCA_T2T)?1:(-1)];
  684. extern uint8_t guard_eq_RFAL_NFCA_T4T[((RFAL_NFCA_SEL_RES_CONF_MASK&(uint8_t)RFAL_NFCA_T4T) == (uint8_t)RFAL_NFCA_T4T)?1:(-1)];
  685. extern uint8_t guard_eq_RFAL_NFCA_NFCDEP[((RFAL_NFCA_SEL_RES_CONF_MASK&(uint8_t)RFAL_NFCA_NFCDEP) == (uint8_t)RFAL_NFCA_NFCDEP)?1:(-1)];
  686. extern uint8_t guard_eq_RFAL_NFCA_T4T_NFCDEP[((RFAL_NFCA_SEL_RES_CONF_MASK&(uint8_t)RFAL_NFCA_T4T_NFCDEP) == (uint8_t)RFAL_NFCA_T4T_NFCDEP)?1:(-1)];
  687. #endif /* RFAL_FEATURE_NFCA */