nfc_worker.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #include "nfc_worker_i.h"
  2. #include <api-hal.h>
  3. #include "nfc_protocols/emv_decoder.h"
  4. #define NFC_WORKER_TAG "nfc worker"
  5. NfcWorker* nfc_worker_alloc(osMessageQueueId_t message_queue) {
  6. NfcWorker* nfc_worker = furi_alloc(sizeof(NfcWorker));
  7. nfc_worker->message_queue = message_queue;
  8. // Worker thread attributes
  9. nfc_worker->thread_attr.name = "nfc_worker";
  10. nfc_worker->thread_attr.stack_size = 8192;
  11. // Initialize rfal
  12. nfc_worker->error = api_hal_nfc_init();
  13. if(nfc_worker->error == ERR_NONE) {
  14. api_hal_nfc_start_sleep();
  15. nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
  16. } else {
  17. nfc_worker_change_state(nfc_worker, NfcWorkerStateBroken);
  18. }
  19. return nfc_worker;
  20. }
  21. void nfc_worker_free(NfcWorker* nfc_worker) {
  22. furi_assert(nfc_worker);
  23. free(nfc_worker);
  24. }
  25. NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker) {
  26. return nfc_worker->state;
  27. }
  28. ReturnCode nfc_worker_get_error(NfcWorker* nfc_worker) {
  29. return nfc_worker->error;
  30. }
  31. void nfc_worker_start(NfcWorker* nfc_worker, NfcWorkerState state) {
  32. furi_assert(nfc_worker);
  33. furi_assert(nfc_worker->state == NfcWorkerStateReady);
  34. nfc_worker_change_state(nfc_worker, state);
  35. nfc_worker->thread = osThreadNew(nfc_worker_task, nfc_worker, &nfc_worker->thread_attr);
  36. }
  37. void nfc_worker_stop(NfcWorker* nfc_worker) {
  38. furi_assert(nfc_worker);
  39. if(nfc_worker->state == NfcWorkerStateBroken) {
  40. return;
  41. }
  42. nfc_worker_change_state(nfc_worker, NfcWorkerStateStop);
  43. }
  44. void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) {
  45. nfc_worker->state = state;
  46. }
  47. void nfc_worker_task(void* context) {
  48. NfcWorker* nfc_worker = context;
  49. api_hal_power_insomnia_enter();
  50. api_hal_nfc_exit_sleep();
  51. if(nfc_worker->state == NfcWorkerStatePoll) {
  52. nfc_worker_poll(nfc_worker);
  53. } else if(nfc_worker->state == NfcWorkerStateReadEMV) {
  54. nfc_worker_read_emv(nfc_worker);
  55. } else if(nfc_worker->state == NfcWorkerStateEmulateEMV) {
  56. nfc_worker_emulate_emv(nfc_worker);
  57. } else if(nfc_worker->state == NfcWorkerStateEmulate) {
  58. nfc_worker_emulate(nfc_worker);
  59. } else if(nfc_worker->state == NfcWorkerStateField) {
  60. nfc_worker_field(nfc_worker);
  61. }
  62. api_hal_nfc_deactivate();
  63. nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
  64. api_hal_power_insomnia_exit();
  65. osThreadExit();
  66. }
  67. void nfc_worker_read_emv(NfcWorker* nfc_worker) {
  68. ReturnCode err;
  69. rfalNfcDevice* dev_list;
  70. EmvApplication emv_app = {};
  71. uint8_t dev_cnt = 0;
  72. uint8_t tx_buff[255] = {};
  73. uint16_t tx_len = 0;
  74. uint8_t* rx_buff;
  75. uint16_t* rx_len;
  76. // Update screen before start searching
  77. NfcMessage message = {.type = NfcMessageTypeEMVNotFound};
  78. while(nfc_worker->state == NfcWorkerStateReadEMV) {
  79. furi_check(
  80. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  81. memset(&emv_app, 0, sizeof(emv_app));
  82. if(api_hal_nfc_detect(&dev_list, &dev_cnt, 100, false)) {
  83. // Card was found. Check that it supports EMV
  84. if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
  85. FURI_LOG_I(NFC_WORKER_TAG, "Send select PPSE command");
  86. tx_len = emv_prepare_select_ppse(tx_buff);
  87. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  88. if(err != ERR_NONE) {
  89. FURI_LOG_E(NFC_WORKER_TAG, "Error during selection PPSE request: %d", err);
  90. message.type = NfcMessageTypeEMVNotFound;
  91. api_hal_nfc_deactivate();
  92. continue;
  93. }
  94. FURI_LOG_I(
  95. NFC_WORKER_TAG, "Select PPSE response received. Start parsing response");
  96. if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) {
  97. FURI_LOG_I(NFC_WORKER_TAG, "Select PPSE responce parced");
  98. } else {
  99. FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application");
  100. message.type = NfcMessageTypeEMVNotFound;
  101. api_hal_nfc_deactivate();
  102. continue;
  103. }
  104. FURI_LOG_I(NFC_WORKER_TAG, "Starting application ...");
  105. tx_len = emv_prepare_select_app(tx_buff, &emv_app);
  106. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  107. if(err != ERR_NONE) {
  108. FURI_LOG_E(
  109. NFC_WORKER_TAG, "Error during application selection request: %d", err);
  110. message.type = NfcMessageTypeEMVNotFound;
  111. api_hal_nfc_deactivate();
  112. continue;
  113. }
  114. FURI_LOG_I(
  115. NFC_WORKER_TAG,
  116. "Select application response received. Start parsing response");
  117. if(emv_decode_select_app_response(rx_buff, *rx_len, &emv_app)) {
  118. FURI_LOG_I(NFC_WORKER_TAG, "Card name: %s", emv_app.name);
  119. memcpy(message.device.emv_card.name, emv_app.name, sizeof(emv_app.name));
  120. } else {
  121. FURI_LOG_E(NFC_WORKER_TAG, "Can't read card name");
  122. message.type = NfcMessageTypeEMVNotFound;
  123. api_hal_nfc_deactivate();
  124. continue;
  125. }
  126. FURI_LOG_I(NFC_WORKER_TAG, "Starting Get Processing Options command ...");
  127. tx_len = emv_prepare_get_proc_opt(tx_buff, &emv_app);
  128. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  129. if(err != ERR_NONE) {
  130. FURI_LOG_E(
  131. NFC_WORKER_TAG, "Error during Get Processing Options command: %d", err);
  132. message.type = NfcMessageTypeEMVNotFound;
  133. api_hal_nfc_deactivate();
  134. continue;
  135. }
  136. if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) {
  137. FURI_LOG_I(NFC_WORKER_TAG, "Card number parsed");
  138. message.type = NfcMessageTypeEMVFound;
  139. memcpy(
  140. message.device.emv_card.number,
  141. emv_app.card_number,
  142. sizeof(emv_app.card_number));
  143. api_hal_nfc_deactivate();
  144. continue;
  145. } else {
  146. // Mastercard doesn't give PAN / card number as GPO response
  147. // Iterate over all files found in application
  148. bool pan_found = false;
  149. for(uint8_t i = 0; (i < emv_app.afl.size) && !pan_found; i += 4) {
  150. uint8_t sfi = emv_app.afl.data[i] >> 3;
  151. uint8_t record_start = emv_app.afl.data[i + 1];
  152. uint8_t record_end = emv_app.afl.data[i + 2];
  153. // Iterate over all records in file
  154. for(uint8_t record = record_start; record <= record_end; ++record) {
  155. tx_len = emv_prepare_read_sfi_record(tx_buff, sfi, record);
  156. err = api_hal_nfc_data_exchange(
  157. tx_buff, tx_len, &rx_buff, &rx_len, false);
  158. if(err != ERR_NONE) {
  159. FURI_LOG_E(
  160. NFC_WORKER_TAG,
  161. "Error reading application sfi %d, record %d",
  162. sfi,
  163. record);
  164. }
  165. if(emv_decode_read_sfi_record(rx_buff, *rx_len, &emv_app)) {
  166. pan_found = true;
  167. break;
  168. }
  169. }
  170. }
  171. if(pan_found) {
  172. FURI_LOG_I(NFC_WORKER_TAG, "Card PAN found");
  173. message.type = NfcMessageTypeEMVFound;
  174. memcpy(
  175. message.device.emv_card.number,
  176. emv_app.card_number,
  177. sizeof(emv_app.card_number));
  178. } else {
  179. FURI_LOG_E(NFC_WORKER_TAG, "Can't read card number");
  180. message.type = NfcMessageTypeEMVNotFound;
  181. }
  182. api_hal_nfc_deactivate();
  183. }
  184. } else {
  185. // Can't find EMV card
  186. FURI_LOG_W(NFC_WORKER_TAG, "Card doesn't support EMV");
  187. message.type = NfcMessageTypeEMVNotFound;
  188. api_hal_nfc_deactivate();
  189. }
  190. } else {
  191. // Can't find EMV card
  192. FURI_LOG_W(NFC_WORKER_TAG, "Can't find any cards");
  193. message.type = NfcMessageTypeEMVNotFound;
  194. api_hal_nfc_deactivate();
  195. }
  196. osDelay(20);
  197. }
  198. }
  199. void nfc_worker_emulate_emv(NfcWorker* nfc_worker) {
  200. ReturnCode err;
  201. uint8_t tx_buff[255] = {};
  202. uint16_t tx_len = 0;
  203. uint8_t* rx_buff;
  204. uint16_t* rx_len;
  205. while(nfc_worker->state == NfcWorkerStateEmulateEMV) {
  206. if(api_hal_nfc_listen(1000)) {
  207. FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected");
  208. // Read data from POS terminal
  209. err = api_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false);
  210. if(err == ERR_NONE) {
  211. FURI_LOG_I(NFC_WORKER_TAG, "Received Select PPSE");
  212. } else {
  213. FURI_LOG_E(NFC_WORKER_TAG, "Error in 1st data exchange: select PPSE");
  214. api_hal_nfc_deactivate();
  215. continue;
  216. }
  217. FURI_LOG_I(NFC_WORKER_TAG, "Transive SELECT PPSE ANS");
  218. tx_len = emv_select_ppse_ans(tx_buff);
  219. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  220. if(err == ERR_NONE) {
  221. FURI_LOG_I(NFC_WORKER_TAG, "Received Select APP");
  222. } else {
  223. FURI_LOG_E(NFC_WORKER_TAG, "Error in 2nd data exchange: select APP");
  224. api_hal_nfc_deactivate();
  225. continue;
  226. }
  227. FURI_LOG_I(NFC_WORKER_TAG, "Transive SELECT APP ANS");
  228. tx_len = emv_select_app_ans(tx_buff);
  229. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  230. if(err == ERR_NONE) {
  231. FURI_LOG_I(NFC_WORKER_TAG, "Received PDOL");
  232. } else {
  233. FURI_LOG_E(NFC_WORKER_TAG, "Error in 3rd data exchange: receive PDOL");
  234. api_hal_nfc_deactivate();
  235. continue;
  236. }
  237. FURI_LOG_I(NFC_WORKER_TAG, "Transive PDOL ANS");
  238. tx_len = emv_get_proc_opt_ans(tx_buff);
  239. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  240. if(err == ERR_NONE) {
  241. FURI_LOG_I(NFC_WORKER_TAG, "Received PDOL");
  242. }
  243. api_hal_nfc_deactivate();
  244. } else {
  245. FURI_LOG_W(NFC_WORKER_TAG, "Can't find reader");
  246. }
  247. osDelay(20);
  248. }
  249. }
  250. void nfc_worker_poll(NfcWorker* nfc_worker) {
  251. rfalNfcDevice* dev_list;
  252. uint8_t dev_cnt;
  253. // Update screen before start searching
  254. NfcMessage message = {.type = NfcMessageTypeDeviceNotFound};
  255. furi_check(osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  256. while(nfc_worker->state == NfcWorkerStatePoll) {
  257. if(api_hal_nfc_detect(&dev_list, &dev_cnt, 100, true)) {
  258. // Send message with first device found
  259. message.type = NfcMessageTypeDeviceFound;
  260. if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCA) {
  261. message.device.type = NfcDeviceTypeNfca;
  262. message.device.nfca = dev_list[0].dev.nfca;
  263. } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCB) {
  264. message.device.type = NfcDeviceTypeNfcb;
  265. message.device.nfcb = dev_list[0].dev.nfcb;
  266. } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCF) {
  267. message.device.type = NfcDeviceTypeNfcf;
  268. message.device.nfcf = dev_list[0].dev.nfcf;
  269. } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCV) {
  270. message.device.type = NfcDeviceTypeNfcv;
  271. message.device.nfcv = dev_list[0].dev.nfcv;
  272. } else {
  273. // TODO show information about all found devices
  274. message.type = NfcMessageTypeDeviceNotFound;
  275. }
  276. furi_check(
  277. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  278. } else {
  279. message.type = NfcMessageTypeDeviceNotFound;
  280. furi_check(
  281. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  282. }
  283. osDelay(5);
  284. }
  285. }
  286. void nfc_worker_emulate(NfcWorker* nfc_worker) {
  287. while(nfc_worker->state == NfcWorkerStateEmulate) {
  288. if(api_hal_nfc_listen(100)) {
  289. FURI_LOG_I(NFC_WORKER_TAG, "Reader detected");
  290. api_hal_nfc_deactivate();
  291. }
  292. osDelay(5);
  293. }
  294. }
  295. void nfc_worker_field(NfcWorker* nfc_worker) {
  296. api_hal_nfc_field_on();
  297. while(nfc_worker->state == NfcWorkerStateField) {
  298. osDelay(50);
  299. }
  300. api_hal_nfc_field_off();
  301. }