metroflip_scene_load.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. // All the app_data browser stuff. Don't worry about this
  19. DialogsFileBrowserOptions browser_options;
  20. Storage* storage = furi_record_open(RECORD_STORAGE);
  21. storage_simply_mkdir(storage, STORAGE_APP_DATA_PATH_PREFIX);
  22. dialog_file_browser_set_basic_options(&browser_options, METROFLIP_FILE_EXTENSION, &I_icon);
  23. browser_options.base_path = STORAGE_APP_DATA_PATH_PREFIX;
  24. FuriString* file_path = furi_string_alloc_set(browser_options.base_path);
  25. if(dialog_file_browser_show(app->dialogs, file_path, file_path, &browser_options)) {
  26. FlipperFormat* format = flipper_format_file_alloc(storage);
  27. do {
  28. if(!flipper_format_file_open_existing(format, furi_string_get_cstr(file_path))) break;
  29. if(!flipper_format_read_string(format, "Card Type", card_type)) {
  30. flipper_format_file_close(format);
  31. flipper_format_file_open_existing(format, furi_string_get_cstr(file_path));
  32. FURI_LOG_I(TAG, "dont have card type in file, detecting..");
  33. MfClassicData* mfc_data = mf_classic_alloc();
  34. if(!mf_classic_load(mfc_data, format, 2)) {
  35. FURI_LOG_I(TAG, "failed");
  36. } else {
  37. FURI_LOG_I(TAG, "success");
  38. }
  39. FURI_LOG_I(TAG, "%d", mfc_data->block[3].data[1]);
  40. app->data_loaded = true;
  41. CardType card_type = determine_card_type(app->nfc, mfc_data, app->data_loaded);
  42. app->mfc_card_type = card_type;
  43. switch(card_type) {
  44. case CARD_TYPE_METROMONEY:
  45. app->card_type = "metromoney";
  46. FURI_LOG_I(TAG, "Detected: Metromoney\n");
  47. break;
  48. case CARD_TYPE_CHARLIECARD:
  49. app->card_type = "charliecard";
  50. FURI_LOG_I(TAG, "Detected: CharlieCard\n");
  51. break;
  52. case CARD_TYPE_SMARTRIDER:
  53. app->card_type = "smartrider";
  54. FURI_LOG_I(TAG, "Detected: SmartRider\n");
  55. break;
  56. case CARD_TYPE_TROIKA:
  57. app->card_type = "troika";
  58. FURI_LOG_I(TAG, "Detected: Troika\n");
  59. break;
  60. case CARD_TYPE_UNKNOWN:
  61. app->card_type = "unknown";
  62. FURI_LOG_I(TAG, "Detected: Unknown card type\n");
  63. //popup_set_header(popup, "Unsupported\n card", 58, 31, AlignLeft, AlignTop);
  64. break;
  65. default:
  66. app->card_type = "unknown";
  67. FURI_LOG_I(TAG, "Detected: Unknown card type\n");
  68. //popup_set_header(popup, "Unsupported\n card", 58, 31, AlignLeft, AlignTop);
  69. break;
  70. }
  71. mf_classic_free(mfc_data);
  72. has_card_type = true;
  73. }
  74. app->file_path = furi_string_get_cstr(file_path);
  75. app->data_loaded = true;
  76. } while(0);
  77. flipper_format_free(format);
  78. }
  79. if(app->data_loaded) {
  80. // Direct to the parsing screen just like the auto scene does
  81. if(!has_card_type) {
  82. app->card_type = furi_string_get_cstr(card_type);
  83. has_card_type = false;
  84. }
  85. scene_manager_next_scene(app->scene_manager, MetroflipSceneParse);
  86. } else {
  87. scene_manager_next_scene(app->scene_manager, MetroflipSceneStart);
  88. }
  89. furi_string_free(file_path);
  90. furi_record_close(RECORD_STORAGE);
  91. }
  92. bool metroflip_scene_load_on_event(void* context, SceneManagerEvent event) {
  93. Metroflip* app = context;
  94. UNUSED(event);
  95. bool consumed = false;
  96. // If they don't select any file in the brwoser and press back button,
  97. // the data is not loaded
  98. if(!app->data_loaded) {
  99. scene_manager_search_and_switch_to_previous_scene(app->scene_manager, MetroflipSceneStart);
  100. }
  101. consumed = true;
  102. return consumed;
  103. }
  104. void metroflip_scene_load_on_exit(void* context) {
  105. Metroflip* app = context;
  106. UNUSED(app);
  107. }