Esempio n. 1
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);
}
Esempio n. 2
0
/*!
  \brief handles a simple read result
  \param data is a pointer to a Io_Message structure
  \param func is an enum representing the action we need to handle
  */
G_MODULE_EXPORT void simple_read_hf(void * data, FuncCall func)
{
	static guint16 lastcount = 0;
	static gboolean just_starting = TRUE;
	Io_Message *message  = NULL;
	OutputData *output  = NULL;
	gint count = 0;
	gchar *tmpbuf = NULL;
	gint page = -1;
	gint canID = -1;
	gint tmpi = 0;
	gint adder = 0;
	gboolean check_header = FALSE;
	gint base_offset = 0;
	guint16 curcount = 0;
	guint8 *ptr8 = NULL;
	guint16 *ptr16 = NULL;
	Firmware_Details *firmware = NULL;
	Serial_Params *serial_params = NULL;

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

	g_return_if_fail(serial_params);
	g_return_if_fail(firmware);

	message = (Io_Message *)data;
	output = (OutputData *)message->payload;
	if (firmware->capabilities & MS3_NEWSERIAL)
	{
		check_header = TRUE;
		adder = 7;
		base_offset = 3;
	}

	switch (func)
	{
		case WRITE_VERIFY:
			printf(_("MS2_WRITE_VERIFY not written yet\n"));
			break;
		case MISMATCH_COUNT:
			printf(_("MS2_MISMATCH_COUNT not written yet\n"));
			break;
		case MS1_CLOCK:
			printf(_("MS1_CLOCK not written yet\n"));
			break;
		case MS2_CLOCK:
			printf(_("MS2_CLOCK not written yet\n"));
			break;
		case NUM_REV:
			if (DATA_GET(global_data,"offline"))
				break;
			count = read_data_f(-1,&message->recv_buf,FALSE);
			if (count > adder)
			{
				ptr8 = (guchar *)message->recv_buf;
				firmware->ecu_revision=(gint)ptr8[0+base_offset];
				ecu_info_update(firmware);
			}
			break;
		case TEXT_REV:
			if (DATA_GET(global_data,"offline"))
				break;
			count = read_data_f(-1,&message->recv_buf,FALSE);
			if (count > adder)
			{
				if (check_header)
				{
					if (message->recv_buf[2] & 0x80)
					{
						MTXDBG(CRITICAL,_("TextRev read error: specifically 0X%x\n"),message->recv_buf[2]);
						flush_serial_f(serial_params->fd,BOTH);
						break;
					}
				}
				firmware->txt_rev_len = count-adder;
				firmware->text_revision = g_markup_escape_text((const gchar *)message->recv_buf+base_offset,count-adder);
				ecu_info_update(firmware);
			}
			break;
		case SIGNATURE:
			if (DATA_GET(global_data,"offline"))
				break;
			count = read_data_f(-1,&message->recv_buf,FALSE);
			if (count > adder)
			{
				if (check_header)
				{
					if (message->recv_buf[2] & 0x80)
					{
						MTXDBG(CRITICAL,_("Signature read error: specifically 0X%x\n"),message->recv_buf[2]);
						flush_serial_f(serial_params->fd,BOTH);
						break;
					}
				}
				firmware->signature_len = count-adder;
				firmware->actual_signature = g_markup_escape_text((const gchar *)message->recv_buf+base_offset,count-adder);
				ecu_info_update(firmware);
			}
			break;
		case MS1_VECONST:
		case MS2_VECONST:
			page = (GINT)DATA_GET(output->data,"page");
			canID = (GINT)DATA_GET(output->data,"canID");
			count = read_data_f(firmware->page_params[page]->length+adder,&message->recv_buf,TRUE);
			if ((count-adder) != firmware->page_params[page]->length)
				break;
			if (check_header)
			{
				if (message->recv_buf[2] & 0x80)
				{
					MTXDBG(CRITICAL,_("MS1/2_VECONST read error: specifically 0X%x\n"),message->recv_buf[2]);
					flush_serial_f(serial_params->fd,BOTH);
					break;
				}
			}
			ms_store_new_block(canID,page,0,
					((guint8 *)message->recv_buf)+base_offset,
					firmware->page_params[page]->length);
			ms_backup_current_data(canID,page);
			tmpi = (GINT)DATA_GET(global_data,"ve_goodread_count");
			DATA_SET(global_data,"ve_goodread_count",GINT_TO_POINTER(++tmpi));
			break;
		case MS1_RT_VARS:
			count = read_data_f(firmware->rtvars_size+adder,&message->recv_buf,TRUE);
			if ((count-adder) != firmware->rtvars_size)
				break;
			if (check_header)
			{
				if (message->recv_buf[2] & 0x80)
				{
					MTXDBG(CRITICAL,_("MS1_RT_VARS read error: specifically 0X%x\n"),message->recv_buf[2]);
					flush_serial_f(serial_params->fd,BOTH);
					break;
				}
			}
			ptr8 = (guchar *)message->recv_buf+base_offset;
			/* Test for MS reset */
			if (just_starting)
			{
				lastcount = ptr8[0];
				just_starting = FALSE;
			}
			/* Check for clock jump from the MS, a 
			 * jump in time from the MS clock indicates 
			 * a reset due to power and/or noise.
			 */
			if ((lastcount - ptr8[0] > 1) && \
					(lastcount - ptr8[0] != 255))
			{
				tmpi = (GINT)DATA_GET(global_data,"reset_count");
				DATA_SET(global_data,"reset_count",GINT_TO_POINTER(++tmpi));
				printf(_("ECU Reset detected!, lastcount %i, current %i\n"),lastcount,ptr8[0]);
				gdk_beep();
			}
			else
			{
				tmpi = (GINT)DATA_GET(global_data,"rt_goodread_count");
				DATA_SET(global_data,"rt_goodread_count",GINT_TO_POINTER(++tmpi));
			}
			lastcount = ptr8[0];
			/* Feed raw buffer over to post_process(void)
			 * as a void * and pass it a pointer to the new
			 * area for the parsed data...
			 */
			process_rt_vars_f(((guint8 *)message->recv_buf)+base_offset,firmware->rtvars_size);
			break;
		case MS2_RT_VARS:
			page = (GINT)DATA_GET(output->data,"page");
			canID = (GINT)DATA_GET(output->data,"canID");
			count = read_data_f(firmware->rtvars_size+adder,&message->recv_buf,TRUE);
			if ((count-adder) != firmware->rtvars_size)
				break;
			if (check_header)
			{
				if (message->recv_buf[2] & 0x80)
				{
					MTXDBG(CRITICAL,_("MS2_RT_VARS read error: specifically 0X%x\n"),message->recv_buf[2]);
					flush_serial_f(serial_params->fd,BOTH);
					break;
				}
			}
			ms_store_new_block(canID,page,0,
					((guint8 *)message->recv_buf)+base_offset,
					firmware->page_params[page]->length);
			ms_backup_current_data(canID,page);
			ptr16 = (guint16 *)message->recv_buf+base_offset;
			/* Test for MS reset */
			if (just_starting)
			{
				if (firmware->bigendian)
				{
					lastcount = GUINT16_TO_BE(ptr16[0]);
					curcount = GUINT16_TO_BE(ptr16[0]);
				}
				else
				{
					lastcount = GUINT16_TO_LE(ptr16[0]);
					curcount = GUINT16_TO_LE(ptr16[0]);
				}
				just_starting = FALSE;
			}
			else
			{
				if (firmware->bigendian)
					curcount = GUINT16_TO_BE(ptr16[0]);
				else
					curcount = GUINT16_TO_LE(ptr16[0]);
			}
			/* Check for clock jump from the MS, a 
			 * jump in time from the MS clock indicates 
			 * a reset due to power and/or noise.
			 */
			if ((lastcount - curcount > 1) && \
					(lastcount - curcount != 65535))
			{
				tmpi = (GINT)DATA_GET(global_data,"reset_count");
				DATA_SET(global_data,"reset_count",GINT_TO_POINTER(++tmpi));
				printf(_("MS2 rtvars reset detected, lastcount is %i, current %i"),lastcount,curcount);
				gdk_beep();
			}
			else
			{
				tmpi = (GINT)DATA_GET(global_data,"rt_goodread_count");
				DATA_SET(global_data,"rt_goodread_count",GINT_TO_POINTER(++tmpi));
			}
			lastcount = curcount;
			/* Feed raw buffer over to post_process(void)
			 * as a void * and pass it a pointer to the new
			 * area for the parsed data...
			 */
			process_rt_vars_f(((guint8 *)message->recv_buf)+base_offset,firmware->rtvars_size);
			break;
		case MS2_BOOTLOADER:
			printf(_("MS2_BOOTLOADER not written yet\n"));
			break;
		case MS1_GETERROR:
			DATA_SET(global_data,"forced_update",GINT_TO_POINTER(TRUE));
			DATA_SET(global_data,"force_page_change",GINT_TO_POINTER(TRUE));
			count = read_data_f(-1,&message->recv_buf,FALSE);
			if (count <= 10)
			{
				thread_update_logbar_f("error_status_view",NULL,g_strdup(_("No ECU Errors were reported....\n")),FALSE,FALSE);
				break;
			}
			if (g_utf8_validate(((gchar *)message->recv_buf)+1,count-1,NULL))
			{
				thread_update_logbar_f("error_status_view",NULL,g_strndup(((gchar *)message->recv_buf+7)+1,count-8),FALSE,FALSE);
				tmpbuf = g_strndup(((gchar *)message->recv_buf)+1,count-1);
				MTXDBG(IO_PROCESS|SERIAL_RD,_("ECU ERROR string: \"%s\"\n"),tmpbuf);
				g_free(tmpbuf);
			}
			else
				thread_update_logbar_f("error_status_view",NULL,g_strdup("The data came back as gibberish, please try again...\n"),FALSE,FALSE);
			break;
		default:
			break;
	}
	EXIT();
	return;
}