subbrute_scene_load_file.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "subbrute_scene_load_file.h"
  2. #include "subbrute_scene_entrypoint.h"
  3. #include "../subbrute_utils.h"
  4. #include <lib/subghz/protocols/registry.h>
  5. #define SUBGHZ_APP_PATH_FOLDER "/ext/subghz"
  6. bool subbrute_load(SubBruteState* context, const char* file_path) {
  7. bool result = false;
  8. Storage* storage = furi_record_open(RECORD_STORAGE);
  9. FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
  10. string_t temp_str;
  11. string_init(temp_str);
  12. uint32_t temp_data32;
  13. do {
  14. if(!flipper_format_file_open_existing(fff_data_file, file_path)) {
  15. FURI_LOG_E(TAG, "Error open file %s", file_path);
  16. string_reset(context->notification_msg);
  17. string_set_str(context->notification_msg, "Error open file");
  18. break;
  19. }
  20. if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) {
  21. FURI_LOG_E(TAG, "Missing or incorrect header");
  22. string_reset(context->notification_msg);
  23. string_set_str(context->notification_msg, "Missing or incorrect header");
  24. break;
  25. }
  26. // Frequency
  27. if(flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) {
  28. FURI_LOG_I(TAG, "Frequency: %d", temp_data32);
  29. context->frequency = temp_data32;
  30. if(!subbrute_is_frequency_allowed(context)) {
  31. break;
  32. }
  33. } else {
  34. FURI_LOG_E(TAG, "Missing or incorrect Frequency");
  35. string_reset(context->notification_msg);
  36. string_set_str(context->notification_msg, "Missing or incorrect Frequency");
  37. break;
  38. }
  39. // Preset
  40. if(!flipper_format_read_string(fff_data_file, "Preset", context->preset)) {
  41. FURI_LOG_E(TAG, "Preset FAIL");
  42. string_reset(context->notification_msg);
  43. string_set_str(context->notification_msg, "Preset FAIL");
  44. }
  45. // Protocol
  46. if(!flipper_format_read_string(fff_data_file, "Protocol", context->protocol)) {
  47. FURI_LOG_E(TAG, "Missing Protocol");
  48. string_reset(context->notification_msg);
  49. string_set_str(context->notification_msg, "Missing Protocol");
  50. break;
  51. } else {
  52. FURI_LOG_I(TAG, "Protocol: %s", string_get_cstr(context->protocol));
  53. }
  54. if(strcmp(string_get_cstr(context->protocol), "RAW") == 0) {
  55. FURI_LOG_E(TAG, "RAW unsupported");
  56. string_reset(context->notification_msg);
  57. string_set_str(context->notification_msg, "RAW unsupported");
  58. break;
  59. }
  60. const SubGhzProtocol* registry =
  61. subghz_protocol_registry_get_by_name(string_get_cstr(context->protocol));
  62. if(registry && registry->type == SubGhzProtocolTypeDynamic) {
  63. FURI_LOG_D(TAG, "Protocol is dynamic - not supported");
  64. string_reset(context->notification_msg);
  65. string_set_str(context->notification_msg, "Dynamic protocol unsupported");
  66. break;
  67. }
  68. context->decoder_result = subghz_receiver_search_decoder_base_by_name(
  69. context->receiver, string_get_cstr(context->protocol));
  70. if(context->decoder_result) {
  71. FURI_LOG_I(TAG, "Found decoder");
  72. } else {
  73. FURI_LOG_E(TAG, "Protocol not found");
  74. string_reset(context->notification_msg);
  75. string_set_str(context->notification_msg, "Protocol not found");
  76. break;
  77. }
  78. // Bit
  79. if(!flipper_format_read_uint32(fff_data_file, "Bit", &temp_data32, 1)) {
  80. FURI_LOG_E(TAG, "Missing or incorrect Bit");
  81. string_reset(context->notification_msg);
  82. string_set_str(context->notification_msg, "Missing or incorrect Bit");
  83. break;
  84. } else {
  85. FURI_LOG_I(TAG, "Bit: %d", temp_data32);
  86. context->bit = temp_data32;
  87. }
  88. // Key
  89. if(!flipper_format_read_string(fff_data_file, "Key", temp_str)) {
  90. FURI_LOG_E(TAG, "Missing or incorrect Key");
  91. string_reset(context->notification_msg);
  92. string_set_str(context->notification_msg, "Missing or incorrect Key");
  93. break;
  94. } else {
  95. FURI_LOG_I(TAG, "Key: %s", string_get_cstr(temp_str));
  96. string_set(context->key, string_get_cstr(temp_str));
  97. }
  98. // TE
  99. if(!flipper_format_read_uint32(fff_data_file, "TE", &temp_data32, 1)) {
  100. FURI_LOG_E(TAG, "Missing or incorrect TE");
  101. //string_reset(context->notification_msg);
  102. //string_set_str(context->notification_msg, "Missing or incorrect TE");
  103. //break;
  104. } else {
  105. FURI_LOG_I(TAG, "TE: %d", temp_data32);
  106. context->te = temp_data32;
  107. }
  108. // Repeat
  109. if(flipper_format_read_uint32(fff_data_file, "Repeat", &temp_data32, 1)) {
  110. FURI_LOG_I(TAG, "Repeat: %d", temp_data32);
  111. context->repeat = temp_data32;
  112. } else {
  113. FURI_LOG_I(TAG, "Repeat: 3 (default)");
  114. context->repeat = 3;
  115. }
  116. result = true;
  117. } while(0);
  118. string_clear(temp_str);
  119. flipper_format_file_close(fff_data_file);
  120. flipper_format_free(fff_data_file);
  121. furi_record_close(RECORD_STORAGE);
  122. if(result) {
  123. FURI_LOG_I(TAG, "Loaded successfully");
  124. string_reset(context->notification_msg);
  125. string_set_str(context->notification_msg, "File looks ok.");
  126. }
  127. return result;
  128. }
  129. void subbrute_scene_load_file_on_enter(SubBruteState* context) {
  130. if(subbrute_load_protocol_from_file(context)) {
  131. context->current_scene = SceneSelectField;
  132. } else {
  133. subbrute_scene_entrypoint_on_enter(context);
  134. context->current_scene = SceneEntryPoint;
  135. }
  136. }
  137. void subbrute_scene_load_file_on_exit(SubBruteState* context) {
  138. UNUSED(context);
  139. }
  140. void subbrute_scene_load_file_on_tick(SubBruteState* context) {
  141. UNUSED(context);
  142. }
  143. void subbrute_scene_load_file_on_event(SubBruteEvent event, SubBruteState* context) {
  144. UNUSED(context);
  145. if(event.evt_type == EventTypeKey) {
  146. if(event.input_type == InputTypeShort) {
  147. switch(event.key) {
  148. case InputKeyDown:
  149. case InputKeyUp:
  150. case InputKeyLeft:
  151. case InputKeyRight:
  152. case InputKeyOk:
  153. break;
  154. case InputKeyBack:
  155. context->current_scene = SceneEntryPoint;
  156. break;
  157. }
  158. }
  159. }
  160. }
  161. void subbrute_scene_load_file_on_draw(Canvas* canvas, SubBruteState* context) {
  162. UNUSED(context);
  163. canvas_clear(canvas);
  164. canvas_set_color(canvas, ColorBlack);
  165. // Frame
  166. //canvas_draw_frame(canvas, 0, 0, 128, 64);
  167. // Title
  168. canvas_set_font(canvas, FontPrimary);
  169. canvas_draw_str_aligned(canvas, 64, 16, AlignCenter, AlignTop, "SubGHz Fuzzer");
  170. canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignTop, "Error: Press back");
  171. }
  172. bool subbrute_load_protocol_from_file(SubBruteState* context) {
  173. string_t file_path;
  174. string_init(file_path);
  175. string_set_str(file_path, SUBGHZ_APP_PATH_FOLDER);
  176. context->environment = subghz_environment_alloc();
  177. context->receiver = subghz_receiver_alloc_init(context->environment);
  178. subghz_receiver_set_filter(context->receiver, SubGhzProtocolFlag_Decodable);
  179. // Input events and views are managed by file_select
  180. DialogsFileBrowserOptions browser_options;
  181. dialog_file_browser_set_basic_options(&browser_options, SUBGHZ_APP_EXTENSION, &I_sub1_10px);
  182. bool res = dialog_file_browser_show(context->dialogs, file_path, file_path, &browser_options);
  183. if(res) {
  184. res = subbrute_load(context, string_get_cstr(file_path));
  185. }
  186. subghz_environment_free(context->environment);
  187. subghz_receiver_free(context->receiver);
  188. string_clear(file_path);
  189. return res;
  190. }