Esempio n. 1
0
/*!
  \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;
}
Esempio n. 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;
}
Esempio n. 3
0
/*!
  \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;
}
Esempio n. 4
0
/*!
  \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;
}
Esempio n. 5
0
/*!
  \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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
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;
}
Esempio n. 11
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;
}
Esempio n. 12
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;
}
Esempio n. 13
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;
}