metroflip_scene_load.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #include "../metroflip_i.h"
  2. #include <dolphin/dolphin.h>
  3. #include <furi.h>
  4. #include <bit_lib.h>
  5. #include <lib/nfc/protocols/nfc_protocol.h>
  6. #include "../api/metroflip/metroflip_api.h"
  7. #define TAG "Metroflip:Scene:Load"
  8. #include "keys.h"
  9. #include <nfc/protocols/mf_classic/mf_classic.h>
  10. void metroflip_scene_load_on_enter(void* context) {
  11. Metroflip* app = (Metroflip*)context;
  12. // We initialized this to be false every time we enter
  13. app->data_loaded = false;
  14. bool has_card_type = false;
  15. // The same string we will use to direct parse scene which plugin to call
  16. // Extracted from the file
  17. FuriString* card_type = furi_string_alloc();
  18. FuriString* device_type = furi_string_alloc();
  19. // All the app_data browser stuff. Don't worry about this
  20. DialogsFileBrowserOptions browser_options;
  21. Storage* storage = furi_record_open(RECORD_STORAGE);
  22. storage_simply_mkdir(storage, STORAGE_APP_DATA_PATH_PREFIX);
  23. dialog_file_browser_set_basic_options(&browser_options, METROFLIP_FILE_EXTENSION, &I_icon);
  24. browser_options.base_path = STORAGE_APP_DATA_PATH_PREFIX;
  25. FuriString* file_path = furi_string_alloc_set(browser_options.base_path);
  26. if(dialog_file_browser_show(app->dialogs, file_path, file_path, &browser_options)) {
  27. FlipperFormat* format = flipper_format_file_alloc(storage);
  28. do {
  29. if(!flipper_format_file_open_existing(format, furi_string_get_cstr(file_path))) break;
  30. if(!flipper_format_read_string(format, "Device type", device_type)) break;
  31. const char* protocol_name = furi_string_get_cstr(device_type);
  32. if(!flipper_format_read_string(format, "Card Type", card_type)) {
  33. flipper_format_file_close(format);
  34. flipper_format_file_open_existing(format, furi_string_get_cstr(file_path));
  35. if(strcmp(protocol_name, "Mifare Classic") == 0) {
  36. MfClassicData* mfc_data = mf_classic_alloc();
  37. if(!mf_classic_load(mfc_data, format, 2)) break;
  38. app->data_loaded = true;
  39. CardType card_type = determine_card_type(app->nfc, mfc_data, app->data_loaded);
  40. app->mfc_card_type = card_type;
  41. has_card_type = true;
  42. switch(card_type) {
  43. case CARD_TYPE_METROMONEY:
  44. app->card_type = "metromoney";
  45. FURI_LOG_I(TAG, "Detected: Metromoney\n");
  46. break;
  47. case CARD_TYPE_CHARLIECARD:
  48. app->card_type = "charliecard";
  49. FURI_LOG_I(TAG, "Detected: CharlieCard\n");
  50. break;
  51. case CARD_TYPE_SMARTRIDER:
  52. app->card_type = "smartrider";
  53. FURI_LOG_I(TAG, "Detected: SmartRider\n");
  54. break;
  55. case CARD_TYPE_TROIKA:
  56. app->card_type = "troika";
  57. FURI_LOG_I(TAG, "Detected: Troika\n");
  58. break;
  59. case CARD_TYPE_GOCARD:
  60. app->card_type = "gocard";
  61. FURI_LOG_I(TAG, "Detected: go card\n");
  62. break;
  63. case CARD_TYPE_UNKNOWN:
  64. app->card_type = "unknown";
  65. //popup_set_header(popup, "Unsupported\n card", 58, 31, AlignLeft, AlignTop);
  66. break;
  67. default:
  68. app->card_type = "unknown";
  69. FURI_LOG_I(TAG, "Detected: Unknown card type\n");
  70. //popup_set_header(popup, "Unsupported\n card", 58, 31, AlignLeft, AlignTop);
  71. break;
  72. }
  73. mf_classic_free(mfc_data);
  74. } else if(strcmp(protocol_name, "Mifare DESFire") == 0) {
  75. MfDesfireData* data = mf_desfire_alloc();
  76. if(!mf_desfire_load(data, format, 2)) break;
  77. app->data_loaded = true;
  78. if(clipper_verify(data)) {
  79. app->card_type = "clipper";
  80. FURI_LOG_I(TAG, "Detected: Clipper");
  81. } else if(itso_verify(data)) {
  82. app->card_type = "itso";
  83. FURI_LOG_I(TAG, "Detected: ITSO");
  84. } else if(myki_verify(data)) {
  85. app->card_type = "myki";
  86. FURI_LOG_I(TAG, "Detected: Myki");
  87. } else if(opal_verify(data)) {
  88. app->card_type = "opal";
  89. FURI_LOG_I(TAG, "Detected: Opal");
  90. } else {
  91. app->card_type = "unknown";
  92. FURI_LOG_I(TAG, "Detected: none");
  93. }
  94. mf_desfire_free(data);
  95. has_card_type = true;
  96. } else {
  97. has_card_type = true;
  98. }
  99. flipper_format_file_close(format);
  100. } else {
  101. has_card_type = false;
  102. }
  103. app->file_path = furi_string_get_cstr(file_path);
  104. strncpy(
  105. app->delete_file_path,
  106. furi_string_get_cstr(file_path),
  107. sizeof(app->delete_file_path) - 1);
  108. app->delete_file_path[sizeof(app->delete_file_path) - 1] = '\0';
  109. app->data_loaded = true;
  110. } while(0);
  111. flipper_format_free(format);
  112. }
  113. if(app->data_loaded) {
  114. // Direct to the parsing screen just like the auto scene does
  115. if(!has_card_type) {
  116. app->card_type = furi_string_get_cstr(card_type);
  117. has_card_type = false;
  118. }
  119. scene_manager_search_and_switch_to_previous_scene(app->scene_manager, MetroflipSceneStart);
  120. scene_manager_next_scene(app->scene_manager, MetroflipSceneParse);
  121. } else {
  122. scene_manager_search_and_switch_to_previous_scene(app->scene_manager, MetroflipSceneStart);
  123. }
  124. furi_string_free(file_path);
  125. furi_record_close(RECORD_STORAGE);
  126. }
  127. bool metroflip_scene_load_on_event(void* context, SceneManagerEvent event) {
  128. Metroflip* app = context;
  129. UNUSED(event);
  130. bool consumed = false;
  131. // If they don't select any file in the brwoser and press back button,
  132. // the data is not loaded
  133. if(!app->data_loaded) {
  134. scene_manager_search_and_switch_to_previous_scene(app->scene_manager, MetroflipSceneStart);
  135. }
  136. consumed = true;
  137. return consumed;
  138. }
  139. void metroflip_scene_load_on_exit(void* context) {
  140. Metroflip* app = context;
  141. UNUSED(app);
  142. }