nfc_worker.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  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. if(nfc_worker->state == NfcWorkerStatePoll) {
  51. nfc_worker_poll(nfc_worker);
  52. } else if(nfc_worker->state == NfcWorkerStateReadEMV) {
  53. nfc_worker_read_emv(nfc_worker);
  54. } else if(nfc_worker->state == NfcWorkerStateEmulateEMV) {
  55. nfc_worker_emulate_emv(nfc_worker);
  56. } else if(nfc_worker->state == NfcWorkerStateEmulate) {
  57. nfc_worker_emulate(nfc_worker);
  58. } else if(nfc_worker->state == NfcWorkerStateField) {
  59. nfc_worker_field(nfc_worker);
  60. }
  61. nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
  62. api_hal_power_insomnia_exit();
  63. osThreadExit();
  64. }
  65. void nfc_worker_read_emv(NfcWorker* nfc_worker) {
  66. ReturnCode err;
  67. rfalNfcDevice* dev_list;
  68. EmvApplication emv_app = {};
  69. uint8_t dev_cnt = 0;
  70. uint8_t tx_buff[255] = {};
  71. uint16_t tx_len = 0;
  72. uint8_t* rx_buff;
  73. uint16_t* rx_len;
  74. // Update screen before start searching
  75. NfcMessage message = {.type = NfcMessageTypeEMVNotFound};
  76. while(nfc_worker->state == NfcWorkerStateReadEMV) {
  77. furi_check(
  78. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  79. memset(&emv_app, 0, sizeof(emv_app));
  80. if(api_hal_nfc_detect(&dev_list, &dev_cnt, 100, false)) {
  81. // Card was found. Check that it supports EMV
  82. if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
  83. FURI_LOG_I(NFC_WORKER_TAG, "Send select PPSE command");
  84. tx_len = emv_prepare_select_ppse(tx_buff);
  85. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  86. if(err != ERR_NONE) {
  87. FURI_LOG_E(NFC_WORKER_TAG, "Error during selection PPSE request: %d", err);
  88. message.type = NfcMessageTypeEMVNotFound;
  89. api_hal_nfc_deactivate();
  90. continue;
  91. }
  92. FURI_LOG_I(
  93. NFC_WORKER_TAG, "Select PPSE response received. Start parsing response");
  94. if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) {
  95. FURI_LOG_I(NFC_WORKER_TAG, "Select PPSE responce parced");
  96. } else {
  97. FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application");
  98. message.type = NfcMessageTypeEMVNotFound;
  99. api_hal_nfc_deactivate();
  100. continue;
  101. }
  102. FURI_LOG_I(NFC_WORKER_TAG, "Starting application ...");
  103. tx_len = emv_prepare_select_app(tx_buff, &emv_app);
  104. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  105. if(err != ERR_NONE) {
  106. FURI_LOG_E(
  107. NFC_WORKER_TAG, "Error during application selection request: %d", err);
  108. message.type = NfcMessageTypeEMVNotFound;
  109. api_hal_nfc_deactivate();
  110. continue;
  111. }
  112. FURI_LOG_I(
  113. NFC_WORKER_TAG,
  114. "Select application response received. Start parsing response");
  115. if(emv_decode_select_app_response(rx_buff, *rx_len, &emv_app)) {
  116. FURI_LOG_I(NFC_WORKER_TAG, "Card name: %s", emv_app.name);
  117. memcpy(message.device.emv_card.name, emv_app.name, sizeof(emv_app.name));
  118. } else {
  119. FURI_LOG_E(NFC_WORKER_TAG, "Can't read card name");
  120. message.type = NfcMessageTypeEMVNotFound;
  121. api_hal_nfc_deactivate();
  122. continue;
  123. }
  124. FURI_LOG_I(NFC_WORKER_TAG, "Starting Get Processing Options command ...");
  125. tx_len = emv_prepare_get_proc_opt(tx_buff, &emv_app);
  126. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  127. if(err != ERR_NONE) {
  128. FURI_LOG_E(
  129. NFC_WORKER_TAG, "Error during Get Processing Options command: %d", err);
  130. message.type = NfcMessageTypeEMVNotFound;
  131. api_hal_nfc_deactivate();
  132. continue;
  133. }
  134. if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) {
  135. FURI_LOG_I(NFC_WORKER_TAG, "Card number parsed");
  136. message.type = NfcMessageTypeEMVFound;
  137. memcpy(
  138. message.device.emv_card.number,
  139. emv_app.card_number,
  140. sizeof(emv_app.card_number));
  141. api_hal_nfc_deactivate();
  142. continue;
  143. } else {
  144. // Mastercard doesn't give PAN / card number as GPO response
  145. // Iterate over all files found in application
  146. bool pan_found = false;
  147. for(uint8_t i = 0; (i < emv_app.afl.size) && !pan_found; i += 4) {
  148. uint8_t sfi = emv_app.afl.data[i] >> 3;
  149. uint8_t record_start = emv_app.afl.data[i + 1];
  150. uint8_t record_end = emv_app.afl.data[i + 2];
  151. // Iterate over all records in file
  152. for(uint8_t record = record_start; record <= record_end; ++record) {
  153. tx_len = emv_prepare_read_sfi_record(tx_buff, sfi, record);
  154. err = api_hal_nfc_data_exchange(
  155. tx_buff, tx_len, &rx_buff, &rx_len, false);
  156. if(err != ERR_NONE) {
  157. FURI_LOG_E(
  158. NFC_WORKER_TAG,
  159. "Error reading application sfi %d, record %d",
  160. sfi,
  161. record);
  162. }
  163. if(emv_decode_read_sfi_record(rx_buff, *rx_len, &emv_app)) {
  164. pan_found = true;
  165. break;
  166. }
  167. }
  168. }
  169. if(pan_found) {
  170. FURI_LOG_I(NFC_WORKER_TAG, "Card PAN found");
  171. message.type = NfcMessageTypeEMVFound;
  172. memcpy(
  173. message.device.emv_card.number,
  174. emv_app.card_number,
  175. sizeof(emv_app.card_number));
  176. } else {
  177. FURI_LOG_E(NFC_WORKER_TAG, "Can't read card number");
  178. message.type = NfcMessageTypeEMVNotFound;
  179. }
  180. api_hal_nfc_deactivate();
  181. }
  182. } else {
  183. // Can't find EMV card
  184. FURI_LOG_W(NFC_WORKER_TAG, "Card doesn't support EMV");
  185. message.type = NfcMessageTypeEMVNotFound;
  186. api_hal_nfc_deactivate();
  187. }
  188. } else {
  189. // Can't find EMV card
  190. FURI_LOG_W(NFC_WORKER_TAG, "Can't find any cards");
  191. message.type = NfcMessageTypeEMVNotFound;
  192. api_hal_nfc_deactivate();
  193. }
  194. osDelay(20);
  195. }
  196. api_hal_nfc_deactivate();
  197. }
  198. void nfc_worker_emulate_emv(NfcWorker* nfc_worker) {
  199. ReturnCode err;
  200. uint8_t tx_buff[255] = {};
  201. uint16_t tx_len = 0;
  202. uint8_t* rx_buff;
  203. uint16_t* rx_len;
  204. while(nfc_worker->state == NfcWorkerStateEmulateEMV) {
  205. if(api_hal_nfc_listen(1000)) {
  206. FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected");
  207. // Read data from POS terminal
  208. err = api_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false);
  209. if(err == ERR_NONE) {
  210. FURI_LOG_I(NFC_WORKER_TAG, "Received Select PPSE");
  211. } else {
  212. FURI_LOG_E(NFC_WORKER_TAG, "Error in 1st data exchange: select PPSE");
  213. api_hal_nfc_deactivate();
  214. continue;
  215. }
  216. FURI_LOG_I(NFC_WORKER_TAG, "Transive SELECT PPSE ANS");
  217. tx_len = emv_select_ppse_ans(tx_buff);
  218. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  219. if(err == ERR_NONE) {
  220. FURI_LOG_I(NFC_WORKER_TAG, "Received Select APP");
  221. } else {
  222. FURI_LOG_E(NFC_WORKER_TAG, "Error in 2nd data exchange: select APP");
  223. api_hal_nfc_deactivate();
  224. continue;
  225. }
  226. FURI_LOG_I(NFC_WORKER_TAG, "Transive SELECT APP ANS");
  227. tx_len = emv_select_app_ans(tx_buff);
  228. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  229. if(err == ERR_NONE) {
  230. FURI_LOG_I(NFC_WORKER_TAG, "Received PDOL");
  231. } else {
  232. FURI_LOG_E(NFC_WORKER_TAG, "Error in 3rd data exchange: receive PDOL");
  233. api_hal_nfc_deactivate();
  234. continue;
  235. }
  236. FURI_LOG_I(NFC_WORKER_TAG, "Transive PDOL ANS");
  237. tx_len = emv_get_proc_opt_ans(tx_buff);
  238. err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  239. if(err == ERR_NONE) {
  240. FURI_LOG_I(NFC_WORKER_TAG, "Received PDOL");
  241. }
  242. api_hal_nfc_deactivate();
  243. } else {
  244. FURI_LOG_W(NFC_WORKER_TAG, "Can't find reader");
  245. }
  246. osDelay(20);
  247. }
  248. }
  249. void nfc_worker_poll(NfcWorker* nfc_worker) {
  250. rfalNfcDevice* dev_list;
  251. uint8_t dev_cnt;
  252. // Update screen before start searching
  253. NfcMessage message = {.type = NfcMessageTypeDeviceNotFound};
  254. furi_check(osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  255. while(nfc_worker->state == NfcWorkerStatePoll) {
  256. if(api_hal_nfc_detect(&dev_list, &dev_cnt, 100, true)) {
  257. // Send message with first device found
  258. message.type = NfcMessageTypeDeviceFound;
  259. if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCA) {
  260. message.device.type = NfcDeviceTypeNfca;
  261. message.device.nfca = dev_list[0].dev.nfca;
  262. } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCB) {
  263. message.device.type = NfcDeviceTypeNfcb;
  264. message.device.nfcb = dev_list[0].dev.nfcb;
  265. } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCF) {
  266. message.device.type = NfcDeviceTypeNfcf;
  267. message.device.nfcf = dev_list[0].dev.nfcf;
  268. } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCV) {
  269. message.device.type = NfcDeviceTypeNfcv;
  270. message.device.nfcv = dev_list[0].dev.nfcv;
  271. } else {
  272. // TODO show information about all found devices
  273. message.type = NfcMessageTypeDeviceNotFound;
  274. }
  275. furi_check(
  276. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  277. } else {
  278. message.type = NfcMessageTypeDeviceNotFound;
  279. furi_check(
  280. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  281. }
  282. osDelay(5);
  283. }
  284. }
  285. void nfc_worker_state_callback(rfalNfcState st) {
  286. (void)st;
  287. }
  288. ReturnCode nfc_worker_trx(
  289. uint8_t* txBuf,
  290. uint16_t txBufSize,
  291. uint8_t** rxData,
  292. uint16_t** rcvLen,
  293. uint32_t fwt) {
  294. ReturnCode err;
  295. err = rfalNfcDataExchangeStart(txBuf, txBufSize, rxData, rcvLen, fwt);
  296. if(err == ERR_NONE) {
  297. do {
  298. rfalNfcWorker();
  299. err = rfalNfcDataExchangeGetStatus();
  300. } while(err == ERR_BUSY);
  301. }
  302. return err;
  303. }
  304. void nfc_worker_exchange(NfcWorker* nfc_worker, rfalNfcDevice* nfc_device) {
  305. ReturnCode err = ERR_NONE;
  306. uint8_t* rxData;
  307. uint16_t* rcvLen;
  308. uint8_t txBuf[100];
  309. uint16_t txLen;
  310. do {
  311. rfalNfcWorker();
  312. switch(rfalNfcGetState()) {
  313. case RFAL_NFC_STATE_ACTIVATED:
  314. err = nfc_worker_trx(NULL, 0, &rxData, &rcvLen, 0);
  315. break;
  316. case RFAL_NFC_STATE_DATAEXCHANGE:
  317. case RFAL_NFC_STATE_DATAEXCHANGE_DONE:
  318. // Not supported
  319. txBuf[0] = ((char)0x68);
  320. txBuf[1] = ((char)0x00);
  321. txLen = 2;
  322. err = nfc_worker_trx(txBuf, txLen, &rxData, &rcvLen, RFAL_FWT_NONE);
  323. break;
  324. case RFAL_NFC_STATE_START_DISCOVERY:
  325. return;
  326. case RFAL_NFC_STATE_LISTEN_SLEEP:
  327. default:
  328. break;
  329. }
  330. } while((err == ERR_NONE) || (err == ERR_SLEEP_REQ));
  331. }
  332. void nfc_worker_emulate(NfcWorker* nfc_worker) {
  333. rfalNfcDiscoverParam params;
  334. params.compMode = RFAL_COMPLIANCE_MODE_NFC;
  335. params.techs2Find = RFAL_NFC_LISTEN_TECH_A;
  336. params.totalDuration = 1000U;
  337. params.devLimit = 1;
  338. params.wakeupEnabled = false;
  339. params.wakeupConfigDefault = true;
  340. params.nfcfBR = RFAL_BR_212;
  341. params.ap2pBR = RFAL_BR_424;
  342. params.maxBR = RFAL_BR_KEEP;
  343. params.GBLen = RFAL_NFCDEP_GB_MAX_LEN;
  344. params.notifyCb = nfc_worker_state_callback;
  345. params.lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_07;
  346. params.lmConfigPA.nfcid[0] = 0x00;
  347. params.lmConfigPA.nfcid[1] = 0x01;
  348. params.lmConfigPA.nfcid[2] = 0x02;
  349. params.lmConfigPA.nfcid[3] = 0x03;
  350. params.lmConfigPA.nfcid[4] = 0x04;
  351. params.lmConfigPA.nfcid[5] = 0x05;
  352. params.lmConfigPA.nfcid[6] = 0x06;
  353. params.lmConfigPA.SENS_RES[0] = 0x44;
  354. params.lmConfigPA.SENS_RES[1] = 0x00;
  355. params.lmConfigPA.SEL_RES = 0x00;
  356. api_hal_nfc_exit_sleep();
  357. ReturnCode ret;
  358. ret = rfalNfcDiscover(&params);
  359. if(ret != ERR_NONE) {
  360. asm("bkpt 1");
  361. return;
  362. }
  363. rfalNfcDevice* nfc_device;
  364. while(nfc_worker->state == NfcWorkerStateEmulate) {
  365. rfalNfcWorker();
  366. if(rfalNfcIsDevActivated(rfalNfcGetState())) {
  367. rfalNfcGetActiveDevice(&nfc_device);
  368. nfc_worker_exchange(nfc_worker, nfc_device);
  369. }
  370. osDelay(10);
  371. }
  372. rfalNfcDeactivate(false);
  373. api_hal_nfc_start_sleep();
  374. }
  375. void nfc_worker_field(NfcWorker* nfc_worker) {
  376. api_hal_nfc_field_on();
  377. while(nfc_worker->state == NfcWorkerStateField) {
  378. osDelay(50);
  379. }
  380. api_hal_nfc_field_off();
  381. }