/*!
  \brief ECU specific toggle button handler
  \param widget is a pointer to the widget the user modified
  \param data is unused
  \returns TRUE
  */
G_MODULE_EXPORT gboolean ecu_toggle_button_handler(GtkWidget *widget, gpointer data)
{
	extern MS2_TTMon_Data *ttm_data;
	gint handler = -1;
	
	ENTER();
	handler = (GINT)OBJ_GET(widget,"handler");

	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
	{       /* It's pressed (or checked) */
		switch ((MS2ToggleHandler)handler)
		{

			case START_TOOTHMON_LOGGER:
				ttm_data->stop = FALSE;
				OBJ_SET(ttm_data->darea,"io_cmd_function",(gpointer)"ms2_e_read_toothmon");
				gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget_f("triggerlogger_buttons_table")),FALSE);
				gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget_f("compositelogger_buttons_table")),FALSE);
				bind_ttm_to_page((GINT)OBJ_GET(widget,"page"));
				io_cmd_f("ms2_e_read_toothmon",NULL);
				break;
			case START_TRIGMON_LOGGER:
				ttm_data->stop = FALSE;
				OBJ_SET(ttm_data->darea,"io_cmd_function",(gpointer)"ms2_e_read_trigmon");
				gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget_f("toothlogger_buttons_table")),FALSE);
				gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget_f("compositelogger_buttons_table")),FALSE);
				bind_ttm_to_page((GINT)OBJ_GET(widget,"page"));
				io_cmd_f("ms2_e_read_trigmon",NULL);
				break;
			case START_COMPOSITEMON_LOGGER:
				ttm_data->stop = FALSE;
				OBJ_SET(ttm_data->darea,"io_cmd_function",(gpointer)"ms2_e_read_compositemon");
				alter_widget_state_f(GTK_WIDGET(lookup_widget_f("toothlogger_buttons_table")),NULL);
				alter_widget_state_f(GTK_WIDGET(lookup_widget_f("triggerlogger_buttons_table")),NULL);
				bind_ttm_to_page((GINT)OBJ_GET(widget,"page"));
				io_cmd_f("ms2_e_read_compositemon",NULL);
				break;
			case STOP_TOOTHMON_LOGGER:
				ttm_data->stop = TRUE;
				gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget_f("triggerlogger_buttons_table")),TRUE);
				gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget_f("compositelogger_buttons_table")),TRUE);
				break;
			case STOP_TRIGMON_LOGGER:
				ttm_data->stop = TRUE;
				alter_widget_state_f(GTK_WIDGET(lookup_widget_f("toothlogger_buttons_table")),NULL);
				alter_widget_state_f(GTK_WIDGET(lookup_widget_f("compositelogger_buttons_table")),NULL);
				break;
			case STOP_COMPOSITEMON_LOGGER:
				ttm_data->stop = TRUE;
				alter_widget_state_f(GTK_WIDGET(lookup_widget_f("toothlogger_buttons_table")),NULL);
				alter_widget_state_f(GTK_WIDGET(lookup_widget_f("triggerlogger_buttons_table")),NULL);
				break;
			default:
				MTXDBG(CRITICAL,_("Default case reached,  i.e. handler not found in global, common or ECU plugins for widget %s, BUG!\n"),glade_get_widget_name(widget));
				break;
		}
	}
	EXIT();
	return TRUE;
}
/*!
  \brief  Burns all outstanding ECU pages to flash
  \param data is a pointer to a Command structure to be passed on the last
  call out
  \param func
  \returns TRUE on success, FALSE otherwise
  */
G_MODULE_EXPORT gboolean burn_all_helper(void *data, FuncCall func)
{
	OutputData *output = NULL;
	Command *command = NULL;
	gint last_page = 0;
	Firmware_Details *firmware = NULL;

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

	last_page = (GINT)DATA_GET(global_data,"last_page");

	if (last_page == -1)
	{
		command = (Command *)data;
		io_cmd_f(NULL,command->post_functions);
		EXIT();
		return TRUE;
	}
	/*printf("burn all helper\n");*/
	if ((firmware->capabilities & MS2) && (firmware->capabilities & MS1))
	{
		EXIT();
		return FALSE;
	}
	if (!DATA_GET(global_data,"offline"))
	{
		/* MS2 extra is slightly different as it's paged like MS1 */
		if (((firmware->capabilities & MS2_E) || (firmware->capabilities & MS1) || (firmware->capabilities & MS1_E)))
		{
			/*		printf("paged burn\n");*/
			output = initialize_outputdata_f();
			DATA_SET(output->data,"page",GINT_TO_POINTER(last_page));
			DATA_SET(output->data,"phys_ecu_page",GINT_TO_POINTER(firmware->page_params[last_page]->phys_ecu_page));
			DATA_SET(output->data,"canID",GINT_TO_POINTER(firmware->canID));
			DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
			io_cmd_f(firmware->burn_command,output);
		}
		else if ((firmware->capabilities & MS2) && (!(firmware->capabilities & MS2_E)))
		{
			/* MS2 std allows all pages to be in ram at will*/
			for (gint i=0;i<firmware->total_pages;i++)
			{
				if (!firmware->page_params[i]->dl_by_default)
					continue;
				output = initialize_outputdata_f();
				DATA_SET(output->data,"page",GINT_TO_POINTER(i));
				DATA_SET(output->data,"phys_ecu_page",GINT_TO_POINTER(firmware->page_params[i]->phys_ecu_page));
				DATA_SET(output->data,"canID",GINT_TO_POINTER(firmware->canID));
				DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
				io_cmd_f(firmware->burn_command,output);
			}
		}
	}
	command = (Command *)data;
	io_cmd_f(NULL,command->post_functions);
	EXIT();
	return TRUE;
}
Exemple #3
0
/*!
 \brief revert_to_previous_data() reverts the VEX import by using the backup
 of the internal datastructures.
 */
G_MODULE_EXPORT void revert_to_previous_data(void)
{
	gint canID=0;
	gint page=0;
	gint offset=0;
	gint total = 0;
	guchar *data = NULL;
	GModule *module = NULL;
	PostFunction *pf = NULL;
	GArray *pfuncs = NULL;
	guint8 **ecu_data_backup = NULL;
	/* Called to back out a load of a VEtable from VEX import */
	Firmware_Details *firmware = NULL;

	firmware = DATA_GET(global_data,"firmware");
	ecu_data_backup = firmware->ecu_data_backup;

	for (page=0;page<firmware->total_pages;page++)
	{
		if (!firmware->page_params[page]->dl_by_default)
			continue;
		if (firmware->chunk_support)
		{
			total = firmware->page_params[page]->length;
			data = g_new0(guchar,total);
			for (offset=0;offset<total;offset++)
				data[offset]=ms_get_ecu_data_backup(canID,page,offset,MTX_U08);
			ms_chunk_write(canID,page,0,total,data);

		}
		else
		{
			for (offset = 0;offset<firmware->page_params[page]->length;offset++)
			{
				if (ms_get_ecu_data_backup(canID,page,offset,MTX_U08) != ms_get_ecu_data(canID,page,offset,MTX_U08))
				{
					ms_send_to_ecu(canID,page,offset,MTX_U08,ecu_data_backup[page][offset], FALSE);
				}
			}
		}
	}
	module = g_module_open(NULL,G_MODULE_BIND_LAZY);
	pfuncs = g_array_new(FALSE,TRUE,sizeof(PostFunction *));

	pf = g_new0(PostFunction,1);
	pf->name = g_strdup("update_ecu_controls_pf");
	if (module)
		g_module_symbol(module,pf->name,(void *)&pf->function);
	pf->w_arg = FALSE;
	pfuncs = g_array_append_val(pfuncs,pf);
	g_module_close(module);
	io_cmd_f(NULL,pfuncs);

	gtk_widget_set_sensitive(lookup_widget_f("tools_undo_vex_button"),FALSE);
	update_logbar_f("tools_view","warning",_("Reverting to previous settings....\n"),FALSE,FALSE,FALSE);
	io_cmd_f(firmware->burn_all_command,NULL);
}
/*!
  \brief This handler is called to issue packets to read each ECU page in turn
  then pass the original post functions to run.
  */
G_MODULE_EXPORT gboolean read_libreems_data(void *data, FuncCall type)
{
	static Firmware_Details *firmware = NULL;
	OutputData *output = NULL;
	Command *command = NULL;
	gint seq = 0;
	GAsyncQueue *queue = NULL;
	gint i = 0;

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

	switch (type)
	{
		case LIBREEMS_ALL:
			if (!DATA_GET(global_data,"offline"))
			{
				g_list_foreach(get_list_f("get_data_buttons"),set_widget_sensitive_f,GINT_TO_POINTER(FALSE));
				for (i=0;i<firmware->total_pages;i++)
				{
					if (!firmware->page_params[i]->dl_by_default)
						continue;
					seq = atomic_sequence();
					output = initialize_outputdata_f();
					DATA_SET(output->data,"canID",GINT_TO_POINTER(firmware->canID));
					DATA_SET(output->data,"sequence_num",GINT_TO_POINTER(seq));
					DATA_SET(output->data,"location_id",GINT_TO_POINTER(firmware->page_params[i]->phys_ecu_page));
					DATA_SET(output->data,"payload_id",GINT_TO_POINTER(REQUEST_RETRIEVE_BLOCK_FROM_RAM));
					DATA_SET(output->data,"offset", GINT_TO_POINTER(0));
					DATA_SET(output->data,"num_wanted", GINT_TO_POINTER(firmware->page_params[i]->length));
					DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
					queue = g_async_queue_new();
					register_packet_queue(SEQUENCE_NUM,queue,seq);
					DATA_SET(output->data,"queue",queue);
					io_cmd_f(firmware->read_command,output);
				}
			}
			command = (Command *)data;
			io_cmd_f(NULL,command->post_functions);
			break;
		default:
			printf("default case, nothing happening here\n");
			break;
	}
	EXIT();
	return TRUE;
}
/*! 
  \brief tells ms2 to fully reboot 
  \param widget is unused
  \param data is unused
 */
G_MODULE_EXPORT gboolean ms2_reboot(GtkWidget *widget, gpointer data)
{
	ENTER();
	io_cmd_f("ms2_reboot",NULL);
	EXIT();
	return TRUE;
}
Exemple #6
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;
}
/*!
  \brief Sends a packet to soft-boot the ECU
  */
G_MODULE_EXPORT void soft_boot_ecu(void)
{
	OutputData *output = NULL;
	ENTER();
	output = initialize_outputdata_f();
	DATA_SET(output->data,"payload_id",GINT_TO_POINTER(REQUEST_SOFT_SYSTEM_RESET));
	io_cmd_f("empty_payload_pkt",output);
	EXIT();
	return;
}
/*!
  \brief Sends a packet to rest the ECU counters
  */
G_MODULE_EXPORT void reset_counters(void)
{
	OutputData *output = NULL;
	ENTER();
	output = initialize_outputdata_f();
	DATA_SET(output->data,"payload_id",GINT_TO_POINTER(REQUEST_CLEAR_COUNTERS_AND_FLAGS_TO_ZERO));
	io_cmd_f("empty_payload_pkt",output);

	EXIT();
	return;
}
Exemple #9
0
/*!
 \brief ms2_ttm_update is a function called by a watch that was set looking
 for the state of a particular variable. When that var is set this function
 is fired off to take care of updating the MS2 TTM display
 \param watch is the pointer to the watch structure
 */
G_MODULE_EXPORT void ms2_ttm_update(RtvWatch *watch)
{
	ENTER();
	ms2_crunch_trigtooth_data();
	ms2_update_trigtooth_display();
	if (ttm_data->stop)
	{
		EXIT();
		return;
	}
	io_cmd_f((gchar *)OBJ_GET(ttm_data->darea,"io_cmd_function"),NULL);
	EXIT();
	return;
}
Exemple #10
0
/*!
 \brief Issues a packet to the ECU to get its interface version. 
 \param length is a pointer to a location to store the length of the data
 received, or NULL
 \returns the Firmware interface version as a text string
 */
G_MODULE_EXPORT void request_interface_version()
{
	OutputData *output = NULL;
	GAsyncQueue *queue = NULL;
	gint seq = atomic_sequence();
	output = initialize_outputdata_f();
	queue = g_async_queue_new();
	//register_packet_queue(PAYLOAD_ID,queue,RESPONSE_INTERFACE_VERSION);
	register_packet_queue(SEQUENCE_NUM,queue,seq);
	DATA_SET(output->data,"sequence_num",GINT_TO_POINTER(seq));
	DATA_SET(output->data,"payload_id",GINT_TO_POINTER(REQUEST_INTERFACE_VERSION));
	DATA_SET(output->data,"queue",queue);
	io_cmd_f("empty_payload_pkt",output);
	return;
}
Exemple #11
0
/*!
 \brief Issues a packet to the ECU to get its build os
 \param length is a pointer to a location to store the length of the data
 received, or NULL
 \returns the Firmware version as a text string
 */
G_MODULE_EXPORT void request_firmware_build_os()
{
	OutputData *output = NULL;
	GAsyncQueue *queue = NULL;
	gint seq = atomic_sequence();
	output = initialize_outputdata_f();
	queue = g_async_queue_new();
	//register_packet_queue(PAYLOAD_ID,queue,RESPONSE_FIRMWARE_COMPILER_OS);
	register_packet_queue(SEQUENCE_NUM,queue,seq);
	DATA_SET(output->data,"sequence_num",GINT_TO_POINTER(seq));
	DATA_SET(output->data,"payload_id",GINT_TO_POINTER(REQUEST_FIRMWARE_COMPILER_OS));
	DATA_SET(output->data,"queue",queue);
	io_cmd_f("empty_payload_pkt",output);
	return;
}
Exemple #12
0
/*!
  \brief Sends a packet to start the datalog streaming from the ECU
  */
G_MODULE_EXPORT void start_streaming(void)
{
	OutputData *output = NULL;
	GByteArray *payload = NULL;
	guint8 byte = 1;/* Start streaming */

	ENTER();
	output = initialize_outputdata_f();
	payload = g_byte_array_new();
	g_byte_array_append(payload,&byte,1);
	DATA_SET(output->data,"payload_id",GINT_TO_POINTER(REQUEST_SET_ASYNC_DATALOG_TYPE));
	DATA_SET(output->data,"payload_data_array",payload);
	io_cmd_f("basic_payload_pkt",output);
	EXIT();
	return;
}
Exemple #13
0
/*! 
  \brief Per firmware plugin function to signal a request for ECU Runtime vars
  */
G_MODULE_EXPORT void signal_read_rtvars(void)
{
	OutputData *output = NULL;	
	Firmware_Details *firmware = NULL;

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

	output = initialize_outputdata_f();
	DATA_SET(output->data,"sequence_num",GINT_TO_POINTER(1));
	DATA_SET(output->data,"payload_id",GINT_TO_POINTER(REQUEST_BASIC_DATALOG));
	DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
	io_cmd_f(firmware->rt_command,output);
	EXIT();
	return;
}
Exemple #14
0
/*!
  \brief post function to issue a read of all ECU data
  */
G_MODULE_EXPORT void spawn_read_all_pf(void)
{
	Firmware_Details *firmware = NULL;

	ENTER();
	firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");
	if (!firmware)
	{
		EXIT();
		return;
	}

	set_title_f(g_strdup(_("Queuing read of all ECU data...")));
	io_cmd_f(firmware->get_all_command,NULL);
	EXIT();
	return;
}
Exemple #15
0
/*!
  \brief handler to issue the needed calls to burn every outstanding page
  to ECU flash
  \param data is a pointer to an Io_Message structure
  \param type is theFuncCall enumeration
  \see Io_Message
  \see FuncCall
  */
G_MODULE_EXPORT gboolean libreems_burn_all(void *data, FuncCall type)
{
	OutputData *output = NULL;
	Command *command = NULL;
	gint last_page = 0;
	Firmware_Details *firmware = NULL;

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

	/*printf("burn all helper\n");*/
	if (!DATA_GET(global_data,"offline"))
	{
		/* LibreEMS allows all pages to be in ram at will*/
		for (gint i=0;i<firmware->total_pages;i++)
		{
			if (firmware->page_params[i]->read_only)
				continue;
			if (firmware->page_params[i]->needs_burn)
			{
				output = initialize_outputdata_f();
				/*printf("Burning page %i (locid %i)\n",i,firmware->page_params[i]->phys_ecu_page);*/
				DATA_SET(output->data,"canID",GINT_TO_POINTER(firmware->canID));
				DATA_SET(output->data,"page",GINT_TO_POINTER(i));
				DATA_SET(output->data,"location_id",GINT_TO_POINTER(firmware->page_params[i]->phys_ecu_page));
				DATA_SET(output->data,"payload_id",GINT_TO_POINTER(REQUEST_BURN_BLOCK_FROM_RAM_TO_FLASH));
				DATA_SET(output->data,"offset",GINT_TO_POINTER(0));
				DATA_SET(output->data,"length",GINT_TO_POINTER(firmware->page_params[i]->length));
				DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
				io_cmd_f(firmware->burn_command,output);
			}
		}
	}
	EXIT();
	return TRUE;
}
Exemple #16
0
/*!
 \brief restore_all_ecu_settings() reads the filename passed and if all checks
 pass the file will be loaded and any values that differ from the values
 currently in the ECU will be replaced.
 \param filename (filename to read for ecu restoration
WARNING:  This function is not yet capable of handling CAN devices, and will
always restore to can ID ZERO (which can be BAD!!), backup/restore needs to
be rewritten..
 */
G_MODULE_EXPORT void restore_all_ecu_settings(gchar *filename)
{
	ConfigFile *cfgfile;
	/*
	GArray *pfuncs = NULL;
	PostFunction *pf = NULL;
	*/
	gchar * section = NULL;
	gchar * msgbuf = NULL;
	gint canID = 0;
	DataSize size = MTX_U08;
	gint page = 0;
	gint offset = 0;
	gint tmpi = 0;
	gint major = 0;
	gint minor = 0;
	gboolean restart = FALSE;
	gchar *tmpbuf = NULL;
	guint8 *data = NULL;
	gchar **keys = NULL;
	gint num_keys = 0;
	gint dload_val = 0;
	PostFunction *pf = NULL;
	GArray *pfuncs = NULL;
	extern gconstpointer *global_data;
	Firmware_Details *firmware = NULL;

	firmware = DATA_GET(global_data,"firmware");
	g_return_if_fail(filename);
	g_return_if_fail(firmware);
	canID = firmware->canID;

	cfgfile = cfg_open_file(filename);
	if (!cfgfile)
	{
		update_logbar_f("tools_view","warning",g_strdup_printf(_(":restore_all_ecu_settings()\n\t Unable to open this file (%s)\n"),filename),FALSE,FALSE,TRUE);
		return;
	}
	if (cfgfile)
	{
		get_file_api_f(cfgfile,&major,&minor);
		if (major != BACKUP_MAJOR_API) 
		{
			update_logbar_f("tools_view","warning",g_strdup_printf(_(":restore_all_ecu_settings()\n\tAPI MAJOR version mismatch: \"%i\" != \"%i\"\n can not load this file for restoration\n"),major,BACKUP_MAJOR_API),FALSE,FALSE,TRUE);
			cfg_free(cfgfile);
			return;
		}
		if (minor != BACKUP_MINOR_API) 
			update_logbar_f("tools_view","warning",g_strdup_printf(_(": restore_all_ecu_settings()\n\tAPI MINOR version mismatch: \"%i\" != \"%i\"\n Will try to load this file for restoration, expect issues\n"),minor,BACKUP_MINOR_API),FALSE,FALSE,TRUE);

		cfg_read_string(cfgfile,"Firmware","name",&tmpbuf);
		if (g_ascii_strcasecmp(g_strdelimit(tmpbuf," ,",'_'),g_strdelimit(firmware->name," ,",'_')) != 0)
		{
			dbg_func_f(CRITICAL,g_strdup_printf(__FILE__": restore_all_ecu_settings()\nFirmware name mismatch:\n\"%s\" != \"%s\",\ncannot load this file for restoration\n",tmpbuf,firmware->name));

			update_logbar_f("tools_view","warning",g_strdup_printf(_(": restore_all_ecu_settings()\nFirmware name mismatch: \"%s\" != \"%s\"\ncan NOT load this file for restoration!\n"),tmpbuf,firmware->name),FALSE,FALSE,TRUE);
			if (tmpbuf)
				g_free(tmpbuf);
			cfg_free(cfgfile);
			return;
		}
		g_free(tmpbuf);
		set_title_f(g_strdup(_("Restoring ECU settings from File")));
		if (DATA_GET(global_data,"realtime_id"))
		{
			stop_tickler_f(RTV_TICKLER);
			restart = TRUE;
		}
		for (page=0;page<firmware->total_pages;page++)
		{
			if (!(firmware->page_params[page]->dl_by_default))
				continue;

			section = g_strdup_printf("page_%i",page);
			if(cfg_read_int(cfgfile,section,"num_variables",&tmpi))
				if (tmpi != firmware->page_params[page]->length)
				{
					update_logbar_f("tools_view","warning",g_strdup_printf(_(": restore_all_ecu_settings()\n\tNumber of variables in backup \"%i\" and firmware specification \"%i\" do NOT match,\n\tcorruption SHOULD be expected\n"),tmpi,firmware->page_params[page]->length),FALSE,FALSE,TRUE);
					dbg_func_f(CRITICAL,g_strdup_printf(_(": restore_all_ecu_settings()\n\tNumber of variables in backup \"%i\" and firmware specification \"%i\" do NOT match,\n\tcorruption SHOULD be expected\n"),tmpi,firmware->page_params[page]->length));
				}
			if (cfg_read_string(cfgfile,section,"data",&tmpbuf))
			{
				keys = parse_keys_f(tmpbuf,&num_keys,",");
				if (num_keys != firmware->page_params[page]->length)
				{
					update_logbar_f("tools_view","warning",g_strdup_printf(_(": restore_all_ecu_settings()\n\tNumber of variables in this backup \"%i\" does NOT match the length of the table \"%i\", expect a crash!!!\n"),num_keys,firmware->page_params[page]->length),FALSE,FALSE,TRUE);
					dbg_func_f(CRITICAL,g_strdup_printf(_(": restore_all_ecu_settings()\n\tNumber of variables in this backup \"%i\" does NOT match the length of the table \"%i\", expect a crash!!!\n"),num_keys,firmware->page_params[page]->length));
				}
				if (firmware->chunk_support)
				{
					data = g_new0(guint8, firmware->page_params[page]->length);
					for (offset=0;offset<num_keys;offset++)
						data[offset]=(guint8)atoi(keys[offset]);
					if (DATA_GET(global_data,"offline"))
						ms_store_new_block(canID,page,0,data,num_keys);
					else
						ms_chunk_write(canID,page,0,num_keys,data);
				}
				else
				{
					if (DATA_GET(global_data,"offline"))
					{
						for (offset=0;offset<num_keys;offset++)
						{
							dload_val = atoi(keys[offset]);
							ms_set_ecu_data(canID,page,offset,size,dload_val);
						}
					}
					else
					{
						for (offset=0;offset<num_keys;offset++)
						{
							dload_val = atoi(keys[offset]);
							if (dload_val != ms_get_ecu_data_last(canID,page,offset,size))
							{
								/*printf("writing data for page %i, offset %i\n",page,offset);*/
								ms_send_to_ecu(canID,page,offset,size,dload_val, FALSE);
							}
						}
						queue_burn_ecu_flash(page);
					}
				}
				g_strfreev(keys);
				g_free(tmpbuf);
			}
			g_free(section);
		}
		start_restore_monitor();
		cfg_free(cfgfile);
	}
	if (DATA_GET(global_data,"offline"))
	{
		pfuncs = g_array_new(FALSE,TRUE,sizeof(PostFunction *));
		pf = g_new0(PostFunction,1);
		pf->name = g_strdup("update_ecu_controls_pf");
		get_symbol_f(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("set_store_black_pf");
		get_symbol_f(pf->name,(void *)&pf->function);
		pf->w_arg = FALSE;
		pfuncs = g_array_append_val(pfuncs,pf);

		io_cmd_f(NULL,pfuncs);
	}
	if (restart)
		start_tickler_f(RTV_TICKLER);
}
Exemple #17
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;
}
Exemple #18
0
/*!
  \brief function to do the actual read calls from the ECU
  \param data is a pointer to the Command structure
  \param func is an enumeration for the type of function
  \returns TRUE on success, FASE otherwise
  */
G_MODULE_EXPORT gboolean read_ve_const(void *data, FuncCall func)
{
	gint last_page;
	OutputData *output = NULL;
	Command *command = NULL;
	gint i = 0;
	Firmware_Details *firmware = NULL;

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

	last_page = (GINT)DATA_GET(global_data,"last_page");
	switch (func)
	{
		case MS1_VECONST:

			if (!DATA_GET(global_data,"offline"))
			{
				g_list_foreach(get_list_f("get_data_buttons"),set_widget_sensitive_f,GINT_TO_POINTER(FALSE));

				for (i=0;i<firmware->total_pages;i++)
					if (firmware->page_params[i]->needs_burn)
						queue_burn_ecu_flash(i);
				for (i=0;i<firmware->total_pages;i++)
				{
					if (!firmware->page_params[i]->dl_by_default)
						continue;
					queue_ms1_page_change(i);
					output = initialize_outputdata_f();
					DATA_SET(output->data,"page",GINT_TO_POINTER(i));
					DATA_SET(output->data,"phys_ecu_page",GINT_TO_POINTER(firmware->page_params[i]->phys_ecu_page));
					DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
					io_cmd_f(firmware->read_command,output);
				}
			}
			command = (Command *)data;
			io_cmd_f(NULL,command->post_functions);
			break;
		case MS2_VECONST:
			if (!DATA_GET(global_data,"offline"))
			{
				g_list_foreach(get_list_f("get_data_buttons"),set_widget_sensitive_f,GINT_TO_POINTER(FALSE));
				for (i=0;i<firmware->total_pages;i++)
					if (firmware->page_params[i]->needs_burn)
						queue_burn_ecu_flash(i);
				for (i=0;i<firmware->total_pages;i++)
				{
					if (!firmware->page_params[i]->dl_by_default)
						continue;
					output = initialize_outputdata_f();
					DATA_SET(output->data,"page",GINT_TO_POINTER(i));
					DATA_SET(output->data,"phys_ecu_page",GINT_TO_POINTER(firmware->page_params[i]->phys_ecu_page));
					DATA_SET(output->data,"canID",GINT_TO_POINTER(firmware->canID));
					DATA_SET(output->data,"offset", GINT_TO_POINTER(0));
					DATA_SET(output->data,"num_bytes", GINT_TO_POINTER(firmware->page_params[i]->length));
					DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
					io_cmd_f(firmware->read_command,output);
				}
			}
			command = (Command *)data;
			io_cmd_f(NULL,command->post_functions);
			break;
		case MS2_E_COMPOSITEMON:
			if (!DATA_GET(global_data,"offline"))
			{
				if (firmware->capabilities & MS2_E)
				{
					for (i=0;i<firmware->total_pages;i++)
						if (firmware->page_params[i]->needs_burn)
							queue_burn_ecu_flash(i);
				}
				output = initialize_outputdata_f();
				DATA_SET(output->data,"page",GINT_TO_POINTER(firmware->compositemon_page));
				DATA_SET(output->data,"phys_ecu_page",GINT_TO_POINTER(firmware->page_params[firmware->compositemon_page]->phys_ecu_page));
				DATA_SET(output->data,"canID",GINT_TO_POINTER(firmware->canID));
				DATA_SET(output->data,"offset", GINT_TO_POINTER(0));
				DATA_SET(output->data,"num_bytes", GINT_TO_POINTER(firmware->page_params[firmware->compositemon_page]->length));
				DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
				io_cmd_f(firmware->read_command,output);
			}
			command = (Command *)data;
			io_cmd_f(NULL,command->post_functions);
			break;
		case MS2_E_TRIGMON:
			if (!DATA_GET(global_data,"offline"))
			{
				if (firmware->capabilities & MS2_E)
				{
					for (i=0;i<firmware->total_pages;i++)
						if (firmware->page_params[i]->needs_burn)
							queue_burn_ecu_flash(i);
				}
				output = initialize_outputdata_f();
				DATA_SET(output->data,"page",GINT_TO_POINTER(firmware->trigmon_page));
				DATA_SET(output->data,"phys_ecu_page",GINT_TO_POINTER(firmware->page_params[firmware->trigmon_page]->phys_ecu_page));
				DATA_SET(output->data,"canID",GINT_TO_POINTER(firmware->canID));
				DATA_SET(output->data,"offset", GINT_TO_POINTER(0));
				DATA_SET(output->data,"num_bytes", GINT_TO_POINTER(firmware->page_params[firmware->trigmon_page]->length));
				DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
				io_cmd_f(firmware->read_command,output);
			}
			command = (Command *)data;
			io_cmd_f(NULL,command->post_functions);
			break;
		case MS2_E_TOOTHMON:
			if (!DATA_GET(global_data,"offline"))
			{
				if (firmware->capabilities & MS2_E)
				{
					for (i=0;i<firmware->total_pages;i++)
						if (firmware->page_params[i]->needs_burn)
							queue_burn_ecu_flash(i);
				}
				output = initialize_outputdata_f();
				DATA_SET(output->data,"page",GINT_TO_POINTER(firmware->toothmon_page));
				DATA_SET(output->data,"phys_ecu_page",GINT_TO_POINTER(firmware->page_params[firmware->toothmon_page]->phys_ecu_page));
				DATA_SET(output->data,"canID",GINT_TO_POINTER(firmware->canID));
				DATA_SET(output->data,"offset", GINT_TO_POINTER(0));
				DATA_SET(output->data,"num_bytes", GINT_TO_POINTER(firmware->page_params[firmware->toothmon_page]->length));
				DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
				io_cmd_f(firmware->read_command,output);
			}
			command = (Command *)data;
			io_cmd_f(NULL,command->post_functions);
			break;
		case MS1_E_TRIGMON:
			if (!DATA_GET(global_data,"offline"))
			{
				for (i=0;i<firmware->total_pages;i++)
					if (firmware->page_params[i]->needs_burn)
						queue_burn_ecu_flash(i);
				queue_ms1_page_change(firmware->trigmon_page);
				output = initialize_outputdata_f();
				DATA_SET(output->data,"page",GINT_TO_POINTER(firmware->trigmon_page));
				DATA_SET(output->data,"phys_ecu_page",GINT_TO_POINTER(firmware->page_params[firmware->trigmon_page]->phys_ecu_page));
				DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
				io_cmd_f(firmware->read_command,output);
				command = (Command *)data;
				io_cmd_f(NULL,command->post_functions);
			}
			break;
		case MS1_E_TOOTHMON:
			if (!DATA_GET(global_data,"offline"))
			{
				for (i=0;i<firmware->total_pages;i++)
					if (firmware->page_params[i]->needs_burn)
						queue_burn_ecu_flash(i);
				queue_ms1_page_change(firmware->toothmon_page);
				output = initialize_outputdata_f();
				DATA_SET(output->data,"page",GINT_TO_POINTER(firmware->toothmon_page));
				DATA_SET(output->data,"phys_ecu_page",GINT_TO_POINTER(firmware->page_params[firmware->toothmon_page]->phys_ecu_page));
				DATA_SET(output->data,"mode", GINT_TO_POINTER(MTX_CMD_WRITE));
				io_cmd_f(firmware->read_command,output);
				command = (Command *)data;
				io_cmd_f(NULL,command->post_functions);
			}
			break;
		default:
			break;
	}
	EXIT();
	return TRUE;
}
Exemple #19
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;
}
Exemple #20
0
/*!
 \brief feed_import_data_to_ecu() Forwards the data in the VEX file to the
 ECU.  NOTE this may have problems with firmware using multiple tables in
 a page, as the VEX format 1.0 does NOT handle that condition.
 \param vex (Vex_Import *) pointer to the Vex_Impot datastructure.
 */
G_MODULE_EXPORT void feed_import_data_to_ecu(Vex_Import *vex)
{
	gint i = 0;
	gchar *tmpbuf = NULL;
	guint8 **ecu_data = NULL;
	guint8 **ecu_data_backup = NULL;
	void *data = NULL;
	gchar * msgbuf = NULL;
	guchar *ptr = NULL;
	guint16 *ptr16 = NULL;
	guint32 *ptr32 = NULL;
	gint total = 0;
	gint canID = 0;
	gint page = -1;
	gint base = 0;
	DataSize size = 0;
	gint mult = 0;
	gint table = -1;
	Firmware_Details *firmware = NULL;

	firmware = DATA_GET(global_data,"firmware");

	ecu_data = firmware->ecu_data;
	ecu_data_backup = firmware->ecu_data_backup;

	/* Since we assume the page is where the table is this can cause
	 * major problems with some firmwares that use two tables inside
	 * of one page....
	 */
	page = vex->page;
	table = vex->table;
	if ((table < 0) || (table >= firmware->total_tables))
	{
		dbg_func_f(CRITICAL,g_strdup_printf(__FILE__": feed_import_data_to_ecu()\n\ttable passed (%i) is out of range(%i)\n",table,firmware->total_tables));
		return;
	}

	/* If dimensions do NOT match, ABORT!!! */
	if (firmware->table_params[table]->x_bincount != vex->total_x_bins)
	{
		msgbuf = g_strdup_printf(_("VEX Import: number of RPM bins inside VEXfile and FIRMWARE DO NOT MATCH (%i!=%i), aborting!!!\n"),firmware->table_params[table]->x_bincount,vex->total_x_bins);
		update_logbar_f("tools_view","warning",msgbuf,FALSE,FALSE,FALSE);
		dbg_func_f(CRITICAL,g_strdup(msgbuf));
		g_free(msgbuf);
		return;
	}
	if (firmware->table_params[table]->y_bincount != vex->total_y_bins)
	{
		msgbuf = g_strdup_printf(_("VEX Import: number of LOAD bins inside VEXfile and FIRMWARE DO NOT MATCH (%i!=%i), aborting!!!\n"),firmware->table_params[table]->y_bincount,vex->total_y_bins);
		update_logbar_f("tools_view","warning",msgbuf,FALSE,FALSE,FALSE);
		dbg_func_f(CRITICAL,g_strdup(msgbuf));
		g_free(msgbuf);
		return;
	}

	/* Backup the ALL pages of data first... */
	for (i=0;i<firmware->total_pages;i++)
	{
		if (!firmware->page_params[i]->dl_by_default)
			continue;
		memset((void *)ecu_data_backup[i], 0, firmware->page_params[i]->length);
		memcpy(ecu_data_backup[i], ecu_data[i],firmware->page_params[i]->length);
	}

	canID = firmware->canID;
	page = firmware->table_params[table]->x_page;
	base = firmware->table_params[table]->x_base;
	size = firmware->table_params[table]->x_size;
	mult = get_multiplier_f(size);
	if (firmware->chunk_support)
	{
		total = vex->total_x_bins;
		data = g_malloc0(mult*total);;
		if (mult == 1)
		{
			ptr = (guchar *)data;
			for (i=0;i<total;i++)
				ptr[i]=vex->x_bins[i];
		}
		if (mult == 2)
		{
			ptr16 = (guint16 *)data;
			for (i=0;i<total;i++)
			{
				if (firmware->bigendian)
					ptr16[i]=GINT16_TO_BE(vex->x_bins[i]);
				else
					ptr16[i]=GINT16_TO_LE(vex->x_bins[i]);
			}
		}
		if (mult == 4)
		{
			ptr32 = (guint32 *)data;
			for (i=0;i<total;i++)
			{
				if (firmware->bigendian)
					ptr32[i]=GINT_TO_BE(vex->x_bins[i]);
				else
					ptr32[i]=GINT_TO_LE(vex->x_bins[i]);
			}
		}
		ms_chunk_write(canID,page,base,(total*mult),data);
	}
	else
	{
		for (i=0;i<vex->total_x_bins;i++)
		{
			if (vex->x_bins[i] != ms_get_ecu_data_last(canID,page,base+(i*mult),size))
				ms_send_to_ecu(canID,page,base+i,size, vex->x_bins[i], TRUE);
		}
	}

	canID = firmware->canID;
	page = firmware->table_params[table]->y_page;
	base = firmware->table_params[table]->y_base;
	size = firmware->table_params[table]->y_size;
	mult = get_multiplier_f(size);
	if (firmware->chunk_support)
	{
		total = vex->total_y_bins;
		data = g_malloc0(mult*total);
		if (mult == 1)
		{
			ptr = (guchar *)data;
			for (i=0;i<total;i++)
				ptr[i]=vex->y_bins[i];
		}
		if (mult == 2)
		{
			ptr16 = (guint16 *)data;
			for (i=0;i<total;i++)
			{
				if (firmware->bigendian)
					ptr16[i]=GINT16_TO_BE(vex->y_bins[i]);
				else
					ptr16[i]=GINT16_TO_LE(vex->y_bins[i]);
			}
		}
		if (mult == 4)
		{
			ptr32 = (guint32 *)data;
			for (i=0;i<total;i++)
			{
				if (firmware->bigendian)
					ptr32[i]=GINT_TO_BE(vex->y_bins[i]);
				else
					ptr32[i]=GINT_TO_LE(vex->y_bins[i]);
			}
		}
		ms_chunk_write(canID,page,base,(total*mult),data);
	}
	else
	{
		for (i=0;i<vex->total_y_bins;i++)
		{
			if (vex->y_bins[i] != ms_get_ecu_data_last(canID,page,base+i,size))
				ms_send_to_ecu(canID,page,base+(i*mult),size,vex->y_bins[i], TRUE);
		}
	}

	canID = firmware->canID;
	page = firmware->table_params[table]->z_page;
	base = firmware->table_params[table]->z_base;
	size = firmware->table_params[table]->z_size;
	mult = get_multiplier_f(size);
	if (firmware->chunk_support)
	{
		total = (vex->total_y_bins)*(vex->total_x_bins);
		data = g_malloc0(mult*total);
		if (mult == 1)
		{
			ptr = (guchar *)data;
			for (i=0;i<total;i++)
				ptr[i]=vex->tbl_bins[i];
		}
		if (mult == 2)
		{
			ptr16 = (guint16 *)data;
			for (i=0;i<total;i++)
			{
				if (firmware->bigendian)
					ptr16[i]=GINT16_TO_BE(vex->tbl_bins[i]);
				else
					ptr16[i]=GINT16_TO_LE(vex->tbl_bins[i]);
			}
		}
		if (mult == 4)
		{
			ptr32 = (guint32 *)data;
			for (i=0;i<total;i++)
			{
				if (firmware->bigendian)
					ptr32[i]=GINT_TO_BE(vex->tbl_bins[i]);
				else
					ptr32[i]=GINT_TO_LE(vex->tbl_bins[i]);
			}
		}
		ms_chunk_write(canID,page,base,(total*mult),data);
	}
	else
	{
		for (i=0;i<((vex->total_y_bins)*(vex->total_x_bins));i++)
		{
			if (vex->tbl_bins[i] != ms_get_ecu_data_last(canID,page,base+i,size))
				ms_send_to_ecu(canID,page,base+(i*mult),size,vex->tbl_bins[i], TRUE);
		}
	}
	io_cmd_f(firmware->burn_all_command,NULL);

	tmpbuf = g_strdup_printf(_("VEX Import: VEtable on page %i updated with data from the VEX file\n"),vex->page);
	update_logbar_f("tools_view",NULL,tmpbuf,FALSE,FALSE,FALSE);
	g_free(tmpbuf);
}