api-hal-nfc.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  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. rfalNfcState state = rfalNfcGetState();
  52. if(state == RFAL_NFC_STATE_NOTINIT) {
  53. return rfalNfcInitialize();
  54. } else if(state == RFAL_NFC_STATE_IDLE) {
  55. return ERR_NONE;
  56. } else {
  57. return ERR_BUSY;
  58. }
  59. }
  60. bool api_hal_nfc_is_busy() {
  61. return rfalNfcGetState() > RFAL_NFC_STATE_IDLE;
  62. }
  63. void api_hal_nfc_field_on() {
  64. api_hal_nfc_exit_sleep();
  65. st25r3916TxRxOn();
  66. }
  67. void api_hal_nfc_field_off() {
  68. st25r3916TxRxOff();
  69. api_hal_nfc_start_sleep();
  70. }
  71. void api_hal_nfc_start_sleep() {
  72. rfalLowPowerModeStart();
  73. }
  74. void api_hal_nfc_exit_sleep() {
  75. rfalLowPowerModeStop();
  76. }
  77. bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t timeout, bool deactivate) {
  78. furi_assert(dev_list);
  79. furi_assert(dev_cnt);
  80. rfalLowPowerModeStop();
  81. rfalNfcState state = rfalNfcGetState();
  82. if(state == RFAL_NFC_STATE_NOTINIT) {
  83. rfalNfcInitialize();
  84. }
  85. rfalNfcDiscoverParam params;
  86. params.compMode = RFAL_COMPLIANCE_MODE_EMV;
  87. params.techs2Find = RFAL_NFC_POLL_TECH_A | RFAL_NFC_POLL_TECH_B | RFAL_NFC_POLL_TECH_F |
  88. RFAL_NFC_POLL_TECH_V | RFAL_NFC_POLL_TECH_AP2P | RFAL_NFC_POLL_TECH_ST25TB;
  89. params.totalDuration = 1000;
  90. params.devLimit = 3;
  91. params.wakeupEnabled = false;
  92. params.wakeupConfigDefault = true;
  93. params.nfcfBR = RFAL_BR_212;
  94. params.ap2pBR = RFAL_BR_424;
  95. params.maxBR = RFAL_BR_KEEP;
  96. params.GBLen = RFAL_NFCDEP_GB_MAX_LEN;
  97. params.notifyCb = NULL;
  98. uint32_t start = DWT->CYCCNT;
  99. rfalNfcDiscover(&params);
  100. while(state != RFAL_NFC_STATE_ACTIVATED) {
  101. rfalNfcWorker();
  102. state = rfalNfcGetState();
  103. FURI_LOG_D("HAL NFC", "Current state %d", state);
  104. if(state == RFAL_NFC_STATE_POLL_ACTIVATION) {
  105. start = DWT->CYCCNT;
  106. continue;
  107. }
  108. if(state == RFAL_NFC_STATE_POLL_SELECT) {
  109. rfalNfcSelect(0);
  110. }
  111. if(DWT->CYCCNT - start > timeout * clocks_in_ms) {
  112. rfalNfcDeactivate(true);
  113. FURI_LOG_D("HAL NFC", "Timeout");
  114. return false;
  115. }
  116. osThreadYield();
  117. }
  118. rfalNfcGetDevicesFound(dev_list, dev_cnt);
  119. if(deactivate) {
  120. rfalNfcDeactivate(false);
  121. rfalLowPowerModeStart();
  122. }
  123. return true;
  124. }
  125. bool api_hal_nfc_listen(ApiHalNfcEmulateParams params, uint32_t timeout) {
  126. api_hal_nfc_exit_sleep();
  127. rfalNfcState state = rfalNfcGetState();
  128. if(state == RFAL_NFC_STATE_NOTINIT) {
  129. rfalNfcInitialize();
  130. } else if(state >= RFAL_NFC_STATE_ACTIVATED) {
  131. rfalNfcDeactivate(false);
  132. }
  133. if(params == ApiHalNfcEmulateParamsMifare) {
  134. rfalNfcDiscover(&api_hal_nfc_emulate_params_mifare);
  135. } else if(params == ApiHalNfcEmulateParamsEMV) {
  136. rfalNfcDiscover(&api_hal_nfc_emulate_params_emv);
  137. }
  138. uint32_t start = DWT->CYCCNT;
  139. while(state != RFAL_NFC_STATE_ACTIVATED) {
  140. rfalNfcWorker();
  141. state = rfalNfcGetState();
  142. FURI_LOG_D("HAL NFC", "Current state %d", state);
  143. if(DWT->CYCCNT - start > timeout * clocks_in_ms) {
  144. rfalNfcDeactivate(true);
  145. return false;
  146. }
  147. if(state == RFAL_NFC_STATE_LISTEN_ACTIVATION) {
  148. start = DWT->CYCCNT;
  149. continue;
  150. }
  151. osThreadYield();
  152. }
  153. return true;
  154. }
  155. ReturnCode api_hal_nfc_data_exchange(uint8_t* tx_buff, uint16_t tx_len, uint8_t** rx_buff, uint16_t** rx_len, bool deactivate) {
  156. furi_assert(rx_buff);
  157. furi_assert(rx_len);
  158. ReturnCode ret;
  159. rfalNfcState state = RFAL_NFC_STATE_ACTIVATED;
  160. ret = rfalNfcDataExchangeStart(tx_buff, tx_len, rx_buff, rx_len, 0);
  161. if(ret != ERR_NONE) {
  162. return ret;
  163. }
  164. uint32_t start = DWT->CYCCNT;
  165. while(state != RFAL_NFC_STATE_DATAEXCHANGE_DONE) {
  166. rfalNfcWorker();
  167. state = rfalNfcGetState();
  168. ret = rfalNfcDataExchangeGetStatus();
  169. FURI_LOG_D("HAL NFC", "Nfc st: %d Data st: %d", state, ret);
  170. if(ret > ERR_SLEEP_REQ) {
  171. return ret;
  172. }
  173. if(ret == ERR_BUSY) {
  174. if(DWT->CYCCNT - start > 1000 * clocks_in_ms) {
  175. return ERR_TIMEOUT;
  176. }
  177. continue;
  178. } else {
  179. start = DWT->CYCCNT;
  180. }
  181. taskYIELD();
  182. }
  183. if(deactivate) {
  184. rfalNfcDeactivate(false);
  185. rfalLowPowerModeStart();
  186. }
  187. return ERR_NONE;
  188. }
  189. void api_hal_nfc_deactivate() {
  190. rfalNfcDeactivate(false);
  191. rfalLowPowerModeStart();
  192. }