wiegand_save.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "../wiegand.h"
  2. void wiegand_data_scene_save_name_text_input_callback(void *context)
  3. {
  4. App *app = context;
  5. view_dispatcher_send_custom_event(app->view_dispatcher, WiegandDataSceneSaveFileEvent);
  6. }
  7. void ensure_dir_exists(Storage *storage)
  8. {
  9. // If apps_data directory doesn't exist, create it.
  10. if (!storage_dir_exists(storage, WIEGAND_APPS_DATA_FOLDER))
  11. {
  12. FURI_LOG_I(TAG, "Creating directory: %s", WIEGAND_APPS_DATA_FOLDER);
  13. storage_simply_mkdir(storage, WIEGAND_APPS_DATA_FOLDER);
  14. }
  15. else
  16. {
  17. FURI_LOG_I(TAG, "Directory exists: %s", WIEGAND_APPS_DATA_FOLDER);
  18. }
  19. // If wiegand directory doesn't exist, create it.
  20. if (!storage_dir_exists(storage, WIEGAND_SAVE_FOLDER))
  21. {
  22. FURI_LOG_I(TAG, "Creating directory: %s", WIEGAND_SAVE_FOLDER);
  23. storage_simply_mkdir(storage, WIEGAND_SAVE_FOLDER);
  24. }
  25. else
  26. {
  27. FURI_LOG_I(TAG, "Directory exists: %s", WIEGAND_SAVE_FOLDER);
  28. }
  29. }
  30. void wiegand_save(void *context)
  31. {
  32. App *app = context;
  33. FuriString *buffer = furi_string_alloc(1024);
  34. FuriString *file_path = furi_string_alloc();
  35. furi_string_printf(
  36. file_path, "%s/%s%s", WIEGAND_SAVE_FOLDER, app->file_name, WIEGAND_SAVE_EXTENSION);
  37. Storage *storage = furi_record_open(RECORD_STORAGE);
  38. ensure_dir_exists(storage);
  39. File *data_file = storage_file_alloc(storage);
  40. if (storage_file_open(
  41. data_file, furi_string_get_cstr(file_path), FSAM_WRITE, FSOM_OPEN_ALWAYS))
  42. {
  43. furi_string_printf(buffer, "Filetype: Flipper Wiegand Key File\n");
  44. storage_file_write(data_file, furi_string_get_cstr(buffer), furi_string_size(buffer));
  45. furi_string_printf(buffer, "Version: 1\n");
  46. storage_file_write(data_file, furi_string_get_cstr(buffer), furi_string_size(buffer));
  47. furi_string_printf(buffer, "Protocol: RAW\n");
  48. storage_file_write(data_file, furi_string_get_cstr(buffer), furi_string_size(buffer));
  49. furi_string_printf(buffer, "Bits: %d\n", bit_count);
  50. storage_file_write(data_file, furi_string_get_cstr(buffer), furi_string_size(buffer));
  51. furi_string_printf(buffer, "RAW_Data: ");
  52. for (int i = 0; i < bit_count; i++)
  53. {
  54. furi_string_cat_printf(
  55. buffer,
  56. "D%d %ld %ld ",
  57. data[i] ? 1 : 0,
  58. data_fall[i] - data_fall[0],
  59. data_rise[i] - data_fall[0]);
  60. }
  61. furi_string_push_back(buffer, '\n');
  62. storage_file_write(data_file, furi_string_get_cstr(buffer), furi_string_size(buffer));
  63. furi_string_printf(buffer, "PACS_Binary: ");
  64. for (int i = 0; i < bit_count; i++)
  65. {
  66. furi_string_cat_printf(buffer, "%d", data[i] ? 1 : 0);
  67. }
  68. furi_string_push_back(buffer, '\n');
  69. storage_file_write(data_file, furi_string_get_cstr(buffer), furi_string_size(buffer));
  70. furi_string_printf(buffer, "PM3_Command: hf ic encode --bin ");
  71. for (int i = 0; i < bit_count; i++)
  72. {
  73. furi_string_cat_printf(buffer, "%d", data[i] ? 1 : 0);
  74. }
  75. furi_string_cat_printf(buffer, " --ki 0\n");
  76. storage_file_write(data_file, furi_string_get_cstr(buffer), furi_string_size(buffer));
  77. storage_file_close(data_file);
  78. }
  79. storage_file_free(data_file);
  80. furi_record_close(RECORD_STORAGE);
  81. furi_string_free(file_path);
  82. furi_string_free(buffer);
  83. }
  84. void wiegand_save_scene_on_enter(void *context)
  85. {
  86. App *app = context;
  87. text_input_reset(app->text_input);
  88. FuriHalRtcDateTime datetime;
  89. furi_hal_rtc_get_datetime(&datetime);
  90. snprintf(
  91. app->file_name,
  92. 50,
  93. "%02d_%02d_%02d_%02d_%02d_%02d",
  94. datetime.year,
  95. datetime.month,
  96. datetime.day,
  97. datetime.hour,
  98. datetime.minute,
  99. datetime.second);
  100. // set_random_name(app->file_name, WIEGAND_KEY_NAME_SIZE);
  101. text_input_set_header_text(app->text_input, "Name the key");
  102. text_input_set_result_callback(
  103. app->text_input,
  104. wiegand_data_scene_save_name_text_input_callback,
  105. app,
  106. app->file_name,
  107. WIEGAND_KEY_NAME_SIZE,
  108. true);
  109. view_dispatcher_switch_to_view(app->view_dispatcher, WiegandTextInputView);
  110. }
  111. bool wiegand_save_scene_on_event(void *context, SceneManagerEvent event)
  112. {
  113. App *app = context;
  114. bool consumed = false;
  115. switch (event.type)
  116. {
  117. case SceneManagerEventTypeCustom:
  118. switch (event.event)
  119. {
  120. case WiegandDataSceneSaveFileEvent:
  121. wiegand_save(app);
  122. data_saved = true;
  123. scene_manager_search_and_switch_to_previous_scene(
  124. app->scene_manager, WiegandDataScene);
  125. consumed = true;
  126. break;
  127. default:
  128. consumed = false;
  129. break;
  130. }
  131. break;
  132. default:
  133. break;
  134. }
  135. return consumed;
  136. }