PageRenderTime 27ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/offline.c

https://gitlab.com/libreems-suite/megatunix
C | 483 lines | 373 code | 55 blank | 55 comment | 35 complexity | 7e524e8f1d353a7d9789fca9670a47c8 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * Copyright (C) 2002-2012 by Dave J. Andruczyk <djandruczyk at yahoo dot com>
  3. *
  4. * Linux Megasquirt tuning software
  5. *
  6. *
  7. * This software comes under the GPL (GNU Public License)
  8. * You may freely copy,distribute etc. this as long as the source code
  9. * is made available for FREE.
  10. *
  11. * No warranty is made or implied. You use this program at your own risk.
  12. */
  13. /*!
  14. \file src/offline.c
  15. \ingroup CoreMtx
  16. \brief The functions for initiating Offline Mode, and offline ECU restore
  17. \author David Andruczyk
  18. */
  19. #include <apicheck.h>
  20. #include <api-versions.h>
  21. #include <debugging.h>
  22. #include <getfiles.h>
  23. #include <glade/glade.h>
  24. #include <gui_handlers.h>
  25. #include <listmgmt.h>
  26. #include <notifications.h>
  27. #include <offline.h>
  28. #include <personalities.h>
  29. #include <plugin.h>
  30. #include <string.h>
  31. #include <threads.h>
  32. #include <widgetmgmt.h>
  33. #include <xmlcomm.h>
  34. extern gconstpointer *global_data;
  35. /*!
  36. \brief set_offline_mode() is called when the "Offline Mode" button is clicked
  37. in the general tab and is used to present the user with list of firmware
  38. choices to select one for loading to work in offline mode (no connection to
  39. an ECU)
  40. */
  41. G_MODULE_EXPORT gboolean set_offline_mode(void)
  42. {
  43. GtkWidget * widget = NULL;
  44. gchar * filename = NULL;
  45. gboolean tmp = TRUE;
  46. GArray *pfuncs = NULL;
  47. PostFunction *pf = NULL;
  48. GAsyncQueue *io_repair_queue = NULL;
  49. Firmware_Details *firmware = NULL;
  50. void (*load_firmware_details)(void *,const gchar *) = NULL;
  51. ENTER();
  52. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  53. io_repair_queue = (GAsyncQueue *)DATA_GET(global_data,"io_repair_queue");
  54. /* Cause Serial Searcher thread to abort.... */
  55. if (io_repair_queue)
  56. g_async_queue_push(io_repair_queue,&tmp);
  57. filename = present_firmware_choices();
  58. if (!filename)
  59. {
  60. DATA_SET(global_data,"offline",GINT_TO_POINTER(FALSE));
  61. DATA_SET(global_data,"interrogated",GINT_TO_POINTER(FALSE));
  62. widget = lookup_widget("interrogate_button");
  63. if (GTK_IS_WIDGET(widget))
  64. gtk_widget_set_sensitive(GTK_WIDGET(widget),TRUE);
  65. widget = lookup_widget("offline_button");
  66. if (GTK_IS_WIDGET(widget))
  67. gtk_widget_set_sensitive(GTK_WIDGET(widget),TRUE);
  68. plugins_shutdown();
  69. /* Does this need a delay? */
  70. personality_choice();
  71. EXIT();
  72. return FALSE;
  73. }
  74. DATA_SET_FULL(global_data,"last_offline_profile",g_strdup(filename),g_free);
  75. DATA_SET(global_data,"offline",GINT_TO_POINTER(TRUE));
  76. DATA_SET(global_data,"interrogated",GINT_TO_POINTER(TRUE));
  77. /* Disable interrogation button */
  78. widget = lookup_widget("interrogate_button");
  79. if (GTK_IS_WIDGET(widget))
  80. gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
  81. widget = lookup_widget("netaccess_table");
  82. if (GTK_IS_WIDGET(widget))
  83. gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
  84. queue_function("kill_conn_warning");
  85. if (!firmware)
  86. {
  87. firmware = g_new0(Firmware_Details,1);
  88. DATA_SET(global_data,"firmware",firmware);
  89. }
  90. if (get_symbol("load_firmware_details",(void **)&load_firmware_details))
  91. {
  92. load_firmware_details(firmware,filename);
  93. }
  94. else
  95. printf("Unable to load firmware details!\n");
  96. pfuncs = g_array_new(FALSE,TRUE,sizeof(PostFunction *));
  97. pf = g_new0(PostFunction,1);
  98. pf->name = g_strdup("update_interrogation_gui_pf");
  99. get_symbol(pf->name,(void **)&pf->function);
  100. pf->w_arg = FALSE;
  101. pfuncs = g_array_append_val(pfuncs,pf);
  102. pf = g_new0(PostFunction,1);
  103. pf->name = g_strdup("load_realtime_map_pf");
  104. get_symbol(pf->name,(void **)&pf->function);
  105. pf->w_arg = FALSE;
  106. pfuncs = g_array_append_val(pfuncs,pf);
  107. pf = g_new0(PostFunction,1);
  108. pf->name = g_strdup("initialize_dashboards_pf");
  109. get_symbol(pf->name,(void **)&pf->function);
  110. pf->w_arg = FALSE;
  111. pfuncs = g_array_append_val(pfuncs,pf);
  112. pf = g_new0(PostFunction,1);
  113. pf->name = g_strdup("load_status_pf");
  114. get_symbol(pf->name,(void **)&pf->function);
  115. pf->w_arg = FALSE;
  116. pfuncs = g_array_append_val(pfuncs,pf);
  117. pf = g_new0(PostFunction,1);
  118. pf->name = g_strdup("load_rt_text_pf");
  119. get_symbol(pf->name,(void **)&pf->function);
  120. pf->w_arg = FALSE;
  121. pfuncs = g_array_append_val(pfuncs,pf);
  122. pf = g_new0(PostFunction,1);
  123. pf->name = g_strdup("load_gui_tabs_pf");
  124. get_symbol(pf->name,(void **)&pf->function);
  125. pf->w_arg = FALSE;
  126. pfuncs = g_array_append_val(pfuncs,pf);
  127. pf = g_new0(PostFunction,1);
  128. pf->name = g_strdup("start_statuscounts_pf");
  129. get_symbol(pf->name,(void **)&pf->function);
  130. pf->w_arg = FALSE;
  131. pfuncs = g_array_append_val(pfuncs,pf);
  132. pf = g_new0(PostFunction,1);
  133. pf->name = g_strdup("disable_burner_buttons_pf");
  134. get_symbol(pf->name,(void **)&pf->function);
  135. pf->w_arg = FALSE;
  136. pfuncs = g_array_append_val(pfuncs,pf);
  137. /* BUG, causes deadlock
  138. pf = g_new0(PostFunction,1);
  139. pf->name = g_strdup("offline_ecu_restore_pf");
  140. get_symbol(pf->name,(void **)&pf->function);
  141. pf->w_arg = FALSE;
  142. pfuncs = g_array_append_val(pfuncs,pf);
  143. */
  144. pf = g_new0(PostFunction,1);
  145. pf->name = g_strdup("setup_menu_handlers_pf");
  146. get_symbol(pf->name,(void **)&pf->function);
  147. pf->w_arg = FALSE;
  148. pfuncs = g_array_append_val(pfuncs,pf);
  149. pf = g_new0(PostFunction,1);
  150. pf->name = g_strdup("enable_3d_buttons_pf");
  151. get_symbol(pf->name,(void **)&pf->function);
  152. pf->w_arg = FALSE;
  153. pfuncs = g_array_append_val(pfuncs,pf);
  154. pf = g_new0(PostFunction,1);
  155. pf->name = g_strdup("ready_msg_pf");
  156. get_symbol(pf->name,(void **)&pf->function);
  157. pf->w_arg = FALSE;
  158. pfuncs = g_array_append_val(pfuncs,pf);
  159. pf = g_new0(PostFunction,1);
  160. pf->name = g_strdup("cleanup_pf");
  161. get_symbol(pf->name,(void **)&pf->function_w_arg);
  162. pf->w_arg = TRUE;
  163. pfuncs = g_array_append_val(pfuncs,pf);
  164. io_cmd(NULL,pfuncs);
  165. /*
  166. io_cmd(firmware->get_all_command,NULL);
  167. */
  168. widget = lookup_widget("binary_logging_frame");
  169. if (GTK_IS_WIDGET(widget))
  170. gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
  171. widget = lookup_widget("interrogate_button");
  172. if (GTK_IS_WIDGET(widget))
  173. gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
  174. widget = lookup_widget("offline_button");
  175. if (GTK_IS_WIDGET(widget))
  176. gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
  177. g_list_foreach(get_list("get_data_buttons"),set_widget_sensitive,GINT_TO_POINTER(FALSE));
  178. pfuncs = g_array_new(FALSE,TRUE,sizeof(PostFunction *));
  179. pf = g_new0(PostFunction,1);
  180. pf->name = g_strdup("reset_temps_pf");
  181. get_symbol(pf->name,(void **)&pf->function);
  182. pf->w_arg = FALSE;
  183. pfuncs = g_array_append_val(pfuncs,pf);
  184. pf = g_new0(PostFunction,1);
  185. pf->name = g_strdup("cleanup_pf");
  186. get_symbol(pf->name,(void **)&pf->function_w_arg);
  187. pf->w_arg = TRUE;
  188. pfuncs = g_array_append_val(pfuncs,pf);
  189. io_cmd(NULL,pfuncs);
  190. EXIT();
  191. return FALSE;
  192. }
  193. /*!
  194. \brief present_firmware_choices() presents a dialog box with the firmware
  195. choices.
  196. \returns the name of the chosen firmware
  197. */
  198. G_MODULE_EXPORT gchar * present_firmware_choices(void)
  199. {
  200. gchar ** filenames = NULL;
  201. GtkWidget *dialog = NULL;
  202. GtkWidget *vbox = NULL;
  203. GtkWidget *hbox = NULL;
  204. GtkWidget *ebox = NULL;
  205. GtkWidget *sep = NULL;
  206. GtkWidget *dummybutton = NULL;
  207. GtkWidget *button = NULL;
  208. GtkWidget *label = NULL;
  209. ListElement *element = NULL;
  210. gchar *tmpbuf = NULL;
  211. GArray *classes = NULL;
  212. GSList *group = NULL;
  213. GList *p_list = NULL;
  214. GList *s_list = NULL;
  215. ConfigFile *cfgfile = NULL;
  216. const gchar * last_file = NULL;
  217. gint major = 0;
  218. gint minor = 0;
  219. guint i = 0;
  220. gint result = 0;
  221. extern gconstpointer *global_data;
  222. gchar * pathstub = NULL;
  223. ENTER();
  224. pathstub = g_build_filename(INTERROGATOR_DATA_DIR,"Profiles",DATA_GET(global_data,"ecu_family"),NULL);
  225. filenames = get_files((const gchar *)DATA_GET(global_data,"project_name"),pathstub,"prof",&classes);
  226. g_free(pathstub);
  227. if (!filenames)
  228. {
  229. MTXDBG(CRITICAL,_("NO Interrogation profiles found, was MegaTunix installed properly?\n"));
  230. EXIT();
  231. return NULL;
  232. }
  233. i = 0;
  234. while (filenames[i])
  235. {
  236. cfgfile = cfg_open_file(filenames[i]);
  237. if (!cfgfile)
  238. {
  239. MTXDBG(CRITICAL,_("Interrogation profile damaged!, was MegaTunix installed properly?\n"));
  240. i++;
  241. continue;
  242. }
  243. get_file_api(cfgfile,&major,&minor);
  244. if ((major != INTERROGATE_MAJOR_API) || (minor != INTERROGATE_MINOR_API))
  245. {
  246. thread_update_logbar("interr_view","warning",g_strdup_printf(_("Interrogation profile API mismatch (%i.%i != %i.%i):\n\tFile %s will be skipped\n"),major,minor,INTERROGATE_MAJOR_API,INTERROGATE_MINOR_API,cfgfile->filename),FALSE,FALSE);
  247. i++;
  248. cfg_free(cfgfile);
  249. continue;
  250. }
  251. cfg_read_string(cfgfile,"interrogation_profile","name",&tmpbuf);
  252. cfg_free(cfgfile);
  253. last_file = (gchar *)DATA_GET(global_data,"last_offline_profile");
  254. if (g_array_index(classes,FileClass,i) == PERSONAL)
  255. {
  256. element = g_new0(ListElement, 1);
  257. element->filename = g_strdup(filenames[i]);
  258. if (g_ascii_strcasecmp(element->filename,last_file) == 0)
  259. element->def = TRUE;
  260. element->name = g_strdup(tmpbuf);
  261. p_list = g_list_append(p_list,(gpointer)element);
  262. }
  263. if (g_array_index(classes,FileClass,i) == SYSTEM)
  264. {
  265. element = g_new0(ListElement, 1);
  266. element->filename = g_strdup(filenames[i]);
  267. if (g_ascii_strcasecmp(element->filename,last_file) == 0)
  268. element->def = TRUE;
  269. element->name = g_strdup(tmpbuf);
  270. s_list = g_list_append(s_list,(gpointer)element);
  271. }
  272. g_free(tmpbuf);
  273. i++;
  274. }
  275. p_list = g_list_sort(p_list,list_sort);
  276. s_list = g_list_sort(s_list,list_sort);
  277. dialog = gtk_dialog_new_with_buttons("Select Firmware",
  278. GTK_WINDOW(lookup_widget("main_window")),
  279. GTK_DIALOG_DESTROY_WITH_PARENT,
  280. "Abort",
  281. GTK_RESPONSE_CANCEL,
  282. "Load",
  283. GTK_RESPONSE_OK,
  284. NULL);
  285. vbox = gtk_vbox_new(TRUE,2);
  286. gtk_container_set_border_width(GTK_CONTAINER(vbox),5);
  287. gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),vbox,TRUE,TRUE,0);
  288. /* Dummies */
  289. dummybutton = gtk_radio_button_new(NULL);
  290. g_object_ref_sink(dummybutton);
  291. group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dummybutton));
  292. if (g_list_length(p_list) > 0)
  293. {
  294. label = gtk_label_new("Custom (personal) Profiles");
  295. gtk_box_pack_start(GTK_BOX(vbox),label,TRUE,TRUE,0);
  296. /* Cycle list for PERSONAL interogation files */
  297. for (i=0;i<g_list_length(p_list);i++)
  298. {
  299. element = (ListElement *)g_list_nth_data(p_list,i);
  300. ebox = gtk_event_box_new();
  301. gtk_box_pack_start(GTK_BOX(vbox),ebox,TRUE,TRUE,0);
  302. hbox = gtk_hbox_new(FALSE,10);
  303. gtk_container_add(GTK_CONTAINER(ebox),hbox);
  304. label = gtk_label_new(element->name);
  305. gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,TRUE,0);
  306. button = gtk_radio_button_new(group);
  307. g_free(OBJ_GET(button,"filename"));
  308. OBJ_SET_FULL(button,"filename",g_strdup(element->filename),g_free);
  309. OBJ_SET(button,"handler",
  310. GINT_TO_POINTER(OFFLINE_FIRMWARE_CHOICE));
  311. g_signal_connect(button,
  312. "toggled",
  313. G_CALLBACK(toggle_button_handler),
  314. NULL);
  315. gtk_box_pack_end(GTK_BOX(hbox),button,FALSE,TRUE,0);
  316. if (element->def)
  317. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),TRUE);
  318. else
  319. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE);
  320. group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
  321. }
  322. sep = gtk_hseparator_new();
  323. gtk_box_pack_start(GTK_BOX(vbox),sep,TRUE,TRUE,0);
  324. }
  325. label = gtk_label_new("System Wide ECU Profiles");
  326. gtk_box_pack_start(GTK_BOX(vbox),label,TRUE,TRUE,0);
  327. /* Cycle list for System interogation files */
  328. for (i=0;i<g_list_length(s_list);i++)
  329. {
  330. element = (ListElement *)g_list_nth_data(s_list,i);
  331. ebox = gtk_event_box_new();
  332. gtk_box_pack_start(GTK_BOX(vbox),ebox,TRUE,TRUE,0);
  333. hbox = gtk_hbox_new(FALSE,10);
  334. gtk_container_add(GTK_CONTAINER(ebox),hbox);
  335. label = gtk_label_new(element->name);
  336. gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,TRUE,0);
  337. button = gtk_radio_button_new(group);
  338. g_free(OBJ_GET(button,"filename"));
  339. OBJ_SET_FULL(button,"filename",g_strdup(element->filename),g_free);
  340. OBJ_SET(button,"handler",
  341. GINT_TO_POINTER(OFFLINE_FIRMWARE_CHOICE));
  342. g_signal_connect(button,
  343. "toggled",
  344. G_CALLBACK(toggle_button_handler),
  345. NULL);
  346. gtk_box_pack_end(GTK_BOX(hbox),button,FALSE,TRUE,0);
  347. if (element->def)
  348. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),TRUE);
  349. else
  350. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE);
  351. group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
  352. }
  353. /*
  354. if (i==1)
  355. gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(button));
  356. else
  357. gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),TRUE);
  358. */
  359. g_strfreev(filenames);
  360. g_array_free(classes,TRUE);
  361. gtk_widget_show_all(dialog);
  362. gtk_window_set_transient_for(GTK_WINDOW(gtk_widget_get_toplevel(dialog)),GTK_WINDOW(lookup_widget("main_window")));
  363. result = gtk_dialog_run(GTK_DIALOG(dialog));
  364. gtk_widget_destroy(dialog);
  365. g_object_unref(dummybutton);
  366. g_list_foreach(p_list,free_element,NULL);
  367. g_list_foreach(s_list,free_element,NULL);
  368. g_list_free(p_list);
  369. g_list_free(s_list);
  370. switch (result)
  371. {
  372. case GTK_RESPONSE_ACCEPT:
  373. case GTK_RESPONSE_OK:
  374. EXIT();
  375. return (gchar *)DATA_GET(global_data,"offline_firmware_choice");
  376. break;
  377. case GTK_RESPONSE_CANCEL:
  378. default:
  379. EXIT();
  380. return NULL;
  381. }
  382. EXIT();
  383. return NULL;
  384. }
  385. /*!
  386. \brief initiates an offline ECU restore from file. Prompts for file, if
  387. valid, it calles the restore_all function from the ECU plugin
  388. */
  389. G_MODULE_EXPORT void offline_ecu_restore_pf(void)
  390. {
  391. MtxFileIO *fileio = NULL;
  392. gchar *filename = NULL;
  393. void (*restore_all_f)(const gchar *);
  394. Firmware_Details *firmware = NULL;
  395. ENTER();
  396. firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
  397. get_symbol("restore_all_ecu_settings",(void **)&restore_all_f);
  398. g_return_if_fail(firmware);
  399. g_return_if_fail(restore_all_f);
  400. if (!DATA_GET(global_data,"interrogated"))
  401. {
  402. EXIT();
  403. return;
  404. }
  405. fileio = g_new0(MtxFileIO ,1);
  406. fileio->default_path = g_strdup(BACKUP_DATA_DIR);
  407. fileio->project = (const gchar *)DATA_GET(global_data,"project_name");
  408. fileio->parent = lookup_widget("main_window");
  409. fileio->on_top = TRUE;
  410. fileio->title = g_strdup("You should load an ECU backup from a file");
  411. fileio->action = GTK_FILE_CHOOSER_ACTION_OPEN;
  412. fileio->shortcut_folders = g_strdup(BACKUP_DATA_DIR);
  413. if (DATA_GET(global_data,"last_offline_filename"))
  414. fileio->default_filename = g_strdup((gchar *)DATA_GET(global_data,"last_offline_filename"));
  415. filename = choose_file(fileio);
  416. if (filename)
  417. {
  418. DATA_SET_FULL(global_data,"last_offline_filename",g_strdup(filename),g_free);
  419. update_logbar("tools_view",NULL,_("Full Restore of ECU Initiated\n"),FALSE,FALSE,FALSE);
  420. restore_all_f(filename);
  421. g_free(filename);
  422. }
  423. else
  424. io_cmd(firmware->get_all_command,NULL);
  425. free_mtxfileio(fileio);
  426. EXIT();
  427. return;
  428. }