furi_hal_nfc.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #include "furi_hal_nfc.h"
  2. #include <st25r3916.h>
  3. #define TAG "FuriHalNfc"
  4. static const uint32_t clocks_in_ms = 64 * 1000;
  5. void furi_hal_nfc_init() {
  6. ReturnCode ret = rfalNfcInitialize();
  7. if(ret == ERR_NONE) {
  8. furi_hal_nfc_start_sleep();
  9. FURI_LOG_I(TAG, "Init OK");
  10. } else {
  11. FURI_LOG_W(TAG, "Initialization failed, RFAL returned: %d", ret);
  12. }
  13. }
  14. bool furi_hal_nfc_is_busy() {
  15. return rfalNfcGetState() != RFAL_NFC_STATE_IDLE;
  16. }
  17. void furi_hal_nfc_field_on() {
  18. furi_hal_nfc_exit_sleep();
  19. st25r3916TxRxOn();
  20. }
  21. void furi_hal_nfc_field_off() {
  22. st25r3916TxRxOff();
  23. furi_hal_nfc_start_sleep();
  24. }
  25. void furi_hal_nfc_start_sleep() {
  26. rfalLowPowerModeStart();
  27. }
  28. void furi_hal_nfc_exit_sleep() {
  29. rfalLowPowerModeStop();
  30. }
  31. bool furi_hal_nfc_detect(
  32. rfalNfcDevice** dev_list,
  33. uint8_t* dev_cnt,
  34. uint32_t timeout,
  35. bool deactivate) {
  36. furi_assert(dev_list);
  37. furi_assert(dev_cnt);
  38. rfalLowPowerModeStop();
  39. rfalNfcState state = rfalNfcGetState();
  40. if(state == RFAL_NFC_STATE_NOTINIT) {
  41. rfalNfcInitialize();
  42. }
  43. rfalNfcDiscoverParam params;
  44. params.compMode = RFAL_COMPLIANCE_MODE_EMV;
  45. params.techs2Find = RFAL_NFC_POLL_TECH_A | RFAL_NFC_POLL_TECH_B | RFAL_NFC_POLL_TECH_F |
  46. RFAL_NFC_POLL_TECH_V | RFAL_NFC_POLL_TECH_AP2P | RFAL_NFC_POLL_TECH_ST25TB;
  47. params.totalDuration = 1000;
  48. params.devLimit = 3;
  49. params.wakeupEnabled = false;
  50. params.wakeupConfigDefault = true;
  51. params.nfcfBR = RFAL_BR_212;
  52. params.ap2pBR = RFAL_BR_424;
  53. params.maxBR = RFAL_BR_KEEP;
  54. params.GBLen = RFAL_NFCDEP_GB_MAX_LEN;
  55. params.notifyCb = NULL;
  56. uint32_t start = DWT->CYCCNT;
  57. rfalNfcDiscover(&params);
  58. while(state != RFAL_NFC_STATE_ACTIVATED) {
  59. rfalNfcWorker();
  60. state = rfalNfcGetState();
  61. FURI_LOG_T(TAG, "Current state %d", state);
  62. if(state == RFAL_NFC_STATE_POLL_ACTIVATION) {
  63. start = DWT->CYCCNT;
  64. continue;
  65. }
  66. if(state == RFAL_NFC_STATE_POLL_SELECT) {
  67. rfalNfcSelect(0);
  68. }
  69. if(DWT->CYCCNT - start > timeout * clocks_in_ms) {
  70. rfalNfcDeactivate(true);
  71. FURI_LOG_T(TAG, "Timeout");
  72. return false;
  73. }
  74. osThreadYield();
  75. }
  76. rfalNfcGetDevicesFound(dev_list, dev_cnt);
  77. if(deactivate) {
  78. rfalNfcDeactivate(false);
  79. rfalLowPowerModeStart();
  80. }
  81. return true;
  82. }
  83. bool furi_hal_nfc_listen(
  84. uint8_t* uid,
  85. uint8_t uid_len,
  86. uint8_t* atqa,
  87. uint8_t sak,
  88. bool activate_after_sak,
  89. uint32_t timeout) {
  90. rfalNfcState state = rfalNfcGetState();
  91. if(state == RFAL_NFC_STATE_NOTINIT) {
  92. rfalNfcInitialize();
  93. } else if(state >= RFAL_NFC_STATE_ACTIVATED) {
  94. rfalNfcDeactivate(false);
  95. }
  96. rfalLowPowerModeStop();
  97. rfalNfcDiscoverParam params = {
  98. .compMode = RFAL_COMPLIANCE_MODE_NFC,
  99. .techs2Find = RFAL_NFC_LISTEN_TECH_A,
  100. .totalDuration = 1000,
  101. .devLimit = 1,
  102. .wakeupEnabled = false,
  103. .wakeupConfigDefault = true,
  104. .nfcfBR = RFAL_BR_212,
  105. .ap2pBR = RFAL_BR_424,
  106. .maxBR = RFAL_BR_KEEP,
  107. .GBLen = RFAL_NFCDEP_GB_MAX_LEN,
  108. .notifyCb = NULL,
  109. .activate_after_sak = activate_after_sak,
  110. };
  111. params.lmConfigPA.nfcidLen = uid_len;
  112. memcpy(params.lmConfigPA.nfcid, uid, uid_len);
  113. params.lmConfigPA.SENS_RES[0] = atqa[0];
  114. params.lmConfigPA.SENS_RES[1] = atqa[1];
  115. params.lmConfigPA.SEL_RES = sak;
  116. rfalNfcDiscover(&params);
  117. uint32_t start = DWT->CYCCNT;
  118. while(state != RFAL_NFC_STATE_ACTIVATED) {
  119. rfalNfcWorker();
  120. state = rfalNfcGetState();
  121. if(DWT->CYCCNT - start > timeout * clocks_in_ms) {
  122. rfalNfcDeactivate(true);
  123. return false;
  124. }
  125. osThreadYield();
  126. }
  127. return true;
  128. }
  129. bool furi_hal_nfc_get_first_frame(uint8_t** rx_buff, uint16_t** rx_len) {
  130. ReturnCode ret =
  131. rfalNfcDataExchangeStart(NULL, 0, rx_buff, rx_len, 0, RFAL_TXRX_FLAGS_DEFAULT);
  132. return ret == ERR_NONE;
  133. }
  134. ReturnCode furi_hal_nfc_data_exchange(
  135. uint8_t* tx_buff,
  136. uint16_t tx_len,
  137. uint8_t** rx_buff,
  138. uint16_t** rx_len,
  139. bool deactivate) {
  140. furi_assert(rx_buff);
  141. furi_assert(rx_len);
  142. ReturnCode ret;
  143. rfalNfcState state = RFAL_NFC_STATE_ACTIVATED;
  144. ret = rfalNfcDataExchangeStart(tx_buff, tx_len, rx_buff, rx_len, 0, RFAL_TXRX_FLAGS_DEFAULT);
  145. if(ret != ERR_NONE) {
  146. return ret;
  147. }
  148. uint32_t start = DWT->CYCCNT;
  149. while(state != RFAL_NFC_STATE_DATAEXCHANGE_DONE) {
  150. rfalNfcWorker();
  151. state = rfalNfcGetState();
  152. ret = rfalNfcDataExchangeGetStatus();
  153. if(ret > ERR_SLEEP_REQ) {
  154. return ret;
  155. }
  156. if(ret == ERR_BUSY) {
  157. if(DWT->CYCCNT - start > 1000 * clocks_in_ms) {
  158. return ERR_TIMEOUT;
  159. }
  160. continue;
  161. } else {
  162. start = DWT->CYCCNT;
  163. }
  164. taskYIELD();
  165. }
  166. if(deactivate) {
  167. rfalNfcDeactivate(false);
  168. rfalLowPowerModeStart();
  169. }
  170. return ERR_NONE;
  171. }
  172. ReturnCode furi_hal_nfc_raw_bitstream_exchange(
  173. uint8_t* tx_buff,
  174. uint16_t tx_bit_len,
  175. uint8_t** rx_buff,
  176. uint16_t** rx_bit_len,
  177. bool deactivate) {
  178. furi_assert(rx_buff);
  179. furi_assert(rx_bit_len);
  180. ReturnCode ret;
  181. rfalNfcState state = RFAL_NFC_STATE_ACTIVATED;
  182. ret =
  183. rfalNfcDataExchangeStart(tx_buff, tx_bit_len, rx_buff, rx_bit_len, 0, RFAL_TXRX_FLAGS_RAW);
  184. if(ret != ERR_NONE) {
  185. return ret;
  186. }
  187. uint32_t start = DWT->CYCCNT;
  188. while(state != RFAL_NFC_STATE_DATAEXCHANGE_DONE) {
  189. rfalNfcWorker();
  190. state = rfalNfcGetState();
  191. ret = rfalNfcDataExchangeGetStatus();
  192. if(ret > ERR_SLEEP_REQ) {
  193. return ret;
  194. }
  195. if(ret == ERR_BUSY) {
  196. if(DWT->CYCCNT - start > 1000 * clocks_in_ms) {
  197. return ERR_TIMEOUT;
  198. }
  199. continue;
  200. } else {
  201. start = DWT->CYCCNT;
  202. }
  203. taskYIELD();
  204. }
  205. if(deactivate) {
  206. rfalNfcDeactivate(false);
  207. rfalLowPowerModeStart();
  208. }
  209. return ERR_NONE;
  210. }
  211. void furi_hal_nfc_deactivate() {
  212. rfalNfcDeactivate(false);
  213. rfalLowPowerModeStart();
  214. }