nfc_worker.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  1. #include "nfc_worker_i.h"
  2. #include <furi_hal.h>
  3. #include "nfc_protocols/emv_decoder.h"
  4. #include "nfc_protocols/mifare_desfire.h"
  5. #include "nfc_protocols/mifare_ultralight.h"
  6. #define TAG "NfcWorker"
  7. /***************************** NFC Worker API *******************************/
  8. NfcWorker* nfc_worker_alloc() {
  9. NfcWorker* nfc_worker = malloc(sizeof(NfcWorker));
  10. // Worker thread attributes
  11. nfc_worker->thread = furi_thread_alloc();
  12. furi_thread_set_name(nfc_worker->thread, "NfcWorker");
  13. furi_thread_set_stack_size(nfc_worker->thread, 8192);
  14. furi_thread_set_callback(nfc_worker->thread, nfc_worker_task);
  15. furi_thread_set_context(nfc_worker->thread, nfc_worker);
  16. nfc_worker->callback = NULL;
  17. nfc_worker->context = NULL;
  18. // Initialize rfal
  19. while(furi_hal_nfc_is_busy()) {
  20. osDelay(10);
  21. }
  22. nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
  23. return nfc_worker;
  24. }
  25. void nfc_worker_free(NfcWorker* nfc_worker) {
  26. furi_assert(nfc_worker);
  27. furi_thread_free(nfc_worker->thread);
  28. free(nfc_worker);
  29. }
  30. NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker) {
  31. return nfc_worker->state;
  32. }
  33. void nfc_worker_start(
  34. NfcWorker* nfc_worker,
  35. NfcWorkerState state,
  36. NfcDeviceData* dev_data,
  37. NfcWorkerCallback callback,
  38. void* context) {
  39. furi_assert(nfc_worker);
  40. furi_assert(dev_data);
  41. while(furi_hal_nfc_is_busy()) {
  42. osDelay(10);
  43. }
  44. nfc_worker->callback = callback;
  45. nfc_worker->context = context;
  46. nfc_worker->dev_data = dev_data;
  47. nfc_worker_change_state(nfc_worker, state);
  48. furi_thread_start(nfc_worker->thread);
  49. }
  50. void nfc_worker_stop(NfcWorker* nfc_worker) {
  51. furi_assert(nfc_worker);
  52. if(nfc_worker->state == NfcWorkerStateBroken || nfc_worker->state == NfcWorkerStateReady) {
  53. return;
  54. }
  55. furi_hal_nfc_stop();
  56. nfc_worker_change_state(nfc_worker, NfcWorkerStateStop);
  57. furi_thread_join(nfc_worker->thread);
  58. }
  59. void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) {
  60. nfc_worker->state = state;
  61. }
  62. /***************************** NFC Worker Thread *******************************/
  63. int32_t nfc_worker_task(void* context) {
  64. NfcWorker* nfc_worker = context;
  65. furi_hal_power_insomnia_enter();
  66. furi_hal_nfc_exit_sleep();
  67. if(nfc_worker->state == NfcWorkerStateDetect) {
  68. nfc_worker_detect(nfc_worker);
  69. } else if(nfc_worker->state == NfcWorkerStateEmulate) {
  70. nfc_worker_emulate(nfc_worker);
  71. } else if(nfc_worker->state == NfcWorkerStateReadEMVApp) {
  72. nfc_worker_read_emv_app(nfc_worker);
  73. } else if(nfc_worker->state == NfcWorkerStateReadEMV) {
  74. nfc_worker_read_emv(nfc_worker);
  75. } else if(nfc_worker->state == NfcWorkerStateEmulateApdu) {
  76. nfc_worker_emulate_apdu(nfc_worker);
  77. } else if(nfc_worker->state == NfcWorkerStateReadMifareUl) {
  78. nfc_worker_read_mifare_ul(nfc_worker);
  79. } else if(nfc_worker->state == NfcWorkerStateEmulateMifareUl) {
  80. nfc_worker_emulate_mifare_ul(nfc_worker);
  81. } else if(nfc_worker->state == NfcWorkerStateReadMifareDesfire) {
  82. nfc_worker_read_mifare_desfire(nfc_worker);
  83. } else if(nfc_worker->state == NfcWorkerStateField) {
  84. nfc_worker_field(nfc_worker);
  85. }
  86. furi_hal_nfc_deactivate();
  87. nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
  88. furi_hal_power_insomnia_exit();
  89. return 0;
  90. }
  91. void nfc_worker_detect(NfcWorker* nfc_worker) {
  92. rfalNfcDevice* dev_list;
  93. rfalNfcDevice* dev;
  94. uint8_t dev_cnt;
  95. nfc_device_data_clear(nfc_worker->dev_data);
  96. NfcDeviceCommonData* result = &nfc_worker->dev_data->nfc_data;
  97. while(nfc_worker->state == NfcWorkerStateDetect) {
  98. if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) {
  99. // Process first found device
  100. dev = &dev_list[0];
  101. result->uid_len = dev->nfcidLen;
  102. memcpy(result->uid, dev->nfcid, dev->nfcidLen);
  103. if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCA) {
  104. result->device = NfcDeviceNfca;
  105. result->atqa[0] = dev->dev.nfca.sensRes.anticollisionInfo;
  106. result->atqa[1] = dev->dev.nfca.sensRes.platformInfo;
  107. result->sak = dev->dev.nfca.selRes.sak;
  108. if(mf_ul_check_card_type(
  109. dev->dev.nfca.sensRes.anticollisionInfo,
  110. dev->dev.nfca.sensRes.platformInfo,
  111. dev->dev.nfca.selRes.sak)) {
  112. result->protocol = NfcDeviceProtocolMifareUl;
  113. } else if(mf_df_check_card_type(
  114. dev->dev.nfca.sensRes.anticollisionInfo,
  115. dev->dev.nfca.sensRes.platformInfo,
  116. dev->dev.nfca.selRes.sak)) {
  117. result->protocol = NfcDeviceProtocolMifareDesfire;
  118. } else if(dev->rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
  119. result->protocol = NfcDeviceProtocolEMV;
  120. } else {
  121. result->protocol = NfcDeviceProtocolUnknown;
  122. }
  123. } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCB) {
  124. result->device = NfcDeviceNfcb;
  125. } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCF) {
  126. result->device = NfcDeviceNfcf;
  127. } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCV) {
  128. result->device = NfcDeviceNfcv;
  129. }
  130. // Notify caller and exit
  131. if(nfc_worker->callback) {
  132. nfc_worker->callback(nfc_worker->context);
  133. }
  134. break;
  135. }
  136. osDelay(100);
  137. }
  138. }
  139. bool nfc_worker_emulate_uid_callback(
  140. uint8_t* buff_rx,
  141. uint16_t buff_rx_len,
  142. uint8_t* buff_tx,
  143. uint16_t* buff_tx_len,
  144. uint32_t* data_type,
  145. void* context) {
  146. furi_assert(context);
  147. NfcWorker* nfc_worker = context;
  148. NfcReaderRequestData* reader_data = &nfc_worker->dev_data->reader_data;
  149. reader_data->size = buff_rx_len / 8;
  150. if(reader_data->size > 0) {
  151. memcpy(reader_data->data, buff_rx, reader_data->size);
  152. if(nfc_worker->callback) {
  153. nfc_worker->callback(nfc_worker->context);
  154. }
  155. }
  156. return true;
  157. }
  158. void nfc_worker_emulate(NfcWorker* nfc_worker) {
  159. NfcDeviceCommonData* data = &nfc_worker->dev_data->nfc_data;
  160. while(nfc_worker->state == NfcWorkerStateEmulate) {
  161. furi_hal_nfc_emulate_nfca(
  162. data->uid,
  163. data->uid_len,
  164. data->atqa,
  165. data->sak,
  166. nfc_worker_emulate_uid_callback,
  167. nfc_worker,
  168. 1000);
  169. }
  170. }
  171. void nfc_worker_read_emv_app(NfcWorker* nfc_worker) {
  172. ReturnCode err;
  173. rfalNfcDevice* dev_list;
  174. EmvApplication emv_app = {};
  175. uint8_t dev_cnt = 0;
  176. uint8_t tx_buff[255] = {};
  177. uint16_t tx_len = 0;
  178. uint8_t* rx_buff;
  179. uint16_t* rx_len;
  180. NfcDeviceData* result = nfc_worker->dev_data;
  181. nfc_device_data_clear(result);
  182. while(nfc_worker->state == NfcWorkerStateReadEMVApp) {
  183. memset(&emv_app, 0, sizeof(emv_app));
  184. if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) {
  185. // Card was found. Check that it supports EMV
  186. if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
  187. result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len;
  188. result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
  189. result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
  190. result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
  191. memcpy(
  192. result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
  193. result->nfc_data.protocol = NfcDeviceProtocolEMV;
  194. FURI_LOG_D(TAG, "Send select PPSE command");
  195. tx_len = emv_prepare_select_ppse(tx_buff);
  196. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  197. if(err != ERR_NONE) {
  198. FURI_LOG_D(TAG, "Error during selection PPSE request: %d", err);
  199. furi_hal_nfc_deactivate();
  200. continue;
  201. }
  202. FURI_LOG_D(TAG, "Select PPSE response received. Start parsing response");
  203. if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) {
  204. FURI_LOG_D(TAG, "Select PPSE responce parced");
  205. // Notify caller and exit
  206. result->emv_data.aid_len = emv_app.aid_len;
  207. memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len);
  208. if(nfc_worker->callback) {
  209. nfc_worker->callback(nfc_worker->context);
  210. }
  211. break;
  212. } else {
  213. FURI_LOG_D(TAG, "Can't find pay application");
  214. furi_hal_nfc_deactivate();
  215. continue;
  216. }
  217. } else {
  218. // Can't find EMV card
  219. FURI_LOG_W(TAG, "Card doesn't support EMV");
  220. furi_hal_nfc_deactivate();
  221. }
  222. } else {
  223. // Can't find EMV card
  224. FURI_LOG_D(TAG, "Can't find any cards");
  225. furi_hal_nfc_deactivate();
  226. }
  227. osDelay(20);
  228. }
  229. }
  230. void nfc_worker_read_emv(NfcWorker* nfc_worker) {
  231. ReturnCode err;
  232. rfalNfcDevice* dev_list;
  233. EmvApplication emv_app = {};
  234. uint8_t dev_cnt = 0;
  235. uint8_t tx_buff[255] = {};
  236. uint16_t tx_len = 0;
  237. uint8_t* rx_buff;
  238. uint16_t* rx_len;
  239. NfcDeviceData* result = nfc_worker->dev_data;
  240. nfc_device_data_clear(result);
  241. while(nfc_worker->state == NfcWorkerStateReadEMV) {
  242. memset(&emv_app, 0, sizeof(emv_app));
  243. if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) {
  244. // Card was found. Check that it supports EMV
  245. if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) {
  246. result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len;
  247. result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
  248. result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
  249. result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
  250. memcpy(
  251. result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
  252. result->nfc_data.protocol = NfcDeviceProtocolEMV;
  253. FURI_LOG_D(TAG, "Send select PPSE command");
  254. tx_len = emv_prepare_select_ppse(tx_buff);
  255. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  256. if(err != ERR_NONE) {
  257. FURI_LOG_D(TAG, "Error during selection PPSE request: %d", err);
  258. furi_hal_nfc_deactivate();
  259. continue;
  260. }
  261. FURI_LOG_D(TAG, "Select PPSE response received. Start parsing response");
  262. if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) {
  263. FURI_LOG_D(TAG, "Select PPSE responce parced");
  264. result->emv_data.aid_len = emv_app.aid_len;
  265. memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len);
  266. } else {
  267. FURI_LOG_D(TAG, "Can't find pay application");
  268. furi_hal_nfc_deactivate();
  269. continue;
  270. }
  271. FURI_LOG_D(TAG, "Starting application ...");
  272. tx_len = emv_prepare_select_app(tx_buff, &emv_app);
  273. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  274. if(err != ERR_NONE) {
  275. FURI_LOG_D(TAG, "Error during application selection request: %d", err);
  276. furi_hal_nfc_deactivate();
  277. continue;
  278. }
  279. FURI_LOG_D(TAG, "Select application response received. Start parsing response");
  280. if(emv_decode_select_app_response(rx_buff, *rx_len, &emv_app)) {
  281. FURI_LOG_D(TAG, "Card name: %s", emv_app.name);
  282. memcpy(result->emv_data.name, emv_app.name, sizeof(emv_app.name));
  283. } else if(emv_app.pdol.size > 0) {
  284. FURI_LOG_D(TAG, "Can't find card name, but PDOL is present.");
  285. } else {
  286. FURI_LOG_D(TAG, "Can't find card name or PDOL");
  287. furi_hal_nfc_deactivate();
  288. continue;
  289. }
  290. FURI_LOG_D(TAG, "Starting Get Processing Options command ...");
  291. tx_len = emv_prepare_get_proc_opt(tx_buff, &emv_app);
  292. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  293. if(err != ERR_NONE) {
  294. FURI_LOG_D(TAG, "Error during Get Processing Options command: %d", err);
  295. furi_hal_nfc_deactivate();
  296. continue;
  297. }
  298. if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) {
  299. FURI_LOG_D(TAG, "Card number parsed");
  300. result->emv_data.number_len = emv_app.card_number_len;
  301. memcpy(result->emv_data.number, emv_app.card_number, emv_app.card_number_len);
  302. // Notify caller and exit
  303. if(nfc_worker->callback) {
  304. nfc_worker->callback(nfc_worker->context);
  305. }
  306. break;
  307. } else {
  308. // Mastercard doesn't give PAN / card number as GPO response
  309. // Iterate over all files found in application
  310. bool pan_found = false;
  311. for(uint8_t i = 0; (i < emv_app.afl.size) && !pan_found; i += 4) {
  312. uint8_t sfi = emv_app.afl.data[i] >> 3;
  313. uint8_t record_start = emv_app.afl.data[i + 1];
  314. uint8_t record_end = emv_app.afl.data[i + 2];
  315. // Iterate over all records in file
  316. for(uint8_t record = record_start; record <= record_end; ++record) {
  317. tx_len = emv_prepare_read_sfi_record(tx_buff, sfi, record);
  318. err = furi_hal_nfc_data_exchange(
  319. tx_buff, tx_len, &rx_buff, &rx_len, false);
  320. if(err != ERR_NONE) {
  321. FURI_LOG_D(
  322. TAG,
  323. "Error reading application sfi %d, record %d",
  324. sfi,
  325. record);
  326. }
  327. if(emv_decode_read_sfi_record(rx_buff, *rx_len, &emv_app)) {
  328. pan_found = true;
  329. break;
  330. }
  331. }
  332. }
  333. if(pan_found) {
  334. FURI_LOG_D(TAG, "Card PAN found");
  335. result->emv_data.number_len = emv_app.card_number_len;
  336. memcpy(
  337. result->emv_data.number,
  338. emv_app.card_number,
  339. result->emv_data.number_len);
  340. if(emv_app.exp_month) {
  341. result->emv_data.exp_mon = emv_app.exp_month;
  342. result->emv_data.exp_year = emv_app.exp_year;
  343. }
  344. if(emv_app.country_code) {
  345. result->emv_data.country_code = emv_app.country_code;
  346. }
  347. if(emv_app.currency_code) {
  348. result->emv_data.currency_code = emv_app.currency_code;
  349. }
  350. // Notify caller and exit
  351. if(nfc_worker->callback) {
  352. nfc_worker->callback(nfc_worker->context);
  353. }
  354. break;
  355. } else {
  356. FURI_LOG_D(TAG, "Can't read card number");
  357. }
  358. furi_hal_nfc_deactivate();
  359. }
  360. } else {
  361. // Can't find EMV card
  362. FURI_LOG_W(TAG, "Card doesn't support EMV");
  363. furi_hal_nfc_deactivate();
  364. }
  365. } else {
  366. // Can't find EMV card
  367. FURI_LOG_D(TAG, "Can't find any cards");
  368. furi_hal_nfc_deactivate();
  369. }
  370. osDelay(20);
  371. }
  372. }
  373. void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) {
  374. ReturnCode err;
  375. uint8_t tx_buff[255] = {};
  376. uint16_t tx_len = 0;
  377. uint8_t* rx_buff;
  378. uint16_t* rx_len;
  379. NfcDeviceCommonData params = {
  380. .uid = {0xCF, 0x72, 0xd4, 0x40},
  381. .uid_len = 4,
  382. .atqa = {0x00, 0x04},
  383. .sak = 0x20,
  384. .device = NfcDeviceNfca,
  385. .protocol = NfcDeviceProtocolEMV,
  386. };
  387. // Test RX data
  388. const uint8_t debug_rx[] = {
  389. 0xba, 0x0b, 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca,
  390. 0xca, 0xfe, 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
  391. 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba,
  392. 0x0b, 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca,
  393. 0xfe, 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
  394. 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b,
  395. 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe,
  396. 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
  397. 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba,
  398. 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa,
  399. 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
  400. 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba, 0xba,
  401. 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa, 0xce,
  402. 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
  403. 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba, 0xba, 0x20,
  404. 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa, 0xce, 0x14,
  405. 0x88, 0x00};
  406. // Test TX data
  407. const uint8_t debug_tx[] = {
  408. 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
  409. 0x10, 0x14, 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad,
  410. 0xbe, 0xef, 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12,
  411. 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
  412. 0x14, 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe,
  413. 0xef, 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34,
  414. 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14,
  415. 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef,
  416. 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56,
  417. 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88,
  418. 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xce,
  419. 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56, 0x78,
  420. 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88, 0x02,
  421. 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xce, 0xee,
  422. 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56, 0x78, 0x9a,
  423. 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88, 0x02, 0x28,
  424. 0x00, 0x00};
  425. while(nfc_worker->state == NfcWorkerStateEmulateApdu) {
  426. if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 300)) {
  427. FURI_LOG_D(TAG, "POS terminal detected");
  428. // Read data from POS terminal
  429. err = furi_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false);
  430. if(err == ERR_NONE) {
  431. FURI_LOG_D(TAG, "Received Select PPSE");
  432. } else {
  433. FURI_LOG_D(TAG, "Error in 1st data exchange: select PPSE");
  434. furi_hal_nfc_deactivate();
  435. continue;
  436. }
  437. FURI_LOG_D(TAG, "Transive SELECT PPSE ANS");
  438. tx_len = emv_select_ppse_ans(tx_buff);
  439. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  440. if(err == ERR_NONE) {
  441. FURI_LOG_D(TAG, "Received Select APP");
  442. } else {
  443. FURI_LOG_D(TAG, "Error in 2nd data exchange: select APP");
  444. furi_hal_nfc_deactivate();
  445. continue;
  446. }
  447. FURI_LOG_D(TAG, "Transive SELECT APP ANS");
  448. tx_len = emv_select_app_ans(tx_buff);
  449. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  450. if(err == ERR_NONE) {
  451. FURI_LOG_D(TAG, "Received PDOL");
  452. } else {
  453. FURI_LOG_D(TAG, "Error in 3rd data exchange: receive PDOL");
  454. furi_hal_nfc_deactivate();
  455. continue;
  456. }
  457. FURI_LOG_D(TAG, "Transive PDOL ANS");
  458. tx_len = emv_get_proc_opt_ans(tx_buff);
  459. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  460. if(err == ERR_NONE) {
  461. FURI_LOG_D(TAG, "Transive PDOL ANS");
  462. } else {
  463. FURI_LOG_D(TAG, "Error in 4rd data exchange: Transive PDOL ANS");
  464. furi_hal_nfc_deactivate();
  465. continue;
  466. }
  467. if(*rx_len != sizeof(debug_rx) || memcmp(rx_buff, debug_rx, sizeof(debug_rx))) {
  468. FURI_LOG_D(TAG, "Failed long message test");
  469. } else {
  470. FURI_LOG_D(TAG, "Correct debug message received");
  471. tx_len = sizeof(debug_tx);
  472. err = furi_hal_nfc_data_exchange(
  473. (uint8_t*)debug_tx, tx_len, &rx_buff, &rx_len, false);
  474. if(err == ERR_NONE) {
  475. FURI_LOG_D(TAG, "Transive Debug message");
  476. }
  477. }
  478. furi_hal_nfc_deactivate();
  479. } else {
  480. FURI_LOG_D(TAG, "Can't find reader");
  481. }
  482. osDelay(20);
  483. }
  484. }
  485. void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) {
  486. ReturnCode err;
  487. rfalNfcDevice* dev_list;
  488. uint8_t dev_cnt = 0;
  489. uint8_t tx_buff[255] = {};
  490. uint16_t tx_len = 0;
  491. uint8_t* rx_buff;
  492. uint16_t* rx_len;
  493. MifareUlDevice mf_ul_read;
  494. NfcDeviceData* result = nfc_worker->dev_data;
  495. nfc_device_data_clear(result);
  496. while(nfc_worker->state == NfcWorkerStateReadMifareUl) {
  497. furi_hal_nfc_deactivate();
  498. memset(&mf_ul_read, 0, sizeof(mf_ul_read));
  499. if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) {
  500. if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCA &&
  501. mf_ul_check_card_type(
  502. dev_list[0].dev.nfca.sensRes.anticollisionInfo,
  503. dev_list[0].dev.nfca.sensRes.platformInfo,
  504. dev_list[0].dev.nfca.selRes.sak)) {
  505. // Get Mifare Ultralight version
  506. FURI_LOG_D(TAG, "Found Mifare Ultralight tag. Reading tag version");
  507. tx_len = mf_ul_prepare_get_version(tx_buff);
  508. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
  509. if(err == ERR_NONE) {
  510. mf_ul_parse_get_version_response(rx_buff, &mf_ul_read);
  511. FURI_LOG_D(
  512. TAG,
  513. "Mifare Ultralight Type: %d, Pages: %d",
  514. mf_ul_read.data.type,
  515. mf_ul_read.pages_to_read);
  516. FURI_LOG_D(TAG, "Reading signature ...");
  517. tx_len = mf_ul_prepare_read_signature(tx_buff);
  518. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  519. FURI_LOG_D(TAG, "Failed reading signature");
  520. memset(mf_ul_read.data.signature, 0, sizeof(mf_ul_read.data.signature));
  521. } else {
  522. mf_ul_parse_read_signature_response(rx_buff, &mf_ul_read);
  523. }
  524. } else if(err == ERR_TIMEOUT) {
  525. FURI_LOG_D(
  526. TAG,
  527. "Card doesn't respond to GET VERSION command. Setting default read parameters");
  528. err = ERR_NONE;
  529. mf_ul_set_default_version(&mf_ul_read);
  530. // Reinit device
  531. furi_hal_nfc_deactivate();
  532. if(!furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) {
  533. FURI_LOG_D(TAG, "Lost connection. Restarting search");
  534. continue;
  535. }
  536. } else {
  537. FURI_LOG_D(
  538. TAG, "Error getting Mifare Ultralight version. Error code: %d", err);
  539. continue;
  540. }
  541. if(mf_ul_read.support_fast_read) {
  542. FURI_LOG_D(TAG, "Reading pages ...");
  543. tx_len = mf_ul_prepare_fast_read(tx_buff, 0x00, mf_ul_read.pages_to_read - 1);
  544. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  545. FURI_LOG_D(TAG, "Failed reading pages");
  546. continue;
  547. } else {
  548. mf_ul_parse_fast_read_response(
  549. rx_buff, 0x00, mf_ul_read.pages_to_read - 1, &mf_ul_read);
  550. }
  551. FURI_LOG_D(TAG, "Reading 3 counters ...");
  552. for(uint8_t i = 0; i < 3; i++) {
  553. tx_len = mf_ul_prepare_read_cnt(tx_buff, i);
  554. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  555. FURI_LOG_W(TAG, "Failed reading Counter %d", i);
  556. mf_ul_read.data.counter[i] = 0;
  557. } else {
  558. mf_ul_parse_read_cnt_response(rx_buff, i, &mf_ul_read);
  559. }
  560. }
  561. FURI_LOG_D(TAG, "Checking tearing flags ...");
  562. for(uint8_t i = 0; i < 3; i++) {
  563. tx_len = mf_ul_prepare_check_tearing(tx_buff, i);
  564. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  565. FURI_LOG_D(TAG, "Error checking tearing flag %d", i);
  566. mf_ul_read.data.tearing[i] = MF_UL_TEARING_FLAG_DEFAULT;
  567. } else {
  568. mf_ul_parse_check_tearing_response(rx_buff, i, &mf_ul_read);
  569. }
  570. }
  571. } else {
  572. // READ card with READ command (4 pages at a time)
  573. for(uint8_t page = 0; page < mf_ul_read.pages_to_read; page += 4) {
  574. FURI_LOG_D(TAG, "Reading pages %d - %d ...", page, page + 3);
  575. tx_len = mf_ul_prepare_read(tx_buff, page);
  576. if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) {
  577. FURI_LOG_D(TAG, "Read pages %d - %d failed", page, page + 3);
  578. continue;
  579. } else {
  580. mf_ul_parse_read_response(rx_buff, page, &mf_ul_read);
  581. }
  582. }
  583. }
  584. // Fill result data
  585. result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len;
  586. result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
  587. result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
  588. result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
  589. result->nfc_data.protocol = NfcDeviceProtocolMifareUl;
  590. memcpy(
  591. result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
  592. result->mf_ul_data = mf_ul_read.data;
  593. // Notify caller and exit
  594. if(nfc_worker->callback) {
  595. nfc_worker->callback(nfc_worker->context);
  596. }
  597. break;
  598. } else {
  599. FURI_LOG_W(TAG, "Tag does not support Mifare Ultralight");
  600. }
  601. } else {
  602. FURI_LOG_D(TAG, "Can't find any tags");
  603. }
  604. osDelay(100);
  605. }
  606. }
  607. void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) {
  608. NfcDeviceCommonData* nfc_common = &nfc_worker->dev_data->nfc_data;
  609. MifareUlDevice mf_ul_emulate;
  610. mf_ul_prepare_emulation(&mf_ul_emulate, &nfc_worker->dev_data->mf_ul_data);
  611. while(nfc_worker->state == NfcWorkerStateEmulateMifareUl) {
  612. furi_hal_nfc_emulate_nfca(
  613. nfc_common->uid,
  614. nfc_common->uid_len,
  615. nfc_common->atqa,
  616. nfc_common->sak,
  617. mf_ul_prepare_emulation_response,
  618. &mf_ul_emulate,
  619. 5000);
  620. // Check if data was modified
  621. if(mf_ul_emulate.data_changed) {
  622. nfc_worker->dev_data->mf_ul_data = mf_ul_emulate.data;
  623. if(nfc_worker->callback) {
  624. nfc_worker->callback(nfc_worker->context);
  625. }
  626. mf_ul_emulate.data_changed = false;
  627. }
  628. }
  629. }
  630. ReturnCode nfc_exchange_full(
  631. uint8_t* tx_buff,
  632. uint16_t tx_len,
  633. uint8_t* rx_buff,
  634. uint16_t rx_cap,
  635. uint16_t* rx_len) {
  636. ReturnCode err;
  637. uint8_t* part_buff;
  638. uint16_t* part_len;
  639. err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &part_buff, &part_len, false);
  640. if(*part_len > rx_cap) {
  641. return ERR_OVERRUN;
  642. }
  643. memcpy(rx_buff, part_buff, *part_len);
  644. *rx_len = *part_len;
  645. while(err == ERR_NONE && rx_buff[0] == 0xAF) {
  646. err = furi_hal_nfc_data_exchange(rx_buff, 1, &part_buff, &part_len, false);
  647. if(*part_len > rx_cap - *rx_len) {
  648. return ERR_OVERRUN;
  649. }
  650. if(*part_len == 0) {
  651. return ERR_PROTO;
  652. }
  653. memcpy(rx_buff + *rx_len, part_buff + 1, *part_len - 1);
  654. *rx_buff = *part_buff;
  655. *rx_len += *part_len - 1;
  656. }
  657. return err;
  658. }
  659. void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) {
  660. ReturnCode err;
  661. rfalNfcDevice* dev_list;
  662. uint8_t dev_cnt = 0;
  663. uint8_t tx_buff[64] = {};
  664. uint16_t tx_len = 0;
  665. uint8_t rx_buff[512] = {};
  666. uint16_t rx_len;
  667. NfcDeviceData* result = nfc_worker->dev_data;
  668. nfc_device_data_clear(result);
  669. MifareDesfireData* data = &result->mf_df_data;
  670. while(nfc_worker->state == NfcWorkerStateReadMifareDesfire) {
  671. furi_hal_nfc_deactivate();
  672. if(!furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) {
  673. osDelay(100);
  674. continue;
  675. }
  676. memset(data, 0, sizeof(MifareDesfireData));
  677. if(dev_list[0].type != RFAL_NFC_LISTEN_TYPE_NFCA ||
  678. !mf_df_check_card_type(
  679. dev_list[0].dev.nfca.sensRes.anticollisionInfo,
  680. dev_list[0].dev.nfca.sensRes.platformInfo,
  681. dev_list[0].dev.nfca.selRes.sak)) {
  682. FURI_LOG_D(TAG, "Tag is not DESFire");
  683. osDelay(100);
  684. continue;
  685. }
  686. FURI_LOG_D(TAG, "Found DESFire tag");
  687. // Fill non-DESFire result data
  688. result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len;
  689. result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo;
  690. result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo;
  691. result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak;
  692. result->nfc_data.device = NfcDeviceNfca;
  693. result->nfc_data.protocol = NfcDeviceProtocolMifareDesfire;
  694. memcpy(result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len);
  695. // Get DESFire version
  696. tx_len = mf_df_prepare_get_version(tx_buff);
  697. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  698. if(err != ERR_NONE) {
  699. FURI_LOG_W(TAG, "Bad exchange getting version, err: %d", err);
  700. continue;
  701. }
  702. if(!mf_df_parse_get_version_response(rx_buff, rx_len, &data->version)) {
  703. FURI_LOG_W(TAG, "Bad DESFire GET_VERSION response");
  704. continue;
  705. }
  706. tx_len = mf_df_prepare_get_free_memory(tx_buff);
  707. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  708. if(err == ERR_NONE) {
  709. data->free_memory = malloc(sizeof(MifareDesfireFreeMemory));
  710. memset(data->free_memory, 0, sizeof(MifareDesfireFreeMemory));
  711. if(!mf_df_parse_get_free_memory_response(rx_buff, rx_len, data->free_memory)) {
  712. FURI_LOG_D(TAG, "Bad DESFire GET_FREE_MEMORY response (normal for pre-EV1 cards)");
  713. free(data->free_memory);
  714. data->free_memory = NULL;
  715. }
  716. }
  717. tx_len = mf_df_prepare_get_key_settings(tx_buff);
  718. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  719. if(err != ERR_NONE) {
  720. FURI_LOG_D(TAG, "Bad exchange getting key settings, err: %d", err);
  721. } else {
  722. data->master_key_settings = malloc(sizeof(MifareDesfireKeySettings));
  723. memset(data->master_key_settings, 0, sizeof(MifareDesfireKeySettings));
  724. if(!mf_df_parse_get_key_settings_response(rx_buff, rx_len, data->master_key_settings)) {
  725. FURI_LOG_W(TAG, "Bad DESFire GET_KEY_SETTINGS response");
  726. free(data->master_key_settings);
  727. data->master_key_settings = NULL;
  728. }
  729. MifareDesfireKeyVersion** key_version_head =
  730. &data->master_key_settings->key_version_head;
  731. for(uint8_t key_id = 0; key_id < data->master_key_settings->max_keys; key_id++) {
  732. tx_len = mf_df_prepare_get_key_version(tx_buff, key_id);
  733. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  734. if(err != ERR_NONE) {
  735. FURI_LOG_W(TAG, "Bad exchange getting key version, err: %d", err);
  736. continue;
  737. }
  738. MifareDesfireKeyVersion* key_version = malloc(sizeof(MifareDesfireKeyVersion));
  739. memset(key_version, 0, sizeof(MifareDesfireKeyVersion));
  740. key_version->id = key_id;
  741. if(!mf_df_parse_get_key_version_response(rx_buff, rx_len, key_version)) {
  742. FURI_LOG_W(TAG, "Bad DESFire GET_KEY_VERSION response");
  743. free(key_version);
  744. continue;
  745. }
  746. *key_version_head = key_version;
  747. key_version_head = &key_version->next;
  748. }
  749. }
  750. tx_len = mf_df_prepare_get_application_ids(tx_buff);
  751. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  752. if(err != ERR_NONE) {
  753. FURI_LOG_W(TAG, "Bad exchange getting application IDs, err: %d", err);
  754. } else {
  755. if(!mf_df_parse_get_application_ids_response(rx_buff, rx_len, &data->app_head)) {
  756. FURI_LOG_W(TAG, "Bad DESFire GET_APPLICATION_IDS response");
  757. }
  758. }
  759. for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
  760. tx_len = mf_df_prepare_select_application(tx_buff, app->id);
  761. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  762. if(!mf_df_parse_select_application_response(rx_buff, rx_len)) {
  763. FURI_LOG_W(TAG, "Bad exchange selecting application, err: %d", err);
  764. continue;
  765. }
  766. tx_len = mf_df_prepare_get_key_settings(tx_buff);
  767. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  768. if(err != ERR_NONE) {
  769. FURI_LOG_W(TAG, "Bad exchange getting key settings, err: %d", err);
  770. } else {
  771. app->key_settings = malloc(sizeof(MifareDesfireKeySettings));
  772. memset(app->key_settings, 0, sizeof(MifareDesfireKeySettings));
  773. if(!mf_df_parse_get_key_settings_response(rx_buff, rx_len, app->key_settings)) {
  774. FURI_LOG_W(TAG, "Bad DESFire GET_KEY_SETTINGS response");
  775. free(app->key_settings);
  776. app->key_settings = NULL;
  777. }
  778. MifareDesfireKeyVersion** key_version_head = &app->key_settings->key_version_head;
  779. for(uint8_t key_id = 0; key_id < app->key_settings->max_keys; key_id++) {
  780. tx_len = mf_df_prepare_get_key_version(tx_buff, key_id);
  781. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  782. if(err != ERR_NONE) {
  783. FURI_LOG_W(TAG, "Bad exchange getting key version, err: %d", err);
  784. continue;
  785. }
  786. MifareDesfireKeyVersion* key_version = malloc(sizeof(MifareDesfireKeyVersion));
  787. memset(key_version, 0, sizeof(MifareDesfireKeyVersion));
  788. key_version->id = key_id;
  789. if(!mf_df_parse_get_key_version_response(rx_buff, rx_len, key_version)) {
  790. FURI_LOG_W(TAG, "Bad DESFire GET_KEY_VERSION response");
  791. free(key_version);
  792. continue;
  793. }
  794. *key_version_head = key_version;
  795. key_version_head = &key_version->next;
  796. }
  797. }
  798. tx_len = mf_df_prepare_get_file_ids(tx_buff);
  799. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  800. if(err != ERR_NONE) {
  801. FURI_LOG_W(TAG, "Bad exchange getting file IDs, err: %d", err);
  802. } else {
  803. if(!mf_df_parse_get_file_ids_response(rx_buff, rx_len, &app->file_head)) {
  804. FURI_LOG_W(TAG, "Bad DESFire GET_FILE_IDS response");
  805. }
  806. }
  807. for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
  808. tx_len = mf_df_prepare_get_file_settings(tx_buff, file->id);
  809. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  810. if(err != ERR_NONE) {
  811. FURI_LOG_W(TAG, "Bad exchange getting file settings, err: %d", err);
  812. continue;
  813. }
  814. if(!mf_df_parse_get_file_settings_response(rx_buff, rx_len, file)) {
  815. FURI_LOG_W(TAG, "Bad DESFire GET_FILE_SETTINGS response");
  816. continue;
  817. }
  818. switch(file->type) {
  819. case MifareDesfireFileTypeStandard:
  820. case MifareDesfireFileTypeBackup:
  821. tx_len = mf_df_prepare_read_data(tx_buff, file->id, 0, 0);
  822. break;
  823. case MifareDesfireFileTypeValue:
  824. tx_len = mf_df_prepare_get_value(tx_buff, file->id);
  825. break;
  826. case MifareDesfireFileTypeLinearRecord:
  827. case MifareDesfireFileTypeCyclicRecord:
  828. tx_len = mf_df_prepare_read_records(tx_buff, file->id, 0, 0);
  829. break;
  830. }
  831. err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len);
  832. if(err != ERR_NONE) {
  833. FURI_LOG_W(TAG, "Bad exchange reading file %d, err: %d", file->id, err);
  834. continue;
  835. }
  836. if(!mf_df_parse_read_data_response(rx_buff, rx_len, file)) {
  837. FURI_LOG_W(TAG, "Bad response reading file %d", file->id);
  838. continue;
  839. }
  840. }
  841. }
  842. // Notify caller and exit
  843. if(nfc_worker->callback) {
  844. nfc_worker->callback(nfc_worker->context);
  845. }
  846. break;
  847. }
  848. }
  849. void nfc_worker_field(NfcWorker* nfc_worker) {
  850. furi_hal_nfc_field_on();
  851. while(nfc_worker->state == NfcWorkerStateField) {
  852. osDelay(50);
  853. }
  854. furi_hal_nfc_field_off();
  855. }