web_crawler_alloc.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. #include <alloc/web_crawler_alloc.h>
  2. /**
  3. * @brief Function to allocate resources for the WebCrawlerApp.
  4. * @return Pointer to the initialized WebCrawlerApp, or NULL on failure.
  5. */
  6. WebCrawlerApp* web_crawler_app_alloc() {
  7. // Initialize the entire structure to zero to prevent undefined behavior
  8. WebCrawlerApp* app = (WebCrawlerApp*)malloc(sizeof(WebCrawlerApp));
  9. // Open GUI
  10. Gui* gui = furi_record_open(RECORD_GUI);
  11. // Initialize UART with the correct callback
  12. if(!flipper_http_init(flipper_http_rx_callback, app)) {
  13. FURI_LOG_E(TAG, "Failed to initialize UART");
  14. return NULL;
  15. }
  16. // Allocate ViewDispatcher
  17. if(!easy_flipper_set_view_dispatcher(&app->view_dispatcher, gui, app)) {
  18. return NULL;
  19. }
  20. view_dispatcher_set_custom_event_callback(
  21. app->view_dispatcher, web_crawler_custom_event_callback);
  22. // Allocate and initialize temp_buffer and path
  23. app->temp_buffer_size_path = 128;
  24. app->temp_buffer_size_ssid = 64;
  25. app->temp_buffer_size_password = 64;
  26. app->temp_buffer_size_file_type = 16;
  27. app->temp_buffer_size_file_rename = 128;
  28. app->temp_buffer_size_http_method = 16;
  29. app->temp_buffer_size_headers = 256;
  30. app->temp_buffer_size_payload = 256;
  31. if(!easy_flipper_set_buffer(&app->temp_buffer_path, app->temp_buffer_size_path)) {
  32. return NULL;
  33. }
  34. if(!easy_flipper_set_buffer(&app->path, app->temp_buffer_size_path)) {
  35. return NULL;
  36. }
  37. if(!easy_flipper_set_buffer(&app->temp_buffer_ssid, app->temp_buffer_size_ssid)) {
  38. return NULL;
  39. }
  40. if(!easy_flipper_set_buffer(&app->ssid, app->temp_buffer_size_ssid)) {
  41. return NULL;
  42. }
  43. if(!easy_flipper_set_buffer(&app->temp_buffer_password, app->temp_buffer_size_password)) {
  44. return NULL;
  45. }
  46. if(!easy_flipper_set_buffer(&app->password, app->temp_buffer_size_password)) {
  47. return NULL;
  48. }
  49. if(!easy_flipper_set_buffer(&app->temp_buffer_file_type, app->temp_buffer_size_file_type)) {
  50. return NULL;
  51. }
  52. if(!easy_flipper_set_buffer(&app->file_type, app->temp_buffer_size_file_type)) {
  53. return NULL;
  54. }
  55. if(!easy_flipper_set_buffer(&app->temp_buffer_file_rename, app->temp_buffer_size_file_rename)) {
  56. return NULL;
  57. }
  58. if(!easy_flipper_set_buffer(&app->file_rename, app->temp_buffer_size_file_rename)) {
  59. return NULL;
  60. }
  61. if(!easy_flipper_set_buffer(&app->temp_buffer_http_method, app->temp_buffer_size_http_method)) {
  62. return NULL;
  63. }
  64. if(!easy_flipper_set_buffer(&app->http_method, app->temp_buffer_size_http_method)) {
  65. return NULL;
  66. }
  67. if(!easy_flipper_set_buffer(&app->temp_buffer_headers, app->temp_buffer_size_headers)) {
  68. return NULL;
  69. }
  70. if(!easy_flipper_set_buffer(&app->headers, app->temp_buffer_size_headers)) {
  71. return NULL;
  72. }
  73. if(!easy_flipper_set_buffer(&app->temp_buffer_payload, app->temp_buffer_size_payload)) {
  74. return NULL;
  75. }
  76. if(!easy_flipper_set_buffer(&app->payload, app->temp_buffer_size_payload)) {
  77. return NULL;
  78. }
  79. // Allocate TextInput views
  80. if(!easy_flipper_set_uart_text_input(
  81. &app->text_input_path,
  82. WebCrawlerViewTextInput,
  83. "Enter URL",
  84. app->temp_buffer_path,
  85. app->temp_buffer_size_path,
  86. NULL,
  87. web_crawler_back_to_request_callback,
  88. &app->view_dispatcher,
  89. app)) {
  90. return NULL;
  91. }
  92. if(!easy_flipper_set_uart_text_input(
  93. &app->text_input_ssid,
  94. WebCrawlerViewTextInputSSID,
  95. "Enter SSID",
  96. app->temp_buffer_ssid,
  97. app->temp_buffer_size_ssid,
  98. NULL,
  99. web_crawler_back_to_wifi_callback,
  100. &app->view_dispatcher,
  101. app)) {
  102. return NULL;
  103. }
  104. if(!easy_flipper_set_uart_text_input(
  105. &app->text_input_password,
  106. WebCrawlerViewTextInputPassword,
  107. "Enter Password",
  108. app->temp_buffer_password,
  109. app->temp_buffer_size_password,
  110. NULL,
  111. web_crawler_back_to_wifi_callback,
  112. &app->view_dispatcher,
  113. app)) {
  114. return NULL;
  115. }
  116. if(!easy_flipper_set_uart_text_input(
  117. &app->text_input_file_type,
  118. WebCrawlerViewTextInputFileType,
  119. "Enter File Type",
  120. app->temp_buffer_file_type,
  121. app->temp_buffer_size_file_type,
  122. NULL,
  123. web_crawler_back_to_file_callback,
  124. &app->view_dispatcher,
  125. app)) {
  126. return NULL;
  127. }
  128. if(!easy_flipper_set_uart_text_input(
  129. &app->text_input_file_rename,
  130. WebCrawlerViewTextInputFileRename,
  131. "Enter File Rename",
  132. app->temp_buffer_file_rename,
  133. app->temp_buffer_size_file_rename,
  134. NULL,
  135. web_crawler_back_to_file_callback,
  136. &app->view_dispatcher,
  137. app)) {
  138. return NULL;
  139. }
  140. if(!easy_flipper_set_uart_text_input(
  141. &app->text_input_headers,
  142. WebCrawlerViewTextInputHeaders,
  143. "Enter Headers",
  144. app->temp_buffer_headers,
  145. app->temp_buffer_size_headers,
  146. NULL,
  147. web_crawler_back_to_request_callback,
  148. &app->view_dispatcher,
  149. app)) {
  150. return NULL;
  151. }
  152. if(!easy_flipper_set_uart_text_input(
  153. &app->text_input_payload,
  154. WebCrawlerViewTextInputPayload,
  155. "Enter Payload",
  156. app->temp_buffer_payload,
  157. app->temp_buffer_size_payload,
  158. NULL,
  159. web_crawler_back_to_request_callback,
  160. &app->view_dispatcher,
  161. app)) {
  162. return NULL;
  163. }
  164. // Allocate VariableItemList views
  165. if(!easy_flipper_set_variable_item_list(
  166. &app->variable_item_list_wifi,
  167. WebCrawlerViewVariableItemListWifi,
  168. web_crawler_wifi_enter_callback,
  169. web_crawler_back_to_configure_callback,
  170. &app->view_dispatcher,
  171. app)) {
  172. return NULL;
  173. }
  174. if(!easy_flipper_set_variable_item_list(
  175. &app->variable_item_list_file,
  176. WebCrawlerViewVariableItemListFile,
  177. web_crawler_file_enter_callback,
  178. web_crawler_back_to_configure_callback,
  179. &app->view_dispatcher,
  180. app)) {
  181. return NULL;
  182. }
  183. if(!easy_flipper_set_variable_item_list(
  184. &app->variable_item_list_request,
  185. WebCrawlerViewVariableItemListRequest,
  186. web_crawler_request_enter_callback,
  187. web_crawler_back_to_configure_callback,
  188. &app->view_dispatcher,
  189. app)) {
  190. return NULL;
  191. }
  192. // set variable items
  193. app->path_item =
  194. variable_item_list_add(app->variable_item_list_request, "Path", 0, NULL, NULL);
  195. app->http_method_item = variable_item_list_add(
  196. app->variable_item_list_request, "HTTP Method", 5, web_crawler_http_method_change, app);
  197. app->headers_item =
  198. variable_item_list_add(app->variable_item_list_request, "Headers", 0, NULL, NULL);
  199. app->payload_item =
  200. variable_item_list_add(app->variable_item_list_request, "Payload", 0, NULL, NULL);
  201. //
  202. app->ssid_item =
  203. variable_item_list_add(app->variable_item_list_wifi, "SSID", 0, NULL, NULL); // index 0
  204. app->password_item =
  205. variable_item_list_add(app->variable_item_list_wifi, "Password", 0, NULL, NULL); // index 1
  206. //
  207. app->file_read_item = variable_item_list_add(
  208. app->variable_item_list_file, "Read File", 0, NULL, NULL); // index 0
  209. app->file_type_item = variable_item_list_add(
  210. app->variable_item_list_file, "Set File Type", 0, NULL, NULL); // index 1
  211. app->file_rename_item = variable_item_list_add(
  212. app->variable_item_list_file, "Rename File", 0, NULL, NULL); // index 2
  213. app->file_delete_item = variable_item_list_add(
  214. app->variable_item_list_file, "Delete File", 0, NULL, NULL); // index 3
  215. if(!app->ssid_item || !app->password_item || !app->file_type_item || !app->file_rename_item ||
  216. !app->path_item || !app->file_read_item || !app->file_delete_item ||
  217. !app->http_method_item || !app->headers_item || !app->payload_item) {
  218. free_all(app, "Failed to add items to VariableItemList");
  219. return NULL;
  220. }
  221. variable_item_set_current_value_text(app->path_item, ""); // Initialize
  222. variable_item_set_current_value_text(app->http_method_item, ""); // Initialize
  223. variable_item_set_current_value_text(app->headers_item, ""); // Initialize
  224. variable_item_set_current_value_text(app->payload_item, ""); // Initialize
  225. variable_item_set_current_value_text(app->ssid_item, ""); // Initialize
  226. variable_item_set_current_value_text(app->password_item, ""); // Initialize
  227. variable_item_set_current_value_text(app->file_type_item, ""); // Initialize
  228. variable_item_set_current_value_text(app->file_rename_item, ""); // Initialize
  229. variable_item_set_current_value_text(app->file_read_item, ""); // Initialize
  230. variable_item_set_current_value_text(app->file_delete_item, ""); // Initialize
  231. // Allocate Submenu views
  232. if(!easy_flipper_set_submenu(
  233. &app->submenu_main,
  234. WebCrawlerViewSubmenuMain,
  235. "Web Crawler v0.8",
  236. web_crawler_exit_app_callback,
  237. &app->view_dispatcher)) {
  238. return NULL;
  239. }
  240. if(!easy_flipper_set_submenu(
  241. &app->submenu_config,
  242. WebCrawlerViewSubmenuConfig,
  243. "Settings",
  244. web_crawler_back_to_main_callback,
  245. &app->view_dispatcher)) {
  246. return NULL;
  247. }
  248. // Add Submenu items
  249. submenu_add_item(
  250. app->submenu_main, "Run", WebCrawlerSubmenuIndexRun, web_crawler_submenu_callback, app);
  251. submenu_add_item(
  252. app->submenu_main, "About", WebCrawlerSubmenuIndexAbout, web_crawler_submenu_callback, app);
  253. submenu_add_item(
  254. app->submenu_main,
  255. "Settings",
  256. WebCrawlerSubmenuIndexConfig,
  257. web_crawler_submenu_callback,
  258. app);
  259. submenu_add_item(
  260. app->submenu_config, "WiFi", WebCrawlerSubmenuIndexWifi, web_crawler_submenu_callback, app);
  261. submenu_add_item(
  262. app->submenu_config, "File", WebCrawlerSubmenuIndexFile, web_crawler_submenu_callback, app);
  263. submenu_add_item(
  264. app->submenu_config,
  265. "Request",
  266. WebCrawlerSubmenuIndexRequest,
  267. web_crawler_submenu_callback,
  268. app);
  269. // Main view
  270. if(!easy_flipper_set_view(
  271. &app->view_loader,
  272. WebCrawlerViewLoader,
  273. web_crawler_loader_draw_callback,
  274. NULL,
  275. web_crawler_back_to_main_callback,
  276. &app->view_dispatcher,
  277. app)) {
  278. return NULL;
  279. }
  280. web_crawler_loader_init(app->view_loader);
  281. //-- WIDGET ABOUT VIEW --
  282. if(!easy_flipper_set_widget(
  283. &app->widget_about,
  284. WebCrawlerViewAbout,
  285. "Web Crawler App\n---\nThis is a web crawler app for Flipper Zero.\n---\nVisit github.com/jblanked for more details.\n---\nPress BACK to return.",
  286. web_crawler_back_to_main_callback,
  287. &app->view_dispatcher)) {
  288. return NULL;
  289. }
  290. if(!easy_flipper_set_widget(
  291. &app->widget_file_read,
  292. WebCrawlerViewFileRead,
  293. "Data will be displayed here.",
  294. web_crawler_back_to_file_callback,
  295. &app->view_dispatcher)) {
  296. return NULL;
  297. }
  298. if(!easy_flipper_set_widget(
  299. &app->widget_file_delete,
  300. WebCrawlerViewFileDelete,
  301. "File deleted.",
  302. web_crawler_back_to_file_callback,
  303. &app->view_dispatcher)) {
  304. return NULL;
  305. }
  306. if(!easy_flipper_set_widget(
  307. &app->widget_result,
  308. WebCrawlerViewWidgetResult,
  309. "Error, try again.",
  310. web_crawler_back_to_main_callback,
  311. &app->view_dispatcher)) {
  312. return NULL;
  313. }
  314. // Load Settings and Update Views
  315. if(!load_settings(
  316. app->path,
  317. app->temp_buffer_size_path,
  318. app->ssid,
  319. app->temp_buffer_size_ssid,
  320. app->password,
  321. app->temp_buffer_size_password,
  322. app->file_rename,
  323. app->temp_buffer_size_file_rename,
  324. app->file_type,
  325. app->temp_buffer_size_file_type,
  326. app->http_method,
  327. app->temp_buffer_size_http_method,
  328. app->headers,
  329. app->temp_buffer_size_headers,
  330. app->payload,
  331. app->temp_buffer_size_payload,
  332. app)) {
  333. FURI_LOG_E(TAG, "Failed to load settings");
  334. } else {
  335. // Update the configuration items based on loaded settings
  336. if(app->path_item) {
  337. variable_item_set_current_value_text(app->path_item, app->path);
  338. } else {
  339. variable_item_set_current_value_text(
  340. app->path_item, "https://httpbin.org/get"); // Initialize
  341. }
  342. if(app->ssid_item) {
  343. variable_item_set_current_value_text(app->ssid_item, app->ssid);
  344. } else {
  345. variable_item_set_current_value_text(app->ssid_item, ""); // Initialize
  346. }
  347. if(app->file_type_item) {
  348. variable_item_set_current_value_text(app->file_type_item, app->file_type);
  349. } else {
  350. variable_item_set_current_value_text(app->file_type_item, ".txt"); // Initialize
  351. }
  352. if(app->file_rename_item) {
  353. variable_item_set_current_value_text(app->file_rename_item, app->file_rename);
  354. } else {
  355. variable_item_set_current_value_text(
  356. app->file_rename_item, "received_data"); // Initialize
  357. }
  358. if(app->http_method_item) {
  359. variable_item_set_current_value_text(app->http_method_item, app->http_method);
  360. } else {
  361. variable_item_set_current_value_text(app->http_method_item, "GET"); // Initialize
  362. }
  363. if(app->headers_item) {
  364. variable_item_set_current_value_text(app->headers_item, app->headers);
  365. } else {
  366. variable_item_set_current_value_text(
  367. app->headers_item, "{\n\t\"Content-Type\": \"application/json\"\n}"); // Initialize
  368. }
  369. if(app->payload_item) {
  370. variable_item_set_current_value_text(app->payload_item, app->payload);
  371. } else {
  372. variable_item_set_current_value_text(
  373. app->payload_item, "{\n\t\"key\": \"value\"\n}"); // Initialize
  374. }
  375. // set the file path for fhttp.file_path
  376. char file_path[128];
  377. snprintf(
  378. file_path,
  379. sizeof(file_path),
  380. "%s%s%s",
  381. RECEIVED_DATA_PATH,
  382. app->file_rename,
  383. app->file_type);
  384. snprintf(fhttp.file_path, sizeof(fhttp.file_path), "%s", file_path);
  385. // update temp buffers
  386. strncpy(app->temp_buffer_path, app->path, app->temp_buffer_size_path - 1);
  387. app->temp_buffer_path[app->temp_buffer_size_path - 1] = '\0';
  388. strncpy(app->temp_buffer_ssid, app->ssid, app->temp_buffer_size_ssid - 1);
  389. app->temp_buffer_ssid[app->temp_buffer_size_ssid - 1] = '\0';
  390. strncpy(app->temp_buffer_file_type, app->file_type, app->temp_buffer_size_file_type - 1);
  391. app->temp_buffer_file_type[app->temp_buffer_size_file_type - 1] = '\0';
  392. strncpy(
  393. app->temp_buffer_file_rename, app->file_rename, app->temp_buffer_size_file_rename - 1);
  394. app->temp_buffer_file_rename[app->temp_buffer_size_file_rename - 1] = '\0';
  395. strncpy(
  396. app->temp_buffer_http_method, app->http_method, app->temp_buffer_size_http_method - 1);
  397. app->temp_buffer_http_method[app->temp_buffer_size_http_method - 1] = '\0';
  398. strncpy(app->temp_buffer_headers, app->headers, app->temp_buffer_size_headers - 1);
  399. app->temp_buffer_headers[app->temp_buffer_size_headers - 1] = '\0';
  400. strncpy(app->temp_buffer_payload, app->payload, app->temp_buffer_size_payload - 1);
  401. app->temp_buffer_payload[app->temp_buffer_size_payload - 1] = '\0';
  402. // Password handling can be omitted for security or handled securely
  403. }
  404. // Start with the Submenu view
  405. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewSubmenuMain);
  406. return app;
  407. }