📄 diag_l3.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 + -