rfal_nfcf.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  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_nfcf.c
  27. *
  28. * \author Gustavo Patricio
  29. *
  30. * \brief Implementation of NFC-F Poller (FeliCa PCD) device
  31. *
  32. * The definitions and helpers methods provided by this module are
  33. * aligned with NFC-F (FeliCa - JIS X6319-4)
  34. *
  35. */
  36. /*
  37. ******************************************************************************
  38. * INCLUDES
  39. ******************************************************************************
  40. */
  41. #include "rfal_nfcf.h"
  42. #include "utils.h"
  43. /*
  44. ******************************************************************************
  45. * ENABLE SWITCH
  46. ******************************************************************************
  47. */
  48. #ifndef RFAL_FEATURE_NFCF
  49. #define RFAL_FEATURE_NFCF false /* NFC-F module configuration missing. Disabled by default */
  50. #endif
  51. #if RFAL_FEATURE_NFCF
  52. /*
  53. ******************************************************************************
  54. * GLOBAL DEFINES
  55. ******************************************************************************
  56. */
  57. #define RFAL_NFCF_SENSF_REQ_LEN_MIN \
  58. 5U /*!< SENSF_RES minimum length */
  59. #define RFAL_NFCF_READ_WO_ENCRYPTION_MIN_LEN \
  60. 15U /*!< Minimum length for a Check Command T3T 5.4.1 */
  61. #define RFAL_NFCF_WRITE_WO_ENCRYPTION_MIN_LEN \
  62. 31U /*!< Minimum length for an Update Command T3T 5.5.1 */
  63. #define RFAL_NFCF_CHECK_RES_MIN_LEN \
  64. 11U /*!< CHECK Response minimum length T3T 1.0 Table 8 */
  65. #define RFAL_NFCF_UPDATE_RES_MIN_LEN \
  66. 11U /*!< UPDATE Response minimum length T3T 1.0 Table 8 */
  67. #define RFAL_NFCF_CHECK_REQ_MAX_LEN \
  68. 86U /*!< Max length of a Check request T3T 1.0 Table 7 */
  69. #define RFAL_NFCF_CHECK_REQ_MAX_SERV \
  70. 15U /*!< Max Services number on Check request T3T 1.0 5.4.1.5 */
  71. #define RFAL_NFCF_CHECK_REQ_MAX_BLOCK \
  72. 15U /*!< Max Blocks number on Check request T3T 1.0 5.4.1.10 */
  73. #define RFAL_NFCF_UPDATE_REQ_MAX_SERV \
  74. 15U /*!< Max Services number Update request T3T 1.0 5.4.1.5 */
  75. #define RFAL_NFCF_UPDATE_REQ_MAX_BLOCK \
  76. 13U /*!< Max Blocks number on Update request T3T 1.0 5.4.1.10 */
  77. /*! MRT Check | Uupdate = (Tt3t x ((A+1) + n (B+1)) x 4^E) + dRWTt3t T3T 5.8
  78. Max values used: A = 7 ; B = 7 ; E = 3 ; n = 15 (NFC Forum n = 15, JIS n = 32)
  79. */
  80. #define RFAL_NFCF_MRT_CHECK_UPDATE ((4096 * (8 + (15 * 8)) * 64) + 16)
  81. /*
  82. ******************************************************************************
  83. * GLOBAL MACROS
  84. ******************************************************************************
  85. */
  86. #define rfalNfcfSlots2CardNum(s) \
  87. ((uint8_t)(s) + 1U) /*!< Converts Time Slot Number (TSN) into num of slots */
  88. /*
  89. ******************************************************************************
  90. * GLOBAL TYPES
  91. ******************************************************************************
  92. */
  93. /*! Structure/Buffer to hold the SENSF_RES with LEN byte prepended */
  94. typedef struct {
  95. uint8_t LEN; /*!< NFC-F LEN byte */
  96. rfalNfcfSensfRes SENSF_RES; /*!< SENSF_RES */
  97. } rfalNfcfSensfResBuf;
  98. /*! Greedy collection for NFCF GRE_POLL_F Activity 1.0 Table 10 */
  99. typedef struct {
  100. uint8_t pollFound; /*!< Number of devices found by the Poll */
  101. uint8_t pollCollision; /*!< Number of collisions detected */
  102. rfalFeliCaPollRes POLL_F[RFAL_NFCF_POLL_MAXCARDS]; /*!< GRE_POLL_F Activity 1.0 Table 10 */
  103. } rfalNfcfGreedyF;
  104. /*! NFC-F SENSF_REQ format Digital 1.1 8.6.1 */
  105. typedef struct {
  106. uint8_t CMD; /*!< Command code: 00h */
  107. uint8_t SC[RFAL_NFCF_SENSF_SC_LEN]; /*!< System Code */
  108. uint8_t RC; /*!< Request Code */
  109. uint8_t TSN; /*!< Time Slot Number */
  110. } rfalNfcfSensfReq;
  111. /*
  112. ******************************************************************************
  113. * LOCAL VARIABLES
  114. ******************************************************************************
  115. */
  116. static rfalNfcfGreedyF gRfalNfcfGreedyF; /*!< Activity's NFCF Greedy collection */
  117. /*
  118. ******************************************************************************
  119. * LOCAL FUNCTION PROTOTYPES
  120. ******************************************************************************
  121. */
  122. static void rfalNfcfComputeValidSENF(
  123. rfalNfcfListenDevice* outDevInfo,
  124. uint8_t* curDevIdx,
  125. uint8_t devLimit,
  126. bool overwrite,
  127. bool* nfcDepFound);
  128. /*
  129. ******************************************************************************
  130. * LOCAL VARIABLES
  131. ******************************************************************************
  132. */
  133. /*******************************************************************************/
  134. static void rfalNfcfComputeValidSENF(
  135. rfalNfcfListenDevice* outDevInfo,
  136. uint8_t* curDevIdx,
  137. uint8_t devLimit,
  138. bool overwrite,
  139. bool* nfcDepFound) {
  140. uint8_t tmpIdx;
  141. bool duplicate;
  142. const rfalNfcfSensfResBuf* sensfBuf;
  143. rfalNfcfSensfResBuf sensfCopy;
  144. /*******************************************************************************/
  145. /* Go through all responses check if valid and duplicates */
  146. /*******************************************************************************/
  147. while((gRfalNfcfGreedyF.pollFound > 0U) && ((*curDevIdx) < devLimit)) {
  148. duplicate = false;
  149. gRfalNfcfGreedyF.pollFound--;
  150. /* MISRA 11.3 - Cannot point directly into different object type, use local copy */
  151. ST_MEMCPY(
  152. (uint8_t*)&sensfCopy,
  153. (uint8_t*)&gRfalNfcfGreedyF.POLL_F[gRfalNfcfGreedyF.pollFound],
  154. sizeof(rfalNfcfSensfResBuf));
  155. /* Point to received SENSF_RES */
  156. sensfBuf = &sensfCopy;
  157. /* Check for devices that are already in device list */
  158. for(tmpIdx = 0; tmpIdx < (*curDevIdx); tmpIdx++) {
  159. if(ST_BYTECMP(
  160. sensfBuf->SENSF_RES.NFCID2,
  161. outDevInfo[tmpIdx].sensfRes.NFCID2,
  162. RFAL_NFCF_NFCID2_LEN) == 0) {
  163. duplicate = true;
  164. break;
  165. }
  166. }
  167. /* If is a duplicate skip this (and not to overwrite)*/
  168. if(duplicate && !overwrite) {
  169. continue;
  170. }
  171. /* Check if response length is OK */
  172. if(((sensfBuf->LEN - RFAL_NFCF_HEADER_LEN) < RFAL_NFCF_SENSF_RES_LEN_MIN) ||
  173. ((sensfBuf->LEN - RFAL_NFCF_HEADER_LEN) > RFAL_NFCF_SENSF_RES_LEN_MAX)) {
  174. continue;
  175. }
  176. /* Check if the response is a SENSF_RES / Polling response */
  177. if(sensfBuf->SENSF_RES.CMD != (uint8_t)RFAL_NFCF_CMD_POLLING_RES) {
  178. continue;
  179. }
  180. /* Check if is an overwrite request or new device*/
  181. if(duplicate && overwrite) {
  182. /* overwrite deviceInfo/GRE_SENSF_RES with SENSF_RES */
  183. outDevInfo[tmpIdx].sensfResLen = (sensfBuf->LEN - RFAL_NFCF_LENGTH_LEN);
  184. ST_MEMCPY(
  185. &outDevInfo[tmpIdx].sensfRes,
  186. &sensfBuf->SENSF_RES,
  187. outDevInfo[tmpIdx].sensfResLen);
  188. continue;
  189. } else {
  190. /* fill deviceInfo/GRE_SENSF_RES with new SENSF_RES */
  191. outDevInfo[(*curDevIdx)].sensfResLen = (sensfBuf->LEN - RFAL_NFCF_LENGTH_LEN);
  192. ST_MEMCPY(
  193. &outDevInfo[(*curDevIdx)].sensfRes,
  194. &sensfBuf->SENSF_RES,
  195. outDevInfo[(*curDevIdx)].sensfResLen);
  196. }
  197. /* Check if this device supports NFC-DEP and signal it (ACTIVITY 1.1 9.3.6.63) */
  198. *nfcDepFound = rfalNfcfIsNfcDepSupported(&outDevInfo[(*curDevIdx)]);
  199. (*curDevIdx)++;
  200. }
  201. }
  202. /*
  203. ******************************************************************************
  204. * GLOBAL FUNCTIONS
  205. ******************************************************************************
  206. */
  207. /*******************************************************************************/
  208. ReturnCode rfalNfcfPollerInitialize(rfalBitRate bitRate) {
  209. ReturnCode ret;
  210. if((bitRate != RFAL_BR_212) && (bitRate != RFAL_BR_424)) {
  211. return ERR_PARAM;
  212. }
  213. EXIT_ON_ERR(ret, rfalSetMode(RFAL_MODE_POLL_NFCF, bitRate, bitRate));
  214. rfalSetErrorHandling(RFAL_ERRORHANDLING_NFC);
  215. rfalSetGT(RFAL_GT_NFCF);
  216. rfalSetFDTListen(RFAL_FDT_LISTEN_NFCF_POLLER);
  217. rfalSetFDTPoll(RFAL_FDT_POLL_NFCF_POLLER);
  218. return ERR_NONE;
  219. }
  220. /*******************************************************************************/
  221. ReturnCode rfalNfcfPollerPoll(
  222. rfalFeliCaPollSlots slots,
  223. uint16_t sysCode,
  224. uint8_t reqCode,
  225. rfalFeliCaPollRes* cardList,
  226. uint8_t* devCnt,
  227. uint8_t* collisions) {
  228. return rfalFeliCaPoll(
  229. slots, sysCode, reqCode, cardList, rfalNfcfSlots2CardNum(slots), devCnt, collisions);
  230. }
  231. /*******************************************************************************/
  232. ReturnCode rfalNfcfPollerCheckPresence(void) {
  233. gRfalNfcfGreedyF.pollFound = 0;
  234. gRfalNfcfGreedyF.pollCollision = 0;
  235. /* ACTIVITY 1.0 & 1.1 - 9.2.3.17 SENSF_REQ must be with number of slots equal to 4
  236. * SC must be 0xFFFF
  237. * RC must be 0x00 (No system code info required) */
  238. return rfalFeliCaPoll(
  239. RFAL_FELICA_4_SLOTS,
  240. RFAL_NFCF_SYSTEMCODE,
  241. RFAL_FELICA_POLL_RC_NO_REQUEST,
  242. gRfalNfcfGreedyF.POLL_F,
  243. rfalNfcfSlots2CardNum(RFAL_FELICA_4_SLOTS),
  244. &gRfalNfcfGreedyF.pollFound,
  245. &gRfalNfcfGreedyF.pollCollision);
  246. }
  247. /*******************************************************************************/
  248. ReturnCode rfalNfcfPollerCollisionResolution(
  249. rfalComplianceMode compMode,
  250. uint8_t devLimit,
  251. rfalNfcfListenDevice* nfcfDevList,
  252. uint8_t* devCnt) {
  253. ReturnCode ret;
  254. bool nfcDepFound;
  255. if((nfcfDevList == NULL) || (devCnt == NULL)) {
  256. return ERR_PARAM;
  257. }
  258. *devCnt = 0;
  259. nfcDepFound = false;
  260. /*******************************************************************************************/
  261. /* ACTIVITY 1.0 - 9.3.6.3 Copy valid SENSF_RES in GRE_POLL_F into GRE_SENSF_RES */
  262. /* ACTIVITY 1.0 - 9.3.6.6 The NFC Forum Device MUST remove all entries from GRE_SENSF_RES[]*/
  263. /* ACTIVITY 1.1 - 9.3.63.59 Populate GRE_SENSF_RES with data from GRE_POLL_F */
  264. /* */
  265. /* CON_DEVICES_LIMIT = 0 Just check if devices from Tech Detection exceeds -> always true */
  266. /* Allow the number of slots open on Technology Detection */
  267. /*******************************************************************************************/
  268. rfalNfcfComputeValidSENF(
  269. nfcfDevList,
  270. devCnt,
  271. ((devLimit == 0U) ? rfalNfcfSlots2CardNum(RFAL_FELICA_4_SLOTS) : devLimit),
  272. false,
  273. &nfcDepFound);
  274. /*******************************************************************************/
  275. /* ACTIVITY 1.0 - 9.3.6.4 */
  276. /* ACTIVITY 1.1 - 9.3.63.60 Check if devices found are lower than the limit */
  277. /* and send a SENSF_REQ if so */
  278. /*******************************************************************************/
  279. if(*devCnt < devLimit) {
  280. /* ACTIVITY 1.0 - 9.3.6.5 Copy valid SENSF_RES and then to remove it
  281. * ACTIVITY 1.1 - 9.3.6.65 Copy and filter duplicates
  282. * For now, due to some devices keep generating different nfcid2, we use 1.0
  283. * Phones detected: Samsung Galaxy Nexus,Samsung Galaxy S3,Samsung Nexus S */
  284. *devCnt = 0;
  285. ret = rfalNfcfPollerPoll(
  286. RFAL_FELICA_16_SLOTS,
  287. RFAL_NFCF_SYSTEMCODE,
  288. RFAL_FELICA_POLL_RC_NO_REQUEST,
  289. gRfalNfcfGreedyF.POLL_F,
  290. &gRfalNfcfGreedyF.pollFound,
  291. &gRfalNfcfGreedyF.pollCollision);
  292. if(ret == ERR_NONE) {
  293. rfalNfcfComputeValidSENF(nfcfDevList, devCnt, devLimit, false, &nfcDepFound);
  294. }
  295. /*******************************************************************************/
  296. /* ACTIVITY 1.1 - 9.3.6.63 Check if any device supports NFC DEP */
  297. /*******************************************************************************/
  298. if(nfcDepFound && (compMode == RFAL_COMPLIANCE_MODE_NFC)) {
  299. ret = rfalNfcfPollerPoll(
  300. RFAL_FELICA_16_SLOTS,
  301. RFAL_NFCF_SYSTEMCODE,
  302. RFAL_FELICA_POLL_RC_SYSTEM_CODE,
  303. gRfalNfcfGreedyF.POLL_F,
  304. &gRfalNfcfGreedyF.pollFound,
  305. &gRfalNfcfGreedyF.pollCollision);
  306. if(ret == ERR_NONE) {
  307. rfalNfcfComputeValidSENF(nfcfDevList, devCnt, devLimit, true, &nfcDepFound);
  308. }
  309. }
  310. }
  311. return ERR_NONE;
  312. }
  313. /*******************************************************************************/
  314. ReturnCode rfalNfcfPollerCheck(
  315. const uint8_t* nfcid2,
  316. const rfalNfcfServBlockListParam* servBlock,
  317. uint8_t* rxBuf,
  318. uint16_t rxBufLen,
  319. uint16_t* rcvdLen) {
  320. uint8_t txBuf[RFAL_NFCF_CHECK_REQ_MAX_LEN];
  321. uint8_t msgIt;
  322. uint8_t i;
  323. ReturnCode ret;
  324. const uint8_t* checkRes;
  325. /* Check parameters */
  326. if((nfcid2 == NULL) || (rxBuf == NULL) || (servBlock == NULL) || (servBlock->numBlock == 0U) ||
  327. (servBlock->numBlock > RFAL_NFCF_CHECK_REQ_MAX_BLOCK) || (servBlock->numServ == 0U) ||
  328. (servBlock->numServ > RFAL_NFCF_CHECK_REQ_MAX_SERV) ||
  329. (rxBufLen < (RFAL_NFCF_LENGTH_LEN + RFAL_NFCF_CHECK_RES_MIN_LEN))) {
  330. return ERR_PARAM;
  331. }
  332. msgIt = 0;
  333. /*******************************************************************************/
  334. /* Compose CHECK command/request */
  335. txBuf[msgIt++] = RFAL_NFCF_CMD_READ_WITHOUT_ENCRYPTION; /* Command Code */
  336. ST_MEMCPY(&txBuf[msgIt], nfcid2, RFAL_NFCF_NFCID2_LEN); /* NFCID2 */
  337. msgIt += RFAL_NFCF_NFCID2_LEN;
  338. txBuf[msgIt++] = servBlock->numServ; /* NoS */
  339. for(i = 0; i < servBlock->numServ; i++) {
  340. txBuf[msgIt++] = (uint8_t)((servBlock->servList[i] >> 0U) & 0xFFU); /* Service Code */
  341. txBuf[msgIt++] = (uint8_t)((servBlock->servList[i] >> 8U) & 0xFFU);
  342. }
  343. txBuf[msgIt++] = servBlock->numBlock; /* NoB */
  344. for(i = 0; i < servBlock->numBlock; i++) {
  345. txBuf[msgIt++] =
  346. servBlock->blockList[i].conf; /* Block list element conf (Flag|Access|Service) */
  347. if((servBlock->blockList[i].conf & 0x80U) !=
  348. 0U) /* Check if 2 or 3 byte block list element */
  349. {
  350. txBuf[msgIt++] =
  351. (uint8_t)(servBlock->blockList[i].blockNum & 0xFFU); /* 1byte Block Num */
  352. } else {
  353. txBuf[msgIt++] =
  354. (uint8_t)((servBlock->blockList[i].blockNum >> 0U) & 0xFFU); /* 2byte Block Num */
  355. txBuf[msgIt++] = (uint8_t)((servBlock->blockList[i].blockNum >> 8U) & 0xFFU);
  356. }
  357. }
  358. /*******************************************************************************/
  359. /* Transceive CHECK command/request */
  360. ret = rfalTransceiveBlockingTxRx(
  361. txBuf,
  362. msgIt,
  363. rxBuf,
  364. rxBufLen,
  365. rcvdLen,
  366. RFAL_TXRX_FLAGS_DEFAULT,
  367. RFAL_NFCF_MRT_CHECK_UPDATE);
  368. if(ret == ERR_NONE) {
  369. /* Skip LEN byte */
  370. checkRes = (rxBuf + RFAL_NFCF_LENGTH_LEN);
  371. /* Check response length */
  372. if(*rcvdLen < (RFAL_NFCF_LENGTH_LEN + RFAL_NFCF_CHECKUPDATE_RES_ST2_POS)) {
  373. ret = ERR_PROTO;
  374. }
  375. /* Check for a valid response */
  376. else if(
  377. (checkRes[RFAL_NFCF_CMD_POS] != (uint8_t)RFAL_NFCF_CMD_READ_WITHOUT_ENCRYPTION_RES) ||
  378. (checkRes[RFAL_NFCF_CHECKUPDATE_RES_ST1_POS] != RFAL_NFCF_STATUS_FLAG_SUCCESS) ||
  379. (checkRes[RFAL_NFCF_CHECKUPDATE_RES_ST2_POS] != RFAL_NFCF_STATUS_FLAG_SUCCESS)) {
  380. ret = ERR_REQUEST;
  381. }
  382. /* CHECK succesfull, remove header */
  383. else {
  384. (*rcvdLen) -= (RFAL_NFCF_LENGTH_LEN + RFAL_NFCF_CHECKUPDATE_RES_NOB_POS);
  385. if(*rcvdLen > 0U) {
  386. ST_MEMMOVE(rxBuf, &checkRes[RFAL_NFCF_CHECKUPDATE_RES_NOB_POS], (*rcvdLen));
  387. }
  388. }
  389. }
  390. return ret;
  391. }
  392. /*******************************************************************************/
  393. ReturnCode rfalNfcfPollerUpdate(
  394. const uint8_t* nfcid2,
  395. const rfalNfcfServBlockListParam* servBlock,
  396. uint8_t* txBuf,
  397. uint16_t txBufLen,
  398. const uint8_t* blockData,
  399. uint8_t* rxBuf,
  400. uint16_t rxBufLen) {
  401. uint8_t i;
  402. uint16_t msgIt;
  403. uint16_t rcvdLen;
  404. uint16_t auxLen;
  405. const uint8_t* updateRes;
  406. ReturnCode ret;
  407. /* Check parameters */
  408. if((nfcid2 == NULL) || (rxBuf == NULL) || (servBlock == NULL) || (txBuf == NULL) ||
  409. (servBlock->numBlock == 0U) || (servBlock->numBlock > RFAL_NFCF_UPDATE_REQ_MAX_BLOCK) ||
  410. (servBlock->numServ == 0U) || (servBlock->numServ > RFAL_NFCF_UPDATE_REQ_MAX_SERV) ||
  411. (rxBufLen < (RFAL_NFCF_LENGTH_LEN + RFAL_NFCF_UPDATE_RES_MIN_LEN))) {
  412. return ERR_PARAM;
  413. }
  414. /* Calculate required txBuffer lenth */
  415. auxLen = (uint16_t)( RFAL_NFCF_CMD_LEN + RFAL_NFCF_NFCID2_LEN + ( servBlock->numServ * sizeof(rfalNfcfServ) ) +
  416. (servBlock->numBlock * sizeof(rfalNfcfBlockListElem)) + (uint16_t)((uint16_t)servBlock->numBlock * RFAL_NFCF_BLOCK_LEN) );
  417. /* Check whether the provided buffer is sufficient for this request */
  418. if(txBufLen < auxLen) {
  419. return ERR_PARAM;
  420. }
  421. msgIt = 0;
  422. /*******************************************************************************/
  423. /* Compose UPDATE command/request */
  424. txBuf[msgIt++] = RFAL_NFCF_CMD_WRITE_WITHOUT_ENCRYPTION; /* Command Code */
  425. ST_MEMCPY(&txBuf[msgIt], nfcid2, RFAL_NFCF_NFCID2_LEN); /* NFCID2 */
  426. msgIt += RFAL_NFCF_NFCID2_LEN;
  427. txBuf[msgIt++] = servBlock->numServ; /* NoS */
  428. for(i = 0; i < servBlock->numServ; i++) {
  429. txBuf[msgIt++] = (uint8_t)((servBlock->servList[i] >> 0U) & 0xFFU); /* Service Code */
  430. txBuf[msgIt++] = (uint8_t)((servBlock->servList[i] >> 8U) & 0xFFU);
  431. }
  432. txBuf[msgIt++] = servBlock->numBlock; /* NoB */
  433. for(i = 0; i < servBlock->numBlock; i++) {
  434. txBuf[msgIt++] =
  435. servBlock->blockList[i].conf; /* Block list element conf (Flag|Access|Service) */
  436. if((servBlock->blockList[i].conf & 0x80U) !=
  437. 0U) /* Check if 2 or 3 byte block list element */
  438. {
  439. txBuf[msgIt++] =
  440. (uint8_t)(servBlock->blockList[i].blockNum & 0xFFU); /* 1byte Block Num */
  441. } else {
  442. txBuf[msgIt++] =
  443. (uint8_t)((servBlock->blockList[i].blockNum >> 0U) & 0xFFU); /* 2byte Block Num */
  444. txBuf[msgIt++] = (uint8_t)((servBlock->blockList[i].blockNum >> 8U) & 0xFFU);
  445. }
  446. }
  447. auxLen = ((uint16_t)servBlock->numBlock * RFAL_NFCF_BLOCK_LEN);
  448. ST_MEMCPY(&txBuf[msgIt], blockData, auxLen); /* Block Data */
  449. msgIt += auxLen;
  450. /*******************************************************************************/
  451. /* Transceive UPDATE command/request */
  452. ret = rfalTransceiveBlockingTxRx(
  453. txBuf,
  454. msgIt,
  455. rxBuf,
  456. rxBufLen,
  457. &rcvdLen,
  458. RFAL_TXRX_FLAGS_DEFAULT,
  459. RFAL_NFCF_MRT_CHECK_UPDATE);
  460. if(ret == ERR_NONE) {
  461. /* Skip LEN byte */
  462. updateRes = (rxBuf + RFAL_NFCF_LENGTH_LEN);
  463. /* Check response length */
  464. if(rcvdLen < (RFAL_NFCF_LENGTH_LEN + RFAL_NFCF_CHECKUPDATE_RES_ST2_POS)) {
  465. ret = ERR_PROTO;
  466. }
  467. /* Check for a valid response */
  468. else if(
  469. (updateRes[RFAL_NFCF_CMD_POS] !=
  470. (uint8_t)RFAL_NFCF_CMD_WRITE_WITHOUT_ENCRYPTION_RES) ||
  471. (updateRes[RFAL_NFCF_CHECKUPDATE_RES_ST1_POS] != RFAL_NFCF_STATUS_FLAG_SUCCESS) ||
  472. (updateRes[RFAL_NFCF_CHECKUPDATE_RES_ST2_POS] != RFAL_NFCF_STATUS_FLAG_SUCCESS)) {
  473. ret = ERR_REQUEST;
  474. } else {
  475. /* MISRA 15.7 - Empty else */
  476. }
  477. }
  478. return ret;
  479. }
  480. /*******************************************************************************/
  481. bool rfalNfcfListenerIsT3TReq(const uint8_t* buf, uint16_t bufLen, uint8_t* nfcid2) {
  482. /* Check cmd byte */
  483. switch(*buf) {
  484. case RFAL_NFCF_CMD_READ_WITHOUT_ENCRYPTION:
  485. if(bufLen < RFAL_NFCF_READ_WO_ENCRYPTION_MIN_LEN) {
  486. return false;
  487. }
  488. break;
  489. case RFAL_NFCF_CMD_WRITE_WITHOUT_ENCRYPTION:
  490. if(bufLen < RFAL_NFCF_WRITE_WO_ENCRYPTION_MIN_LEN) {
  491. return false;
  492. }
  493. break;
  494. default:
  495. return false;
  496. }
  497. /* Output NFID2 if requested */
  498. if(nfcid2 != NULL) {
  499. ST_MEMCPY(nfcid2, &buf[RFAL_NFCF_CMD_LEN], RFAL_NFCF_NFCID2_LEN);
  500. }
  501. return true;
  502. }
  503. #endif /* RFAL_FEATURE_NFCF */