passy_scene_read.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "../passy_i.h"
  2. #include "../passy_reader.h"
  3. #include <dolphin/dolphin.h>
  4. #define TAG "PassySceneRead"
  5. static PassyReader* passy_reader = NULL;
  6. void passy_scene_detect_scan_callback(NfcScannerEvent event, void* context) {
  7. furi_assert(context);
  8. Passy* passy = context;
  9. passy->proto = NULL;
  10. // detect the type of protocol, either 4a/4b and then run the specific poller callback functions yada yada yada
  11. if(event.type == NfcScannerEventTypeDetected) {
  12. if(event.data.protocols && *event.data.protocols == NfcProtocolIso14443_4a) {
  13. passy->proto = "4a";
  14. } else if(event.data.protocols && *event.data.protocols == NfcProtocolIso14443_4b) {
  15. passy->proto = "4b";
  16. } else {
  17. FURI_LOG_E(TAG, "Unknown protocol detected, %d", *event.data.protocols);
  18. }
  19. if(passy->proto && strlen(passy->proto) > 0) {
  20. view_dispatcher_send_custom_event(
  21. passy->view_dispatcher, PassyCustomEventReaderDetected);
  22. } else {
  23. view_dispatcher_send_custom_event(
  24. passy->view_dispatcher, PassyCustomEventReaderRestart);
  25. }
  26. }
  27. }
  28. void passy_scene_read_on_enter(void* context) {
  29. Passy* passy = context;
  30. dolphin_deed(DolphinDeedNfcRead);
  31. // Setup view
  32. Popup* popup = passy->popup;
  33. popup_set_header(popup, "Reading", 68, 30, AlignLeft, AlignTop);
  34. popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
  35. passy->scanner = nfc_scanner_alloc(passy->nfc);
  36. nfc_scanner_start(
  37. passy->scanner, passy_scene_detect_scan_callback, passy); // starts a scanner instance
  38. passy_blink_start(passy);
  39. view_dispatcher_switch_to_view(passy->view_dispatcher, PassyViewPopup);
  40. }
  41. bool passy_scene_read_on_event(void* context, SceneManagerEvent event) {
  42. Passy* passy = context;
  43. bool consumed = false;
  44. Popup* popup = passy->popup;
  45. if(event.type == SceneManagerEventTypeCustom) {
  46. if(event.event == PassyCustomEventReaderSuccess) {
  47. if(passy->read_type == PassyReadCOM) {
  48. scene_manager_next_scene(passy->scene_manager, PassySceneAdvancedMenu);
  49. } else {
  50. scene_manager_next_scene(passy->scene_manager, PassySceneReadSuccess);
  51. }
  52. consumed = true;
  53. } else if(event.event == PassyCustomEventReaderError) {
  54. passy->last_sw = passy_reader->last_sw;
  55. scene_manager_next_scene(passy->scene_manager, PassySceneReadError);
  56. consumed = true;
  57. } else if(event.event == PassyCustomEventReaderRestart) {
  58. nfc_scanner_stop(passy->scanner);
  59. nfc_scanner_start(passy->scanner, passy_scene_detect_scan_callback, passy);
  60. consumed = true;
  61. } else if(event.event == PassyCustomEventReaderDetected) {
  62. nfc_scanner_stop(passy->scanner);
  63. nfc_scanner_free(passy->scanner);
  64. passy->scanner = NULL;
  65. if(strcmp(passy->proto, "4b") == 0) {
  66. FURI_LOG_I(TAG, "detected 4B protocol");
  67. passy->poller = nfc_poller_alloc(passy->nfc, NfcProtocolIso14443_4b);
  68. passy_reader = passy_reader_alloc(passy);
  69. nfc_poller_start(passy->poller, passy_reader_poller_callback, passy_reader);
  70. passy->bytes_total = 0;
  71. } else if(strcmp(passy->proto, "4a") == 0) {
  72. FURI_LOG_I(TAG, "detected 4A protocol");
  73. passy->poller = nfc_poller_alloc(passy->nfc, NfcProtocolIso14443_4a);
  74. passy_reader = passy_reader_alloc(passy);
  75. nfc_poller_start(passy->poller, passy_reader_poller_callback, passy_reader);
  76. passy->bytes_total = 0;
  77. } else {
  78. view_dispatcher_send_custom_event(
  79. passy->view_dispatcher, PassyCustomEventReaderError);
  80. }
  81. popup_set_header(popup, "Detected", 68, 30, AlignLeft, AlignTop);
  82. } else if(event.event == PassyCustomEventReaderAuthenticated) {
  83. popup_set_header(popup, "Authenticated", 68, 30, AlignLeft, AlignTop);
  84. } else if(event.event == PassyCustomEventReaderReading) {
  85. if(passy->bytes_total == 0) {
  86. popup_set_header(popup, "Reading", 68, 30, AlignLeft, AlignTop);
  87. } else {
  88. // Update the header with the current bytes read
  89. char header[32];
  90. snprintf(
  91. header,
  92. sizeof(header),
  93. "Reading\n%d/%dk",
  94. passy->offset,
  95. (passy->bytes_total / 1024));
  96. popup_set_header(popup, header, 68, 30, AlignLeft, AlignTop);
  97. }
  98. }
  99. } else if(event.type == SceneManagerEventTypeBack) {
  100. scene_manager_search_and_switch_to_previous_scene(
  101. passy->scene_manager, PassySceneMainMenu);
  102. consumed = true;
  103. }
  104. return consumed;
  105. }
  106. void passy_scene_read_on_exit(void* context) {
  107. Passy* passy = context;
  108. if(passy_reader) {
  109. passy_reader_free(passy_reader);
  110. passy_reader = NULL;
  111. }
  112. if(passy->poller) {
  113. nfc_poller_stop(passy->poller);
  114. nfc_poller_free(passy->poller);
  115. passy->poller = NULL;
  116. }
  117. if(passy->scanner) {
  118. nfc_scanner_stop(passy->scanner);
  119. nfc_scanner_free(passy->scanner);
  120. passy->scanner = NULL;
  121. }
  122. // Clear view
  123. popup_reset(passy->popup);
  124. passy_blink_stop(passy);
  125. }