nfc_magic_scanner.c 5.2 KB

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