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

📄 diag_l0_me.c

📁 Freediag contains various drivers (ISO9141, ISO14230, SAEJ1850-VPW, SAEJ1850-PWM) for different adap
💻 C
📖 第 1 页 / 共 2 页
字号:

	if (diag_l0_debug & DIAG_DEBUG_IOCTL)
		fprintf(stderr, "%s: device fd %d info %x initbus type %d proto %d\n",
			DIAG_MODULE, fd, dev, in->type,
			dev ? dev->dev_protocol : -1);

	if (!dev)
		return(-1);

	/* Empty our Receive buffer and wait for idle bus */
	(void)diag_os_read( fd, cbuf, sizeof(cbuf), 200);

	if (in->type == DIAG_L1_INITBUS_5BAUD)
		rv = diag_l0_muleng_slowinit(fd, in, dev);
	else
	{
		/* Do wakeup on first TX */
		dev->dev_wakeup = in->type;
		dev->dev_state = MULENG_STATE_FASTSTART;
	}

	return(rv);
}

/*
 * Set speed/parity etc
 *
 * If called by the user then we ignore what he says and use 19200
 * 8 none 1
 */
diag_l0_muleng_setspeed(int fd, int speed, int bits,
		int stop_bits, int parflag )
{
	struct diag_l0_muleng_device *dev;

	dev = diag_l0_muleng_finddev(fd);	/* Find dev for this fd */

	return (diag_os_tty_setup(fd, &dev->dev_ttystate, 19200, 8, 1,
				DIAG_L1_PAR_N) );
}

/*
 * Routine to read a whole ME message
 * which is 14 bytes
 */
diag_l0_muleng_getmsg(int fd, u_int8_t *dp)
{
	int offset = 0;
	int cnt;

	while (offset != 14)
	{
		cnt = diag_os_read(fd, &dp[offset], 14 - offset, 200);
		if (cnt < 0)
			return(cnt);
		offset += cnt;
	}
	return(offset);
}

/* 
 * Safe write routine
 */
diag_l0_muleng_write(int fd, char *dp, int txlen)
{
	int cnt, i;

	if ( (diag_l0_debug & (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA)) ==
			(DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA) )
	{
		fprintf(stderr, "%s: device fd %d sending to ME device: ",
			DIAG_MODULE, fd);
		for (i=0; i<txlen; i++)
				fprintf(stderr, "0x%02x ", dp[i] & 0xff); 
		fprintf(stderr, "\n");
	}

	/*
	 * And send it to the interface
	 */
	while ((cnt = write(fd, dp, txlen)) != txlen)
	{
		/* Partial write */
		if (cnt <  0)
		{
			/* error */
			if (errno != EINTR)
			{
				perror("write");
				fprintf(stderr, "%s: write returned error %d !!\n", DIAG_MODULE, errno);
				return(-1);
			}
			/* errno - EINTR is OK */
		}
		/* Successfully wrote cnt bytes (or 0 && EINTR), so inc pointers and continue */
		txlen -= cnt;
		dp += cnt;
	}
	return(0);
}


/*
 * Send a load of data
 *
 * Returns 0 on success, -1 on failure
 *
 * This routine will do a fastinit if needed, but all 5 baud inits
 * will have been done by the slowinit() code
 */
diag_l0_muleng_send(int fd, int subinterface, char *data, int len)
{
	int cnt, i, cmd, rv;

	u_int8_t *dp;
	u_int8_t txbuf[1024];
	int txlen;
	u_int8_t kwpbuf[2];
	struct diag_l0_muleng_device *dev;

	dev = diag_l0_muleng_finddev(fd);	/* Find an unused diag block */

	if (diag_l0_debug & DIAG_DEBUG_WRITE)
	{
		fprintf(stderr, "%s: device fd %d send %d bytes protocol %d ",
			DIAG_MODULE, fd, len, dev->dev_protocol);
		if (diag_l0_debug & DIAG_DEBUG_DATA)
		{
			int i;
			for (i=0; i<len; i++)
				fprintf(stderr, "0x%x ", data[i] & 0xff); 
			fprintf(stderr, "\n");
		}
	}

	if (dev->dev_state == MULENG_STATE_RAW)
	{
		/* Raw mode, no pretty processing */
		rv = diag_l0_muleng_write(fd, data, len);
		return (rv);
	}
	
	/*
	 * Figure out cmd to send depending on the hardware we have been
	 * told to use and whether we need to do fastinit or not
	 */
	switch (dev->dev_protocol)
	{
	case DIAG_L1_ISO9141:
		cmd = 0x10;
		break;

	case DIAG_L1_ISO14230:
		if (dev->dev_wakeup == DIAG_L1_INITBUS_FAST)
			cmd = 0x87;
		else
			cmd = 0x88;
		dev->dev_wakeup = 0;	/* We've done the wakeup now */
		break;

	case DIAG_L1_J1850_VPW:
		cmd = 0x02;
		break;

	case DIAG_L1_J1850_PWM:
		cmd = 0x04;
		break;

	case DIAG_L1_CAN:
		cmd = 0x08;
		break;
	}

	/*
	 * Build message into send buffer, and calculate checksum and
	 * send it
	 */
	memset(txbuf, 0, sizeof(txbuf));

	txbuf[0] = INTERFACE_ADDRESS;
	txbuf[1] = cmd;
	txbuf[2] = len;
	memcpy(&txbuf[3], data, len);

	(void)diag_l0_muleng_txcksum(txbuf);
	rv = diag_l0_muleng_write(fd, txbuf, 15);

	return(rv);
}

/*
 * Get data (blocking), returns number of chars read, between 1 and len
 * If timeout is set to 0, this becomes non-blocking
 *
 * This attempts to read whole message, so if we receive any data, timeout
 * is restarted
 *
 * Messages received from the ME device are 14 bytes long, this will
 * always be called with enough "len" to receive the max 11 byte message
 * (there are 2 header and 1 checksum byte)
 */
diag_l0_muleng_recv(int fd , int subinterface, char *data, int len, int timeout)
{
	int cksum, cnt, i;

	struct diag_l0_muleng_device *dev;
	dev = diag_l0_muleng_finddev(fd);	/* Find an unused diag block */

	if (diag_l0_debug & DIAG_DEBUG_READ)
		fprintf(stderr,
			"%s: fd %d recv upto %d bytes timeout %d, rxlen %d offset %d\n",
			DIAG_MODULE, fd, len, timeout, dev->dev_rxlen, dev->dev_rdoffset);

	/*
	 * Deal with 5 Baud init states where first two bytes read by
	 * user are the keybytes received from the interface, and where
	 * we are using the interface in pass thru mode on ISO09141 protocols
	 */
	switch (dev->dev_state)
	{
	case MULENG_STATE_KWP_SENDKB1:
		if (len >= 2)
		{
			data[0] = dev->dev_kb1;
			data[1] = dev->dev_kb2;
			dev->dev_state =  MULENG_STATE_OPEN;
			return (2);
		}
		else if (len == 1)
		{
			*data = dev->dev_kb1;
			dev->dev_state = MULENG_STATE_KWP_SENDKB2;
			return (1);
		}
		return(0);	/* Strange, user asked for 0 bytes */
		

	case MULENG_STATE_KWP_SENDKB2:
		if (len >= 1)
		{
			*data = dev->dev_kb2;
			dev->dev_state =  MULENG_STATE_OPEN;
			return (1);
		}
		return(0);	/* Strange, user asked for 0 bytes */


	case MULENG_STATE_RAW:
		cnt = diag_os_read(fd, data, len, timeout);
		if (diag_l0_debug & DIAG_DEBUG_READ)
			fprintf(stderr, "%s: fd %d read %d bytes\n", DIAG_MODULE,
				fd, cnt);
		return (cnt);

	case MULENG_STATE_FASTSTART:
		/* Extend timeout for 1st recv */
		timeout = 200;
		dev->dev_state = MULENG_STATE_OPEN;
		/* Drop thru */
	default:		/* Some other mode */
		break;
	}

	if (dev->dev_rxlen >= 14)
	{
		/*
		 * There's a full packet been received, but the user
		 * has only asked for a few bytes from it previously
		 * Of the packet, bytes x[2]->x[11] are the network data
		 * others are header from the ME device
		 *
		 * The amount of data remaining to be sent to user is
		 * as below, -1 because the checksum is at the end
		 */
		int bufbytes = dev->dev_rxlen - dev->dev_rdoffset - 1;

		if (bufbytes <= len)
		{
			memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], bufbytes);
			dev->dev_rxlen = dev->dev_rdoffset = 0;
			return(bufbytes);
		}
		else
		{
			memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], len);
			dev->dev_rdoffset += len;
			return(len);
		}
	}

	/*
	 * There's either no data waiting, or only a partial read in the
	 * buffer, read some more
	 */

	while (dev->dev_rxlen < 14)
	{
		while ( (cnt = diag_os_read(fd, &dev->dev_rxbuf[dev->dev_rxlen],
			14 - dev->dev_rxlen, timeout)) <= 0)
		{
			if (cnt == DIAG_ERR_TIMEOUT)
				return (DIAG_ERR_TIMEOUT);
			if (cnt == 0)
			{
				/* Error, EOF */
				fprintf(stderr, "%s: read returned EOF !!\n", DIAG_MODULE);
				return(-1);
			}
			if (errno != EINTR)
			{
				/* Error, EOF */
				fprintf(stderr, "%s: read returned error %d !!\n", DIAG_MODULE, errno);
				return(-1);
			}
		}
		dev->dev_rxlen += cnt;
	}

	/* OK, got whole message */
	if (diag_l0_debug & DIAG_DEBUG_READ)
	{
		int i;
		fprintf(stderr,
			"%s: fd %d received from ME: ", DIAG_MODULE, fd);
		for (i=0; i < dev->dev_rxlen; i++)
				fprintf(stderr, "0x%x ",
					dev->dev_rxbuf[i] & 0xff); 
		fprintf(stderr, "\n");
	}
	/*
	 * Check the checksum, 2nd byte onward
	 */
	for (i=1, cnt = 0; i < 13; i++)
		 cnt += dev->dev_rxbuf[i];
	if ((cnt & 0xff) != dev->dev_rxbuf[13])
	{
/* XXX, we should deal with this properly rather than just printing a message */
		int i;
		fprintf(stderr,"Got bad checksum from ME device 0x%x != 0x%x\n",
			cnt & 0xff, dev->dev_rxbuf[13]);
		fprintf(stderr,"PC Serial port probably out of spec.\n");
		fprintf(stderr,"RX Data: ");
		for (i=0; i < dev->dev_rxlen; i++)
				fprintf(stderr, "0x%x ",
					dev->dev_rxbuf[i] & 0xff); 
		fprintf(stderr, "\n");
	}


	/*
	 * Check the type
	 */
	if (dev->dev_rxbuf[1] == 0x80)
	{
		/* It's an error message not a data frame */
		dev->dev_rxlen = 0;

		if (diag_l0_debug & DIAG_DEBUG_READ)
			fprintf(stderr,
				"%s: fd %d ME returns err 0x%x : s/w v 0x%x i/f cap. 0x%x\n",

				DIAG_MODULE, fd, dev->dev_rxbuf[3],
				dev->dev_rxbuf[2], dev->dev_rxbuf[4]);

		switch (dev->dev_rxbuf[3])
		{
		case 0x05:	/* No ISO response to request */
		case 0x07:	/* No J1850 response to request */
		case 0x0c:	/* No KWP response to request */
			return(DIAG_ERR_TIMEOUT);

		default:
			return(-1);
		}
		/* NOTREACHED */
	}

	dev->dev_rdoffset = 2;		/* Skip the ME header */

	/* Copy data to user */
	cnt = (len>11) ? 11 : cnt;
	cnt = (cnt>(13-dev->dev_rdoffset)) ? 13-dev->dev_rdoffset : cnt;

	memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], cnt);
	dev->dev_rdoffset += cnt;
	if (dev->dev_rdoffset == 13)
	{
		/* End of message, reset pointers */
		dev->dev_rxlen = 0;
		dev->dev_rdoffset = 0;
	}
	return(cnt);
}

int
diag_l0_muleng_getflags(int fd)
{
	/*
	 * ISO14230/J1850 protocol does L2 framing, ISO9141 doesn't
	 */
	struct diag_l0_muleng_device *dev;
	int flags;

	dev = diag_l0_muleng_finddev(fd);	/* Find an unused diag block */

	flags = 0;
	switch (dev->dev_protocol)
	{
	case DIAG_L1_J1850_VPW:
	case DIAG_L1_J1850_PWM:
			flags = DIAG_L1_DOESL2CKSUM;
			flags |= DIAG_L1_DOESL2FRAME;
			break;
	case DIAG_L1_ISO9141:
			flags = DIAG_L1_SLOW ;
/* XX does it ?		flags |= DIAG_L1_DOESL2CKSUM; */
			break;

 	case DIAG_L1_ISO14230:
			flags = DIAG_L1_SLOW | DIAG_L1_FAST | DIAG_L1_PREFFAST;
			flags |= DIAG_L1_DOESL2FRAME;
			flags |= DIAG_L1_DOESSLOWINIT;
			flags |= DIAG_L1_DOESL2CKSUM;
			break;

	}

	if (diag_l0_debug & DIAG_DEBUG_PROTO)
		fprintf(stderr,
			"%s: getflags fd %d proto %d flags 0x%x\n",
			DIAG_MODULE, fd, dev->dev_protocol, flags);

	return( flags );
}

⌨️ 快捷键说明

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