api-hal-nfc.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "api-hal-nfc.h"
  2. #include <st25r3916.h>
  3. static const uint32_t clocks_in_ms = 64 * 1000;
  4. static const rfalNfcDiscoverParam api_hal_nfc_emulate_params_mifare = {
  5. .compMode = RFAL_COMPLIANCE_MODE_NFC,
  6. .techs2Find = RFAL_NFC_LISTEN_TECH_A,
  7. .totalDuration = 1000,
  8. .devLimit = 1,
  9. .wakeupEnabled = false,
  10. .wakeupConfigDefault = true,
  11. .nfcfBR = RFAL_BR_212,
  12. .ap2pBR = RFAL_BR_424,
  13. .maxBR = RFAL_BR_KEEP,
  14. .GBLen = RFAL_NFCDEP_GB_MAX_LEN,
  15. .notifyCb = NULL,
  16. .lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_07,
  17. .lmConfigPA.nfcid[0] = 0X36,
  18. .lmConfigPA.nfcid[1] = 0x9C,
  19. .lmConfigPA.nfcid[2] = 0xE7,
  20. .lmConfigPA.nfcid[3] = 0xB1,
  21. .lmConfigPA.nfcid[4] = 0x0A,
  22. .lmConfigPA.nfcid[5] = 0xC1,
  23. .lmConfigPA.nfcid[6] = 0x34,
  24. .lmConfigPA.SENS_RES[0] = 0x44,
  25. .lmConfigPA.SENS_RES[1] = 0x00,
  26. .lmConfigPA.SEL_RES = 0x00,
  27. };
  28. static const rfalNfcDiscoverParam api_hal_nfc_emulate_params_emv = {
  29. .compMode = RFAL_COMPLIANCE_MODE_EMV,
  30. .techs2Find = RFAL_NFC_LISTEN_TECH_A,
  31. .totalDuration = 1000,
  32. .devLimit = 1,
  33. .wakeupEnabled = false,
  34. .wakeupConfigDefault = true,
  35. .nfcfBR = RFAL_BR_212,
  36. .ap2pBR = RFAL_BR_424,
  37. .maxBR = RFAL_BR_KEEP,
  38. .GBLen = RFAL_NFCDEP_GB_MAX_LEN,
  39. .notifyCb = NULL,
  40. .lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_04,
  41. .lmConfigPA.nfcid[0] = 0XCF,
  42. .lmConfigPA.nfcid[1] = 0x72,
  43. .lmConfigPA.nfcid[2] = 0xD4,
  44. .lmConfigPA.nfcid[3] = 0x40,
  45. .lmConfigPA.SENS_RES[0] = 0x04,
  46. .lmConfigPA.SENS_RES[1] = 0x00,
  47. .lmConfigPA.SEL_RES = 0x20,
  48. };
  49. ReturnCode api_hal_nfc_init() {
  50. // Check if Nfc worker was started
  51. if(rfalNfcGetState() > RFAL_NFC_STATE_NOTINIT) {
  52. return ERR_NONE;
  53. }
  54. return rfalNfcInitialize();
  55. }
  56. bool api_hal_nfc_is_busy() {
  57. return rfalNfcGetState() > RFAL_NFC_STATE_IDLE;
  58. }
  59. void api_hal_nfc_field_on() {
  60. api_hal_nfc_exit_sleep();
  61. st25r3916TxRxOn();
  62. }
  63. void api_hal_nfc_field_off() {
  64. st25r3916TxRxOff();
  65. api_hal_nfc_start_sleep();
  66. }
  67. void api_hal_nfc_start_sleep() {
  68. rfalLowPowerModeStart();
  69. }
  70. void api_hal_nfc_exit_sleep() {
  71. rfalLowPowerModeStop();
  72. }
  73. bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t timeout, bool deactivate) {
  74. furi_assert(dev_list);
  75. furi_assert(dev_cnt);
  76. rfalLowPowerModeStop();
  77. rfalNfcState state = rfalNfcGetState();
  78. if(state == RFAL_NFC_STATE_NOTINIT) {
  79. rfalNfcInitialize();
  80. }
  81. rfalNfcDiscoverParam params;
  82. params.compMode = RFAL_COMPLIANCE_MODE_EMV;
  83. params.techs2Find = RFAL_NFC_POLL_TECH_A | RFAL_NFC_POLL_TECH_B | RFAL_NFC_POLL_TECH_F |
  84. RFAL_NFC_POLL_TECH_V | RFAL_NFC_POLL_TECH_AP2P | RFAL_NFC_POLL_TECH_ST25TB;
  85. params.totalDuration = 1000;
  86. params.devLimit = 3;
  87. params.wakeupEnabled = false;
  88. params.wakeupConfigDefault = true;
  89. params.nfcfBR = RFAL_BR_212;
  90. params.ap2pBR = RFAL_BR_424;
  91. params.maxBR = RFAL_BR_KEEP;
  92. params.GBLen = RFAL_NFCDEP_GB_MAX_LEN;
  93. params.notifyCb = NULL;
  94. uint32_t start = DWT->CYCCNT;
  95. rfalNfcDiscover(&params);
  96. while(state != RFAL_NFC_STATE_ACTIVATED) {
  97. rfalNfcWorker();
  98. state = rfalNfcGetState();
  99. FURI_LOG_D("HAL NFC", "Current state %d", state);
  100. if(state == RFAL_NFC_STATE_POLL_ACTIVATION) {
  101. start = DWT->CYCCNT;
  102. continue;
  103. }
  104. if(state == RFAL_NFC_STATE_POLL_SELECT) {
  105. rfalNfcSelect(0);
  106. }
  107. if(DWT->CYCCNT - start > timeout * clocks_in_ms) {
  108. rfalNfcDeactivate(true);
  109. FURI_LOG_D("HAL NFC", "Timeout");
  110. return false;
  111. }
  112. osThreadYield();
  113. }
  114. rfalNfcGetDevicesFound(dev_list, dev_cnt);
  115. if(deactivate) {
  116. rfalNfcDeactivate(false);
  117. rfalLowPowerModeStart();
  118. }
  119. return true;
  120. }
  121. bool api_hal_nfc_listen(ApiHalNfcEmulateParams params, uint32_t timeout) {
  122. api_hal_nfc_exit_sleep();
  123. rfalNfcState state = rfalNfcGetState();
  124. if(state == RFAL_NFC_STATE_NOTINIT) {
  125. rfalNfcInitialize();
  126. } else if(state >= RFAL_NFC_STATE_ACTIVATED) {
  127. rfalNfcDeactivate(false);
  128. }
  129. if(params == ApiHalNfcEmulateParamsMifare) {
  130. rfalNfcDiscover(&api_hal_nfc_emulate_params_mifare);
  131. } else if(params == ApiHalNfcEmulateParamsEMV) {
  132. rfalNfcDiscover(&api_hal_nfc_emulate_params_emv);
  133. }
  134. uint32_t start = DWT->CYCCNT;
  135. while(state != RFAL_NFC_STATE_ACTIVATED) {
  136. rfalNfcWorker();
  137. state = rfalNfcGetState();
  138. FURI_LOG_D("HAL NFC", "Current state %d", state);
  139. if(DWT->CYCCNT - start > timeout * clocks_in_ms) {
  140. rfalNfcDeactivate(true);
  141. return false;
  142. }
  143. if(state == RFAL_NFC_STATE_LISTEN_ACTIVATION) {
  144. start = DWT->CYCCNT;
  145. continue;
  146. }
  147. osThreadYield();
  148. }
  149. return true;
  150. }
  151. ReturnCode api_hal_nfc_data_exchange(uint8_t* tx_buff, uint16_t tx_len, uint8_t** rx_buff, uint16_t** rx_len, bool deactivate) {
  152. furi_assert(rx_buff);
  153. furi_assert(rx_len);
  154. ReturnCode ret;
  155. rfalNfcState state = RFAL_NFC_STATE_ACTIVATED;
  156. ret = rfalNfcDataExchangeStart(tx_buff, tx_len, rx_buff, rx_len, 0);
  157. if(ret != ERR_NONE) {
  158. return ret;
  159. }
  160. uint32_t start = DWT->CYCCNT;
  161. while(state != RFAL_NFC_STATE_DATAEXCHANGE_DONE) {
  162. rfalNfcWorker();
  163. state = rfalNfcGetState();
  164. ret = rfalNfcDataExchangeGetStatus();
  165. FURI_LOG_D("HAL NFC", "Nfc st: %d Data st: %d", state, ret);
  166. if(ret > ERR_SLEEP_REQ) {
  167. return ret;
  168. }
  169. if(ret == ERR_BUSY) {
  170. if(DWT->CYCCNT - start > 1000 * clocks_in_ms) {
  171. return ERR_TIMEOUT;
  172. }
  173. continue;
  174. } else {
  175. start = DWT->CYCCNT;
  176. }
  177. taskYIELD();
  178. }
  179. if(deactivate) {
  180. rfalNfcDeactivate(false);
  181. rfalLowPowerModeStart();
  182. }
  183. return ERR_NONE;
  184. }
  185. void api_hal_nfc_deactivate() {
  186. rfalNfcDeactivate(false);
  187. rfalLowPowerModeStart();
  188. }