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

📄 scantool_cli.c

📁 Freediag contains various drivers (ISO9141, ISO14230, SAEJ1850-VPW, SAEJ1850-PWM) for different adap
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	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 * */#include <config.h>#include "diag_os.h" /* operating specific includes */#include "scantool.h"#include <time.h>#include <sys/stat.h>#include "scantool_cli.h"static char *cvsid = "$Id: scantool_cli.c,v 1.24 2002/09/11 19:59:02 rpalmeida Exp $";char *progname;FILE		*global_logfp;		/* Monitor log output file pointer */#define LOG_FORMAT	"FREEDIAG log format 0.2"FILE		*instream;/* ROOT main menu *//* Sub menus */extern struct cmd_tbl_entry set_cmd_table[];extern struct cmd_tbl_entry debug_cmd_table[];extern struct cmd_tbl_entry test_cmd_table[];extern struct cmd_tbl_entry diag_cmd_table[];extern struct cmd_tbl_entry vag_cmd_table[];/* Main menu commands */int cmd_help(int argc, char **argv);int cmd_exit(int argc, char **argv);int cmd_monitor(int argc, char **argv);int cmd_watch(int argc, char **argv);int cmd_cleardtc(int argc, char **argv);int cmd_ecus(int argc, char **argv);int cmd_log(int argc, char **argv);int cmd_stoplog(int argc, char **argv);int cmd_play(int argc, char **argv);int cmd_dumpdata(int argc, char **argv);int cmd_scan(int argc, char **argv);int cmd_date(int argc, char **argv);int cmd_rem(int argc, char **argv);int cmd_source(int argc, char **argv);struct cmd_tbl_entry root_cmd_table[] ={	{ "scan", "scan", "Start SCAN process", cmd_scan, 0, NULL},	{ "monitor", "monitor [english/metric]", "Continuously monitor rpm etc",		cmd_monitor, 0, NULL},	{ "log", "log <filename>", "Log monitor data to <filename>",		cmd_log, 0, NULL},	{ "stoplog", "stoplog", "Stop logging", cmd_stoplog, 0, NULL},#if notdef	{ "play", "play filename", "Play back data from <filename>",		cmd_play, FLAG_HIDDEN, NULL},#endif	{ "cleardtc", "cleardtc", "Clear DTCs from ECU", cmd_cleardtc, 0, NULL},	{ "ecus", "ecus", "Show ECU information", cmd_ecus, 0, NULL},	{ "watch", "watch [raw/nodecode/nol3]",		"Watch the diagnostic bus and, if not in raw/nol3 mode, decode data",		cmd_watch, 0, NULL},	{ "set", "set <parameter value>",		"Sets/displays parameters, \"set help\" for more info", NULL,		0, set_cmd_table},	{ "test", "test <command [params]>",		"Perform various tests, \"test help\" for more info", NULL,		0, test_cmd_table},	{ "diag", "diag <command [params]>",		"Extended diagnostic functions, \"diag help\" for more info", NULL,		0, diag_cmd_table},	{ "vw", "vw <command [params]",		"VW diagnostic protocol functions, \"vw help\" for more info", NULL,		0, vag_cmd_table},	{ "debug", "debug [parameter = value]",		"Sets/displays debug stuff, \"debug help\" for more info", NULL,		0, debug_cmd_table},	{ "date", "date", "Prints date & time", cmd_date, FLAG_HIDDEN, NULL},	{ "#", "#", "Does nothing", cmd_rem, FLAG_HIDDEN, NULL},	{ "source", "source <file>", "Read commands from a file", cmd_source, 0, NULL},	{ "help", "help [command]", "Gives help for a command",		cmd_help, 0, NULL },	{ "quit", "quit", "Exits program", cmd_exit, 0, NULL},	{ "exit", "exit", "Exits program", cmd_exit, FLAG_HIDDEN, NULL},	{ NULL, NULL, NULL, NULL, 0, NULL}};#define INPUT_MAX 1024/* * Caller must free returned buffer.  Used if we don't * have readline, and when reading init or command files. * No line editing or history. */static char *basic_get_input(char *prompt){	char *input;	input = malloc(INPUT_MAX);	if (!input)	    	return NULL;	while (1) {	    	if (prompt)		{			printf("%s", prompt);			fflush(stdout);		}		if (fgets(input, INPUT_MAX, instream))			break;		else		{			if (feof(instream))			{				free(input);				return NULL;			} else				/* Ignore error and try again */				clearerr(instream);		}	}	input[strlen(input)-1] = '\0';  /* Remove trailing CR */	return input;}#if HAVE_LIBREADLINE#include <readline/readline.h>#include <readline/history.h>/* Caller must free returned buffer */static char *get_input(char *prompt){	char *input;	input = readline(prompt);	if (input && *input)	    	add_history(input);    	return input;}static voidreadline_init(void){    	/*	 * Could do fancy command completion someday, but for	 * now, at least disable the default filename completion.	 */    	rl_bind_key('\t', rl_insert);}#elsestatic char *get_input(char *prompt){    	return basic_get_input(prompt);}static void readline_init(void) {}#endifstatic char *command_line_input(char *prompt){    	if (instream == stdin)		return get_input(prompt);	/* Reading from init or command file; no prompting or history */	return basic_get_input(NULL);}intcmd_exit(int argc, char **argv){	return (CMD_EXIT);}int help_common(int argc, char **argv, struct cmd_tbl_entry *cmd_table){/*	int i;*/	struct cmd_tbl_entry *ctp;	if (argc > 1)	{		/* Single command help */		int found = 0;		ctp = cmd_table;		while (ctp->command)		{			if (strcasecmp(ctp->command, argv[1]) == 0)			{				printf("%s: %s\n", ctp->command, ctp->help);				printf("Usage: %s\n", ctp->usage);				found++;				break;			}			ctp++;		}		if (!found)		{			printf("help: %s: no such command\n", argv[1]);		}	}	else	{			/* Print help */		printf("Available commands are :-\n");		ctp = cmd_table;		while (ctp->command)		{			if ((ctp->flags & FLAG_HIDDEN) == 0)				printf("	%s\n", ctp->usage);			ctp++;		}		printf("\nTry \"help <command>\" for further help\n");	}	return (CMD_OK);}intcmd_help(int argc, char **argv){	help_common(argc, argv, root_cmd_table);	return (CMD_OK);}intcmd_date(int argc, char **argv){	struct tm *tm;	time_t now;	now = time(NULL);	tm = localtime(&now);	printf("%s", asctime(tm));	return (CMD_OK);}intcmd_rem(int argc, char **argv){	return (CMD_OK);}struct timeval log_start;static voidlog_timestamp(char *prefix){    	struct timeval tv;	long sec, usec;	gettimeofday(&tv, NULL);	if (tv.tv_usec < log_start.tv_usec)	{	    	tv.tv_usec += 1000*1000;		tv.tv_sec--;	}	sec = tv.tv_sec - log_start.tv_sec;	usec = tv.tv_usec - log_start.tv_usec;	fprintf(global_logfp, "%s %04d.%03d ", prefix, sec, usec / 1000);}static voidlog_command(int argc, char **argv){    	int i;    	if (!global_logfp)	    	return;	log_timestamp(">");	for (i = 0; i < argc; i++)	    	fprintf(global_logfp, " %s", argv[i]);	fprintf(global_logfp, "\n");}intcmd_log(int argc, char **argv){    	char *file;	struct stat buf;	time_t now;	int i;	if (global_logfp != NULL)	{		printf("Already logging\n");		return(CMD_FAILED);	}	/* Turn on logging */	if (argc > 1)	    	file = argv[1];	else	{	    	file = malloc(20);		if (!file)		{		    	printf("Can't allocate space for filename\n");		    	return(CMD_FAILED);		}		for (i = 0; i < 99; i++)		{			sprintf(file, "log.%02d", i);			if (stat(file, &buf) == -1			    && errno == ENOENT)			    	break;		}		if (i > 99)		{		    	printf("Can't create log.<nn>\n");			free(file);			return(CMD_FAILED);		}	}	global_logfp = fopen(file, "w");	if (global_logfp == NULL)	{		printf("Failed to create log file %s\n", file);		free(file);		return(CMD_FAILED);	}	now = time(NULL);	gettimeofday(&log_start, NULL);	fprintf(global_logfp, "%s\n", LOG_FORMAT);	log_timestamp("#");	fprintf(global_logfp, "logging started at %s",		asctime(localtime(&now)));	printf("Logging to file %s\n", file);	free(file);	return (CMD_OK);}intcmd_stoplog(int argc, char **argv){	/* Turn off logging */	if (global_logfp == NULL)	{		printf("Logging was not on\n");		return(CMD_FAILED);	}	fclose(global_logfp);	global_logfp = NULL;	return (CMD_OK);}intcmd_play(int argc, char **argv){	FILE *fp;	int linenr;	/* Turn on logging for monitor mode */	if (argc < 2)		return(CMD_USAGE);	fp = fopen(argv[1], "r");	if (fp == NULL)	{		printf("Failed to open log file %s\n", argv[1]);		return(CMD_FAILED);	}	linenr = 0;	/* Read data file in */	/* XXX logging */	/* Loop and call display routines */	while (1)	{			int ch;		printf("DATE:	+/- to step, S/E to goto start or end, Q to quit\n");		ch = getc(stdin);		switch (ch)		{		case '-':		case '+':		case 'E':		case 'e':		case 'S':		case 's':		case 'Q':		case 'q':			break;		}			}	fclose(fp);	return (CMD_OK);}intcmd_watch(int argc, char **argv){	int rv;	diag_l2_conn_t *d_l2_conn;	diag_l3_conn_t *d_l3_conn;	int fd;	int rawmode = 0;	int nodecode = 0;	int nol3 = 0;	if (argc > 1)	{		if (strcasecmp(argv[1], "raw") == 0)			rawmode = 1;		else if (strcasecmp(argv[1], "nodecode") == 0)			nodecode = 1;		else if (strcasecmp(argv[1], "nol3") == 0)			nol3 = 1;		else		{			printf("Don't understand \"%s\"\n", argv[1]);			return(CMD_USAGE);		}	}	rv = diag_init();	if (rv != 0)	{		fprintf(stderr, "diag_init failed\n");		return(-1);	}	fd = diag_l2_open(set_interface, set_subinterface, set_L1protocol);	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_FAILED);	}	if (rawmode)		d_l2_conn = diag_l2_StartCommunications(fd, DIAG_L2_PROT_RAW,			0, set_speed, 			set_destaddr, 			set_testerid);	else		d_l2_conn = diag_l2_StartCommunications(fd, set_L2protocol,			DIAG_L2_TYPE_MONINIT, set_speed, set_destaddr, set_testerid);	if (d_l2_conn == 0)	{		printf("Failed to connect to hardware in monitor mode\n");		return(CMD_FAILED);	}	if (rawmode == 0) 	{		/* Put the SAE J1979 stack on top of the ISO device */		if (nol3 == 0)		{			d_l3_conn = diag_l3_start("SAEJ1979", d_l2_conn);			if (d_l3_conn == NULL)			{				printf("Failed to enable SAEJ1979 mode\n");				return(CMD_FAILED);			}		}		else			d_l3_conn = NULL;		printf("Waiting for data to be received\n");		while (1)		{			if (d_l3_conn)				rv = diag_l3_recv(d_l3_conn, 10000,					j1979_watch_rcv,					(nodecode) ? NULL:(void *)d_l3_conn);			else				rv = diag_l2_recv(d_l2_conn, 10000,					j1979_watch_rcv, NULL);			if (rv == 0)				continue;			if (rv == DIAG_ERR_TIMEOUT)				continue;		}	}	else	{		/*		 * And just read stuff, callback routine will print out the data		 */		printf("Waiting for data to be received\n");		while (1)		{			rv = diag_l2_recv(d_l2_conn, 10000,				j1979_data_rcv, (void *)RQST_HANDLE_WATCH);			if (rv == 0)				continue;			if (rv == DIAG_ERR_TIMEOUT)				continue;			printf("recv returns %d\n", rv);			break;		}	}	return(CMD_OK);}struct pid;typedef void (formatter)(char *, int, struct pid *, response_t *, int);#define DATA_VALID(p, d)	(d[p->pid].type == TYPE_GOOD)#define DATA_1(p, n, d)		(d[p->pid].data[n])#define DATA_2(p, n, d)		(DATA_1(p, n, d) * 256 + DATA_1(p, n+1, d))#define DATA_RAW(p, n, d)	(p->bytes == 1 ? DATA_1(p, n, d) : \	    					 DATA_2(p, n, d))#define DATA_SCALED(p, v)	(v * p->scale1 + p->offset1)#define DATA_ENGLISH(p, v)	(v * p->scale2 + p->offset2)struct pid {	int	pid;	char	*desc;	formatter *sprintf;	int	bytes;	char	*fmt1;		// SI	double	scale1;	double	offset1;	char	*fmt2;		// English (typically)	double	scale2;	double	offset2;};

⌨️ 快捷键说明

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