rfal_nfcf.c 23 KB

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