rfal_nfca.c 34 KB

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