Beispiel #1
0
/*!
  \brief signal handler when the user selects an ECU personality. Extracts the
  data from the data object and sets the necessary bits in the global data
  object container.
  \param widget is the toggle button clicked
  \param data is the pointer to the PersonaElement structure
  \see PersonaElement
  \returns TRUE unused element is NULL
  */
G_MODULE_EXPORT gboolean persona_selection(GtkWidget *widget, gpointer data)
{
	PersonaElement *element = (PersonaElement *)data;

	if (!element)
		return FALSE;
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
	{
		if (element->baud_str)
			DATA_SET_FULL(global_data,"ecu_baud_str", g_strdup(element->baud_str),g_free);
		else
			DATA_SET(global_data,"ecu_baud_str", NULL);
		if (element->ecu_lib)
			DATA_SET_FULL(global_data,"ecu_lib", g_strdup(element->ecu_lib),g_free);
		else
			DATA_SET(global_data,"ecu_lib", NULL);
		if (element->common_lib)
			DATA_SET_FULL(global_data,"common_lib", g_strdup(element->common_lib),g_free);
		else
			DATA_SET(global_data,"common_lib", NULL);
		if (element->dirname)
			DATA_SET_FULL(global_data,"ecu_dirname", g_strdup(element->dirname),g_free);
		else
			DATA_SET(global_data,"ecu_dirname", NULL);
		if (element->filename)
			DATA_SET_FULL(global_data,"ecu_family", g_strdup(element->filename),g_free);
		else
			DATA_SET(global_data,"ecu_family", NULL);
	}
	return TRUE;
}
Beispiel #2
0
/*!
 \brief ECU Specif gets called to send a block of values to the ECU.
 \param canID is the can identifier (0-14)
 \param locID is the locationID in which the value refers to.
 \param offset is the offset from the beginning of the page that this data
 refers to.
 \param num_bytes is the length of block to sent
 \param block is the block of data to be sent which better damn well be
 int ECU byte order if there is an endianness thing..
 */
G_MODULE_EXPORT void libreems_chunk_write(gint canID, gint locID, gint offset, gint num_bytes, guint8 * block)
{
	OutputData *output = NULL;
	Firmware_Details *firmware = NULL;

	ENTER();
	firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");

	MTXDBG(SERIAL_WR,_("Sending canID %i, locID %i, offset %i, num_bytes %i, data %p\n"),canID,locID,offset,num_bytes,block);
	output = initialize_outputdata_f();
	DATA_SET(output->data,"canID", GINT_TO_POINTER(canID));
	DATA_SET(output->data,"location_id", GINT_TO_POINTER(locID));
	DATA_SET(output->data,"payload_id", GINT_TO_POINTER(REQUEST_UPDATE_BLOCK_IN_RAM));
	DATA_SET(output->data,"offset", GINT_TO_POINTER(offset));
	DATA_SET(output->data,"length", GINT_TO_POINTER(num_bytes));
	DATA_SET_FULL(output->data,"data", (gpointer)block, g_free);
	DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CHUNK_WRITE));

	libreems_store_new_block(canID,locID,offset,block,num_bytes);
	output->queue_update = TRUE;
	io_cmd_f(firmware->write_command,output);
	/*
	DATA_SET(global_data,"last_page",GINT_TO_POINTER(page));
	*/
	EXIT();
	return;
}
Beispiel #3
0
/*!
 \brief add_additional_rtt() is called as a post function for Tab loading
 to add an RTT on a normal widget tab. (AE wizard currently)
 \param widget, pointer to widget containing the data needed
 */
G_MODULE_EXPORT void add_additional_rtt(GtkWidget *widget)
{
	GHashTable *rtt_hash = NULL;
	gchar * ctrl_name = NULL;
	gchar * source = NULL;
	Rt_Text *rt_text = NULL;
	gboolean show_prefix = FALSE;

	rtt_hash = DATA_GET(global_data,"rtt_hash");
	ctrl_name = OBJ_GET(widget,"ctrl_name");
	source = OBJ_GET(widget,"source");
	show_prefix = (GBOOLEAN)OBJ_GET(widget,"show_prefix");

	if (!rtt_hash)
	{
		rtt_hash = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,dealloc_rtt);
		DATA_SET_FULL(global_data,"rtt_hash",(gpointer)rtt_hash,g_hash_table_destroy);
	}

	if ((rtt_hash) && (ctrl_name) && (source))
		rt_text = add_rtt(widget,ctrl_name,source,show_prefix);

	if (rt_text)
	{
		if (!g_hash_table_lookup(rtt_hash,ctrl_name))
			g_hash_table_insert(rtt_hash,
					g_strdup(ctrl_name),
					(gpointer)rt_text);
	}
	return;
}
Beispiel #4
0
/*!
  \brief load_rt_sliders() is called to load up the runtime slider 
  configuration from the file specified in the firmware's interrogation 
  profile, and populate the gui with the newly created sliders.
  */
G_MODULE_EXPORT void load_rt_sliders(void)
{
	GHashTable *rt_sliders = NULL;
	gchar *filename = NULL;
	xmlDoc * doc = NULL;
	xmlNode *root_element = NULL;
	gboolean res = FALSE;
	gchar *pathstub = NULL;
	Firmware_Details *firmware = NULL;

	firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");

	if (!DATA_GET(global_data,"interrogated"))
	{
		MTXDBG(CRITICAL,_("ERROR, NOT interrogated, returning!\n"));
		return;
	}

	if (DATA_GET(global_data,"leaving"))
	{
		MTXDBG(CRITICAL,_("ERROR, \"leaving\" set, returning!\n"));
		return;
	}
	if (!DATA_GET(global_data,"rtvars_loaded"))
	{
		MTXDBG(CRITICAL,_("CRITICAL ERROR, Realtime Variable definitions NOT LOADED!!!\n"));
		return;
	}
	set_title(g_strdup(_("Loading RT Sliders...")));
	rt_sliders = (GHashTable *)DATA_GET(global_data,"rt_sliders");
	if (!rt_sliders)
	{
		rt_sliders = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,dealloc_slider);
		DATA_SET_FULL(global_data,"rt_sliders",rt_sliders,g_hash_table_destroy);
	}
	pathstub = g_build_filename(RTSLIDERS_DATA_DIR,firmware->sliders_map_file,NULL);
	filename = get_file((const gchar *)DATA_GET(global_data,"project_name"),pathstub,"xml");
	g_free(pathstub);
	LIBXML_TEST_VERSION
		doc = xmlReadFile(filename, NULL, 0);
	g_free(filename);
	if (doc == NULL)
	{
		printf(_("error: could not parse file %s\n"),filename);
		return;
	}
	root_element = xmlDocGetRootElement(doc);
	size_group_left = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
	size_group_right = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
	res = load_rts_xml_elements(root_element,"rt_rts",rt_sliders,0,RUNTIME_TAB);
	if (!res)
		MTXDBG(CRITICAL,_("Runtime Sliders XML parse/load failure\n"));
	xmlFreeDoc(doc);
	xmlCleanupParser();

	return;
}
Beispiel #5
0
/*!
  \brief populate_limits() scans the datalog data and sets the minimum and 
  maximum values based on the span of the data in the file
  \param log_info is the pointer to log info structure
  */
G_MODULE_EXPORT void populate_limits(Log_Info *log_info)
{
	guint i = 0;
	gint j = 0;
	gconstpointer * object = NULL;
	GArray *array = NULL;
	gfloat val = 0.0;
	gfloat lower = 0.0;
	gfloat upper = 0.0;
	gint tmpi = 0;
	gint len = 0;

	ENTER();
	for (i=0;i<log_info->field_count;i++)
	{
		object = NULL;
		array = NULL;
		lower = 0.0;
		upper = 0.0;
		tmpi = 0;
		len = 0;
		object = (gconstpointer *)g_ptr_array_index(log_info->log_list, i);
		array = (GArray *)DATA_GET(object,"data_array");
		len = array->len;
		for (j=0;j<len;j++)
		{
			val = g_array_index(array,gfloat, j);
			if (val < lower)
				lower = val;
			if (val >upper )
				upper = val;

		}
		tmpi = floor(lower) -1.0;
		DATA_SET_FULL(object,"real_lower", (gpointer)g_strdup_printf("%i",tmpi),g_free);
		tmpi = ceil(upper) + 1.0;
		DATA_SET_FULL(object,"real_upper", (gpointer)g_strdup_printf("%i",tmpi),g_free);

	}
	EXIT();
	return;
}
Beispiel #6
0
/*!
  \brief get_list returns the list referenced by name
  \param key is the Text name of list to return a pointer to
  \returns pointer to GList
  \see store_list
  */
G_MODULE_EXPORT GList * get_list(const gchar * key)
{
	ENTER();
	if (!lists_hash)
	{
		lists_hash = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,NULL);
		DATA_SET_FULL(global_data,"lists_hash",lists_hash,dealloc_lists_hash);
	}
	EXIT();
	return (GList *)g_hash_table_lookup(lists_hash,key);
}
Beispiel #7
0
/*!
  \brief store_list stores a list by a textual name
  \param key is the Text name of list to store
  \param list pointer to list to store
  \see get_list
  */
G_MODULE_EXPORT void store_list(const gchar * key, GList * list)
{
	ENTER();
	if (!lists_hash)
	{
		lists_hash = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,NULL);
		DATA_SET_FULL(global_data,"lists_hash",lists_hash,dealloc_lists_hash);
	}
	g_hash_table_replace(lists_hash,g_strdup(key),(gpointer)list);
	EXIT();
	return;
}
Beispiel #8
0
/*!
  \brief populate_master() stores a pointer to all of the glade loaded 
  widgets into a master hashtable so that it can be recalled by name 
  anywhere in the program.
  \param widget is the pointer to Widget
  \param user_data is the pointer to ConfigFile structure
  */
G_MODULE_EXPORT void populate_master(GtkWidget *widget, gpointer user_data )
{
	gchar *name = NULL;
	gchar *fullname = NULL;
	gchar *prefix = NULL;
	GHashTable *dynamic_widgets = NULL;
	ConfigFile *cfg = (ConfigFile *) user_data;
	/*!
	 Populates a big master hashtable of all dynamic widgets so that 
	 various functions can do a lookup for the widgets name and get it's
	 GtkWidget * for manipulation.  We do NOT insert the topframe
	 widgets from the XML tree as if more than 1 tab loads there will 
	 be a clash, and there's no need to store the top frame widget 
	 anyways...
	 */
	if (GTK_IS_CONTAINER(widget))
		gtk_container_foreach(GTK_CONTAINER(widget),populate_master,user_data);
	if (!cfg_read_string(cfg,"global","id_prefix",&prefix))
		prefix = g_strdup("");

	name = (char *)glade_get_widget_name(widget);
	/*printf("name of widget stored is %s\n",name);*/

	if (name == NULL)
	{
		g_free(prefix);
		return;
	}
	if (g_strrstr((gchar *)name,"topframe"))
	{
		g_free(prefix);
		return;
	}
	dynamic_widgets = DATA_GET(global_data,"dynamic_widgets");
	if(!dynamic_widgets)
	{
		dynamic_widgets = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,NULL);
		DATA_SET_FULL(global_data,"dynamic_widgets",dynamic_widgets,g_hash_table_destroy);
	}
	fullname = g_strdup_printf("%s%s",prefix,name);
	OBJ_SET_FULL(widget,"fullname",g_strdup(fullname),g_free);
	OBJ_SET(widget,"last_value",GINT_TO_POINTER(-G_MAXINT));
	if (!g_hash_table_lookup(dynamic_widgets,fullname))
		g_hash_table_insert(dynamic_widgets,g_strdup(fullname),(gpointer)widget);
	else
		MTXDBG(CRITICAL,_("Key %s  for widget %s from file %s already exists in master table\n"),name,fullname,cfg->filename);

	g_free(prefix);
	g_free(fullname);
}
Beispiel #9
0
/*!
  \brief initiates an offline ECU restore from file. Prompts for file, if
  valid, it calles the restore_all function from the ECU plugin
  */
G_MODULE_EXPORT void offline_ecu_restore_pf(void)
{
	MtxFileIO *fileio = NULL;
	gchar *filename = NULL;
	void (*restore_all_f)(const gchar *);
	Firmware_Details *firmware = NULL;

	ENTER();
	firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
	get_symbol("restore_all_ecu_settings",(void **)&restore_all_f);

	g_return_if_fail(firmware);
	g_return_if_fail(restore_all_f);

	if (!DATA_GET(global_data,"interrogated"))
	{
		EXIT();
		return;
	}

	fileio = g_new0(MtxFileIO ,1);
	fileio->default_path = g_strdup(BACKUP_DATA_DIR);
	fileio->project = (const gchar *)DATA_GET(global_data,"project_name");
	fileio->parent = lookup_widget("main_window");
	fileio->on_top = TRUE;
	fileio->title = g_strdup("You should load an ECU backup from a file");
	fileio->action = GTK_FILE_CHOOSER_ACTION_OPEN;
	fileio->shortcut_folders = g_strdup(BACKUP_DATA_DIR);
	if (DATA_GET(global_data,"last_offline_filename"))
	fileio->default_filename = g_strdup((gchar *)DATA_GET(global_data,"last_offline_filename"));

	filename = choose_file(fileio);
	if (filename)
	{
		DATA_SET_FULL(global_data,"last_offline_filename",g_strdup(filename),g_free);
		update_logbar("tools_view",NULL,_("Full Restore of ECU Initiated\n"),FALSE,FALSE,FALSE);
		restore_all_f(filename);
		g_free(filename);
	}
	else
		io_cmd(firmware->get_all_command,NULL);

	free_mtxfileio(fileio);
	EXIT();
	return;
}
Beispiel #10
0
/*!
  \brief register_widget() adds a widget to the master hashtable (dynamic_widgets)
  \see dynamic_widgets
  \param name is the Name of widget to store (any strings are allowed)
  \param widget is the Pointer to the widget to be stored by name.
  \see deregister_widget
  */
G_MODULE_EXPORT void register_widget(gchar *name, GtkWidget * widget)
{
	GHashTable *dynamic_widgets = NULL;

	dynamic_widgets = DATA_GET(global_data,"dynamic_widgets");
	if(!dynamic_widgets)
	{
		dynamic_widgets = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,NULL);
		DATA_SET_FULL(global_data,"dynamic_widgets",dynamic_widgets,g_hash_table_destroy);
	}
	if (g_hash_table_lookup(dynamic_widgets,name))
	{
		
		g_hash_table_replace(dynamic_widgets,g_strdup(name),(gpointer)widget);
		MTXDBG(CRITICAL,_("Widget named \"%s\" already exists in master table replacing it!\n"),name);
	}
	else
		g_hash_table_insert(dynamic_widgets,g_strdup(name),(gpointer)widget);
}
Beispiel #11
0
/*!
  \brief register_rt_range() creates the slider from the passed data, 
  and attaches it the the gui. This is called during gui tab loading to embed
  sliders into regular tabs.
  \param widget is the widget defined in Gui datamap file. Used
  to load all the necessary attributes to stick the control in the right place.
  */
G_MODULE_EXPORT void register_rt_range(GtkWidget * widget)
{
	gconstpointer *object = NULL;
	Rtv_Map *rtv_map = NULL;
	GHashTable *rt_sliders = NULL;
	GHashTable *aw_sliders = NULL;
	GHashTable *ww_sliders = NULL;
	GHashTable *enr_sliders = NULL;
	gchar * source = NULL;
	const gchar *name = NULL;
	TabIdent ident;
	Rt_Slider *slider = NULL;

	rtv_map = (Rtv_Map *)DATA_GET(global_data,"rtv_map");
	source = (gchar *)OBJ_GET(widget,"source");
	ident = (TabIdent)(GINT)OBJ_GET(widget,"tab_ident");
	name = glade_get_widget_name(widget);
		
	g_return_if_fail(rtv_map);
	g_return_if_fail(source);


	object = (gconstpointer *)g_hash_table_lookup(rtv_map->rtv_hash,source);

	rt_sliders = (GHashTable *)DATA_GET(global_data,"rt_sliders");
	aw_sliders = (GHashTable *)DATA_GET(global_data,"aw_sliders");
	ww_sliders = (GHashTable *)DATA_GET(global_data,"ww_sliders");
	enr_sliders = (GHashTable *)DATA_GET(global_data,"enr_sliders");
	if (!rt_sliders)
	{
		rt_sliders = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,dealloc_slider);
		DATA_SET_FULL(global_data,"rt_sliders",rt_sliders,g_hash_table_destroy);
	}
	if (!aw_sliders)
	{
		aw_sliders = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,dealloc_slider);
		DATA_SET_FULL(global_data,"aw_sliders",aw_sliders,g_hash_table_destroy);
	}
	if (!ww_sliders)
	{
		ww_sliders = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,dealloc_slider);
		DATA_SET_FULL(global_data,"ww_sliders",ww_sliders,g_hash_table_destroy);
	}
	if (!enr_sliders)
	{
		enr_sliders = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,dealloc_slider);
		DATA_SET_FULL(global_data,"enr_sliders",enr_sliders,g_hash_table_destroy);
	}
	
	if  (!(object))
	{
		MTXDBG(CRITICAL,_("ERROR! There is no datasource named \"%s\", Check config of widget %s\n"),source,(name == NULL ? "undefined":name));
		return;
	}
	slider = (Rt_Slider *)g_malloc0(sizeof(Rt_Slider));
	slider->ctrl_name = g_strdup((name == NULL ? "undefined":name));
	slider->tbl = -1;
	slider->table_num = -1;
	slider->row = -1;
	slider->history = (GArray *) DATA_GET(object,"history");
	slider->friendly_name = (gchar *) DATA_GET(object,"dlog_gui_name");
	slider->temp_dep = (GBOOLEAN)DATA_GET(object,"temp_dep");
	if ((gchar *)DATA_GET(object,"real_lower"))
		slider->lower = (GINT)strtol((gchar *)DATA_GET(object,"real_lower"),NULL,10);
	else
		printf(_("No \"real_lower\" value defined for control name %s, datasource %s\n"),slider->ctrl_name,source);
	if ((gchar *)DATA_GET(object,"real_upper"))
		slider->upper = (GINT)strtol((gchar *)DATA_GET(object,"real_upper"),NULL,10);
	else
		printf(_("No \"real_upper\" value defined for control name %s, datasource %s\n"),slider->ctrl_name,source);
	slider->object = object;
	slider->textval = NULL;
	if (GTK_IS_SCALE(widget))
	{
		slider->type = MTX_RANGE;
		slider->pbar = widget;
	}
	/* generic container (Table/box HOLDING a mtx pbar */
	else if (GTK_IS_CONTAINER(widget))
	{
		GtkProgressBarOrientation orient;
		/* We don't like GTK+'s progress bar, so rip it out and 
		 * stick in my custom version instead.  Get the orientation
		 * first...
		 */
		orient = (GtkProgressBarOrientation)(GINT)OBJ_GET(widget,"orientation");
		slider->pbar = mtx_progress_bar_new();
		mtx_progress_bar_set_hold_time(MTX_PROGRESS_BAR(slider->pbar),(GINT)DATA_GET(global_data,"pbar_hold_time"));
		gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(slider->pbar),orient);
		gtk_container_add(GTK_CONTAINER(widget),slider->pbar);
		slider->type = MTX_PROGRESS;
	}

	switch (ident)
	{
		case RUNTIME_TAB:
			printf("inserted slider into runtime tab!\n");
			g_hash_table_insert(rt_sliders,g_strdup(slider->ctrl_name),(gpointer)slider);
			break;
		case ENRICHMENTS_TAB:
			g_hash_table_insert(enr_sliders,g_strdup(slider->ctrl_name),(gpointer)slider);
			break;
		case WARMUP_WIZ_TAB:
			g_hash_table_insert(ww_sliders,g_strdup(slider->ctrl_name),(gpointer)slider);
			break;
		case ACCEL_WIZ_TAB:
			g_hash_table_insert(aw_sliders,g_strdup(slider->ctrl_name),(gpointer)slider);
			break;
		default:
			break;
	}


}
Beispiel #12
0
/*!
  \brief set_offline_mode() is called when the "Offline Mode" button is clicked
  in the general tab and is used to present the user with list of firmware 
  choices to select one for loading to work in offline mode (no connection to
  an ECU)
  */
G_MODULE_EXPORT gboolean set_offline_mode(void)
{
	GtkWidget * widget = NULL;
	gchar * filename = NULL;
	gboolean tmp = TRUE;
	GArray *pfuncs = NULL;
	PostFunction *pf = NULL;
	GAsyncQueue *io_repair_queue = NULL;
	Firmware_Details *firmware = NULL;
	void (*load_firmware_details)(void *,const gchar *) = NULL;

	ENTER();
	firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
	io_repair_queue = (GAsyncQueue *)DATA_GET(global_data,"io_repair_queue");

	/* Cause Serial Searcher thread to abort.... */
	if (io_repair_queue)
		g_async_queue_push(io_repair_queue,&tmp);

	filename = present_firmware_choices();
	if (!filename)
	{
		DATA_SET(global_data,"offline",GINT_TO_POINTER(FALSE));
		DATA_SET(global_data,"interrogated",GINT_TO_POINTER(FALSE));
		widget = lookup_widget("interrogate_button");
		if (GTK_IS_WIDGET(widget))
			gtk_widget_set_sensitive(GTK_WIDGET(widget),TRUE);
		widget = lookup_widget("offline_button");
		if (GTK_IS_WIDGET(widget))
			gtk_widget_set_sensitive(GTK_WIDGET(widget),TRUE);
		plugins_shutdown();
		/* Does this need a delay? */
		personality_choice();

		EXIT();
		return FALSE;
	}

	DATA_SET_FULL(global_data,"last_offline_profile",g_strdup(filename),g_free);
	DATA_SET(global_data,"offline",GINT_TO_POINTER(TRUE));
	DATA_SET(global_data,"interrogated",GINT_TO_POINTER(TRUE));

	/* Disable interrogation button */
	widget = lookup_widget("interrogate_button");
	if (GTK_IS_WIDGET(widget))
		gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);

	widget = lookup_widget("netaccess_table");
	if (GTK_IS_WIDGET(widget))
		gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);

	queue_function("kill_conn_warning");

	if (!firmware)
	{
		firmware = g_new0(Firmware_Details,1);
		DATA_SET(global_data,"firmware",firmware);
	}
	if (get_symbol("load_firmware_details",(void **)&load_firmware_details))
	{
		load_firmware_details(firmware,filename);
	}
	else
		printf("Unable to load firmware details!\n");

	pfuncs = g_array_new(FALSE,TRUE,sizeof(PostFunction *));

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("update_interrogation_gui_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("load_realtime_map_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("initialize_dashboards_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("load_status_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("load_rt_text_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("load_gui_tabs_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("start_statuscounts_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("disable_burner_buttons_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	/* BUG, causes deadlock
	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("offline_ecu_restore_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);
	*/

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("setup_menu_handlers_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("enable_3d_buttons_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("ready_msg_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("cleanup_pf");
	get_symbol(pf->name,(void **)&pf->function_w_arg);
	pf->w_arg = TRUE;
	pfuncs = g_array_append_val(pfuncs,pf);

	io_cmd(NULL,pfuncs);

	/*
	   io_cmd(firmware->get_all_command,NULL);
	 */

	widget = lookup_widget("binary_logging_frame");
	if (GTK_IS_WIDGET(widget))
		gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
	widget = lookup_widget("interrogate_button");
	if (GTK_IS_WIDGET(widget))
		gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
	widget = lookup_widget("offline_button");
	if (GTK_IS_WIDGET(widget))
		gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
	g_list_foreach(get_list("get_data_buttons"),set_widget_sensitive,GINT_TO_POINTER(FALSE));

	pfuncs = g_array_new(FALSE,TRUE,sizeof(PostFunction *));

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("reset_temps_pf");
	get_symbol(pf->name,(void **)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("cleanup_pf");
	get_symbol(pf->name,(void **)&pf->function_w_arg);
	pf->w_arg = TRUE;
	pfuncs = g_array_append_val(pfuncs,pf);
	io_cmd(NULL,pfuncs);
	EXIT();
	return FALSE;
}
Beispiel #13
0
/*!
  \brief main() is the typical main function in a C program, it performs
  all core initialization, loading of all main parameters, initializing handlers
  and entering gtk_main to process events until program close
  \param argc is the count of command line arguments
  \param argv is the array of command line args
  \returns TRUE
  */
gint main(gint argc, gchar ** argv)
{
	Serial_Params *serial_params = NULL;
	GAsyncQueue *queue = NULL;
	GTimer *timer = NULL;
	GCond *rtv_thread_cond = NULL;
	GMutex *dash_mutex = NULL;
	GMutex *rtt_mutex = NULL;
	GMutex *rtv_mutex = NULL;
	GMutex *rtv_thread_mutex = NULL;
	GMutex *serio_mutex = NULL;
	gint id = 0;
	setlocale(LC_ALL,"");
#ifdef __WIN32__
	bindtextdomain(PACKAGE, "C:\\Program Files\\MegaTunix\\dist\\locale");
#else
	bindtextdomain(PACKAGE, LOCALEDIR);
#endif
	textdomain (PACKAGE);

#ifdef DEBUG
	printf("This is a debug release, Git hash: %s\n",GIT_HASH);
#endif
	// Not needed?
//	gdk_threads_init();
	gtk_init(&argc, &argv);
	glade_init();

	/* Check if OpenGL is supported. */
	if (gdk_gl_query() == FALSE) {
		g_print("OpenGL not supported\n");
		return 0;
	}
	else
		gl_ability = TRUE;

//	gdk_gl_init_check(&argc, &argv);
//	gl_ability = gtk_gl_init_check(&argc, &argv);

	global_data = g_new0(gconstpointer, 1);

	/* Condition Variables */
	rtv_thread_cond = g_new0(GCond,1);
	g_cond_init(rtv_thread_cond);
	DATA_SET(global_data,"rtv_thread_cond",rtv_thread_cond);
	/* Mutexes */
	dash_mutex = g_new0(GMutex, 1);
	g_mutex_init(dash_mutex);
	DATA_SET(global_data,"dash_mutex",dash_mutex);
	rtt_mutex = g_new0(GMutex, 1);
	g_mutex_init(rtt_mutex);
	DATA_SET(global_data,"rtt_mutex",rtt_mutex);
	rtv_mutex = g_new0(GMutex, 1);
	g_mutex_init(rtv_mutex);
	DATA_SET(global_data,"rtv_mutex",rtv_mutex);
	rtv_thread_mutex = g_new0(GMutex, 1);
	g_mutex_init(rtv_thread_mutex);
	DATA_SET(global_data,"rtv_thread_mutex",rtv_thread_mutex);
	serio_mutex = g_new0(GMutex, 1);
	g_mutex_init(serio_mutex);
	DATA_SET(global_data,"serio_mutex",serio_mutex);

	/* For testing if gettext works
	   printf(_("Hello World!\n"));
	 */

	/* Build table of strings to enum values */
	build_string_2_enum_table();
	serial_params = (Serial_Params *)g_malloc0(sizeof(Serial_Params));
	DATA_SET(global_data,"serial_params",serial_params);

	handle_args(argc,argv);	/* handle CLI arguments */

	/* This will exit mtx if the locking fails! */
	/* Prevents multiple instances  but stops esoteric usess too 
	 * create_mtx_lock();
	 * */
	open_debug();		/* Open debug log */

	ENTER();
	/* Allocate memory  */
	init();			/* Initialize global vars */
	make_mtx_dirs();	/* Create config file dirs if missing */

	/* Create Message passing queues */
	queue = g_async_queue_new();
	DATA_SET_FULL(global_data,"io_data_queue",queue,g_async_queue_unref);
	queue = g_async_queue_new();
	DATA_SET_FULL(global_data,"slave_msg_queue",queue,g_async_queue_unref);
	queue = g_async_queue_new();
	DATA_SET_FULL(global_data,"io_repair_queue",queue,g_async_queue_unref);

	read_config();
	setup_gui();		

	gtk_rc_parse_string("style \"override\"\n{\n\tGtkTreeView::horizontal-separator = 0\n\tGtkTreeView::vertical-separator = 0\n}\nwidget_class \"*\" style \"override\"");

	/* This doesn't do any GUI stuff so can run as is... */
	id = g_timeout_add(2000,(GSourceFunc)flush_binary_logs,NULL);
    DATA_SET(global_data,"binlog_flush_id",GINT_TO_POINTER(id));

	sleep_calib();
	/* Check for first_time flag, if so, run first time wizard, otherwise
	   load personality choice
	   */
	timer = g_timer_new();
	DATA_SET_FULL(global_data,"mtx_uptime_timer",timer,g_timer_destroy);
	g_idle_add((GSourceFunc)check_for_first_time,NULL);
	
	DATA_SET(global_data,"ready",GINT_TO_POINTER(TRUE));

	gdk_threads_enter();
	gtk_main();
	gdk_threads_leave();
	EXIT();
	return (0);
}
Beispiel #14
0
/*!
  \brief Locks the serial port
  \param name is the name of the serial port device to lock
  \returns TRUE on lock success, FALSE otherwise
  */
G_MODULE_EXPORT gboolean lock_serial(gchar * name)
{
#ifndef __WIN32__
	gchar *tmpbuf = NULL;
	gchar *lock = NULL;
	gchar **vector = NULL;
	gchar *contents = NULL;
	gboolean res = FALSE;
	GError *err = NULL;
	guint i = 0;

	/*printf("told to lock serial port %s\n",name); */
	/* If no /proc (i.e. os-X), just fake it and return */
	if (!g_file_test("/var/lock",G_FILE_TEST_IS_DIR))
		return TRUE;

	tmpbuf = g_strdup_printf("/var/lock/LCK..");
	vector = g_strsplit(name,PSEP,-1);
	for (i=0;i<g_strv_length(vector);i++)
	{
		if ((g_strcasecmp(vector[i],"") == 0) || (g_strcasecmp(vector[i],"dev") == 0) || (g_strcasecmp(vector[i],"tmp") == 0))
			continue;
		lock = g_strconcat(tmpbuf,vector[i],NULL);
		cleanup(tmpbuf);
	}
	g_strfreev(vector);
	if (g_file_test(lock,G_FILE_TEST_IS_REGULAR))
	{
//		printf("found existing lock!\n");
		if(g_file_get_contents(lock,&contents,NULL,&err))
		{
			gint pid = 0;
//			printf("read existing lock\n");
			vector = g_strsplit(g_strchug(contents)," ", -1);
//			printf("lock had %i fields\n",g_strv_length(vector));
			pid = (GINT)g_ascii_strtoull(vector[0],NULL,10);
//			printf("pid in lock \"%i\"\n",pid);
			cleanup(contents);
			g_strfreev(vector);
			tmpbuf = g_strdup_printf("/proc/%i",pid);
			res = g_file_test(tmpbuf,G_FILE_TEST_IS_DIR);
			cleanup(tmpbuf);
			if (res)
			{
//				printf("process active\n");
				return FALSE;
			}
			else
				g_remove(lock);
		}
		
	}
	contents = g_strdup_printf("     %i",getpid());
	res = g_file_set_contents(lock,contents,-1,&err);
	cleanup(contents);
	if (res)
	{
		DATA_SET_FULL(global_data,"serial_lockfile",(gpointer)lock,cleanup);
		return TRUE;
	}
	else
		printf(_("Error setting serial lock %s\n"),(gchar *)strerror(errno));
#endif
	return TRUE;
}
/*!
  \brief load_rtv_xml_multi_expressions() is called when a "multi_expr_keys" key is found in
  a realtime map, and triggers the loading of al lthe keys/values that
  will allow megatunix to process a special variable that requires handling of
  multiple circumstances
  \param object is the place to store the retrieved data
  \param node is the xml node that contains the data
  \see check_dependancies
  */
G_MODULE_EXPORT void load_rtv_xml_multi_expressions(gconstpointer *object, xmlNode *node)
{
	gchar *tmpbuf = NULL;
	gchar ** keys = NULL;
	gchar ** l_limits = NULL;
	gchar ** u_limits = NULL;
	gchar ** ltables = NULL;
	gchar ** ul_mults = NULL;
	gchar ** ul_adds = NULL;
	gint num_keys = 0;
	gint i = 0;
	gint lowest = 0;
	gint highest = 0;
	GHashTable *hash = NULL;
	MultiExpr *multi = NULL;

	if (!generic_xml_gchar_find(node,"multi_expr_keys",&tmpbuf))
	{
		MTXDBG(CRITICAL,_("Can't find \"multi_expr_keys\" in the xml, exiting!\n"));
		exit (-4);
	}
	else
	{
		keys = parse_keys(tmpbuf,&num_keys,",");
		g_free(tmpbuf);
	}

	if (!generic_xml_gchar_find(node,"lower_limits",&tmpbuf))
	{
		MTXDBG(CRITICAL,_("Key \"lower_limits\" NOT FOUND in xml, EXITING!!\n"));
		exit (-4);
	}
	else
	{
		l_limits = g_strsplit(tmpbuf,",",-1);
		g_free(tmpbuf);
	}
	if (!generic_xml_gchar_find(node,"upper_limits",&tmpbuf))
	{
		MTXDBG(CRITICAL,_("Key \"upper_limits\" NOT FOUND in xml, EXITING!!\n"));
		exit (-4);
	}
	else
	{
		u_limits = g_strsplit(tmpbuf,",",-1);
		g_free(tmpbuf);
	}
	if (!generic_xml_gchar_find(node,"multi_lookuptables",&tmpbuf))
	{
		MTXDBG(CRITICAL,_("Key \"multi_lookuptables\" NOT FOUND in xml, EXITING!!\n"));
		exit (-4);
	}
	else
	{
		ltables = g_strsplit(tmpbuf,",",-1);
		g_free(tmpbuf);
	}
	if (!generic_xml_gchar_find(node,"fromecu_mults",&tmpbuf))
	{
		MTXDBG(CRITICAL,_("Key \"fromecu_mults\" NOT FOUND in xml, EXITING!!\n"));
		exit (-4);
	}
	else
	{
		ul_mults = g_strsplit(tmpbuf,",",-1);
		g_free(tmpbuf);
	}
	if (!generic_xml_gchar_find(node,"fromecu_adds",&tmpbuf))
	{
		MTXDBG(CRITICAL,_("Key \"fromecu_adds\" NOT FOUND in xml, EXITING!!\n"));
		exit (-4);
	}
	else
	{
		ul_adds = g_strsplit(tmpbuf,",",-1);
		g_free(tmpbuf);
	}
	if (!generic_xml_gchar_find(node,"source_key",&tmpbuf))
	{
		MTXDBG(CRITICAL,_("Key \"source_key\" NOT FOUND in xml, EXITING!!\n"));
		exit (-4);
	}
	else
	{
		DATA_SET_FULL(object,"source_key",g_strdup(tmpbuf),g_free);
		g_free(tmpbuf);
	}
	/* Create hash table to store structures for each one */
	hash = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,free_multi_expr);
	lowest = G_MAXINT32;
	highest = G_MININT32;
	for (i=0;i<num_keys;i++)
	{
		multi = g_new0(MultiExpr, 1);
		multi->lower_limit = (GINT)strtol(l_limits[i],NULL,10);
		multi->upper_limit = (GINT)strtol(u_limits[i],NULL,10);
		if (multi->lower_limit < lowest)
			lowest = multi->lower_limit;
		if (multi->upper_limit > highest)
			highest = multi->upper_limit;

		if (strlen(ltables[i]) == 0)
			multi->lookuptable = NULL;
		else
			multi->lookuptable = g_strdup(ltables[i]);
		multi->fromecu_mult = g_new0(gfloat, 1);
		multi->fromecu_add = g_new0(gfloat, 1);
		*multi->fromecu_mult = (gfloat)g_strtod(ul_mults[i],NULL);
		*multi->fromecu_add = (gfloat)g_strtod(ul_adds[i],NULL);

		g_hash_table_insert(hash,g_strdup(keys[i]),multi);
	}
	DATA_SET_FULL(object,"real_lower",g_strdup_printf("%i",lowest),g_free);
	DATA_SET_FULL(object,"real_upper",g_strdup_printf("%i",highest),g_free);
	g_strfreev(l_limits);
	g_strfreev(u_limits);
	g_strfreev(ltables);
	g_strfreev(ul_mults);
	g_strfreev(ul_adds);
	g_strfreev(keys);
	DATA_SET_FULL(object,"multi_expr_hash",hash,g_hash_table_destroy);
}
Beispiel #16
0
/*!
  \brief load_table() physically handles loading the table datafrom disk, 
  populating and array and sotring a pointer to that array in the lookuptables
  hashtable referenced by the table_name passed
  \param table_name is the key to lookuptables hashtable
  \param filename is the filename to load table data from
  \returns TRUE on success, FALSE on failure
  */
G_MODULE_EXPORT gboolean load_table(gchar *table_name, gchar *filename)
{
	GIOStatus status;
	GIOChannel *iochannel;
	gboolean done = FALSE;
	GHashTable *lookuptables = NULL;
	gchar * str = NULL;
	gchar * tmp = NULL;
	gchar * end = NULL;
	GString *a_line; 
	LookupTable *lookuptable = NULL;
	gint tmparray[2048]; /* bad idea being static!!*/
	gchar ** vector = NULL;
	gint i = 0;

	ENTER();
	iochannel = g_io_channel_new_file(filename,"r", NULL);
	status = g_io_channel_seek_position(iochannel,0,G_SEEK_SET,NULL);
	if (status != G_IO_STATUS_NORMAL)
	{
		MTXDBG(CRITICAL,_("Error seeking to beginning of the file\n"));
	}
	while (!done)	
	{
		a_line = g_string_new("\0");
		status = g_io_channel_read_line_string(iochannel, a_line, NULL, NULL);
		if (status == G_IO_STATUS_EOF)
			done = TRUE;
		else
		{
			/*	str = g_strchug(g_strdup(a_line->str));*/
			str = g_strchug(a_line->str);
			if (g_str_has_prefix(str,"DB"))
			{
				str+=2; /* move 2 places in	*/
				end = g_strrstr(str,"T");
				tmp = g_strndup(str,end-str);
				tmparray[i]=atoi(tmp);
				g_free(tmp);
				i++;
			}
		}
		g_string_free(a_line,TRUE);
	}
	g_io_channel_shutdown(iochannel,TRUE,NULL);
	g_io_channel_unref(iochannel);

	vector = g_strsplit(filename,PSEP,-1);
	lookuptable = g_new0(LookupTable, 1);
	lookuptable->array = (gint *)g_memdup(&tmparray,i*sizeof(gint));
	lookuptable->filename = g_strdup(vector[g_strv_length(vector)-1]);
	g_strfreev(vector);
	lookuptables = (GHashTable *)DATA_GET(global_data,"lookuptables");
	if (!lookuptables)
	{
		lookuptables = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,dealloc_lookuptable);
		DATA_SET_FULL(global_data,"lookuptables",lookuptables,g_hash_table_destroy);
	}
	g_hash_table_replace((GHashTable *)DATA_GET(global_data,"lookuptables"),g_strdup(table_name),lookuptable);
	/*g_hash_table_foreach(DATA_GET(global_data,"lookuptables"),dump_lookuptables,NULL);*/

	EXIT();
	return TRUE;
}
Beispiel #17
0
/*!
  \brief load_gui_tabs_pf() is called after interrogation completes 
  successfully. It's purpose is to load all the glade files and 
  datamaps as specified in the interrogation profile of the detected firmware. 
  */
G_MODULE_EXPORT gboolean load_gui_tabs_pf(void)
{
	gint i = 0;
	gint cur = 0;
	ConfigFile *cfgfile = NULL;
	gchar * map_file = NULL;
	gchar * glade_file = NULL;
	gchar * tmpbuf = NULL;
	gchar * tab_name = NULL;
	gchar * tab_ident = NULL;
	gboolean tmpi = FALSE;
	GtkWidget *label = NULL;
	GtkWidget *container = NULL;
	GtkWidget *child = NULL;
	GtkWidget *notebook = NULL;
	GtkWidget *item = NULL;
	TabInfo *tabinfo = NULL;
	GPtrArray *tabinfos = NULL;
	extern GdkColor red;
	gboolean * hidden_list = NULL;
	Firmware_Details *firmware = NULL;
	CmdLineArgs *args = NULL;
	gchar * pathstub = NULL;

	ENTER();
	firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
	args = (CmdLineArgs *)DATA_GET(global_data,"args");

	if (DATA_GET(global_data,"tabs_loaded"))
	{
		EXIT();
		return FALSE;
	}
	if (!firmware)
	{
		EXIT();
		return FALSE;
	}
	if (!firmware->tab_list)
	{
		EXIT();
		return FALSE;
	}
	if (!firmware->tab_confs)
	{
		EXIT();
		return FALSE;
	}
	if (args->inhibit_tabs)
	{
		EXIT();
		return FALSE;
	}

	set_title(g_strdup(_("Loading Gui Tabs...")));
	notebook = lookup_widget("toplevel_notebook");
	hidden_list = (gboolean *)DATA_GET(global_data,"hidden_list");
	tabinfos = g_ptr_array_new();

	while (firmware->tab_list[i])
	{

		pathstub = g_build_filename(GUI_DATA_DIR,firmware->tab_list[i],NULL);
		glade_file = get_file((const gchar *)DATA_GET(global_data,"project_name"),pathstub,"glade");
		g_free(pathstub);
		pathstub = g_build_filename(GUI_DATA_DIR,firmware->tab_confs[i],NULL);
		map_file = get_file((const gchar *)DATA_GET(global_data,"project_name"),pathstub,"datamap");
		g_free(pathstub);
		if (!g_file_test(glade_file,G_FILE_TEST_EXISTS))
		{
			MTXDBG(TABLOADER|CRITICAL,_("GLADE FILE: \"%s.glade\" NOT FOUND\n"),firmware->tab_list[i]);
			update_logbar("interr_view","warning",g_strdup(_("Glade File: ")),FALSE,FALSE,TRUE);
			update_logbar("interr_view","info",g_strdup_printf("\"%s.glade\"",firmware->tab_list[i]),FALSE,FALSE,TRUE);
			update_logbar("interr_view","warning",g_strdup(_("  is MISSING!\n")),FALSE,FALSE,TRUE);
			i++;
			continue;
		}
		if (!g_file_test(map_file,G_FILE_TEST_EXISTS))
		{
			MTXDBG(TABLOADER|CRITICAL,_("DATAMAP: \"%s.datamap\" NOT FOUND\n"),firmware->tab_confs[i]);
			update_logbar("interr_view","warning",g_strdup(_("Datamap File: ")),FALSE,FALSE,TRUE);
			update_logbar("interr_view","info",g_strdup_printf("\"%s.datamap\"",firmware->tab_confs[i]),FALSE,FALSE,TRUE);
			update_logbar("interr_view","warning",g_strdup(_("  is MISSING!\n")),FALSE,FALSE,TRUE);
			i++;
			continue;
		}
		cfgfile = cfg_open_file(map_file);
		if (cfgfile)
		{
			tabinfo = g_new0(TabInfo, 1);
			tabinfo->glade_file = g_strdup(glade_file);
			tabinfo->datamap_file = g_strdup(map_file);

			cfg_read_string(cfgfile,"global","tab_name",&tab_name);

			label = gtk_label_new(NULL);
			tabinfo->tab_label = label;
			gtk_label_set_markup_with_mnemonic(GTK_LABEL(label),tab_name);
			if (cfg_read_boolean(cfgfile,"global","ellipsize",&tmpi))
			{
				if (tmpi)
				{
					OBJ_SET(label,"ellipsize_preferred",GINT_TO_POINTER(TRUE));
					if (DATA_GET(global_data,"ellipsize_tabs"))
						gtk_label_set_ellipsize(GTK_LABEL(label),PANGO_ELLIPSIZE_END);
				}
			}
			if (cfg_read_string(cfgfile,"global","bind_to_list",&tmpbuf))
			{
				OBJ_SET_FULL(label,"bind_to_list",g_strdup(tmpbuf),g_free);
				bind_to_lists(label,tmpbuf);
				g_free(tmpbuf);
				if (cfg_read_string(cfgfile,"global","match_type",&tmpbuf))
				{
					tmpi = translate_string(tmpbuf);
					g_free(tmpbuf);
					OBJ_SET(label,"match_type",GINT_TO_POINTER(tmpi));
				}
			}
			gtk_misc_set_alignment(GTK_MISC(label),0,0.5);
			container = gtk_vbox_new(1,0);
			if (cfg_read_string(cfgfile,"topframe","tab_ident",&tab_ident))
			{
				tmpi = translate_string(tab_ident);
				g_free(tab_ident);
				OBJ_SET(container,"tab_ident",GINT_TO_POINTER(tmpi));
			}
			g_free(tab_name);
			OBJ_SET_FULL(label,"glade_file",g_strdup(glade_file),cleanup);
			OBJ_SET_FULL(label,"datamap_file",g_strdup(map_file),cleanup);
			OBJ_SET(label,"not_rendered",GINT_TO_POINTER(TRUE));
			gtk_notebook_append_page(GTK_NOTEBOOK(notebook),container,label);
			gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(notebook),container,TRUE);
			gtk_widget_show(container);
			cur = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook))-1;
			tabinfo->page_num = cur;
			tabinfo->notebook = GTK_NOTEBOOK(notebook);
			if (hidden_list[cur] == TRUE)
			{
				child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),cur);
				label = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook),child);
				gtk_widget_hide(child);
				gtk_widget_hide(label);
				item = lookup_widget("show_tab_visibility_menuitem");
				gtk_widget_modify_text(gtk_bin_get_child(GTK_BIN(item)),GTK_STATE_NORMAL,&red);
			}
			g_ptr_array_add(tabinfos,(gpointer)tabinfo);
		}
		cfg_free(cfgfile);
		g_free(map_file);
		g_free(glade_file);
		i++;

		if (!firmware)
			break;
	}
	preload_deps(tabinfos);
	DATA_SET_FULL(global_data,"tabinfos",tabinfos,dealloc_tabinfos);
	DATA_SET(global_data,"tabs_loaded",GINT_TO_POINTER(TRUE));
	MTXDBG(TABLOADER,_("All is well, leaving...\n\n"));
	set_title(g_strdup(_("Gui Tabs Loaded...")));
	gdk_flush();
	EXIT();
	return TRUE;
}
Beispiel #18
0
/*!
  \brief main() is the typical main function in a C program, it performs
  all core initialization, loading of all main parameters, initializing handlers
  and entering gtk_main to process events until program close
  \param argc is the count of command line arguments
  \param argv is the array of command line args
  \returns TRUE
  */
gint main(gint argc, gchar ** argv)
{
	Serial_Params *serial_params = NULL;
	GAsyncQueue *queue = NULL;
	GCond *cond = NULL;
	GMutex *mutex = NULL;
	gint id = 0;
	setlocale(LC_ALL,"");
#ifdef __WIN32__
	bindtextdomain(PACKAGE, "C:\\Program Files\\MegaTunix\\dist\\locale");
#else
	bindtextdomain(PACKAGE, LOCALEDIR);
#endif
	textdomain (PACKAGE);

#ifdef DEBUG
	printf("This is a debug release, Git hash: %s\n",MTX_GIT_HASH);
#endif
	if(!g_thread_supported())
		g_thread_init(NULL);
	gdk_threads_init();
	gtk_init(&argc, &argv);
	glade_init();

	gdk_gl_init_check(&argc, &argv);
	gl_ability = gtk_gl_init_check(&argc, &argv);

	global_data = g_new0(gconstpointer, 1);

	/* Condition variables */
	cond = g_cond_new();
	DATA_SET(global_data,"statuscounts_cond",cond);
	cond = g_cond_new();
	DATA_SET(global_data,"io_dispatch_cond",cond);
	cond = g_cond_new();
	DATA_SET(global_data,"gui_dispatch_cond",cond);
	cond = g_cond_new();
	DATA_SET(global_data,"pf_dispatch_cond",cond);
	cond = g_cond_new();
	DATA_SET(global_data,"rtv_thread_cond",cond);

	/* Mutexes */
	mutex = g_mutex_new();
	DATA_SET(global_data,"serio_mutex",mutex);
	mutex = g_mutex_new();
	DATA_SET(global_data,"rtt_mutex",mutex);
	mutex = g_mutex_new();
	DATA_SET(global_data,"rtv_mutex",mutex);
	mutex = g_mutex_new();
	DATA_SET(global_data,"dash_mutex",mutex);
	mutex = g_mutex_new();
	DATA_SET(global_data,"statuscounts_mutex",mutex);
	mutex = g_mutex_new();
	DATA_SET(global_data,"io_dispatch_mutex",mutex);
	mutex = g_mutex_new();
	DATA_SET(global_data,"gui_dispatch_mutex",mutex);
	mutex = g_mutex_new();
	DATA_SET(global_data,"pf_dispatch_mutex",mutex);
	mutex = g_mutex_new();
	DATA_SET(global_data,"rtv_thread_mutex",mutex);

	/* For testing if gettext works
	   printf(_("Hello World!\n"));
	 */

	/* Build table of strings to enum values */
	build_string_2_enum_table();
	serial_params = (Serial_Params *)g_malloc0(sizeof(Serial_Params));
	DATA_SET(global_data,"serial_params",serial_params);

	handle_args(argc,argv);	/* handle CLI arguments */

	/* This will exit mtx if the locking fails! */
	create_mtx_lock();
	open_debug();		/* Open debug log */
	/* Allocate memory  */
	init();			/* Initialize global vars */
	make_mtx_dirs();	/* Create config file dirs if missing */

	/* Create Message passing queues */
	queue = g_async_queue_new();
	DATA_SET_FULL(global_data,"io_data_queue",queue,g_async_queue_unref);
	queue = g_async_queue_new();
	DATA_SET_FULL(global_data,"slave_msg_queue",queue,g_async_queue_unref);
	queue = g_async_queue_new();
	DATA_SET_FULL(global_data,"pf_dispatch_queue",queue,g_async_queue_unref);
	queue = g_async_queue_new();
	DATA_SET_FULL(global_data,"gui_dispatch_queue",queue,g_async_queue_unref);
	queue = g_async_queue_new();
	DATA_SET_FULL(global_data,"io_repair_queue",queue,g_async_queue_unref);

	read_config();
	setup_gui();		

	gtk_rc_parse_string("style \"override\"\n{\n\tGtkTreeView::horizontal-separator = 0\n\tGtkTreeView::vertical-separator = 0\n}\nwidget_class \"*\" style \"override\"");

	id = g_timeout_add_full(-50,16,(GSourceFunc)pf_dispatcher,NULL,NULL);
	DATA_SET(global_data,"pf_dispatcher_id",GINT_TO_POINTER(id));
	id = g_timeout_add_full(-35,35,(GSourceFunc)gui_dispatcher,NULL,NULL);
	DATA_SET(global_data,"gui_dispatcher_id",GINT_TO_POINTER(id));
	id = g_timeout_add(1000,(GSourceFunc)flush_binary_logs,NULL);
        DATA_SET(global_data,"binlog_flush_id",GINT_TO_POINTER(id));

	sleep_calib();
	/* Check for first_time flag, if so, run first tiem wizard, otherwise
	   load personality choice
	   */
	gdk_threads_add_timeout(500,(GSourceFunc)check_for_first_time,NULL);
	

	DATA_SET(global_data,"ready",GINT_TO_POINTER(TRUE));
	gdk_threads_enter();
	gtk_main();
	gdk_threads_leave();
	return (0) ;
}
Beispiel #19
0
/*!
 \brief ECU specifc that gets called to send a value to the ECU. 
 \param canID is the can Identifier
 \param locID is the Location ID to where this value belongs
 \param offset is the offset from the beginning of the page that this data
 refers to.
 \param size is an enumeration corresponding to how big this variable is
 \param value is the value that should be sent to the ECU At page/offset
 \param queue_update if true queues a gui update, used to prevent
 a horrible stall when doing an ECU restore or batch load...
 */
G_MODULE_EXPORT void libreems_send_to_ecu(gint canID, gint locID, gint offset, DataSize size, gint value, gboolean queue_update)
{
	static Firmware_Details *firmware = NULL;
	OutputData *output = NULL;
	guint8 *data = NULL;
	guint16 u16 = 0;
	gint16 s16 = 0;
	guint32 u32 = 0;
	gint32 s32 = 0;

	ENTER();
	if (!firmware)
		firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");

	g_return_if_fail(firmware);
	g_return_if_fail(offset >= 0);

	MTXDBG(SERIAL_WR,_("Sending locID %i, offset %i, value %i \n"),locID,offset,value);

	switch (size)
	{
		case MTX_CHAR:
		case MTX_S08:
		case MTX_U08:
			/*printf("8 bit var %i at offset %i\n",value,offset);*/
			break;
		case MTX_S16:
		case MTX_U16:
			/*printf("16 bit var %i at offset %i\n",value,offset);*/
			break;
		case MTX_S32:
		case MTX_U32:
			/*printf("32 bit var %i at offset %i\n",value,offset);*/
			break;
		default:
			printf(_("libreems_send_to_ecu() ERROR!!! Size undefined for variable at canID %i, offset %i\n"),locID,offset);
	}
	output = initialize_outputdata_f();
	DATA_SET(output->data,"location_id", GINT_TO_POINTER(locID));
	DATA_SET(output->data,"payload_id", GINT_TO_POINTER(REQUEST_UPDATE_BLOCK_IN_RAM));
	DATA_SET(output->data,"offset", GINT_TO_POINTER(offset));
	DATA_SET(output->data,"size", GINT_TO_POINTER(size));
	DATA_SET(output->data,"value", GINT_TO_POINTER(value));
	DATA_SET(output->data,"length", GINT_TO_POINTER(get_multiplier_f(size)));
	DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_SIMPLE_WRITE));
	/* Get memory */
	data = g_new0(guint8,get_multiplier_f(size));
	switch (size)
	{
		case MTX_CHAR:
		case MTX_U08:
			data[0] = (guint8)value;
			break;
		case MTX_S08:
			data[0] = (gint8)value;
			break;
		case MTX_U16:
			if (firmware->bigendian)
				u16 = GUINT16_TO_BE((guint16)value);
			else
				u16 = GUINT16_TO_LE((guint16)value);
			data[0] = (guint8)u16;
			data[1] = (guint8)((guint16)u16 >> 8);
			break;
		case MTX_S16:
			if (firmware->bigendian)
				s16 = GINT16_TO_BE((gint16)value);
			else
				s16 = GINT16_TO_LE((gint16)value);
			data[0] = (guint8)s16;
			data[1] = (guint8)((gint16)s16 >> 8);
			break;
		case MTX_S32:
			if (firmware->bigendian)
				s32 = GINT32_TO_BE((gint32)value);
			else
				s32 = GINT32_TO_LE((gint32)value);
			data[0] = (guint8)s32;
			data[1] = (guint8)((gint32)s32 >> 8);
			data[2] = (guint8)((gint32)s32 >> 16);
			data[3] = (guint8)((gint32)s32 >> 24);
			break;
		case MTX_U32:
			if (firmware->bigendian)
				u32 = GUINT32_TO_BE((guint32)value);
			else
				u32 = GUINT32_TO_LE((guint32)value);
			data[0] = (guint8)u32;
			data[1] = (guint8)((guint32)u32 >> 8);
			data[2] = (guint8)((guint32)u32 >> 16);
			data[3] = (guint8)((guint32)u32 >> 24);
			break;
		default:
			break;
	}
	DATA_SET_FULL(output->data,"data",(gpointer)data, g_free);
	/* Set it here otherwise there's a risk of a missed burn due to 
	 * a potential race condition in the burn checker
	 */
	libreems_set_ecu_data(canID,locID,offset,size,value);
	/* IF the packet fails, update_write_status will rollback properly */

	output->queue_update = queue_update;
	io_cmd_f(firmware->write_command,output);
	EXIT();
	return;
}
Beispiel #20
0
/*!
  \brief read_log_header() First we read the first line,  try to determine 
  if the delimiter is a COMMA, or a TAB. 
  \param iochannel is the iochannel that represents the input file
  \param log_info is the the Log_Info structure
  */
G_MODULE_EXPORT void read_log_header(GIOChannel *iochannel, Log_Info *log_info )
{
	GString *a_line = g_string_new("\0");
	GIOStatus  status = G_IO_STATUS_ERROR;
	gchar *delimiter = NULL;
	gchar **fields = NULL;
	gint num_fields = 0;
	GArray *array = NULL;
	gconstpointer *object = NULL;
	gint i = 0;
	Rtv_Map *rtv_map;
	extern gconstpointer *global_data;
	
	rtv_map = DATA_GET(global_data,"rtv_map");

read_again:
	status = g_io_channel_read_line_string(iochannel,a_line,NULL,NULL); 

	if (status == G_IO_STATUS_NORMAL) /* good read */
	{
		/* This searched for a quoted string which should be the 
		 * ecu signature.  pre 0.9.15 versions of megatunix shoved the
		 * internal name of the firmware in there which is a problem as
		 * it makes the logs locked to megatunix which is a bad thing 
		 * as it hurts interoperability.  0.9.16+ changes this to use 
		 * the REAL signature returned by the firmware. 
		 */
		if (g_strrstr(a_line->str,"\"") != NULL)
		{
			log_info->signature = g_strdup(g_strstrip(g_strdelimit(a_line->str,"\"\n\r",' ')));
			/*printf(_("LOG signature is \"%s\"\n"),log_info->signature);*/
			if (DATA_GET(global_data,"offline"))
			{
				printf("rtv_map->applicable_signatures is \"%s\"\n",rtv_map->applicable_signatures);
				if (rtv_map->applicable_signatures)
				{
					if (strstr(rtv_map->applicable_signatures,log_info->signature) != NULL)
						printf(_("Good this firmware is compatible with the firmware we're using\n"));
					else
						printf(_("mismatch between datalog and current firmware, playback via full gui will probably not work like you expected\n"));
				}
			}
			goto read_again;
		}

		if (g_strrstr(a_line->str,",") != NULL)
			delimiter = g_strdup(",");
		else if (g_strrstr(a_line->str,"\t") != NULL)
			delimiter = g_strdup("\t");

		/* Store delimiter in structure */
		log_info->delimiter = g_strdup(delimiter);
		/* Store field names as well... 
		 * log_info->fields is a string vector (char **)
		 * that is NULL terminated thanks to g_strsplit(void)
		 */
		fields = parse_keys(a_line->str,&num_fields,delimiter);

		log_info->field_count = num_fields;
		/* Create objects, arrays and storage points... */
		for (i=0;i<num_fields;i++)
		{
			array = NULL;
			object = g_new0(gconstpointer, 1);
			array = g_array_sized_new(FALSE,TRUE,sizeof(gfloat),4096);
			DATA_SET(object,"data_array",(gpointer)array);
			g_free(DATA_GET(object,"lview_name"));
			DATA_SET_FULL(object,"lview_name",g_strdup(g_strstrip(fields[i])),g_free);
			g_ptr_array_add(log_info->log_list,object);
		}
		/* Enable parameter selection button */
		gtk_widget_set_sensitive(lookup_widget("logviewer_select_params_button"), TRUE);
		OBJ_SET(lookup_widget("logviewer_trace_darea"),"log_info",(gpointer)log_info);

	}
	g_free(delimiter);

}
Beispiel #21
0
/*
 *\brief handle_transaction_hf is defined in comm.xml to handle the results
 of certain IO operations. This runs in the IOthread context so it CAN NOT
 do any GUI operations, but can queue gui ops via the thread_update_* calls
 \param data is a pointer to an Io_Message structure
 \param type is the FuncCall enumeration
 \see Io_Message
 \see FuncCall
 */
G_MODULE_EXPORT void handle_transaction_hf(void * data, FuncCall type)
{
	static Firmware_Details *firmware = NULL;
	Io_Message *message = NULL;
	OutputData *output = NULL;
	OutputData *retry = NULL;
	GAsyncQueue *queue = NULL;
	LibreEMS_Packet *packet = NULL;
	gint payload_id = 0;
	gint seq = 0;
	gint clock = 0;
	gint id = 0;
	gint tmpi = 0;
	gint canID = 0;
	gint length = 0;
	gint locID = 0;
	gint offset = 0;
	gint size = 0;
	gint page = 0;
	gint errorcode = 0;
	const gchar * errmsg = NULL;
	GTimeVal tval;

	ENTER();
	if (!firmware)
		firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
	message = (Io_Message *)data;
	output = (OutputData *)message->payload;
	g_return_if_fail(firmware);
	g_return_if_fail(message);
	g_return_if_fail(output);

	/* Get common data */
	seq = (GINT)DATA_GET(output->data,"sequence_num");
	canID = (GINT)DATA_GET(output->data,"canID");
	locID = (GINT)DATA_GET(output->data,"location_id");
	offset = (GINT)DATA_GET(output->data,"offset");
	size = (GINT)DATA_GET(output->data,"num_wanted");
	length = (GINT)DATA_GET(output->data,"length");

	switch (type)
	{
		case GENERIC_READ:
			packet = retrieve_packet(output->data,NULL);
			queue = (GAsyncQueue *)DATA_GET(output->data,"queue");
			if (queue)
			{
				deregister_packet_queue(SEQUENCE_NUM,queue,seq);
				g_async_queue_unref(queue);
				DATA_SET(output->data,"queue",NULL);
			}
			if (packet)
			{
				if (packet->is_nack)
					printf("GENERIC_READ packet ACK FAILURE!\n");
				else
				{

					/*printf("Packet arrived for GENERIC_READ case with sequence %i (%.2X), locID %i\n",seq,seq,locID);
					  printf("store new block locid %i, offset %i, data %p raw pkt len %i, payload len %i, num_wanted %i\n",locID,offset,packet->data+packet->payload_base_offset,packet->raw_length,packet->payload_length,size);
					  */
					libreems_store_new_block(canID,locID,offset,packet->data+packet->payload_base_offset,size);
					libreems_backup_current_data(canID,locID);

					libreems_packet_cleanup(packet);
					tmpi = (GINT)DATA_GET(global_data,"ve_goodread_count");
					DATA_SET(global_data,"ve_goodread_count",GINT_TO_POINTER(++tmpi));
				}
			}
			else
			{
				printf("timeout, no packet found in GENERIC_READ queue for sequence %i (%.2X), locID %i\n",seq,seq,locID);
				retry = initialize_outputdata_f();
				seq = atomic_sequence();
				DATA_SET(retry->data,"canID",DATA_GET(output->data,"canID"));
				DATA_SET(retry->data,"sequence_num",GINT_TO_POINTER(seq));
				DATA_SET(retry->data,"location_id",DATA_GET(output->data,"location_id"));
				DATA_SET(retry->data,"payload_id",DATA_GET(output->data,"payload_id"));
				DATA_SET(retry->data,"offset",DATA_GET(output->data,"offset"));
				DATA_SET(retry->data,"num_wanted",DATA_GET(output->data,"num_wanted"));
				DATA_SET(retry->data,"mode",DATA_GET(output->data,"mode"));
				queue = g_async_queue_new();
				register_packet_queue(SEQUENCE_NUM,queue,seq);
				DATA_SET(retry->data,"queue",queue);
				io_cmd_f(firmware->read_command,retry);
				printf("Re-issued command sent, seq %i!\n",seq);
			}
			break;
		case BENCHTEST_RESPONSE:
			packet = retrieve_packet(output->data,NULL);
			queue = (GAsyncQueue *)DATA_GET(output->data,"queue");
			if (queue)
			{
				deregister_packet_queue(SEQUENCE_NUM,queue,seq);
				g_async_queue_unref(queue);
				DATA_SET(output->data,"queue",NULL);
			}
			if (packet)
			{
				if (packet->is_nack)
				{
					errorcode = ((guint8)packet->data[packet->payload_base_offset] << 8) + (guint8)packet->data[packet->payload_base_offset+1];
					errmsg = lookup_error(errorcode);
					thread_update_logbar_f("libreems_benchtest_view","warning",g_strdup_printf(_("Benchtest Packet ERROR, Code (0X%.4X), \"%s\"\n"),errorcode,errmsg),FALSE,FALSE);
				}
				else
				{
					/* get the current clock/addition value*/
					clock = (GINT)DATA_GET(output->data,"clock");
					/* If bumping, increase the total time */
					if (DATA_GET(output->data,"bump"))
					{
						thread_update_logbar_f("libreems_benchtest_view",NULL,g_strdup_printf(_("Benchtest bumped by the user (added %.2f seconds to the clock), Total time remaining is now %.2f seconds\n"),clock/1000.0, ((GINT)DATA_GET(global_data,"benchtest_total")+clock)/1000.0),FALSE,FALSE);
						DATA_SET(global_data,"benchtest_total",GINT_TO_POINTER(((GINT)DATA_GET(global_data,"benchtest_total")+clock)));
					}
					else if (DATA_GET(output->data, "start")) /* start */
					{
						thread_update_logbar_f("libreems_benchtest_view",NULL,g_strdup_printf(_("Initiating LibreEMS Benchtest: Run time should be about %.1f seconds...\n"),clock/1000.0),FALSE,FALSE);
						id = g_timeout_add(500,benchtest_clock_update_wrapper,GINT_TO_POINTER(clock));
						DATA_SET(global_data,"benchtest_clock_id",GINT_TO_POINTER(id));
					}
					else if (DATA_GET(output->data, "stop")) /* stop */
						thread_update_logbar_f("libreems_benchtest_view",NULL,g_strdup_printf(_("Benchtest stopped by the user...\n")),FALSE,FALSE);

				}
				libreems_packet_cleanup(packet);
			}
			break;
		case GENERIC_FLASH_WRITE:
			packet = retrieve_packet(output->data,"FLASH_write_queue");
			goto handle_write;
			break;
		case GENERIC_RAM_WRITE:
			packet = retrieve_packet(output->data,"RAM_write_queue");
handle_write:
			if (packet)
			{
				/*printf("Packet arrived for GENERIC_RAM_WRITE case locID %i\n",locID);*/
				if (packet->is_nack)
				{
					printf("DATA Write Response PACKET NACK ERROR, rollback not implemented yet!!!!\n");
					message->status = FALSE;
				}
				update_write_status(data);
				libreems_packet_cleanup(packet);
			}
			else
			{
				printf("timeout, no packet found in GENERIC_[RAM|FLASH]_WRITE queue for sequence %i (%.2X), locID %i\n",seq,seq,locID);
				retry = initialize_outputdata_f();
				seq = atomic_sequence();
				DATA_SET(retry->data,"canID",DATA_GET(output->data,"canID"));
				DATA_SET(retry->data,"page",DATA_GET(output->data,"page"));
				DATA_SET(retry->data,"sequence_num",GINT_TO_POINTER(seq));
				DATA_SET(retry->data,"location_id",DATA_GET(output->data,"location_id"));
				DATA_SET(retry->data,"payload_id",DATA_GET(output->data,"payload_id"));
				DATA_SET(retry->data,"offset",DATA_GET(output->data,"offset"));
				DATA_SET(retry->data,"size",DATA_GET(output->data,"size"));
				DATA_SET(retry->data,"value",DATA_GET(output->data,"value"));
				DATA_SET(retry->data,"length",DATA_GET(output->data,"length"));
				DATA_SET(retry->data,"data",DATA_GET(output->data,"data"));
				DATA_SET(retry->data,"mode",DATA_GET(output->data,"mode"));
				queue = g_async_queue_new();
				register_packet_queue(SEQUENCE_NUM,queue,seq);
				DATA_SET(retry->data,"queue",queue);
				if (type == GENERIC_RAM_WRITE)
					io_cmd_f(firmware->write_command,retry);
				if (type == GENERIC_FLASH_WRITE)
					io_cmd_f("generic_FLASH_write",retry);
				printf("Re-issued command sent, seq %i!\n",seq);
			}
			break;
		case GENERIC_BURN:
			packet = retrieve_packet(output->data,"burn_queue");
			if (packet)
			{
				/*printf("Packet arrived for GENERIC_BURN case locID %i\n",locID);*/
				if (packet->is_nack)
				{
					printf("BURN Flash Response PACKET NACK ERROR. Ack! I Don't know what to do now!!!!\n");
					message->status = FALSE;
				}
				else
				{
					/*printf("burn success!\n");*/
					post_single_burn_pf(data);
				}
				update_write_status(data);
				libreems_packet_cleanup(packet);
			}
			else
			{
				printf("timeout, no packet found in GENERIC_BURN queue for sequence %i (%.2X), locID %i\n",seq,seq,locID);
				retry = initialize_outputdata_f();
				seq = atomic_sequence();
				DATA_SET(retry->data,"canID",DATA_GET(output->data,"canID"));
				DATA_SET(retry->data,"page",DATA_GET(output->data,"page"));
				DATA_SET(retry->data,"sequence_num",GINT_TO_POINTER(seq));
				DATA_SET(retry->data,"location_id",DATA_GET(output->data,"location_id"));
				DATA_SET(retry->data,"payload_id",DATA_GET(output->data,"payload_id"));
				DATA_SET(retry->data,"offset",DATA_GET(output->data,"offset"));
				DATA_SET(retry->data,"length",DATA_GET(output->data,"length"));
				DATA_SET(retry->data,"mode",DATA_GET(output->data,"mode"));
				queue = g_async_queue_new();
				register_packet_queue(SEQUENCE_NUM,queue,seq);
				DATA_SET(retry->data,"queue",queue);
				io_cmd_f(firmware->burn_command,retry);
			}
			break;
		case EMPTY_PAYLOAD:
			packet = retrieve_packet(output->data,NULL);
			queue = (GAsyncQueue *)DATA_GET(output->data,"queue");
			if (queue)
			{
				deregister_packet_queue(SEQUENCE_NUM,queue,seq);
				g_async_queue_unref(queue);
				DATA_SET(output->data,"queue",NULL);
			}
			if (packet)
			{
				payload_id = packet->payload_id;
				switch (payload_id)
				{
					case RESPONSE_FIRMWARE_VERSION:
						DATA_SET_FULL(global_data,"fw_version",g_strndup((const gchar *)(packet->data+packet->payload_base_offset),packet->payload_length),g_free);
						update_ecu_info();
						break;
					case RESPONSE_INTERFACE_VERSION:
						DATA_SET_FULL(global_data,"int_version",g_strndup((const gchar *)(packet->data+packet->payload_base_offset),packet->payload_length),g_free);
						update_ecu_info();
						break;
					case RESPONSE_DECODER_NAME:
						DATA_SET_FULL(global_data,"decoder_name",g_strndup((const gchar *)(packet->data+packet->payload_base_offset),packet->payload_length),g_free);
						update_ecu_info();
						break;
					case RESPONSE_FIRMWARE_BUILD_DATE:
						DATA_SET_FULL(global_data,"build_date",g_strndup((const gchar *)(packet->data+packet->payload_base_offset),packet->payload_length),g_free);
						update_ecu_info();
						break;
					case RESPONSE_FIRMWARE_COMPILER_VERSION:
						DATA_SET_FULL(global_data,"compiler",g_strndup((const gchar *)(packet->data+packet->payload_base_offset),packet->payload_length),g_free);
						update_ecu_info();
						break;
					case RESPONSE_FIRMWARE_COMPILER_OS:
						DATA_SET_FULL(global_data,"build_os",g_strndup((const gchar *)(packet->data+packet->payload_base_offset),packet->payload_length),g_free);
						update_ecu_info();
						break;
					default:
						printf("payload ID not matched, %i!\n",payload_id);
						break;
				}
				libreems_packet_cleanup(packet);
			}
			else
				printf("EMPTY PAYLOAD PACKET TIMEOUT, retry not implemented for this one yet!!\n");
			break;
		default:
			printf("MegaTunix does NOT know how to handle this packet response type..\n");
			break;
	}
	EXIT();
	return;
}