コード例 #1
0
ファイル: serialio.c プロジェクト: toxicgumbo/MegaTunix
/*!
  \brief setup_serial_params() is another wrapper that calls the appropriate
  calls to initialize the serial port to the proper speed, bits, flow, parity
  etc..
  */
G_MODULE_EXPORT void setup_serial_params(void)
{
	GMutex *serio_mutex = NULL;
	gchar * baud_str = NULL;
	Parity parity = NONE;
	gint baudrate = 0;
	gint bits = 0;
	gint stop = 0;
	Serial_Params *serial_params = NULL;
#ifndef __WIN32__
	speed_t baud;
#endif
	serial_params = DATA_GET(global_data,"serial_params");
	serio_mutex = DATA_GET(global_data,"serio_mutex");
	baud_str = DATA_GET(global_data,"ecu_baud_str");

	if (!parse_baud_str(baud_str,&baudrate,&bits,&parity,&stop))
		MTXDBG(SERIAL_RD|SERIAL_WR|CRITICAL,_("ERROR! couldn't parse ecu_baud string %s\n"),baud_str);

	DATA_SET(global_data,"ecu_baud",GINT_TO_POINTER(baudrate));
	if (serial_params->open == FALSE)
		return;
	if (DATA_GET(global_data,"network_mode"))
	{
		printf("network mode, exiting!\n");
		return;
	}
	/*printf("setup_serial_params entered\n");*/
	g_mutex_lock(serio_mutex);

#ifdef __WIN32__
	win32_setup_serial_params(serial_params->fd,baudrate,bits,parity,stop);
#else
	/* Save serial port status */
	tcgetattr(serial_params->fd,&serial_params->oldtio);

	g_mutex_unlock(serio_mutex);

	flush_serial(serial_params->fd, BOTH);
	g_mutex_lock(serio_mutex);

	/* Sets up serial port for the modes we want to use. 
	 * NOTE: Original serial tio params are stored and restored 
	 * in the open_serial() and close_serial() functions.
	 */

	/*clear struct for new settings*/
	memset(&serial_params->newtio, 0, sizeof(serial_params->newtio)); 
	/* 
	 * BAUDRATE: Set bps rate. You could also use cfsetispeed and 
	 * cfsetospeed
	 * CRTSCTS : output hardware flow control (only used if the cable has
	 * all necessary lines. See sect. 7 of Serial-HOWTO)
	 * CS8     : 8n1 (8bit,no parity,1 stopbit)
	 * CLOCAL  : local connection, no modem contol
	 * CREAD   : enable receiving characters
	 */

	/* Set baud (posix way) */

	switch (baudrate)
	{
		case 8192:
			baud = B38400;
			break;
		case 9600:
			baud = B9600;
			break;
		case 19200:
			baud = B19200;
			break;
		case 38400:
			baud = B38400;
			break;
		case 57600:
			baud = B57600;
			break;
		case 115200:
			baud = B115200;
			break;
		default:
			/* Assume 9600 */
			baud = B9600;
	}

	cfsetispeed(&serial_params->newtio, baud);
	cfsetospeed(&serial_params->newtio, baud);

	/* Mask and set to 8N1 mode... */
	/* Mask out HW flow control */
	serial_params->newtio.c_cflag &= ~(CRTSCTS);

	/* Set additional flags, note |= syntax.. */
	/* CLOCAL == Ignore modem control lines
	   CREAD == Enable receiver
	   */
	serial_params->newtio.c_cflag |= CLOCAL | CREAD;
	/* Mask out Bit size */
	serial_params->newtio.c_cflag &= ~(CSIZE);
	switch (bits)
	{
		case 8:
			serial_params->newtio.c_cflag |= CS8;
			break;
		case 7:
			serial_params->newtio.c_cflag |= CS7;
			break;
		case 6:
			serial_params->newtio.c_cflag |= CS6;
			break;
		case 5:
			serial_params->newtio.c_cflag |= CS5;
			break;
	}
	/* Mask out Parity Flags */
	serial_params->newtio.c_cflag &= ~(PARENB | PARODD);
	switch (parity)
	{
		case ODD:
			serial_params->newtio.c_cflag |= (PARENB | PARODD);
			break;
		case EVEN:
			serial_params->newtio.c_cflag |= PARENB;
			break;
		case NONE:
			break;
	}
	/* Mask out Stip bit flags */
	serial_params->newtio.c_cflag &= ~(CSTOPB);
	if (stop == 2)
		serial_params->newtio.c_cflag |= CSTOPB;
	/* 1 stop bit is default */


	/* RAW Input */
	/* Ignore signals, disable canonical, echo, etc */
	/*
	serial_params->newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | IEXTEN | ISIG);
	*/
	serial_params->newtio.c_lflag = 0;

	/* Disable software flow control */
	serial_params->newtio.c_iflag &= ~(IXON | IXOFF | IXANY );
	/*
	serial_params->newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
			                           | INLCR | IGNCR | ICRNL );
						   */
	serial_params->newtio.c_iflag = IGNBRK;


	/* Set raw output */
	/*
	serial_params->newtio.c_oflag &= ~OPOST;
	*/
	serial_params->newtio.c_oflag = 0;

	/* 
	   initialize all control characters 
	   default values can be found in /usr/include/termios.h, and are given
	   in the comments, but we don't need them here
	 */
	serial_params->newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */
	serial_params->newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
	serial_params->newtio.c_cc[VERASE]   = 0;     /* del */
	serial_params->newtio.c_cc[VKILL]    = 0;     /* @ */
	serial_params->newtio.c_cc[VEOF]     = 0;     /* Ctrl-d */
	serial_params->newtio.c_cc[VEOL]     = 0;     /* '\0' */
	/* Fredcooke say vmin = 1 solves his hang on close issue with
	   his broken FTDI driver,  but that will break interrogation unless I
	   completely transition to nonblocking IO */
	serial_params->newtio.c_cc[VMIN]     = 0;     
	serial_params->newtio.c_cc[VTIME]    = 1;     /* 100ms timeout */

	/* PIS Specific (odd baud rate) DISABLED */
	/*
	if (ioctl(serial_params->fd, TIOCGSERIAL, &serial_params->oldctl) != 0)
		MTXDBG(SERIAL_RD|SERIAL_WR|CRITICAL, _("Error getting serial line information error %s\n"),strerror(errno));
	else
	{
		MTXDBG(SERIAL_RD|SERIAL_WR, _("Get serial line info call OK\n"));
		// copy ioctl structure
		memcpy(&serial_params->newctl, &serial_params->oldctl, sizeof(serial_params->newctl));

		// and if we are PIS 8192 make a custom divisor
		if (baudrate == 8192)
		{
			if (serial_params->newctl.baud_base < 115200)
				serial_params->newctl.baud_base = 115200;

			serial_params->newctl.custom_divisor = 14;
			serial_params->newctl.flags |= (ASYNC_SPD_MASK & ASYNC_SPD_CUST);

			if (ioctl(serial_params->fd, TIOCSSERIAL, &serial_params->newctl) != 0)
				MTXDBG(SERIAL_RD|SERIAL_WR|CRITICAL,_("Error setting ioctl\n"));
			else
				MTXDBG(SERIAL_RD|SERIAL_WR,_("Set ioctl OK\n"));
		}
	}
	*/
	tcsetattr(serial_params->fd, TCSANOW, &serial_params->newtio);
#endif
	g_mutex_unlock(serio_mutex);
	flush_serial(serial_params->fd,BOTH);
	return;
}
コード例 #2
0
ファイル: interrogate.c プロジェクト: toxicgumbo/MegaTunix
/*!
 \brief validate_and_load_tests() loads the list of tests from the system
 checks them for validity, and populates the passed array and hashtables
 with them
 \param tests is a pointer to a pointer of a GArray structure of the tests
 \param tests_hash is a pointer to a pointer of a hashtable of the Tests
 \returns TRUE on success, FALSE otherwise
 */
G_MODULE_EXPORT gboolean validate_and_load_tests(GArray **tests, GHashTable **tests_hash)
{
	ConfigFile *cfgfile;
	Detection_Test *test = NULL;
	gchar * filename = NULL;
	gchar *section = NULL;
	gchar * tmpbuf = NULL;
	gchar ** vector = NULL;
	gint total_tests = 0;
	gint result = 0;
	gint major = 0;
	gint minor = 0;
	gint i = 0;
	gint j = 0;

	filename = get_file(g_build_filename(INTERROGATOR_DATA_DIR,"Profiles",DATA_GET(global_data,"ecu_family"),"tests.cfg",NULL),NULL);
	if (!filename)
	{
		update_logbar_f("interr_view","warning",g_strdup_printf(_("Interrogation profile tests file %s not found!\n"),filename),FALSE,FALSE,TRUE);
		return FALSE;
	}

	cfgfile = cfg_open_file(filename);
	if (!cfgfile)
		return FALSE;
	get_file_api_f(cfgfile,&major,&minor);
	if ((major != INTERROGATE_MAJOR_API) || (minor != INTERROGATE_MINOR_API))
	{
		update_logbar_f("interr_view","warning",g_strdup_printf(_("Interrogation profile tests API mismatch (%i.%i != %i.%i):\n\tFile %s.\n"),major,minor,INTERROGATE_MAJOR_API,INTERROGATE_MINOR_API,filename),FALSE,FALSE,TRUE);
		g_free(filename);
		cfg_free(cfgfile);
		return FALSE;
	}

	*tests_hash = g_hash_table_new_full(g_str_hash,g_str_equal,NULL,test_cleanup);

	MTXDBG(INTERROGATOR,_("File %s, opened successfully\n"),filename);
	*tests = g_array_new(FALSE,TRUE,sizeof(Detection_Test *));
	cfg_read_int(cfgfile,"interrogation_tests","total_tests",&total_tests);
	for (i=0;i<total_tests;i++)
	{
		test = g_new0(Detection_Test, 1);
		section = g_strdup_printf("test_%.2i",i);
		if (!cfg_read_string(cfgfile,section,"test_name",&test->test_name))
		{
			MTXDBG(INTERROGATOR,_("test_name for %s is NULL\n"),section);
			g_free(section);
			break;
		}
		if (!cfg_read_string(cfgfile,section,"test_result_type",&tmpbuf))
		{
			MTXDBG(INTERROGATOR,_("test_result_type for %s is NULL\n"),section);
			g_free(section);
			break;
		}
		else
		{
			test->result_type = translate_string_f(tmpbuf);
			g_free(tmpbuf);
		}
		if (!cfg_read_string(cfgfile,section,"test_func",&test->test_func))
		{
			MTXDBG(INTERROGATOR,_("test_function for %s is NULL\n"),section);
			g_free(section);
			break;
		}
		get_symbol_f(test->test_func,(void *)&test->function);
		cfg_read_string(cfgfile,section,"test_desc",
				&test->test_desc);
		g_free(section);
		g_array_append_val(*tests,test);
		g_hash_table_insert(*tests_hash,test->test_name,test);
	}
	cfg_free(cfgfile);
	g_free(filename);
	return TRUE;
}
コード例 #3
0
ファイル: interrogate.c プロジェクト: toxicgumbo/MegaTunix
/*!
  \brief Compares the results of the test runs with the available 
  interrogation profiles, favoring USER profiles over system ones.
  If we have a match, allocated resources for a Firmware structure, and load
  the firmware details.
  \param tests is a pointer to a GArray of tests
  \param tests_hash is a pointer to the hashtable of tests
  \returns TRUE on if we hit a match, FALSE otherwise
  */
G_MODULE_EXPORT gboolean determine_ecu(GArray *tests, GHashTable *tests_hash)
{
	gboolean retval = TRUE;
	gint i = 0;
	Detection_Test *test = NULL;
	gint num_tests = tests->len;
	gboolean match = FALSE;
	gchar * filename = NULL;
	gchar ** filenames = NULL;
	GArray *classes = NULL;
	Firmware_Details *firmware = NULL;
	extern gconstpointer *global_data;

	filenames = get_files(g_build_filename(INTERROGATOR_DATA_DIR,"Profiles",DATA_GET(global_data,"ecu_family"),NULL),g_strdup("prof"),&classes);
	if (!filenames)
	{
		MTXDBG(INTERROGATOR|CRITICAL,_("NO Interrogation profiles found, was MegaTunix installed properly?\n\n"));
		return FALSE;
	}
	i = 0;
	while (filenames[i])
	{
		if (check_for_match(tests_hash,filenames[i]))
		{
			match = TRUE;
			filename = g_strdup(filenames[i]);
			break;
		}
		i++;
	}
	g_strfreev(filenames);
	g_array_free(classes,TRUE);
	/* Update the screen with the data... */
	for (i=0;i<num_tests;i++)
	{
		test = g_array_index(tests,Detection_Test *,i);
		if (test->result_type == RESULT_DATA)
		{
			MTXDBG(INTERROGATOR,_("Command (%s): returned %i byts\n"),test->test_desc,test->num_bytes);
			thread_update_logbar_f("interr_view","info",g_strdup_printf("Command (%s): returned %i bytes)\n",test->test_desc,test->num_bytes),FALSE,FALSE);
		}
		if (test->result_type == RESULT_TEXT)
		{
			MTXDBG(INTERROGATOR,_("Command (%s): returned (%s)\n"),test->test_desc,test->result_str);
			thread_update_logbar_f("interr_view","info",g_strdup_printf("Command (%s): returned (%s)\n",test->test_desc,test->result_str),FALSE,FALSE);
		}
		else if (test->result_type == RESULT_LIST)
		{
			MTXDBG(INTERROGATOR,_("Command (%s): returned %i elements\n"),test->test_desc,g_list_length((GList *)test->result));
			thread_update_logbar_f("interr_view","info",g_strdup_printf("Command (%s): returned %i elements\n",test->test_desc,g_list_length((GList *)test->result)),FALSE,FALSE);
		}
	}
	if (match == FALSE) /* (we DID NOT find one) */
	{
		MTXDBG(INTERROGATOR|CRITICAL,_("Firmware NOT DETECTED, Enable Interrogation debugging, retry interrogation,\nclose megatunix, and send ~/MTXlog.txt to the author for analysis with a note\ndescribing which firmware you are attempting to talk to.\n"));
		update_logbar_f("interr_view","warning",g_strdup("Firmware NOT DETECTED, Enable Interrogation debugging, retry interrogation,\nclose megatunix, and send ~/MTXlog.txt to the author for analysis with a note\ndescribing which firmware you are attempting to talk to.\n"),FALSE,FALSE,TRUE);
		retval = FALSE;
	}
	else
	{
		if (!firmware)
		{
			firmware = g_new0(Firmware_Details,1);
			DATA_SET(global_data,"firmware",firmware);
		}

		if (!load_firmware_details(firmware,filename))
			retval = FALSE;
	}
	g_free(filename);
	return(retval);
}
コード例 #4
0
ファイル: interrogate.c プロジェクト: toxicgumbo/MegaTunix
/*
 \brief Queries the ECU for the details of a specific location ID
 \param loc_id, the location ID to get more information about
 \returns a pointer to a Location_Details structure
 \see Location_Details
 */
G_MODULE_EXPORT Location_Details *request_location_id_details(guint16 loc_id)
{
	OutputData *output = NULL;
	GAsyncQueue *queue = NULL;
	FreeEMS_Packet *packet = NULL;
	GTimeVal tval;
	GList *list = NULL;
	Serial_Params *serial_params = NULL;
	guint8 *buf = NULL;
	Location_Details *details = NULL;
	/* Raw packet */
	guint8 pkt[LOCATION_ID_DETAILS_REQ_PKT_LEN];
	gint res = 0;
	gint i = 0;
	gint h = 0;
	gint l = 0;
	gint tmpi = 0;
	guint8 sum = 0;
	gint tmit_len = 0;

	serial_params = DATA_GET(global_data,"serial_params");
	g_return_val_if_fail(serial_params,NULL);

	pkt[HEADER_IDX] = 0;
	pkt[H_PAYLOAD_IDX] = (REQUEST_LOCATION_ID_DETAILS & 0xff00 ) >> 8;
	pkt[L_PAYLOAD_IDX] = (REQUEST_LOCATION_ID_DETAILS & 0x00ff );
	pkt[L_PAYLOAD_IDX+1] = (loc_id & 0xff00) >> 8;	/* H location bits */
	pkt[L_PAYLOAD_IDX+2] = (loc_id & 0x00ff); 	/* L location bits */
	for (i=0;i<LOCATION_ID_DETAILS_REQ_PKT_LEN-1;i++)
		sum += pkt[i];
	pkt[LOCATION_ID_DETAILS_REQ_PKT_LEN-1] = sum;
	buf = finalize_packet((guint8 *)&pkt,LOCATION_ID_DETAILS_REQ_PKT_LEN,&tmit_len);
	queue = g_async_queue_new();
	register_packet_queue(PAYLOAD_ID,queue,RESPONSE_LOCATION_ID_DETAILS);
	if (!write_wrapper_f(serial_params->fd,buf, tmit_len, NULL))
	{
		deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_LOCATION_ID_DETAILS);
		g_free(buf);
		g_async_queue_unref(queue);
		return NULL;
	}
	g_free(buf);
	g_get_current_time(&tval);
	g_time_val_add(&tval,500000);
	packet = g_async_queue_timed_pop(queue,&tval);
	deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_LOCATION_ID_DETAILS);
	g_async_queue_unref(queue);
	if (packet)
	{
		/*printf("packet payload length %i\n",packet->payload_length);*/
		if (packet->payload_length != 12)
			printf("ERROR in locationID details response!\n");
		details = g_new0(Location_Details, 1);
		tmpi = 0;
		h = packet->data[packet->payload_base_offset];
		l = packet->data[packet->payload_base_offset+1];
		details->flags = (h << 8) + l;
		/*printf("loc id details flags %i\n",details->flags);*/
		h = packet->data[packet->payload_base_offset+2];
		l = packet->data[packet->payload_base_offset+3];
		details->parent = (h << 8) + l;
		/*printf("loc id details parent %i\n",details->parent);*/
		details->ram_page = packet->data[packet->payload_base_offset+4];
		details->flash_page = packet->data[packet->payload_base_offset+5];
		/*printf("loc id details ram_page %i\n",details->ram_page);*/
		/*printf("loc id details flash_page %i\n",details->flash_page);*/
		h = packet->data[packet->payload_base_offset+6];
		l = packet->data[packet->payload_base_offset+7];
		details->ram_address = (h << 8) + l;
		/*printf("loc id details ram_address %0x\n",details->ram_address);*/
		h = packet->data[packet->payload_base_offset+8];
		l = packet->data[packet->payload_base_offset+9];
		details->flash_address = (h << 8) + l;
		/*printf("loc id details flash_address %0x\n",details->flash_address);*/
		h = packet->data[packet->payload_base_offset+10];
		l = packet->data[packet->payload_base_offset+11];
		details->length = (h << 8) + l;
		/*printf("loc id details length %i\n",details->length);*/
		freeems_packet_cleanup(packet);
	}
	return details;
}
コード例 #5
0
ファイル: interrogate.c プロジェクト: toxicgumbo/MegaTunix
/*
 \brief Queries the ECU for a location ID list
 \paranm length is a pointer to a location where this function can store the
 length of data received, or NULL
 \returns a pointer to a Link list (GList) of location ID's
 */
G_MODULE_EXPORT GList *raw_request_location_ids(gint * length)
{
	OutputData *output = NULL;
	GAsyncQueue *queue = NULL;
	FreeEMS_Packet *packet = NULL;
	GTimeVal tval;
	GList *list = NULL;
	Serial_Params *serial_params = NULL;
	guint8 *buf = NULL;
	/* Raw packet */
	gint len = LOCATION_ID_LIST_REQ_PKT_LEN;
	guint8 pkt[LOCATION_ID_LIST_REQ_PKT_LEN];
	gint req = REQUEST_LIST_OF_LOCATION_IDS;
	gint resp = RESPONSE_LIST_OF_LOCATION_IDS;
	gint res = 0;
	gint i = 0;
	gint h = 0;
	gint l = 0;
	gint tmpi = 0;
	guint8 sum = 0;
	gint tmit_len = 0;
	guint8 flag = BLOCK_BITS_AND;
	guint16 bits = 0;

	serial_params = DATA_GET(global_data,"serial_params");
	g_return_val_if_fail(serial_params,NULL);

	pkt[HEADER_IDX] = 0;
	pkt[H_PAYLOAD_IDX] = (req & 0xff00 ) >> 8;
	pkt[L_PAYLOAD_IDX] = (req & 0x00ff );
	pkt[L_PAYLOAD_IDX+1] = flag;	/* AND/OR */
	bits |= BLOCK_IS_INDEXABLE | BLOCK_IN_RAM;
	pkt[L_PAYLOAD_IDX+2] = (bits & 0xff00) >> 8;	/* H bits */
	pkt[L_PAYLOAD_IDX+3] = (bits & 0x00ff); 	/* L bits */
	for (i=0;i<len-1;i++)
		sum += pkt[i];
	pkt[len-1] = sum;
	buf = finalize_packet((guint8 *)&pkt,len,&tmit_len);
	queue = g_async_queue_new();
	register_packet_queue(PAYLOAD_ID,queue,resp);
	if (!write_wrapper_f(serial_params->fd,buf, tmit_len, NULL))
	{
		deregister_packet_queue(PAYLOAD_ID,queue,resp);
		g_free(buf);
		g_async_queue_unref(queue);
		return NULL;
	}
	g_free(buf);
	g_get_current_time(&tval);
	g_time_val_add(&tval,500000);
	packet = g_async_queue_timed_pop(queue,&tval);
	deregister_packet_queue(PAYLOAD_ID,queue,resp);
	g_async_queue_unref(queue);
	if (packet)
	{
		for (i=0;i<packet->payload_length;i++)
		{
			tmpi = 0;
			h = packet->data[packet->payload_base_offset+i];
			i++;
			l = packet->data[packet->payload_base_offset+i];
			tmpi = (h << 8) + l;
			list = g_list_append(list,GINT_TO_POINTER(tmpi));
		}
		if (length)
			*length = packet->payload_length;
		freeems_packet_cleanup(packet);
	}
	return list;
}
コード例 #6
0
ファイル: interrogate.c プロジェクト: toxicgumbo/MegaTunix
/*!
 \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 gchar * raw_request_interface_version(gint *length)
{
	OutputData *output = NULL;
	GAsyncQueue *queue = NULL;
	FreeEMS_Packet *packet = NULL;
	gchar *version = NULL;
	GTimeVal tval;
	Serial_Params *serial_params = NULL;
	guint8 *buf = NULL;
	/* Raw packet */
	gint len = INTERFACE_VERSION_REQ_PKT_LEN;
	guint8 pkt[INTERFACE_VERSION_REQ_PKT_LEN];
	gint req = REQUEST_INTERFACE_VERSION;
	gint resp = RESPONSE_INTERFACE_VERSION;
	gint res = 0;
	gint i = 0;
	guint8 sum = 0;
	gint tmit_len = 0;

	serial_params = DATA_GET(global_data,"serial_params");
	g_return_val_if_fail(serial_params,NULL);

	if (DATA_GET(global_data,"offline"))
		return g_strdup("Offline");

	pkt[HEADER_IDX] = 0;
	pkt[H_PAYLOAD_IDX] = (req & 0xff00 ) >> 8;
	pkt[L_PAYLOAD_IDX] = (req & 0x00ff );
	for (i=0;i<len-1;i++)
		sum += pkt[i];
	pkt[len-1] = sum;
	buf = finalize_packet((guint8 *)&pkt,len,&tmit_len);
	queue = g_async_queue_new();
	register_packet_queue(PAYLOAD_ID,queue,resp);
	if (!write_wrapper_f(serial_params->fd,buf, tmit_len, NULL))
	{
		deregister_packet_queue(PAYLOAD_ID,queue,resp);
		g_free(buf);
		g_async_queue_unref(queue);
		return NULL;
	}
	g_free(buf);
	g_get_current_time(&tval);
	g_time_val_add(&tval,500000);
	packet = g_async_queue_timed_pop(queue,&tval);
	deregister_packet_queue(PAYLOAD_ID,queue,resp);
	g_async_queue_unref(queue);
	/*
	   if (packet)
	   printf("Firmware version PACKET ARRIVED!\n");
	   else
	   printf("TIMEOUT\n");
	 */

	if (packet)
	{
		version = g_strndup((const gchar *)(packet->data+packet->payload_base_offset),packet->payload_length);
		if (length)
			*length = packet->payload_length;
		freeems_packet_cleanup(packet);
	}
	return version;
}
コード例 #7
0
ファイル: libreems_helpers.c プロジェクト: JacobD10/MegaTunix
/*
 *\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;
}
コード例 #8
0
/*! 
  \brief handles runtime variables with complex ECU/Family specific handlers
  \param object is a pointer to the object to store the data within
  \param cfgfile is a pointer to the ConfigFile structure
  \param section is the section within the file
  \param symbol is the symbol name within the section
  \param type is an enumeration representing the type of RT var
  */
G_MODULE_EXPORT void common_rtv_loader(gconstpointer *object, xmlNode *node, gchar *symbol, ComplexExprType type)
{
	static Firmware_Details *firmware = NULL;
	gchar * name = NULL;
	gint tmpi = 0;
	gchar *tmpbuf = NULL;

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

	switch (type)
	{
		case ECU_EMB_BIT:
			/* ECU Embedded bitfield 4 params */
			name=NULL;
			name=g_strdup_printf("%s_locID",symbol);

			if (!generic_xml_gint_find(node,name,&tmpi))
				MTXDBG(RTMLOADER|COMPLEX_EXPR|CRITICAL,_("ECU_EMB_BIT, failure looking for:%s\n"),name);
			DATA_SET(object,name,GINT_TO_POINTER(tmpi));
			g_free(name);
			name=NULL;
			name=g_strdup_printf("%s_offset",symbol);
			if (!generic_xml_gint_find(node,name,&tmpi))
				MTXDBG(RTMLOADER|COMPLEX_EXPR|CRITICAL,_("ECU_EMB_BIT, failure looking for:%s\n"),name);
			DATA_SET(object,name,GINT_TO_POINTER(tmpi));
			g_free(name);
			name=NULL;
			name=g_strdup_printf("%s_canID",symbol);
			if (!generic_xml_gint_find(node,name,&tmpi))
				tmpi = firmware->canID;
			DATA_SET(object,name,GINT_TO_POINTER(tmpi));
			g_free(name);
			name=NULL;
			name=g_strdup_printf("%s_bitmask",symbol);
			if (!generic_xml_gint_find(node,name,&tmpi))
				MTXDBG(RTMLOADER|COMPLEX_EXPR|CRITICAL,_("ECU_EMB_BIT, failure looking for:%s\n"),name);
			DATA_SET(object,name,GINT_TO_POINTER(tmpi));
			g_free(name);
			name=NULL;
			break;
		case ECU_VAR:
			/* ECU std variable, canID/locID/offset/size */
			name=NULL;
			name=g_strdup_printf("%s_canID",symbol);
			if (!generic_xml_gint_find(node,name,&tmpi))
				tmpi = firmware->canID;

			DATA_SET(object,name,GINT_TO_POINTER(tmpi));
			g_free(name);
			name=NULL;
			name=g_strdup_printf("%s_locID",symbol);
			if (!generic_xml_gint_find(node,name,&tmpi))
				MTXDBG(RTMLOADER|COMPLEX_EXPR|CRITICAL,_("ECU_VAR, failure looking for:%s\n"),name);
			DATA_SET(object,name,GINT_TO_POINTER(tmpi));
			g_free(name);
			name=NULL;
			name=g_strdup_printf("%s_offset",symbol);
			if (!generic_xml_gint_find(node,name,&tmpi))
				MTXDBG(RTMLOADER|COMPLEX_EXPR|CRITICAL,_("ECU_VAR, failure looking for:%s\n"),name);
			DATA_SET(object,name,GINT_TO_POINTER(tmpi));
			g_free(name);
			name=NULL;
			name=g_strdup_printf("%s_size",symbol);
			if (!generic_xml_gchar_find(node,name,&tmpbuf))
				tmpi = MTX_U08;
			else
			{
				tmpi = translate_string_f(tmpbuf);
				g_free(tmpbuf);
			}
			DATA_SET(object,name,GINT_TO_POINTER(tmpi));
			g_free(name);
			name=NULL;
			break;
		default:
			EXIT();
			return;
			break;
	}
	EXIT();
	return;
}