passy_scene_read.c 5.4 KB

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