nfc_worker.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. #include "nfc_worker_i.h"
  2. #include <furi_hal.h>
  3. #include "nfc_protocols/emv_decoder.h"
  4. #include "nfc_protocols/mifare_ultralight.h"
  5. #define TAG "NfcWorker"
  6. /***************************** NFC Worker API *******************************/
  7. NfcWorker* nfc_worker_alloc() {
  8. NfcWorker* nfc_worker = malloc(sizeof(NfcWorker));
  9. // Worker thread attributes
  10. nfc_worker->thread = furi_thread_alloc();
  11. furi_thread_set_name(nfc_worker->thread, "NfcWorker");
  12. furi_thread_set_stack_size(nfc_worker->thread, 8192);
  13. furi_thread_set_callback(nfc_worker->thread, nfc_worker_task);
  14. furi_thread_set_context(nfc_worker->thread, nfc_worker);
  15. nfc_worker->callback = NULL;
  16. nfc_worker->context = NULL;
  17. // Initialize rfal
  18. while(furi_hal_nfc_is_busy()) {
  19. osDelay(10);
  20. }
  21. nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
  22. return nfc_worker;
  23. }
  24. void nfc_worker_free(NfcWorker* nfc_worker) {
  25. furi_assert(nfc_worker);
  26. furi_thread_free(nfc_worker->thread);
  27. free(nfc_worker);
  28. }
  29. NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker) {
  30. return nfc_worker->state;
  31. }
  32. void nfc_worker_start(
  33. NfcWorker* nfc_worker,
  34. NfcWorkerState state,
  35. NfcDeviceData* dev_data,
  36. NfcWorkerCallback callback,
  37. void* context) {
  38. furi_assert(nfc_worker);
  39. furi_assert(dev_data);
  40. while(furi_hal_nfc_is_busy()) {
  41. osDelay(10);
  42. }
  43. nfc_worker->callback = callback;
  44. nfc_worker->context = context;
  45. nfc_worker->dev_data = dev_data;
  46. nfc_worker_change_state(nfc_worker, state);
  47. furi_thread_start(nfc_worker->thread);
  48. }
  49. void nfc_worker_stop(NfcWorker* nfc_worker) {
  50. furi_assert(nfc_worker);
  51. if(nfc_worker->state == NfcWorkerStateBroken || nfc_worker->state == NfcWorkerStateReady) {
  52. return;
  53. }
  54. furi_hal_nfc_stop();
  55. nfc_worker_change_state(nfc_worker, NfcWorkerStateStop);
  56. furi_thread_join(nfc_worker->thread);
  57. }
  58. void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) {
  59. nfc_worker->state = state;
  60. }
  61. /***************************** NFC Worker Thread *******************************/
  62. int32_t nfc_worker_task(void* context) {
  63. NfcWorker* nfc_worker = context;
  64. furi_hal_power_insomnia_enter();
  65. furi_hal_nfc_exit_sleep();
  66. if(nfc_worker->state == NfcWorkerStateDetect) {
  67. nfc_worker_detect(nfc_worker);
  68. } else if(nfc_worker->state == NfcWorkerStateEmulate) {
  69. nfc_worker_emulate(nfc_worker);
  70. } else if(nfc_worker->state == NfcWorkerStateReadEMVApp) {
  71. nfc_worker_read_emv_app(nfc_worker);
  72. } else if(nfc_worker->state == NfcWorkerStateReadEMV) {
  73. nfc_worker_read_emv(nfc_worker);
  74. } else if(nfc_worker->state == NfcWorkerStateEmulateApdu) {
  75. nfc_worker_emulate_apdu(nfc_worker);
  76. } else if(nfc_worker->state == NfcWorkerStateReadMifareUl) {
  77. nfc_worker_read_mifare_ul(nfc_worker);
  78. } else if(nfc_worker->state == NfcWorkerStateEmulateMifareUl) {
  79. nfc_worker_emulate_mifare_ul(nfc_worker);
  80. } else if(nfc_worker->state == NfcWorkerStateField) {
  81. nfc_worker_field(nfc_worker);
  82. }
  83. furi_hal_nfc_deactivate();
  84. nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
  85. furi_hal_power_insomnia_exit();
  86. return 0;
  87. }
  88. void nfc_worker_detect(NfcWorker* nfc_worker) {
  89. rfalNfcDevice* dev_list;
  90. rfalNfcDevice* dev;
  91. uint8_t dev_cnt;
  92. NfcDeviceCommonData* result = &nfc_worker->dev_data->nfc_data;
  93. while(nfc_worker->state == NfcWorkerStateDetect) {
  94. if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) {
  95. // Process first found device
  96. dev = &dev_list[0];
  97. result->uid_len = dev->nfcidLen;
  98. memcpy(result->uid, dev->nfcid, dev->nfcidLen);
  99. if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCA) {
  100. result->device = NfcDeviceNfca;
  101. result->atqa[0] = dev->dev.nfca.sensRes.anticollisionInfo;
  102. result->atqa[1] = dev->dev.nfca.sensRes.platformInfo;
  103. result->sak = dev->dev.nfca.selRes.sak;
  104. if(mf_ul_check_card_type(
  105. dev->dev.nfca.sensRes.anticollisionInfo,
  106. dev->dev.nfca.sensRes.platformInfo,
  107. dev->dev.nfca.selRes.sak)) {
  108. result->protocol = NfcDeviceProtocolMifareUl;
  109. } else if(dev->rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
  110. result->protocol = NfcDeviceProtocolEMV;
  111. } else {
  112. result->protocol = NfcDeviceProtocolUnknown;
  113. }
  114. } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCB) {
  115. result->device = NfcDeviceNfcb;
  116. } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCF) {
  117. result->device = NfcDeviceNfcf;
  118. } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCV) {
  119. result->device = NfcDeviceNfcv;
  120. }
  121. // Notify caller and exit
  122. if(nfc_worker->callback) {
  123. nfc_worker->callback(nfc_worker->context);
  124. }
  125. break;
  126. }
  127. osDelay(100);
  128. }
  129. }
  130. bool nfc_worker_emulate_uid_callback(
  131. uint8_t* buff_rx,
  132. uint16_t buff_rx_len,
  133. uint8_t* buff_tx,
  134. uint16_t* buff_tx_len,
  135. uint32_t* data_type,
  136. void* context) {
  137. furi_assert(context);
  138. NfcWorker* nfc_worker = context;
  139. NfcReaderRequestData* reader_data = &nfc_worker->dev_data->reader_data;
  140. reader_data->size = buff_rx_len / 8;
  141. if(reader_data->size > 0) {
  142. memcpy(reader_data->data, buff_rx, reader_data->size);
  143. if(nfc_worker->callback) {
  144. nfc_worker->callback(nfc_worker->context);
  145. }
  146. }
  147. return true;
  148. }
  149. void nfc_worker_emulate(NfcWorker* nfc_worker) {
  150. NfcDeviceCommonData* data = &nfc_worker->dev_data->nfc_data;
  151. while(nfc_worker->state == NfcWorkerStateEmulate) {
  152. furi_hal_nfc_emulate_nfca(
  153. data->uid,
  154. data->uid_len,
  155. data->atqa,
  156. data->sak,
  157. nfc_worker_emulate_uid_callback,
  158. nfc_worker,
  159. 1000);
  160. }
  161. }
  162. void nfc_worker_read_emv_app(NfcWorker* nfc_worker) {
  163. ReturnCode err;
  164. rfalNfcDevice* dev_list;
  165. EmvApplication emv_app = {};
  166. uint8_t dev_cnt = 0;
  167. uint8_t tx_buff[255] = {};
  168. uint16_t tx_len = 0;
  169. uint8_t* rx_buff;
  170. uint16_t* rx_len;
  171. NfcDeviceData* result = nfc_worker->dev_data;
  172. while(nfc_worker->state == NfcWorkerStateReadEMVApp) {
  173. memset(&emv_app, 0, sizeof(emv_app));
  174. if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) {
  175. // Card was found. Check that it supports EMV
  176. if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
  177. result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len;
  178. result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
  179. result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
  180. result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
  181. memcpy(
  182. result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
  183. result->nfc_data.protocol = NfcDeviceProtocolEMV;
  184. FURI_LOG_D(TAG, "Send select PPSE command");
  185. tx_len = emv_prepare_select_ppse(tx_buff);
  186. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  187. if(err != ERR_NONE) {
  188. FURI_LOG_D(TAG, "Error during selection PPSE request: %d", err);
  189. furi_hal_nfc_deactivate();
  190. continue;
  191. }
  192. FURI_LOG_D(TAG, "Select PPSE response received. Start parsing response");
  193. if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) {
  194. FURI_LOG_D(TAG, "Select PPSE responce parced");
  195. // Notify caller and exit
  196. result->emv_data.aid_len = emv_app.aid_len;
  197. memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len);
  198. if(nfc_worker->callback) {
  199. nfc_worker->callback(nfc_worker->context);
  200. }
  201. break;
  202. } else {
  203. FURI_LOG_D(TAG, "Can't find pay application");
  204. furi_hal_nfc_deactivate();
  205. continue;
  206. }
  207. } else {
  208. // Can't find EMV card
  209. FURI_LOG_W(TAG, "Card doesn't support EMV");
  210. furi_hal_nfc_deactivate();
  211. }
  212. } else {
  213. // Can't find EMV card
  214. FURI_LOG_D(TAG, "Can't find any cards");
  215. furi_hal_nfc_deactivate();
  216. }
  217. osDelay(20);
  218. }
  219. }
  220. void nfc_worker_read_emv(NfcWorker* nfc_worker) {
  221. ReturnCode err;
  222. rfalNfcDevice* dev_list;
  223. EmvApplication emv_app = {};
  224. uint8_t dev_cnt = 0;
  225. uint8_t tx_buff[255] = {};
  226. uint16_t tx_len = 0;
  227. uint8_t* rx_buff;
  228. uint16_t* rx_len;
  229. NfcDeviceData* result = nfc_worker->dev_data;
  230. while(nfc_worker->state == NfcWorkerStateReadEMV) {
  231. memset(&emv_app, 0, sizeof(emv_app));
  232. if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) {
  233. // Card was found. Check that it supports EMV
  234. if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
  235. result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len;
  236. result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
  237. result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
  238. result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
  239. memcpy(
  240. result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
  241. result->nfc_data.protocol = NfcDeviceProtocolEMV;
  242. FURI_LOG_D(TAG, "Send select PPSE command");
  243. tx_len = emv_prepare_select_ppse(tx_buff);
  244. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  245. if(err != ERR_NONE) {
  246. FURI_LOG_D(TAG, "Error during selection PPSE request: %d", err);
  247. furi_hal_nfc_deactivate();
  248. continue;
  249. }
  250. FURI_LOG_D(TAG, "Select PPSE response received. Start parsing response");
  251. if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) {
  252. FURI_LOG_D(TAG, "Select PPSE responce parced");
  253. result->emv_data.aid_len = emv_app.aid_len;
  254. memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len);
  255. } else {
  256. FURI_LOG_D(TAG, "Can't find pay application");
  257. furi_hal_nfc_deactivate();
  258. continue;
  259. }
  260. FURI_LOG_D(TAG, "Starting application ...");
  261. tx_len = emv_prepare_select_app(tx_buff, &emv_app);
  262. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  263. if(err != ERR_NONE) {
  264. FURI_LOG_D(TAG, "Error during application selection request: %d", err);
  265. furi_hal_nfc_deactivate();
  266. continue;
  267. }
  268. FURI_LOG_D(TAG, "Select application response received. Start parsing response");
  269. if(emv_decode_select_app_response(rx_buff, *rx_len, &emv_app)) {
  270. FURI_LOG_D(TAG, "Card name: %s", emv_app.name);
  271. memcpy(result->emv_data.name, emv_app.name, sizeof(emv_app.name));
  272. } else if(emv_app.pdol.size > 0) {
  273. FURI_LOG_D(TAG, "Can't find card name, but PDOL is present.");
  274. } else {
  275. FURI_LOG_D(TAG, "Can't find card name or PDOL");
  276. furi_hal_nfc_deactivate();
  277. continue;
  278. }
  279. FURI_LOG_D(TAG, "Starting Get Processing Options command ...");
  280. tx_len = emv_prepare_get_proc_opt(tx_buff, &emv_app);
  281. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  282. if(err != ERR_NONE) {
  283. FURI_LOG_D(TAG, "Error during Get Processing Options command: %d", err);
  284. furi_hal_nfc_deactivate();
  285. continue;
  286. }
  287. if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) {
  288. FURI_LOG_D(TAG, "Card number parsed");
  289. result->emv_data.number_len = emv_app.card_number_len;
  290. memcpy(result->emv_data.number, emv_app.card_number, emv_app.card_number_len);
  291. // Notify caller and exit
  292. if(nfc_worker->callback) {
  293. nfc_worker->callback(nfc_worker->context);
  294. }
  295. break;
  296. } else {
  297. // Mastercard doesn't give PAN / card number as GPO response
  298. // Iterate over all files found in application
  299. bool pan_found = false;
  300. for(uint8_t i = 0; (i < emv_app.afl.size) && !pan_found; i += 4) {
  301. uint8_t sfi = emv_app.afl.data[i] >> 3;
  302. uint8_t record_start = emv_app.afl.data[i + 1];
  303. uint8_t record_end = emv_app.afl.data[i + 2];
  304. // Iterate over all records in file
  305. for(uint8_t record = record_start; record <= record_end; ++record) {
  306. tx_len = emv_prepare_read_sfi_record(tx_buff, sfi, record);
  307. err = furi_hal_nfc_data_exchange(
  308. tx_buff, tx_len, &rx_buff, &rx_len, false);
  309. if(err != ERR_NONE) {
  310. FURI_LOG_D(
  311. TAG,
  312. "Error reading application sfi %d, record %d",
  313. sfi,
  314. record);
  315. }
  316. if(emv_decode_read_sfi_record(rx_buff, *rx_len, &emv_app)) {
  317. pan_found = true;
  318. break;
  319. }
  320. }
  321. }
  322. if(pan_found) {
  323. FURI_LOG_D(TAG, "Card PAN found");
  324. result->emv_data.number_len = emv_app.card_number_len;
  325. memcpy(
  326. result->emv_data.number,
  327. emv_app.card_number,
  328. result->emv_data.number_len);
  329. if(emv_app.exp_month) {
  330. result->emv_data.exp_mon = emv_app.exp_month;
  331. result->emv_data.exp_year = emv_app.exp_year;
  332. }
  333. if(emv_app.country_code) {
  334. result->emv_data.country_code = emv_app.country_code;
  335. }
  336. if(emv_app.currency_code) {
  337. result->emv_data.currency_code = emv_app.currency_code;
  338. }
  339. // Notify caller and exit
  340. if(nfc_worker->callback) {
  341. nfc_worker->callback(nfc_worker->context);
  342. }
  343. break;
  344. } else {
  345. FURI_LOG_D(TAG, "Can't read card number");
  346. }
  347. furi_hal_nfc_deactivate();
  348. }
  349. } else {
  350. // Can't find EMV card
  351. FURI_LOG_W(TAG, "Card doesn't support EMV");
  352. furi_hal_nfc_deactivate();
  353. }
  354. } else {
  355. // Can't find EMV card
  356. FURI_LOG_D(TAG, "Can't find any cards");
  357. furi_hal_nfc_deactivate();
  358. }
  359. osDelay(20);
  360. }
  361. }
  362. void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) {
  363. ReturnCode err;
  364. uint8_t tx_buff[255] = {};
  365. uint16_t tx_len = 0;
  366. uint8_t* rx_buff;
  367. uint16_t* rx_len;
  368. NfcDeviceCommonData params = {
  369. .uid = {0xCF, 0x72, 0xd4, 0x40},
  370. .uid_len = 4,
  371. .atqa = {0x00, 0x04},
  372. .sak = 0x20,
  373. .device = NfcDeviceNfca,
  374. .protocol = NfcDeviceProtocolEMV,
  375. };
  376. // Test RX data
  377. const uint8_t debug_rx[] = {
  378. 0xba, 0x0b, 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca,
  379. 0xca, 0xfe, 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
  380. 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba,
  381. 0x0b, 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca,
  382. 0xfe, 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
  383. 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b,
  384. 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe,
  385. 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
  386. 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba,
  387. 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa,
  388. 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
  389. 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba, 0xba,
  390. 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa, 0xce,
  391. 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
  392. 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba, 0xba, 0x20,
  393. 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa, 0xce, 0x14,
  394. 0x88, 0x00};
  395. // Test TX data
  396. const uint8_t debug_tx[] = {
  397. 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
  398. 0x10, 0x14, 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad,
  399. 0xbe, 0xef, 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12,
  400. 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
  401. 0x14, 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe,
  402. 0xef, 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34,
  403. 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14,
  404. 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef,
  405. 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56,
  406. 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88,
  407. 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xce,
  408. 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56, 0x78,
  409. 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88, 0x02,
  410. 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xce, 0xee,
  411. 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56, 0x78, 0x9a,
  412. 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88, 0x02, 0x28,
  413. 0x00, 0x00};
  414. while(nfc_worker->state == NfcWorkerStateEmulateApdu) {
  415. if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 300)) {
  416. FURI_LOG_D(TAG, "POS terminal detected");
  417. // Read data from POS terminal
  418. err = furi_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false);
  419. if(err == ERR_NONE) {
  420. FURI_LOG_D(TAG, "Received Select PPSE");
  421. } else {
  422. FURI_LOG_D(TAG, "Error in 1st data exchange: select PPSE");
  423. furi_hal_nfc_deactivate();
  424. continue;
  425. }
  426. FURI_LOG_D(TAG, "Transive SELECT PPSE ANS");
  427. tx_len = emv_select_ppse_ans(tx_buff);
  428. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  429. if(err == ERR_NONE) {
  430. FURI_LOG_D(TAG, "Received Select APP");
  431. } else {
  432. FURI_LOG_D(TAG, "Error in 2nd data exchange: select APP");
  433. furi_hal_nfc_deactivate();
  434. continue;
  435. }
  436. FURI_LOG_D(TAG, "Transive SELECT APP ANS");
  437. tx_len = emv_select_app_ans(tx_buff);
  438. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  439. if(err == ERR_NONE) {
  440. FURI_LOG_D(TAG, "Received PDOL");
  441. } else {
  442. FURI_LOG_D(TAG, "Error in 3rd data exchange: receive PDOL");
  443. furi_hal_nfc_deactivate();
  444. continue;
  445. }
  446. FURI_LOG_D(TAG, "Transive PDOL ANS");
  447. tx_len = emv_get_proc_opt_ans(tx_buff);
  448. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  449. if(err == ERR_NONE) {
  450. FURI_LOG_D(TAG, "Transive PDOL ANS");
  451. } else {
  452. FURI_LOG_D(TAG, "Error in 4rd data exchange: Transive PDOL ANS");
  453. furi_hal_nfc_deactivate();
  454. continue;
  455. }
  456. if(*rx_len != sizeof(debug_rx) || memcmp(rx_buff, debug_rx, sizeof(debug_rx))) {
  457. FURI_LOG_D(TAG, "Failed long message test");
  458. } else {
  459. FURI_LOG_D(TAG, "Correct debug message received");
  460. tx_len = sizeof(debug_tx);
  461. err = furi_hal_nfc_data_exchange(
  462. (uint8_t*)debug_tx, tx_len, &rx_buff, &rx_len, false);
  463. if(err == ERR_NONE) {
  464. FURI_LOG_D(TAG, "Transive Debug message");
  465. }
  466. }
  467. furi_hal_nfc_deactivate();
  468. } else {
  469. FURI_LOG_D(TAG, "Can't find reader");
  470. }
  471. osDelay(20);
  472. }
  473. }
  474. void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) {
  475. ReturnCode err;
  476. rfalNfcDevice* dev_list;
  477. uint8_t dev_cnt = 0;
  478. uint8_t tx_buff[255] = {};
  479. uint16_t tx_len = 0;
  480. uint8_t* rx_buff;
  481. uint16_t* rx_len;
  482. MifareUlDevice mf_ul_read;
  483. NfcDeviceData* result = nfc_worker->dev_data;
  484. while(nfc_worker->state == NfcWorkerStateReadMifareUl) {
  485. furi_hal_nfc_deactivate();
  486. memset(&mf_ul_read, 0, sizeof(mf_ul_read));
  487. if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) {
  488. if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCA &&
  489. mf_ul_check_card_type(
  490. dev_list[0].dev.nfca.sensRes.anticollisionInfo,
  491. dev_list[0].dev.nfca.sensRes.platformInfo,
  492. dev_list[0].dev.nfca.selRes.sak)) {
  493. // Get Mifare Ultralight version
  494. FURI_LOG_D(TAG, "Found Mifare Ultralight tag. Reading tag version");
  495. tx_len = mf_ul_prepare_get_version(tx_buff);
  496. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  497. if(err == ERR_NONE) {
  498. mf_ul_parse_get_version_response(rx_buff, &mf_ul_read);
  499. FURI_LOG_D(
  500. TAG,
  501. "Mifare Ultralight Type: %d, Pages: %d",
  502. mf_ul_read.data.type,
  503. mf_ul_read.pages_to_read);
  504. FURI_LOG_D(TAG, "Reading signature ...");
  505. tx_len = mf_ul_prepare_read_signature(tx_buff);
  506. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  507. FURI_LOG_D(TAG, "Failed reading signature");
  508. memset(mf_ul_read.data.signature, 0, sizeof(mf_ul_read.data.signature));
  509. } else {
  510. mf_ul_parse_read_signature_response(rx_buff, &mf_ul_read);
  511. }
  512. } else if(err == ERR_TIMEOUT) {
  513. FURI_LOG_D(
  514. TAG,
  515. "Card doesn't respond to GET VERSION command. Setting default read parameters");
  516. err = ERR_NONE;
  517. mf_ul_set_default_version(&mf_ul_read);
  518. // Reinit device
  519. furi_hal_nfc_deactivate();
  520. if(!furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) {
  521. FURI_LOG_D(TAG, "Lost connection. Restarting search");
  522. continue;
  523. }
  524. } else {
  525. FURI_LOG_D(
  526. TAG, "Error getting Mifare Ultralight version. Error code: %d", err);
  527. continue;
  528. }
  529. if(mf_ul_read.support_fast_read) {
  530. FURI_LOG_D(TAG, "Reading pages ...");
  531. tx_len = mf_ul_prepare_fast_read(tx_buff, 0x00, mf_ul_read.pages_to_read - 1);
  532. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  533. FURI_LOG_D(TAG, "Failed reading pages");
  534. continue;
  535. } else {
  536. mf_ul_parse_fast_read_response(
  537. rx_buff, 0x00, mf_ul_read.pages_to_read - 1, &mf_ul_read);
  538. }
  539. FURI_LOG_D(TAG, "Reading 3 counters ...");
  540. for(uint8_t i = 0; i < 3; i++) {
  541. tx_len = mf_ul_prepare_read_cnt(tx_buff, i);
  542. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  543. FURI_LOG_W(TAG, "Failed reading Counter %d", i);
  544. mf_ul_read.data.counter[i] = 0;
  545. } else {
  546. mf_ul_parse_read_cnt_response(rx_buff, i, &mf_ul_read);
  547. }
  548. }
  549. FURI_LOG_D(TAG, "Checking tearing flags ...");
  550. for(uint8_t i = 0; i < 3; i++) {
  551. tx_len = mf_ul_prepare_check_tearing(tx_buff, i);
  552. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  553. FURI_LOG_D(TAG, "Error checking tearing flag %d", i);
  554. mf_ul_read.data.tearing[i] = MF_UL_TEARING_FLAG_DEFAULT;
  555. } else {
  556. mf_ul_parse_check_tearing_response(rx_buff, i, &mf_ul_read);
  557. }
  558. }
  559. } else {
  560. // READ card with READ command (4 pages at a time)
  561. for(uint8_t page = 0; page < mf_ul_read.pages_to_read; page += 4) {
  562. FURI_LOG_D(TAG, "Reading pages %d - %d ...", page, page + 3);
  563. tx_len = mf_ul_prepare_read(tx_buff, page);
  564. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  565. FURI_LOG_D(TAG, "Read pages %d - %d failed", page, page + 3);
  566. continue;
  567. } else {
  568. mf_ul_parse_read_response(rx_buff, page, &mf_ul_read);
  569. }
  570. }
  571. }
  572. // Fill result data
  573. result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len;
  574. result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
  575. result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
  576. result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
  577. result->nfc_data.protocol = NfcDeviceProtocolMifareUl;
  578. memcpy(
  579. result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
  580. result->mf_ul_data = mf_ul_read.data;
  581. // Notify caller and exit
  582. if(nfc_worker->callback) {
  583. nfc_worker->callback(nfc_worker->context);
  584. }
  585. break;
  586. } else {
  587. FURI_LOG_W(TAG, "Tag does not support Mifare Ultralight");
  588. }
  589. } else {
  590. FURI_LOG_D(TAG, "Can't find any tags");
  591. }
  592. osDelay(100);
  593. }
  594. }
  595. void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) {
  596. NfcDeviceCommonData* nfc_common = &nfc_worker->dev_data->nfc_data;
  597. MifareUlDevice mf_ul_emulate;
  598. mf_ul_prepare_emulation(&mf_ul_emulate, &nfc_worker->dev_data->mf_ul_data);
  599. while(nfc_worker->state == NfcWorkerStateEmulateMifareUl) {
  600. furi_hal_nfc_emulate_nfca(
  601. nfc_common->uid,
  602. nfc_common->uid_len,
  603. nfc_common->atqa,
  604. nfc_common->sak,
  605. mf_ul_prepare_emulation_response,
  606. &mf_ul_emulate,
  607. 5000);
  608. // Check if data was modified
  609. if(mf_ul_emulate.data_changed) {
  610. nfc_worker->dev_data->mf_ul_data = mf_ul_emulate.data;
  611. if(nfc_worker->callback) {
  612. nfc_worker->callback(nfc_worker->context);
  613. }
  614. mf_ul_emulate.data_changed = false;
  615. }
  616. }
  617. }
  618. void nfc_worker_field(NfcWorker* nfc_worker) {
  619. furi_hal_nfc_field_on();
  620. while(nfc_worker->state == NfcWorkerStateField) {
  621. osDelay(50);
  622. }
  623. furi_hal_nfc_field_off();
  624. }