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

📄 scantool.c

📁 Freediag contains various drivers (ISO9141, ISO14230, SAEJ1850-VPW, SAEJ1850-PWM) for different adap
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (mode > J1979_MODE_MAX)		return(-1);	else		msg.len = mode_lengths[mode];		msg.data = data;	data[0] = mode;	data[1] = p1;	data[2] = p2;	data[3] = p3;	data[4] = p4;	data[5] = p5;	data[6] = p6;	data[7] = p7;	diag_l3_send(d_conn, &msg);	/* And get response(s) within a short while */	rv = diag_l3_recv(d_conn, 300, j1979_data_rcv, handle);	if (rv < 0)	{		/* Try again */		if (diag_cmd_debug > 0xF8)		{			printf("retry\n");		}		diag_l3_send(d_conn, &msg);		rv = diag_l3_recv(d_conn, 300, j1979_data_rcv, handle);		if (rv < 0)		{			rv = do_l3_md1pid0_rqst(global_l2_conn);			if (rv < 0)				printf("resync failed, connection to ECU may be lost");			return(rv);		}	}	switch ((u_int32_t)handle)	{	/* We dont process the info in watch/decode mode */	case RQST_HANDLE_WATCH:	case RQST_HANDLE_DECODE:		return(rv);	}	/*	 * Go thru the ecu_data and see what was received.	 */	for (i=0, ep=ecu_info; i<ecu_count; i++, ep++)	{		if (ep->rxmsg)		{			/* Some data arrived from this ecu */			rxmsg = ep->rxmsg;			rxdata = ep->rxmsg->data;			switch (mode)			{			case 1:				if (rxdata[0] != 0x41)				{					ep->mode1_data[p1].type = TYPE_FAILED;					break;				}				memcpy(ep->mode1_data[p1].data, rxdata,					rxmsg->len);				ep->mode1_data[p1].len = rxmsg->len;				ep->mode1_data[p1].type = TYPE_GOOD;				break;			case 2:				if (rxdata[0] != 0x42)				{					ep->mode2_data[p1].type = TYPE_FAILED;					break;				}				memcpy(ep->mode2_data[p1].data, rxdata,					rxmsg->len);				ep->mode2_data[p1].len = rxmsg->len;				ep->mode2_data[p1].type = TYPE_GOOD;				break;			}			}	}	return(0);}/* * Send some data to the ECU (L3) */intl3_do_send(diag_l3_conn_t *d_conn, char *data, int len, void *handle){	diag_msg_t	msg;	int rv;	/* Put in src/dest etc, L3 or L2 may override/ignore them */	msg.src = set_testerid;	msg.dest = set_destaddr;	msg.len = len;		msg.data = data;	diag_l3_send(d_conn, &msg);	/* And get response(s) */	rv = diag_l3_recv(d_conn, 300, j1979_data_rcv, handle);	return (rv);}/* *  Same but L2 type */intl2_do_send(diag_l2_conn_t *d_conn, char *data, int len, void *handle){	diag_msg_t	msg;	int rv;	/* Put in src/dest etc, L2 may override/ignore them */	msg.src = set_testerid;	msg.dest = set_destaddr;	msg.len = len;		msg.data = data;	diag_l2_send(d_conn, &msg);	/* And get response(s) */	rv = diag_l2_recv(d_conn, 300, l2raw_data_rcv, handle);	return (rv);}/* * Common start routine used by all protocols * - initialises the diagnostic layer * - opens a Layer 2 device for the specified Layer 1 protocol * If necessary tries to poll the ECU * returns L2 file descriptor */diag_l2_conn_t * do_l2_common_start(int L1protocol, int L2protocol,	u_int32_t type, int bitrate, u_int8_t target, u_int8_t source ){	int rv, fd;	diag_l2_conn_t *d_conn = NULL;	int l2flags;	/* Clear out all ECU data as we're starting again */	clear_data();	rv = diag_init();	if (rv != 0)	{		fprintf(stderr, "diag_init failed\n");		return(NULL);	}	rv = diag_l2_open(set_interface, set_subinterface, L1protocol);	if (rv < 0)	{		if ((rv != DIAG_ERR_BADIFADAPTER) &&			(rv != DIAG_ERR_PROTO_NOTSUPP))				printf("Failed to open hardware interface\n");		return(NULL);	}	fd = rv;	/* Now do the Layer 2 startcommunications */	d_conn = diag_l2_StartCommunications(fd, L2protocol, type,		bitrate, target, source);	if (d_conn == NULL)	{		diag_l2_close(fd);		return(NULL);	}	/*	 * Now Get the L2 flags, and if this is a network type where	 * startcommunications always works, we have to try and see if	 * the ECU is there	 *	 * Some interface types will always return success from StartComms()	 * but you only know if the ECU is on the network if you then can	 * send/receive data to it in the appropriate format.	 * For those type of interfaces we send a J1979 mode1 pid1 request	 * (since we are a scantool, thats the correct thing to send)	 */	if (diag_l2_ioctl(d_conn, DIAG_IOCTL_GET_L2_FLAGS, &l2flags) != 0)	{		printf("Failed to get Layer 2 flags\n");		diag_l2_close(fd);		return(NULL);	}	if (l2flags & DIAG_L2_FLAG_CONNECTS_ALWAYS)	{		rv = do_l3_md1pid0_rqst(d_conn);		if (rv < 0)		{			/* Not actually there, close L2 and go */			diag_l2_close(fd);			return(NULL);		}	}	return(d_conn);}/* * Send a mode1 pid1 request and wait for a response. This is used to * (a) See if there is an ECU there * (b) Error recovery if we get multiple timeouts on an ECU * * It cant use the normal request routine, since that calls this * * * XXX This is wrong and needs to talk to L3 not L2, so this breaks * on ISO9141 type interfaces */int do_l3_md1pid0_rqst( diag_l2_conn_t *d_conn ){	diag_msg_t	msg;	diag_msg_t	*rmsg;	u_int8_t data[256];	int rv;	int errval = DIAG_ERR_GENERAL;	/* Create mode 1 pid 0 message */	msg.src = set_testerid;	msg.dest = set_destaddr;	msg.len = 2;	msg.data = data;	data[0] = 1;	data[1] = 0;	// Do a L2 request ...	rmsg = diag_l2_request(d_conn, &msg, &errval);	if (rmsg != NULL)	{		/* Check its a Mode1 Pid0 response */			if (rmsg->len < 1)		{			return(DIAG_ERR_BADDATA);			}		if (rmsg->data[0] != 0x41)		{			return(DIAG_ERR_BADDATA);			}		return(0);	}	return(errval);}/* * 9141 init */int do_l2_9141_start(int destaddr){	diag_l2_conn_t *d_conn;	d_conn = do_l2_common_start(DIAG_L1_ISO9141, DIAG_L2_PROT_ISO9141_2,		DIAG_L2_TYPE_SLOWINIT, set_speed, (u_int8_t)destaddr,		set_testerid);	if (d_conn == NULL)		return(-1);	/* Connected ! */	global_l2_conn = d_conn;	return(0);}/* * 14120 init */intdo_l2_14230_start(int init_type){	diag_l2_conn_t *d_conn;	int flags = 0;	if (set_addrtype == 1)		flags = DIAG_L2_TYPE_FUNCADDR;	else		flags = 0;	flags |= DIAG_L2_IDLE_J1978;	/* Use J1978 idle msgs */	flags |= (init_type & DIAG_L2_TYPE_INITMASK) ;	d_conn = do_l2_common_start(DIAG_L1_ISO14230, DIAG_L2_PROT_ISO14230,		flags, set_speed, 0x33, set_testerid);	if (d_conn == NULL)		return(-1);	/* Connected ! */	global_l2_conn = d_conn;	return(0);}/* * J1850 init, J1850 interface type passed as l1_type */intdo_l2_j1850_start(int l1_type){	int fd, rv;	int flags = 0;	diag_l2_conn_t *d_conn;	d_conn = do_l2_common_start(l1_type, DIAG_L2_PROT_SAEJ1850,		flags, set_speed, 0x6a, set_testerid);	if (d_conn == NULL)		return(-1);	/* Connected ! */	global_l2_conn = d_conn;	return(0);}/* * Generic init, using parameters set by user */do_l2_generic_start(void){	diag_l2_conn_t *d_conn;	int fd, rv;	int flags = 0;	rv = diag_init();	if (rv != 0)	{		fprintf(stderr, "diag_init failed\n");		return(-1);	}	/* Open interface using hardware type ISO14230 */	fd = diag_l2_open(set_interface, set_subinterface, set_L1protocol);	if (fd < 0)	{		if ((fd != DIAG_ERR_BADIFADAPTER) &&			(fd != DIAG_ERR_PROTO_NOTSUPP))			printf("Failed to open hardware interface protocol %d\n",				set_L1protocol);		return(-1);	}	if (set_addrtype == 1)		flags = DIAG_L2_TYPE_FUNCADDR;	else		flags = 0;	flags |= (set_initmode & DIAG_L2_TYPE_INITMASK) ;	d_conn = diag_l2_StartCommunications(fd, set_L2protocol,		flags, set_speed, set_destaddr, set_testerid);	if (d_conn == NULL)	{		diag_l2_close(fd);		return(-1);	}	/* Connected ! */		global_l2_conn = d_conn;	global_l2_fd = fd;	/* Saved for close */	return(0);}/* * Gets the data for every supported test * * Returns <0 on failure, 0 on good and 1 on interrupted * * If Interruptible is 1, then this is interruptible by the stdin * becoming ready for read (using diag_os_read() with a timeout of 0) * * It is used in "Interuptible" mode when doing "monitor" command */intdo_j1979_getdata(int interruptible){	int i,j, rv;	diag_l3_conn_t *d_conn;	ecu_data_t *ep;	diag_msg_t *msg;	d_conn = global_l3_conn;	/*	 * Now get all the data supported	 */	for (i=3; i<0x100; i++)	{		if (merged_mode1_info[i])		{			rv = l3_do_j1979_rqst(d_conn, 0x1, i, 0x00,				0x00, 0x00, 0x00, 0x00, 0x00, (void *)0);			if (rv < 0)			{				printf("Mode 1 Pid 0x%x request failed %d\n",					i, rv);			}			else			{				msg = find_ecu_msg(0, 0x41);				if (msg == NULL)					printf("Mode 1 Pid 0x%x request no-data %d\n",					i, rv);			}			if (interruptible)			{				rv = diag_os_read(fileno(stdin), NULL, 0, 0);				if (rv == 0)					return(1);			}		}	}	/* Get mode2/pid2 (DTC that caused freezeframe) */	rv = l3_do_j1979_rqst(d_conn, 0x2, 2, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, (void *)0);	if (rv < 0) 	{		printf("Mode 2 Pid 2 request failed %d\n", rv);		return(0);	}	msg = find_ecu_msg(0, 0x42);	if (msg == NULL)	{		printf("Mode 2 Pid 2 request no-data %d\n", rv);		return(0);	}	/* Now go thru the ECUs that have responded with mode2 info */	for (j=0, ep=ecu_info; j<ecu_count; j++, ep++)	{		if ( (ep->mode1_data[2].type == TYPE_GOOD) &&			(ep->mode1_data[2].data[2] |				ep->mode1_data[2].data[3]) )		{			for (i=3; i<=0x100; i++)			{				if (ep->mode2_info[i])				{					rv = l3_do_j1979_rqst(d_conn, 0x2, i, 0x00,						0x00, 0x00, 0x00, 0x00, 0x00, (void *)0);					if (rv < 0)					{						printf("Mode 2 Pid 0x%x request failed %d\n", i, rv);					}					msg = find_ecu_msg(0, 0x42);					if (msg == NULL)					{						printf("Mode 2 Pid 2 request no-data %d\n", rv);						return(0);					}									}				if (interruptible)				{					rv = diag_os_read(fileno(stdin), NULL, 0, 0);					if (rv == 0)					{						return(1);					}				}			}		}	}	return(0);}/* * Find out basic info from the ECU (what it supports, DTCs etc) * * This is the basic work horse routine */voiddo_j1979_basics(){	diag_l3_conn_t *d_conn;	ecu_data_t *ep;	int i;	int o2monitoring = 0;	d_conn = global_l3_conn;	/*	 * Get supported PIDs and Tests etc	 */	do_j1979_getpids();	global_state = STATE_SCANDONE ;	/*	 * Get current DTCs/MIL lamp status/Tests supported for this ECU	 * and test, and wait for those tests to complete	 */	do_j1979_getdtcs();	/*	 * Get data supported by ECU, non-interruptibly	 */	do_j1979_getdata(0);	/*	 * And now do stuff with that data	 */	for (i=0, ep=ecu_info; i<ecu_count; i++, ep++)	{		if ( (ep->mode1_data[2].type == TYPE_GOOD) &&			(ep->mode1_data[2].data[2] | ep->mode1_data[2].data[3]) )		{			printf("ECU %d Freezeframe data exists, caused by DTC ",				i);			print_single_dtc(ep->mode1_data[2].data[2] , ep->mode1_data[2].data[3]);			printf("\n");		}		if (ep->mode1_data[0x1c].type == TYPE_GOOD)		{			printf("ECU %d is ", i);			switch(ep->mode1_data[0x1c].data[2])			{			case 1:				printf("OBD II (California ARB)");				break;			case 2:				printf("OBD (Federal EPA)");				break;			case 3:				printf("OBD and OBD II");				break;			case 4:				printf("OBD I");				break;			case 5:				printf("not OBD");				break;			case 6:				printf("EOBD (Europe)");				break;			default:				printf("unknown (%d)", ep->mode1_data[0x1c].data[2]);				break;			}			printf(" compliant\n");		}		/*		 * If ECU supports Oxygen sensor monitoring, then do O2 sensor		 * stuff		 */		if ( (ep->mode1_data[1].type == TYPE_GOOD) &&			(ep->mode1_data[1].data[4] & 0x20) )		{			o2monitoring = 1;		}	}	do_j1979_getO2sensors();	if (o2monitoring > 0)	{		do_j1979_O2tests();	}	else	{		printf("Oxygen (O2) sensor monitoring not supported\n");	}}print_single_dtc(u_int8_t d0, u_int8_t d1){	char db[2];	db[0] = d0;	db[1] = d1;	printf("%s", diag_dtc_decode(db, 2, set_vehicle, set_ecu,		DIAG_DTC_PROTOCOL_J2012) );	return (0);

⌨️ 快捷键说明

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