web_crawler_callback.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. // web_crawler_callback.h
  2. static bool sent_get_request = false;
  3. static bool get_success = false;
  4. static bool already_success = false;
  5. static WebCrawlerApp *app_instance = NULL;
  6. // Forward declaration of callback functions
  7. static void web_crawler_setting_item_path_clicked(void *context, uint32_t index);
  8. static void web_crawler_setting_item_ssid_clicked(void *context, uint32_t index);
  9. static void web_crawler_setting_item_password_clicked(void *context, uint32_t index);
  10. static void web_crawler_view_draw_callback(Canvas *canvas, void *context)
  11. {
  12. UNUSED(context);
  13. WebCrawlerApp *app = app_instance;
  14. if (!app)
  15. {
  16. FURI_LOG_E(TAG, "App is NULL");
  17. return;
  18. }
  19. canvas_clear(canvas);
  20. canvas_set_font(canvas, FontSecondary);
  21. if (fhttp.state == INACTIVE)
  22. {
  23. canvas_draw_str(canvas, 0, 7, "Wifi Dev Board disconnected.");
  24. canvas_draw_str(canvas, 0, 17, "Please connect to the board.");
  25. canvas_draw_str(canvas, 0, 32, "If you board is connected,");
  26. canvas_draw_str(canvas, 0, 42, "make sure you have flashed");
  27. canvas_draw_str(canvas, 0, 52, "your Dev Board with the");
  28. canvas_draw_str(canvas, 0, 62, "FlipperHTTP firmware.");
  29. return;
  30. }
  31. if (app->path)
  32. {
  33. if (!sent_get_request)
  34. {
  35. canvas_draw_str(canvas, 0, 10, "Sending GET request...");
  36. // Perform GET request and handle the response
  37. get_success = flipper_http_get_request(app->path);
  38. canvas_draw_str(canvas, 0, 20, "Sent!");
  39. if (get_success)
  40. {
  41. canvas_draw_str(canvas, 0, 30, "Receiving data...");
  42. get_success = true;
  43. }
  44. else
  45. {
  46. canvas_draw_str(canvas, 0, 30, "Failed.");
  47. }
  48. sent_get_request = true;
  49. }
  50. else
  51. {
  52. if (get_success && fhttp.state == RECEIVING)
  53. {
  54. canvas_draw_str(canvas, 0, 10, "Receiving and parsing data...");
  55. already_success = true;
  56. }
  57. else if (get_success && fhttp.state == IDLE && fhttp.received_data == NULL && already_success)
  58. {
  59. already_success = true;
  60. canvas_draw_str(canvas, 0, 10, "Data saved to file.");
  61. canvas_draw_str(canvas, 0, 20, "Press BACK to return.");
  62. }
  63. else if (get_success && fhttp.state == IDLE && fhttp.received_data == NULL && !already_success)
  64. {
  65. canvas_draw_str(canvas, 0, 10, "Receiving and parsing data...");
  66. }
  67. else
  68. {
  69. if (fhttp.state == ISSUE)
  70. {
  71. if (strstr(fhttp.last_response, "[ERROR] Not connected to Wifi. Failed to reconnect.") != NULL)
  72. {
  73. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  74. canvas_draw_str(canvas, 0, 50, "Update your config settings.");
  75. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  76. }
  77. else if (strstr(fhttp.last_response, "[ERROR] Failed to connect to Wifi.") != NULL)
  78. {
  79. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  80. canvas_draw_str(canvas, 0, 50, "Update your config settings.");
  81. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  82. }
  83. else
  84. {
  85. canvas_draw_str(canvas, 0, 10, "[ERROR] Failed to sync data.");
  86. canvas_draw_str(canvas, 0, 30, "If this is your third attempt,");
  87. canvas_draw_str(canvas, 0, 40, "it's likely your URL is not");
  88. canvas_draw_str(canvas, 0, 50, "compabilbe or correct.");
  89. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  90. }
  91. }
  92. else
  93. {
  94. canvas_draw_str(canvas, 0, 10, "GET request failed.");
  95. canvas_draw_str(canvas, 0, 20, "Press BACK to return.");
  96. }
  97. get_success = false;
  98. }
  99. }
  100. }
  101. else
  102. {
  103. canvas_draw_str(canvas, 0, 10, "URL not set.");
  104. }
  105. }
  106. /**
  107. * @brief Navigation callback to handle exiting from other views to the submenu.
  108. * @param context The context - WebCrawlerApp object.
  109. * @return WebCrawlerViewSubmenu
  110. */
  111. static uint32_t web_crawler_back_to_main_callback(void *context)
  112. {
  113. UNUSED(context);
  114. sent_get_request = false;
  115. get_success = false;
  116. already_success = false;
  117. if (app_instance && app_instance->textbox)
  118. {
  119. widget_reset(app_instance->textbox);
  120. }
  121. return WebCrawlerViewSubmenu; // Return to the main submenu view
  122. }
  123. /**
  124. * @brief Navigation callback to handle returning to the Configure screen.
  125. * @param context The context - WebCrawlerApp object.
  126. * @return WebCrawlerViewConfigure
  127. */
  128. static uint32_t web_crawler_back_to_configure_callback(void *context)
  129. {
  130. UNUSED(context);
  131. return WebCrawlerViewConfigure; // Return to the Configure screen
  132. }
  133. /**
  134. * @brief Navigation callback to handle exiting the app from the main submenu.
  135. * @param context The context - unused
  136. * @return VIEW_NONE to exit the app
  137. */
  138. static uint32_t web_crawler_exit_app_callback(void *context)
  139. {
  140. UNUSED(context);
  141. return VIEW_NONE;
  142. }
  143. /**
  144. * @brief Handle submenu item selection.
  145. * @param context The context - WebCrawlerApp object.
  146. * @param index The WebCrawlerSubmenuIndex item that was clicked.
  147. */
  148. static void web_crawler_submenu_callback(void *context, uint32_t index)
  149. {
  150. WebCrawlerApp *app = (WebCrawlerApp *)context;
  151. furi_check(app);
  152. switch (index)
  153. {
  154. case WebCrawlerSubmenuIndexRun:
  155. sent_get_request = false; // Reset the flag
  156. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewRun);
  157. break;
  158. case WebCrawlerSubmenuIndexAbout:
  159. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewAbout);
  160. break;
  161. case WebCrawlerSubmenuIndexSetPath:
  162. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewConfigure);
  163. break;
  164. case WebCrawlerSubmenuIndexData:
  165. if (!load_received_data())
  166. {
  167. if (app_instance->textbox)
  168. {
  169. widget_reset(app_instance->textbox);
  170. widget_add_text_scroll_element(
  171. app_instance->textbox,
  172. 0,
  173. 0,
  174. 128,
  175. 64, "File is empty.");
  176. }
  177. }
  178. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewData);
  179. break;
  180. default:
  181. FURI_LOG_E(TAG, "Unknown submenu index");
  182. break;
  183. }
  184. }
  185. /**
  186. * @brief Configuration enter callback to handle different items.
  187. * @param context The context - WebCrawlerApp object.
  188. * @param index The index of the item that was clicked.
  189. */
  190. static void web_crawler_config_enter_callback(void *context, uint32_t index)
  191. {
  192. switch (index)
  193. {
  194. case 0:
  195. web_crawler_setting_item_path_clicked(context, index);
  196. break;
  197. case 1:
  198. web_crawler_setting_item_ssid_clicked(context, index);
  199. break;
  200. case 2:
  201. web_crawler_setting_item_password_clicked(context, index);
  202. break;
  203. default:
  204. FURI_LOG_E(TAG, "Unknown configuration item index");
  205. break;
  206. }
  207. }
  208. /**
  209. * @brief Callback for when the user finishes entering the URL.
  210. * @param context The context - WebCrawlerApp object.
  211. */
  212. static void web_crawler_set_path_updated(void *context)
  213. {
  214. WebCrawlerApp *app = (WebCrawlerApp *)context;
  215. furi_check(app);
  216. // Store the entered URL from temp_buffer_path to path
  217. strncpy(app->path, app->temp_buffer_path, app->temp_buffer_size_path - 1);
  218. if (app->path_item)
  219. {
  220. variable_item_set_current_value_text(app->path_item, app->path);
  221. // Save the URL to the settings
  222. save_settings(app->path, app->ssid, app->password);
  223. // send to UART
  224. if (!flipper_http_save_wifi(app->ssid, app->password))
  225. {
  226. FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
  227. FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
  228. }
  229. FURI_LOG_D(TAG, "URL saved: %s", app->path);
  230. }
  231. // Return to the Configure view
  232. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewConfigure);
  233. }
  234. /**
  235. * @brief Callback for when the user finishes entering the SSID.
  236. * @param context The context - WebCrawlerApp object.
  237. */
  238. static void web_crawler_set_ssid_updated(void *context)
  239. {
  240. WebCrawlerApp *app = (WebCrawlerApp *)context;
  241. furi_check(app);
  242. // Store the entered SSID from temp_buffer_ssid to ssid
  243. strncpy(app->ssid, app->temp_buffer_ssid, app->temp_buffer_size_ssid - 1);
  244. if (app->ssid_item)
  245. {
  246. variable_item_set_current_value_text(app->ssid_item, app->ssid);
  247. // Save the SSID to the settings
  248. save_settings(app->path, app->ssid, app->password);
  249. // send to UART
  250. if (!flipper_http_save_wifi(app->ssid, app->password))
  251. {
  252. FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
  253. FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
  254. }
  255. FURI_LOG_D(TAG, "SSID saved: %s", app->ssid);
  256. }
  257. // Return to the Configure view
  258. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewConfigure);
  259. }
  260. /**
  261. * @brief Callback for when the user finishes entering the Password.
  262. * @param context The context - WebCrawlerApp object.
  263. */
  264. static void web_crawler_set_password_update(void *context)
  265. {
  266. WebCrawlerApp *app = (WebCrawlerApp *)context;
  267. furi_check(app);
  268. // Store the entered Password from temp_buffer_password to password
  269. strncpy(app->password, app->temp_buffer_password, app->temp_buffer_size_password - 1);
  270. if (app->password_item)
  271. {
  272. variable_item_set_current_value_text(app->password_item, app->password);
  273. // Save the Password to the settings
  274. save_settings(app->path, app->ssid, app->password);
  275. // send to UART
  276. if (!flipper_http_save_wifi(app->ssid, app->password))
  277. {
  278. FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
  279. FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
  280. }
  281. FURI_LOG_D(TAG, "Password saved: %s", app->password);
  282. }
  283. // Return to the Configure view
  284. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewConfigure);
  285. }
  286. /**
  287. * @brief Handler for Path configuration item click.
  288. * @param context The context - WebCrawlerApp object.
  289. * @param index The index of the item that was clicked.
  290. */
  291. static void web_crawler_setting_item_path_clicked(void *context, uint32_t index)
  292. {
  293. WebCrawlerApp *app = (WebCrawlerApp *)context;
  294. furi_check(app);
  295. UNUSED(index);
  296. // Set up the text input
  297. text_input_set_header_text(app->text_input_path, "Enter URL");
  298. // Initialize temp_buffer with existing path
  299. if (app->path)
  300. {
  301. strncpy(app->temp_buffer_path, app->path, app->temp_buffer_size_path - 1);
  302. }
  303. else
  304. {
  305. strncpy(app->temp_buffer_path, "https://www.google.com/", app->temp_buffer_size_path - 1);
  306. }
  307. app->temp_buffer_path[app->temp_buffer_size_path - 1] = '\0';
  308. // Configure the text input
  309. bool clear_previous_text = false;
  310. text_input_set_result_callback(
  311. app->text_input_path,
  312. web_crawler_set_path_updated,
  313. app,
  314. app->temp_buffer_path,
  315. app->temp_buffer_size_path,
  316. clear_previous_text);
  317. // Set the previous callback to return to Configure screen
  318. view_set_previous_callback(
  319. text_input_get_view(app->text_input_path),
  320. web_crawler_back_to_configure_callback);
  321. // Show text input dialog
  322. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewTextInput);
  323. }
  324. /**
  325. * @brief Handler for SSID configuration item click.
  326. * @param context The context - WebCrawlerApp object.
  327. * @param index The index of the item that was clicked.
  328. */
  329. static void web_crawler_setting_item_ssid_clicked(void *context, uint32_t index)
  330. {
  331. WebCrawlerApp *app = (WebCrawlerApp *)context;
  332. furi_check(app);
  333. UNUSED(index);
  334. // Set up the text input
  335. text_input_set_header_text(app->text_input_ssid, "Enter SSID");
  336. // Initialize temp_buffer with existing SSID
  337. if (app->ssid)
  338. {
  339. strncpy(app->temp_buffer_ssid, app->ssid, app->temp_buffer_size_ssid - 1);
  340. }
  341. else
  342. {
  343. strncpy(app->temp_buffer_ssid, "SSID-2G-", app->temp_buffer_size_ssid - 1);
  344. }
  345. app->temp_buffer_ssid[app->temp_buffer_size_ssid - 1] = '\0';
  346. // Configure the text input
  347. bool clear_previous_text = false;
  348. text_input_set_result_callback(
  349. app->text_input_ssid,
  350. web_crawler_set_ssid_updated,
  351. app,
  352. app->temp_buffer_ssid,
  353. app->temp_buffer_size_ssid,
  354. clear_previous_text);
  355. // Set the previous callback to return to Configure screen
  356. view_set_previous_callback(
  357. text_input_get_view(app->text_input_ssid),
  358. web_crawler_back_to_configure_callback);
  359. // Show text input dialog
  360. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewTextInputSSID);
  361. }
  362. /**
  363. * @brief Handler for Password configuration item click.
  364. * @param context The context - WebCrawlerApp object.
  365. * @param index The index of the item that was clicked.
  366. */
  367. static void web_crawler_setting_item_password_clicked(void *context, uint32_t index)
  368. {
  369. WebCrawlerApp *app = (WebCrawlerApp *)context;
  370. furi_check(app);
  371. UNUSED(index);
  372. // Set up the text input
  373. text_input_set_header_text(app->text_input_password, "Enter Password");
  374. // Initialize temp_buffer with existing password
  375. strncpy(app->temp_buffer_password, app->password, app->temp_buffer_size_password - 1);
  376. app->temp_buffer_password[app->temp_buffer_size_password - 1] = '\0';
  377. // Configure the text input
  378. bool clear_previous_text = false;
  379. text_input_set_result_callback(
  380. app->text_input_password,
  381. web_crawler_set_password_update,
  382. app,
  383. app->temp_buffer_password,
  384. app->temp_buffer_size_password,
  385. clear_previous_text);
  386. // Set the previous callback to return to Configure screen
  387. view_set_previous_callback(
  388. text_input_get_view(app->text_input_password),
  389. web_crawler_back_to_configure_callback);
  390. // Show text input dialog
  391. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewTextInputPassword);
  392. }