web_crawler_i.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. #ifndef WEB_CRAWLER_I_H
  2. #define WEB_CRAWLER_I_H
  3. /**
  4. * @brief Function to allocate resources for the WebCrawlerApp.
  5. * @return Pointer to the initialized WebCrawlerApp, or NULL on failure.
  6. */
  7. static WebCrawlerApp *web_crawler_app_alloc()
  8. {
  9. // Initialize the entire structure to zero to prevent undefined behavior
  10. WebCrawlerApp *app = (WebCrawlerApp *)malloc(sizeof(WebCrawlerApp));
  11. if (!app)
  12. {
  13. FURI_LOG_E(TAG, "Failed to allocate WebCrawlerApp");
  14. return NULL;
  15. }
  16. memset(app, 0, sizeof(WebCrawlerApp));
  17. // Open GUI
  18. Gui *gui = furi_record_open(RECORD_GUI);
  19. if (!gui)
  20. {
  21. FURI_LOG_E(TAG, "Failed to open GUI record");
  22. free_resources(app);
  23. return NULL;
  24. }
  25. // Allocate ViewDispatcher
  26. app->view_dispatcher = view_dispatcher_alloc();
  27. if (!app->view_dispatcher)
  28. {
  29. FURI_LOG_E(TAG, "Failed to allocate ViewDispatcher");
  30. furi_record_close(RECORD_GUI);
  31. free(app);
  32. return NULL;
  33. }
  34. // Attach ViewDispatcher to GUI
  35. view_dispatcher_attach_to_gui(app->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
  36. view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
  37. // Initialize UART with the correct callback
  38. if (!flipper_http_init(flipper_http_rx_callback, app))
  39. {
  40. FURI_LOG_E(TAG, "Failed to initialize UART");
  41. free_all(app, "Failed to initialize UART");
  42. return NULL;
  43. }
  44. // Allocate and initialize temp_buffer and path
  45. app->temp_buffer_size_path = 128;
  46. app->temp_buffer_path = malloc(app->temp_buffer_size_path);
  47. if (!app->temp_buffer_path)
  48. {
  49. FURI_LOG_E(TAG, "Failed to allocate temp_buffer_path");
  50. free_all(app, "Failed to allocate temp_buffer_path");
  51. return NULL;
  52. }
  53. app->temp_buffer_path[0] = '\0';
  54. // Allocate path
  55. app->path = malloc(app->temp_buffer_size_path);
  56. if (!app->path)
  57. {
  58. FURI_LOG_E(TAG, "Failed to allocate path");
  59. free_all(app, "Failed to allocate path");
  60. return NULL;
  61. }
  62. app->path[0] = '\0';
  63. // Allocate and initialize temp_buffer_ssid
  64. app->temp_buffer_size_ssid = 128;
  65. app->temp_buffer_ssid = malloc(app->temp_buffer_size_ssid);
  66. if (!app->temp_buffer_ssid)
  67. {
  68. FURI_LOG_E(TAG, "Failed to allocate temp_buffer_ssid");
  69. free_all(app, "Failed to allocate temp_buffer_ssid");
  70. return NULL;
  71. }
  72. app->temp_buffer_ssid[0] = '\0';
  73. // Allocate ssid
  74. app->ssid = malloc(app->temp_buffer_size_ssid);
  75. if (!app->ssid)
  76. {
  77. FURI_LOG_E(TAG, "Failed to allocate ssid");
  78. free_all(app, "Failed to allocate ssid");
  79. return NULL;
  80. }
  81. app->ssid[0] = '\0';
  82. // Allocate and initialize temp_buffer_password
  83. app->temp_buffer_size_password = 128;
  84. app->temp_buffer_password = malloc(app->temp_buffer_size_password);
  85. if (!app->temp_buffer_password)
  86. {
  87. FURI_LOG_E(TAG, "Failed to allocate temp_buffer_password");
  88. free_all(app, "Failed to allocate temp_buffer_password");
  89. return NULL;
  90. }
  91. app->temp_buffer_password[0] = '\0';
  92. // Allocate password
  93. app->password = malloc(app->temp_buffer_size_password);
  94. if (!app->password)
  95. {
  96. FURI_LOG_E(TAG, "Failed to allocate password");
  97. free_all(app, "Failed to allocate password");
  98. return NULL;
  99. }
  100. app->password[0] = '\0';
  101. // Allocate TextInput views
  102. app->text_input_path = text_input_alloc();
  103. if (!app->text_input_path)
  104. {
  105. free_all(app, "Failed to allocate TextInput for Path");
  106. return NULL;
  107. }
  108. app->text_input_ssid = text_input_alloc();
  109. if (!app->text_input_ssid)
  110. {
  111. free_all(app, "Failed to allocate TextInput for SSID");
  112. return NULL;
  113. }
  114. app->text_input_password = text_input_alloc();
  115. if (!app->text_input_password)
  116. {
  117. free_all(app, "Failed to allocate TextInput for Password");
  118. return NULL;
  119. }
  120. // Add TextInput views with unique view IDs
  121. view_dispatcher_add_view(
  122. app->view_dispatcher,
  123. WebCrawlerViewTextInput,
  124. text_input_get_view(app->text_input_path));
  125. view_dispatcher_add_view(
  126. app->view_dispatcher,
  127. WebCrawlerViewTextInputSSID,
  128. text_input_get_view(app->text_input_ssid));
  129. view_dispatcher_add_view(
  130. app->view_dispatcher,
  131. WebCrawlerViewTextInputPassword,
  132. text_input_get_view(app->text_input_password));
  133. // Set previous callback for TextInput views to return to Configure screen
  134. view_set_previous_callback(
  135. text_input_get_view(app->text_input_path),
  136. web_crawler_back_to_configure_callback);
  137. view_set_previous_callback(
  138. text_input_get_view(app->text_input_ssid),
  139. web_crawler_back_to_configure_callback);
  140. view_set_previous_callback(
  141. text_input_get_view(app->text_input_password),
  142. web_crawler_back_to_configure_callback);
  143. // Allocate Configuration screen
  144. app->variable_item_list_config = variable_item_list_alloc();
  145. if (!app->variable_item_list_config)
  146. {
  147. free_all(app, "Failed to allocate VariableItemList for Configuration");
  148. return NULL;
  149. }
  150. variable_item_list_reset(app->variable_item_list_config);
  151. // Add "Path" item to the configuration screen
  152. app->path_item = variable_item_list_add(
  153. app->variable_item_list_config,
  154. "Path",
  155. 1, // Number of possible values (1 for a single text value)
  156. NULL, // No change callback needed
  157. NULL // No context needed
  158. );
  159. if (!app->path_item)
  160. {
  161. free_all(app, "Failed to add Path item to VariableItemList");
  162. return NULL;
  163. }
  164. variable_item_set_current_value_text(app->path_item, ""); // Initialize
  165. // Add "SSID" item to the configuration screen
  166. app->ssid_item = variable_item_list_add(
  167. app->variable_item_list_config,
  168. "SSID",
  169. 1, // Number of possible values (1 for a single text value)
  170. NULL, // No change callback needed
  171. NULL // No context needed
  172. );
  173. if (!app->ssid_item)
  174. {
  175. free_all(app, "Failed to add SSID item to VariableItemList");
  176. return NULL;
  177. }
  178. variable_item_set_current_value_text(app->ssid_item, ""); // Initialize
  179. // Add "Password" item to the configuration screen
  180. app->password_item = variable_item_list_add(
  181. app->variable_item_list_config,
  182. "Password",
  183. 1, // Number of possible values (1 for a single text value)
  184. NULL, // No change callback needed
  185. NULL // No context needed
  186. );
  187. if (!app->password_item)
  188. {
  189. free_all(app, "Failed to add Password item to VariableItemList");
  190. return NULL;
  191. }
  192. variable_item_set_current_value_text(app->password_item, ""); // Initialize
  193. // Set a single enter callback for all configuration items
  194. variable_item_list_set_enter_callback(
  195. app->variable_item_list_config,
  196. web_crawler_config_enter_callback,
  197. app);
  198. // Set previous callback for configuration screen
  199. view_set_previous_callback(
  200. variable_item_list_get_view(app->variable_item_list_config),
  201. web_crawler_back_to_main_callback);
  202. // Add Configuration view to ViewDispatcher
  203. view_dispatcher_add_view(
  204. app->view_dispatcher,
  205. WebCrawlerViewConfigure,
  206. variable_item_list_get_view(app->variable_item_list_config));
  207. // Allocate Submenu view
  208. app->submenu = submenu_alloc();
  209. if (!app->submenu)
  210. {
  211. FURI_LOG_E(TAG, "Failed to allocate Submenu");
  212. free_all(app, "Failed to allocate Submenu");
  213. return NULL;
  214. }
  215. submenu_set_header(app->submenu, "Web Crawler v0.2");
  216. // Add items to Submenu
  217. submenu_add_item(app->submenu, "Run", WebCrawlerSubmenuIndexRun, web_crawler_submenu_callback, app);
  218. submenu_add_item(app->submenu, "About", WebCrawlerSubmenuIndexAbout, web_crawler_submenu_callback, app);
  219. submenu_add_item(app->submenu, "Configure", WebCrawlerSubmenuIndexSetPath, web_crawler_submenu_callback, app);
  220. submenu_add_item(app->submenu, "Read File", WebCrawlerSubmenuIndexData, web_crawler_submenu_callback, app);
  221. // Set previous callback for Submenu
  222. view_set_previous_callback(submenu_get_view(app->submenu), web_crawler_exit_app_callback);
  223. // Add Submenu view to ViewDispatcher
  224. view_dispatcher_add_view(
  225. app->view_dispatcher,
  226. WebCrawlerViewSubmenu,
  227. submenu_get_view(app->submenu));
  228. // Allocate Main view
  229. app->view_main = view_alloc();
  230. if (!app->view_main)
  231. {
  232. free_all(app, "Failed to allocate Main view");
  233. return NULL;
  234. }
  235. view_set_draw_callback(app->view_main, web_crawler_view_draw_callback);
  236. view_set_previous_callback(app->view_main, web_crawler_back_to_main_callback);
  237. // Add Main view to ViewDispatcher
  238. view_dispatcher_add_view(app->view_dispatcher, WebCrawlerViewRun, app->view_main);
  239. //-- WIDGET ABOUT VIEW --
  240. // Allocate and add About view
  241. app->widget_about = widget_alloc();
  242. if (!app->widget_about)
  243. {
  244. FURI_LOG_E(TAG, "Failed to allocate About widget");
  245. free_all(app, "Failed to allocate About widget");
  246. return NULL;
  247. }
  248. // Reset the widget before adding elements
  249. widget_reset(app->widget_about);
  250. widget_add_text_scroll_element(
  251. app->widget_about,
  252. 0,
  253. 0,
  254. 128,
  255. 64,
  256. "Web Crawler App\n"
  257. "---\n"
  258. "This is a web crawler app for Flipper Zero.\n"
  259. "---\n"
  260. "Visit github.com/jblanked for more details.\n"
  261. "---\n"
  262. "Press BACK to return.");
  263. view_set_previous_callback(widget_get_view(app->widget_about), web_crawler_back_to_main_callback);
  264. view_dispatcher_add_view(app->view_dispatcher, WebCrawlerViewAbout, widget_get_view(app->widget_about));
  265. //-- TEXTBOX DATA VIEW --
  266. app->textbox = widget_alloc();
  267. if (!app->textbox)
  268. {
  269. FURI_LOG_E(TAG, "Failed to allocate Textbox");
  270. free_all(app, "Failed to allocate Textbox");
  271. return NULL;
  272. }
  273. widget_reset(app->textbox);
  274. widget_add_text_scroll_element(
  275. app->textbox,
  276. 0,
  277. 0,
  278. 128,
  279. 64, "Data will be displayed here.");
  280. view_set_previous_callback(widget_get_view(app->textbox), web_crawler_back_to_main_callback);
  281. view_dispatcher_add_view(app->view_dispatcher, WebCrawlerViewData, widget_get_view(app->textbox));
  282. // Load Settings and Update Views
  283. if (!load_settings(app->path, app->temp_buffer_size_path, app->ssid, app->temp_buffer_size_ssid, app->password, app->temp_buffer_size_password, app))
  284. {
  285. FURI_LOG_E(TAG, "Failed to load settings");
  286. }
  287. else
  288. {
  289. // Update the configuration items based on loaded settings
  290. if (app->path[0] != '\0')
  291. {
  292. variable_item_set_current_value_text(app->path_item, app->path);
  293. }
  294. else
  295. {
  296. variable_item_set_current_value_text(app->path_item, ""); // Initialize
  297. }
  298. if (app->ssid[0] != '\0')
  299. {
  300. variable_item_set_current_value_text(app->ssid_item, app->ssid);
  301. }
  302. else
  303. {
  304. variable_item_set_current_value_text(app->ssid_item, ""); // Initialize
  305. }
  306. // Password handling can be omitted for security or handled securely
  307. }
  308. app_instance = app;
  309. // Start with the Submenu view
  310. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewSubmenu);
  311. return app;
  312. }
  313. #endif // WEB_CRAWLER_I_H