⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scantool_diag.c

📁 Freediag contains various drivers (ISO9141, ISO14230, SAEJ1850-VPW, SAEJ1850-PWM) for different adap
💻 C
字号:
/*
 *	freediag - Vehicle Diagnostic Utility
 *
 *
 * Copyright (C) 2001 Richard Almeida & Ibex Ltd (rpa@ibex.co.uk)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *************************************************************************
 *
 *
 * Mostly ODBII Compliant Scan Tool (as defined in SAE J1978)
 *
 * CLI routines - diag subcommand
 *
 * This is extended stuff for playing with ECUs, allowing you to
 * start a L2 connection to an ECU, add a L3 connection etc
 *
 */

#include "diag_os.h" /* operating specific includes */

#include "scantool.h"

static char *cvsid = "$Id: scantool_diag.c,v 1.5 2002/09/11 19:59:02 rpalmeida Exp $";

int cmd_diag_help(int argc, char **argv);
int cmd_diag_quit(int argc, char **argv);

int cmd_diag_disconnect(int argc, char **argv);
int cmd_diag_connect(int argc, char **argv);
int cmd_diag_sendreq(int argc, char **argv);
int cmd_diag_read(int argc, char **argv);

int cmd_diag_addl3(int argc, char **argv);

int cmd_diag_probe(int argc, char **argv);
int cmd_diag_fastprobe(int argc, char **argv);

struct cmd_tbl_entry diag_cmd_table[] =
{
	{ "help", "help [command]", "Gives help for a command",
		cmd_diag_help, 0, NULL},

	{ "connect", "connect", "Connect to ECU", cmd_diag_connect, 0, NULL},

	{ "disconnect", "disconnect", "Disconnect from ECU", cmd_diag_disconnect,
		0, NULL},

	{ "sendreq", "sendreq data0 data1 data2 ...", "Send a command to the ECU and print response",
		cmd_diag_sendreq, 0, NULL},
	{ "sr", "sendreq data0 data1 data2 ...", "Send a command to the ECU and print response",
		cmd_diag_sendreq, FLAG_HIDDEN, NULL},
	{ "read", "read [waittime]",
		"Receive some data from the ECU waiting waittime seconds",
		cmd_diag_read, 0, NULL},
	{ "rx", "read [waittime]", "Receive some data from the ECU",
		cmd_diag_read, FLAG_HIDDEN, NULL},

	{ "addl3", "addl3 protocol", "Add [start] a L3 protocol",
		cmd_diag_addl3, 0, NULL},

	{ "probe", "probe start_addr stop_addr", "Scan bus using ISO9141 5 baud init [slow!]", cmd_diag_probe, 0, NULL},
	{ "fastprobe", "fastprobe start_addr stop_addr [func]", "Scan bus using ISO14230 fast init with physical or functional addressing", cmd_diag_fastprobe, 0, NULL},
	{ "quit", "quit", "Return to previous menu level",
		cmd_diag_quit, 0, NULL},
	{ "exit", "exit", "Return to previous menu level",
		cmd_diag_quit, FLAG_HIDDEN, NULL},

	{ NULL, NULL, NULL, NULL, 0, NULL}
};

int
cmd_diag_quit(int argc, char **argv)
{
	return (CMD_UP);
}

int
cmd_diag_help(int argc, char **argv)
{
	help_common(argc, argv, diag_cmd_table);
	return (0);
}

int
cmd_diag_addl3(int argc, char **argv)
{
	int i;
	char *l3_protos[] = { "SAEJ1979", "VAG", NULL };
	char *proto;

	/* Add a L3 stack above the open L2 */
	if (global_state < STATE_CONNECTED)
	{
		printf("Not connected to ECU\n");
		return(CMD_OK);
	}
	if (global_state > STATE_CONNECTED)
	{
		printf("L3 protocol already connected\n");
		return(CMD_OK);
	}
	if (argc == 1)
	{
		return(CMD_USAGE);
	}
	if (strcmp(argv[1], "?") == 0)
	{
		printf("Valid protocols are: ");
		for (i=0; i<100; i++)
		{
			if (l3_protos[i] == NULL)
				break;
			printf("%s ", l3_protos[i]);
		}
		printf("\n");
		return(CMD_OK);
	}
	for (i=0, proto = NULL; i<100; i++)
	{
		if (l3_protos[i] == NULL)
			break;
		if (strcasecmp(l3_protos[i], argv[1]) == 0)
		{
			proto = l3_protos[i];
			break;
		}
	}
	if (proto == NULL)
	{
		printf("No such protocol, use %s ? for list of protocols\n",
			argv[0]);
		return(CMD_OK);
	}
	else
	{
		global_l3_conn = diag_l3_start(proto, global_l2_conn);

		if (global_l3_conn) {
			global_state = STATE_L3ADDED ;
			printf("Done\n");
		}
		else
		{
			printf("Failed to add L3 protocol\n");
		}
	}

	return(CMD_OK);
}


int
cmd_diag_probe_common(int argc, char **argv, int fastflag)
{
	unsigned int start, end, i, rv, fd;
	diag_l2_conn_t *d_conn;
	int funcmode = 0;

	if (argc < 3)
		return(CMD_USAGE);

	start = htoi(argv[1]);
	end = htoi(argv[2]);

	if (fastflag)
	{
		if (strcasecmp(argv[3], "func") == 0)
			funcmode = DIAG_L2_TYPE_FUNCADDR;
	}

	if ( (start < 0) || (start > 255) || (end < 0) || (end > 255))
	{
		printf("Values must be between 0 and 255\n");
		return(CMD_OK);
	}
	if (end < start)
	{
		printf("Start must not be greater than End address\n");
		return(CMD_OK);
	}

	rv = diag_init();
	if (rv < 0)
	{
		printf("Failed to initialise diagnostic layer\n");
		return(CMD_OK);
	}
	/* Open interface using hardware type ISO9141 */
	fd = diag_l2_open(set_interface, set_subinterface,
		DIAG_L1_ISO9141);
	if (fd < 0)
	{
		printf("Failed to open hardware interface ");
		if (fd == DIAG_ERR_PROTO_NOTSUPP)
			printf(", does not support requested L1 protocol\n");
		else if (fd == DIAG_ERR_BADIFADAPTER)
			printf(", adapter probably not connected\n");
		else
			printf("\n");
		return(CMD_OK);
	}

	printf("Scanning address : ");
	for (i=start; i<=end; i++)
	{
		printf("0x%x ", i);
		fflush(stdout) ;


		if (fastflag)
			d_conn = diag_l2_StartCommunications(fd,
				DIAG_L2_PROT_ISO14230,
				DIAG_L2_TYPE_FASTINIT | funcmode,
				set_speed, i, set_testerid);
		else
			d_conn = diag_l2_StartCommunications(fd,
				DIAG_L2_PROT_ISO9141,
				DIAG_L2_TYPE_SLOWINIT,
				set_speed, i, set_testerid);

		if (d_conn != NULL)
		{
			int gotsome;
			struct diag_l2_data d;

			printf(" connected !!\n", i);
			fflush(stdout);

			global_state = STATE_CONNECTED;
			global_l2_conn = d_conn;

			/* Get the keybytes */
			diag_l2_ioctl(d_conn, DIAG_IOCTL_GET_L2_DATA, &d);
			if (fastflag)
				printf("Keybytes: 0x%x 0x%x\n", d.kb1, d.kb2);
			else
				printf("msg 00: 0x%x 0x%x\n", d.kb1, d.kb2);

			/* Now read some data */

			rv = 0; gotsome = 0;
			while (rv >= 0)
			{
				rv = diag_l2_recv(d_conn, 2000, l2raw_data_rcv, NULL);
				if (rv > 0)
					gotsome = 1;
			}
			if (gotsome)
				printf("\n");
			else if (rv != DIAG_ERR_TIMEOUT)
				printf("- read failed %d\n", rv);

			/* XXX until we can disconnect from an ECU */
			return(CMD_OK);
		}
	}
	diag_l2_close(fd);
	printf("\n");
	return(CMD_OK);
}

int
cmd_diag_probe(int argc, char **argv)
{
	return(cmd_diag_probe_common(argc, argv, 0));
}

int
cmd_diag_fastprobe(int argc, char **argv)
{
	return(cmd_diag_probe_common(argc, argv, 1));
}

int
cmd_diag_connect(int argc, char **argv)
{
	int rv;

	rv = do_l2_generic_start();
	if (rv == 0)
	{
		printf("Connection to ECU established\n");
		global_state = STATE_CONNECTED;
	}
	else
	{
		printf("Connection to ECU failed\n");
		printf("Please check :-\n");
		printf("	Adapter is connected to PC\n");
		printf("	Cable is connected to Vehicle\n");
		printf("	Vehicle is switched on\n");
	}
	return (CMD_OK);
}

int
cmd_diag_disconnect(int argc, char **argv)
{
	if (global_state < STATE_CONNECTED)
	{
		printf("Not connected to ECU\n");
		return(CMD_OK);
	}

	if (global_state >= STATE_L3ADDED)
	{
		/* Close L3 protocol */
		diag_l3_stop(global_l3_conn);
	}
	diag_l2_StopCommunications(global_l2_conn);
	diag_l2_close(global_l2_fd);

	global_l2_conn = NULL;
	global_state = STATE_IDLE;

	return(CMD_OK);
}


int
cmd_diag_read(int argc, char **argv)
{
	int timeout = 0;

	if (global_state < STATE_CONNECTED)
	{
		printf("Not connected to ECU\n");
		return(CMD_OK);
	}

	if (argc > 1)
		timeout = atoi(argv[1]) * 1000;

	if (global_state < STATE_L3ADDED)
	{
		/* No L3 protocol, do L2 stuff */
		(void)diag_l2_recv(global_l2_conn, timeout, l2raw_data_rcv,
			NULL);

	}
	else
	{
		(void)diag_l3_recv(global_l3_conn, timeout, j1979_data_rcv,
			(void *)RQST_HANDLE_WATCH);
	}
	return(CMD_OK);
}

/*
 * Send some data, and wait for a response
 */
int
cmd_diag_sendreq(int argc, char **argv)
{
	u_int8_t	data[1024];
	int	len;
	int	i, j, rv;

	if (global_state < STATE_CONNECTED)
	{
		printf("Not connected to ECU\n");
		return(CMD_OK);
	}

	if (argc < 2)
	{
		printf("Too few arguments\n");
		return(CMD_USAGE);
	}

	memset(data, 0, sizeof(data));
	
	for (i=1, j=0; i < argc; i++, j++)
		data[j] = htoi(argv[i]);
	len = j ;


	if (global_state < STATE_L3ADDED)
	{
		rv = l2_do_send( global_l2_conn, data, len,
			(void *)RQST_HANDLE_DECODE);
	}
	else
	{
		/* Send data with handle to tell callback to print results */
		rv = l3_do_send( global_l3_conn, data, len,
			(void *)RQST_HANDLE_DECODE);
	}

	if (rv != 0)
	{
		if (rv == DIAG_ERR_TIMEOUT)
			printf("No data received\n");
		else
			printf("sendreq: failed error %d\n", rv);
	}
	return(CMD_OK);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -