nfc_magic_scanner.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include "nfc_magic_scanner.h"
  2. #include "protocols/gen1a/gen1a_poller.h"
  3. #include "protocols/gen2/gen2_poller.h"
  4. #include "protocols/gen4/gen4_poller.h"
  5. #include <nfc/nfc_poller.h>
  6. #include <furi/furi.h>
  7. typedef enum {
  8. NfcMagicScannerSessionStateIdle,
  9. NfcMagicScannerSessionStateActive,
  10. NfcMagicScannerSessionStateStopRequest,
  11. } NfcMagicScannerSessionState;
  12. struct NfcMagicScanner {
  13. Nfc* nfc;
  14. NfcMagicScannerSessionState session_state;
  15. NfcMagicProtocol current_protocol;
  16. uint32_t gen4_password;
  17. bool magic_protocol_detected;
  18. NfcMagicScannerCallback callback;
  19. void* context;
  20. FuriThread* scan_worker;
  21. };
  22. static const NfcProtocol nfc_magic_scanner_not_magic_protocols[] = {
  23. NfcProtocolIso14443_3b,
  24. NfcProtocolIso15693_3,
  25. NfcProtocolFelica,
  26. };
  27. static void nfc_magic_scanner_reset(NfcMagicScanner* instance) {
  28. instance->session_state = NfcMagicScannerSessionStateIdle;
  29. instance->current_protocol = NfcMagicProtocolGen1;
  30. }
  31. NfcMagicScanner* nfc_magic_scanner_alloc(Nfc* nfc) {
  32. furi_assert(nfc);
  33. NfcMagicScanner* instance = malloc(sizeof(NfcMagicScanner));
  34. instance->nfc = nfc;
  35. return instance;
  36. }
  37. void nfc_magic_scanner_free(NfcMagicScanner* instance) {
  38. furi_assert(instance);
  39. free(instance);
  40. }
  41. void nfc_magic_scanner_set_gen4_password(NfcMagicScanner* instance, uint32_t password) {
  42. furi_assert(instance);
  43. instance->gen4_password = password;
  44. }
  45. static int32_t nfc_magic_scanner_worker(void* context) {
  46. furi_assert(context);
  47. NfcMagicScanner* instance = context;
  48. furi_assert(instance->session_state == NfcMagicScannerSessionStateActive);
  49. while(instance->session_state == NfcMagicScannerSessionStateActive) {
  50. do {
  51. if(instance->current_protocol == NfcMagicProtocolGen1) {
  52. instance->magic_protocol_detected = gen1a_poller_detect(instance->nfc);
  53. if(instance->magic_protocol_detected) {
  54. break;
  55. }
  56. } else if(instance->current_protocol == NfcMagicProtocolGen4) {
  57. Gen4PollerError error = gen4_poller_detect(instance->nfc, instance->gen4_password);
  58. instance->magic_protocol_detected = (error == Gen4PollerErrorNone);
  59. if(instance->magic_protocol_detected) {
  60. break;
  61. }
  62. } else if(instance->current_protocol == NfcMagicProtocolGen2) {
  63. Gen2PollerError error = gen2_poller_detect(instance->nfc);
  64. instance->magic_protocol_detected = (error == Gen2PollerErrorNone);
  65. if(instance->magic_protocol_detected) {
  66. break;
  67. }
  68. } else if(instance->current_protocol == NfcMagicProtocolClassic) {
  69. NfcPoller* poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfClassic);
  70. instance->magic_protocol_detected = nfc_poller_detect(poller);
  71. nfc_poller_free(poller);
  72. if(instance->magic_protocol_detected) {
  73. break;
  74. }
  75. }
  76. } while(false);
  77. if(instance->magic_protocol_detected) {
  78. NfcMagicScannerEvent event = {
  79. .type = NfcMagicScannerEventTypeDetected,
  80. .data.protocol = instance->current_protocol,
  81. };
  82. instance->callback(event, instance->context);
  83. break;
  84. }
  85. if(instance->current_protocol == NfcMagicProtocolNum - 1) {
  86. bool not_magic_protocol_detected = false;
  87. for(size_t i = 0; i < COUNT_OF(nfc_magic_scanner_not_magic_protocols); i++) {
  88. NfcProtocol protocol = nfc_magic_scanner_not_magic_protocols[i];
  89. NfcPoller* poller = nfc_poller_alloc(instance->nfc, protocol);
  90. not_magic_protocol_detected = nfc_poller_detect(poller);
  91. nfc_poller_free(poller);
  92. if(not_magic_protocol_detected) {
  93. break;
  94. }
  95. }
  96. if(not_magic_protocol_detected) {
  97. NfcMagicScannerEvent event = {
  98. .type = NfcMagicScannerEventTypeDetectedNotMagic,
  99. };
  100. instance->callback(event, instance->context);
  101. break;
  102. }
  103. }
  104. instance->current_protocol = (instance->current_protocol + 1) % NfcMagicProtocolNum;
  105. }
  106. nfc_magic_scanner_reset(instance);
  107. return 0;
  108. }
  109. void nfc_magic_scanner_start(
  110. NfcMagicScanner* instance,
  111. NfcMagicScannerCallback callback,
  112. void* context) {
  113. furi_assert(instance);
  114. furi_assert(callback);
  115. instance->callback = callback;
  116. instance->context = context;
  117. instance->scan_worker = furi_thread_alloc();
  118. furi_thread_set_name(instance->scan_worker, "NfcMagicScanWorker");
  119. furi_thread_set_context(instance->scan_worker, instance);
  120. furi_thread_set_stack_size(instance->scan_worker, 4 * 1024);
  121. furi_thread_set_callback(instance->scan_worker, nfc_magic_scanner_worker);
  122. furi_thread_start(instance->scan_worker);
  123. instance->session_state = NfcMagicScannerSessionStateActive;
  124. }
  125. void nfc_magic_scanner_stop(NfcMagicScanner* instance) {
  126. furi_assert(instance);
  127. instance->session_state = NfcMagicScannerSessionStateStopRequest;
  128. furi_thread_join(instance->scan_worker);
  129. instance->session_state = NfcMagicScannerSessionStateIdle;
  130. furi_thread_free(instance->scan_worker);
  131. instance->scan_worker = NULL;
  132. instance->callback = NULL;
  133. instance->context = NULL;
  134. }