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

📄 diag_l3.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.
 *
 *************************************************************************
 *
 * L3 code, interface to diagnostic protocols such as SAEJ1979 (ODB II), VAG,
 * etc
 *
 *
 *
 * Timers. As most L3 protocols run idle timers, the hard work is done here,
 *	The timer code calls the L3 timer for each L3 connection with the
 *	time difference between "now" and the timer in the L3 connection
 *	structure, so L3 can quickly check to see if it needs to do a retry
 */

#include <stdlib.h>
#include <stdio.h>

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

#include <fcntl.h>
#include <string.h>
#include <errno.h>

#include <time.h>

#include "diag.h"
#include "diag_l1.h"
#include "diag_l2.h"
#include "diag_l3.h"
#include "diag_err.h"
#include "diag_general.h"

static char *cvsid = "$Id: diag_l3.c,v 1.4 2002/04/15 04:22:04 bjorn_helgaas Exp $";

int diag_l3_debug = 0;

#define DIAG_MODULE "diag_l3"

int diag_l3_j1979_start(diag_l3_conn_t *);
int diag_l3_j1979_stop(diag_l3_conn_t *);
int diag_l3_j1979_send(diag_l3_conn_t *, diag_msg_t *);
int diag_l3_j1979_recv(diag_l3_conn_t *, int timeout,
	void (* rcv_call_back)(void *handle ,diag_msg_t *) , void *);
char * diag_l3_j1979_decode(diag_l3_conn_t *, diag_msg_t *);
void diag_l3_j1979_timer(diag_l3_conn_t *, int ms);

int diag_l3_vag_start(diag_l3_conn_t *);
int diag_l3_vag_stop(diag_l3_conn_t *);
int diag_l3_vag_send(diag_l3_conn_t *, diag_msg_t *);
int diag_l3_vag_recv(diag_l3_conn_t *, int timeout,
	void (* rcv_call_back)(void *handle ,diag_msg_t *) , void *);
char * diag_l3_vag_decode(diag_l3_conn_t *, diag_msg_t *);


diag_l3_proto_t diag_l3_protocols[] =
{

	{ "SAEJ1979", diag_l3_j1979_start, diag_l3_j1979_stop,
		diag_l3_j1979_send, diag_l3_j1979_recv, NULL,
		diag_l3_j1979_decode, diag_l3_j1979_timer  },
	{ "VAG", diag_l3_vag_start, diag_l3_vag_stop,
		diag_l3_vag_send, diag_l3_vag_recv, NULL,
		diag_l3_vag_decode, NULL },
	{ "ISO14230", NULL, NULL, NULL, NULL, NULL, NULL }
};


diag_l3_conn_t	*diag_l3_list = NULL;

/*
 * Protocol start (connect a protocol on top of a L2 connection
 */
diag_l3_conn_t *
diag_l3_start(char *protocol, diag_l2_conn_t *d_l2_conn)
{
	diag_l3_conn_t *d_l3_conn = NULL;
	int i, rv;
	diag_l3_proto_t *dp;
	int found = 0;

	if (diag_l3_debug & DIAG_DEBUG_OPEN)
		printf("%s: start protocol %s l2 0x%x\n",
			DIAG_MODULE, protocol, d_l2_conn);


	/* Find the protocol */
	for (i=0, dp=diag_l3_protocols; i<ARRAY_SIZE(diag_l3_protocols); i++, dp++)
	{
		if (strcasecmp(protocol, dp->proto_name) == 0)
		{
			found = 1;
			break;
		}
	}

	if (found)
	{
		if (diag_l3_debug & DIAG_DEBUG_OPEN)
			printf("%s: start protocol %s found\n",
				DIAG_MODULE, dp->proto_name);
		/*
		 * Malloc us a L3
		 */
		d_l3_conn = calloc(1, sizeof(diag_l3_conn_t));
		if (d_l3_conn != NULL)
		{
			d_l3_conn->d_l3l2_conn = d_l2_conn;
			d_l3_conn->d_l3_proto = dp;

			/* Get L2 flags */
			(void)diag_l2_ioctl(d_l2_conn,
				DIAG_IOCTL_GET_L2_FLAGS,
				&d_l3_conn->d_l3l2_flags);

			/* Get L1 flags */
			(void)diag_l2_ioctl(d_l2_conn,
				DIAG_IOCTL_GET_L1_FLAGS,
				&d_l3_conn->d_l3l1_flags);

			/* Call the proto routine */
			rv = dp->diag_l3_proto_start(d_l3_conn);
			if (rv < 0)
			{
				free(d_l3_conn);
				d_l3_conn = NULL;
			}
		}
		/*
		 * Set time to now
		 */
		(void)gettimeofday(&d_l3_conn->timer, NULL);
		/*
		 * And add to list
		 */
		if (d_l3_conn)
		{
			d_l3_conn->next = diag_l3_list;
			diag_l3_list = d_l3_conn;
		}
	}

	if (diag_l3_debug & DIAG_DEBUG_OPEN)
		printf("%s: start returns 0x%x\n",
			DIAG_MODULE, d_l3_conn);

	return(d_l3_conn);
}

/*
 * Just call the appropriate protocol routine
 */
int diag_l3_stop(diag_l3_conn_t *d_l3_conn)
{
	diag_l3_conn_t *dl, *dlast;
	int rv;

	diag_l3_proto_t *dp = d_l3_conn->d_l3_proto;

	/* Remove from list */
	if (d_l3_conn == diag_l3_list)
	{
		/* 1st in list */
		diag_l3_list = d_l3_conn->next;
	} else {
		for ( dl = diag_l3_list->next, dlast = diag_l3_list;
				dl ; dl = dl->next )
		{
			if (dl == d_l3_conn)
			{
				dlast->next = dl->next;
				break;
			}
			dlast = dl;
		}
	}

	rv = dp->diag_l3_proto_stop(d_l3_conn);

	free(d_l3_conn);

	return(rv);
}

int diag_l3_send(diag_l3_conn_t *d_l3_conn, diag_msg_t *msg)
{
	int rv;
	diag_l3_proto_t *dp = d_l3_conn->d_l3_proto;

	(void)gettimeofday(&d_l3_conn->timer, NULL);
	rv = dp->diag_l3_proto_send(d_l3_conn, msg);

	return(rv);
}

int diag_l3_recv(diag_l3_conn_t *d_l3_conn, int timeout,
	void (* rcv_call_back)(void *handle ,diag_msg_t *) , void *handle)
{
	diag_l3_proto_t *dp = d_l3_conn->d_l3_proto;

	return(dp->diag_l3_proto_recv(d_l3_conn, timeout,
		rcv_call_back, handle));
}

char *diag_l3_decode(diag_l3_conn_t *d_l3_conn, diag_msg_t *msg)
{
	diag_l3_proto_t *dp = d_l3_conn->d_l3_proto;

	return(dp->diag_l3_proto_decode(d_l3_conn, msg));
}

int diag_l3_ioctl(diag_l3_conn_t *d_l3_conn, int cmd, void *data)
{
	int rv = 0;
	diag_l3_proto_t *dp = d_l3_conn->d_l3_proto;

	/* Call the L3 ioctl routine */
	if (dp->diag_l3_proto_ioctl)
		rv = dp->diag_l3_proto_ioctl(d_l3_conn, cmd, data);

	if (rv < 0)
		return(rv);

	/* And now the L2 ioctl routine, which will call the L1 one etc */
	rv = diag_l2_ioctl(d_l3_conn->d_l3l2_conn, cmd, data);

	return(rv);
}


void diag_l3_timer()
{
	/*
	 * Regular timer routine
	 * Call protocol specific timer
	 */
	diag_l3_conn_t *conn;
	struct timeval now;
	int ms, sec;

	(void)gettimeofday(&now, NULL);

	for (conn = diag_l3_list ; conn ; conn = conn->next )
	{
		/* Call L3 timer routine for this connection */
		diag_l3_proto_t *dp = conn->d_l3_proto;

		sec = (now.tv_sec - conn->timer.tv_sec);
		ms = ((now.tv_usec/1000) - (conn->timer.tv_usec/1000));
		if (ms < 0)
		{
			ms += 1000;
			sec--;
		}
		ms += (sec * 1000);

		if (dp->diag_l3_proto_timer)
			(void)dp->diag_l3_proto_timer(conn, ms);
	}
}

⌨️ 快捷键说明

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