nfc_magic_worker.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include "nfc_magic_worker_i.h"
  2. #include "lib/magic/magic.h"
  3. #define TAG "NfcMagicWorker"
  4. static void
  5. nfc_magic_worker_change_state(NfcMagicWorker* nfc_magic_worker, NfcMagicWorkerState state) {
  6. furi_assert(nfc_magic_worker);
  7. nfc_magic_worker->state = state;
  8. }
  9. NfcMagicWorker* nfc_magic_worker_alloc() {
  10. NfcMagicWorker* nfc_magic_worker = malloc(sizeof(NfcMagicWorker));
  11. // Worker thread attributes
  12. nfc_magic_worker->thread =
  13. furi_thread_alloc_ex("NfcMagicWorker", 8192, nfc_magic_worker_task, nfc_magic_worker);
  14. nfc_magic_worker->callback = NULL;
  15. nfc_magic_worker->context = NULL;
  16. nfc_magic_worker_change_state(nfc_magic_worker, NfcMagicWorkerStateReady);
  17. return nfc_magic_worker;
  18. }
  19. void nfc_magic_worker_free(NfcMagicWorker* nfc_magic_worker) {
  20. furi_assert(nfc_magic_worker);
  21. furi_thread_free(nfc_magic_worker->thread);
  22. free(nfc_magic_worker);
  23. }
  24. void nfc_magic_worker_stop(NfcMagicWorker* nfc_magic_worker) {
  25. furi_assert(nfc_magic_worker);
  26. nfc_magic_worker_change_state(nfc_magic_worker, NfcMagicWorkerStateStop);
  27. furi_thread_join(nfc_magic_worker->thread);
  28. }
  29. void nfc_magic_worker_start(
  30. NfcMagicWorker* nfc_magic_worker,
  31. NfcMagicWorkerState state,
  32. NfcDeviceData* dev_data,
  33. NfcMagicWorkerCallback callback,
  34. void* context) {
  35. furi_assert(nfc_magic_worker);
  36. furi_assert(dev_data);
  37. nfc_magic_worker->callback = callback;
  38. nfc_magic_worker->context = context;
  39. nfc_magic_worker->dev_data = dev_data;
  40. nfc_magic_worker_change_state(nfc_magic_worker, state);
  41. furi_thread_start(nfc_magic_worker->thread);
  42. }
  43. int32_t nfc_magic_worker_task(void* context) {
  44. NfcMagicWorker* nfc_magic_worker = context;
  45. if(nfc_magic_worker->state == NfcMagicWorkerStateCheck) {
  46. nfc_magic_worker_check(nfc_magic_worker);
  47. } else if(nfc_magic_worker->state == NfcMagicWorkerStateWrite) {
  48. nfc_magic_worker_write(nfc_magic_worker);
  49. } else if(nfc_magic_worker->state == NfcMagicWorkerStateWipe) {
  50. nfc_magic_worker_wipe(nfc_magic_worker);
  51. }
  52. nfc_magic_worker_change_state(nfc_magic_worker, NfcMagicWorkerStateReady);
  53. return 0;
  54. }
  55. void nfc_magic_worker_write(NfcMagicWorker* nfc_magic_worker) {
  56. bool card_found_notified = false;
  57. FuriHalNfcDevData nfc_data = {};
  58. MfClassicData* src_data = &nfc_magic_worker->dev_data->mf_classic_data;
  59. while(nfc_magic_worker->state == NfcMagicWorkerStateWrite) {
  60. if(furi_hal_nfc_detect(&nfc_data, 200)) {
  61. if(!card_found_notified) {
  62. nfc_magic_worker->callback(
  63. NfcMagicWorkerEventCardDetected, nfc_magic_worker->context);
  64. card_found_notified = true;
  65. }
  66. furi_hal_nfc_sleep();
  67. if(!magic_wupa()) {
  68. FURI_LOG_E(TAG, "Not Magic card");
  69. nfc_magic_worker->callback(
  70. NfcMagicWorkerEventWrongCard, nfc_magic_worker->context);
  71. break;
  72. }
  73. if(!magic_data_access_cmd()) {
  74. FURI_LOG_E(TAG, "Not Magic card");
  75. nfc_magic_worker->callback(
  76. NfcMagicWorkerEventWrongCard, nfc_magic_worker->context);
  77. break;
  78. }
  79. for(size_t i = 0; i < 64; i++) {
  80. FURI_LOG_D(TAG, "Writing block %d", i);
  81. if(!magic_write_blk(i, &src_data->block[i])) {
  82. FURI_LOG_E(TAG, "Failed to write %d block", i);
  83. nfc_magic_worker->callback(NfcMagicWorkerEventFail, nfc_magic_worker->context);
  84. break;
  85. }
  86. }
  87. nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context);
  88. break;
  89. } else {
  90. if(card_found_notified) {
  91. nfc_magic_worker->callback(
  92. NfcMagicWorkerEventNoCardDetected, nfc_magic_worker->context);
  93. card_found_notified = false;
  94. }
  95. }
  96. furi_delay_ms(300);
  97. }
  98. magic_deactivate();
  99. }
  100. void nfc_magic_worker_check(NfcMagicWorker* nfc_magic_worker) {
  101. bool card_found_notified = false;
  102. while(nfc_magic_worker->state == NfcMagicWorkerStateCheck) {
  103. if(magic_wupa()) {
  104. if(!card_found_notified) {
  105. nfc_magic_worker->callback(
  106. NfcMagicWorkerEventCardDetected, nfc_magic_worker->context);
  107. card_found_notified = true;
  108. }
  109. nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context);
  110. break;
  111. } else {
  112. if(card_found_notified) {
  113. nfc_magic_worker->callback(
  114. NfcMagicWorkerEventNoCardDetected, nfc_magic_worker->context);
  115. card_found_notified = false;
  116. }
  117. }
  118. furi_delay_ms(300);
  119. }
  120. magic_deactivate();
  121. }
  122. void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) {
  123. MfClassicBlock block;
  124. memset(&block, 0, sizeof(MfClassicBlock));
  125. block.value[0] = 0x01;
  126. block.value[1] = 0x02;
  127. block.value[2] = 0x03;
  128. block.value[3] = 0x04;
  129. block.value[4] = 0x04;
  130. block.value[5] = 0x08;
  131. block.value[6] = 0x04;
  132. while(nfc_magic_worker->state == NfcMagicWorkerStateWipe) {
  133. magic_deactivate();
  134. furi_delay_ms(300);
  135. if(!magic_wupa()) continue;
  136. if(!magic_wipe()) continue;
  137. if(!magic_data_access_cmd()) continue;
  138. if(!magic_write_blk(0, &block)) continue;
  139. nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context);
  140. break;
  141. }
  142. magic_deactivate();
  143. }